What is the difference between (click) and (change) in Angular5? - angular5

I am new to angular5 and having trouble understanding the difference between (click) and (change):
<mat-row *matRowDef="let row; columns: displayedColumns; let i = index"
(click)="onSourceDatabaseChange($event, row,i)"
(change)="onSourceDatabaseChange($event, row, i)"
</mat-row>
When do they fire and what do they do?

(click) calls the specified function when a user clicks on the given element (in your example, when a user clicks on a row.
The (change) event binds to HTML's onChange event. This event is fired for <input>, <select>, and <textarea> elements when a change to the element's value is committed by the user.
The (change) event can also be specifically implemented by other Angular components. It is generally implemented on components where the contents of the component are changed by the user.

Related

Bootstrap Table row-clicked event

I'm using a <b-table> component in a Vue project and I need to define a function to be triggered when a row is clicked. I heard that there is a #row-clicked property in b-table so I tried to use it and I can put simple functions inside of it, I mean I can get console prints etc but nothing more complicated...
I want two functions to be executed when a row is clicked. The functions are now bound to a button inside of every row, but I dont want use it like this, I just need to click the related row to make them work. Here is the current version of the b-table component;
<b-table
:items="displayByType"
:fields="displayColumn"
responsive="sm"
:per-page="perPage"
:current-page="currentPage"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
:filter="filter"
:filter-included-fields="filterOn"
#filtered="onFiltered"
hover
#row-clicked="test"
>
And here is the two functions that I want to be triggered when a row is clicked...
toggleRightBar(){
document.body.classList.toggle("right-bar-enabled");
}
changeRightBarContent(row){
this.$store.dispatch("rightbar/changeRightBarInfo", tableData[row]);
},
There is a JavaScript folder that I export column names and row data. I also a have Rightbar, when a row is clicked, I want to enable the rightbar so that the user can see detailed information about that specific row.
At last, here is the button that I use to make these two functions work;
<template #cell(detail)="row">
<button #click="toggleRightBar(); changeRightBarContent(row.index);" class="btn btn-outline-primary toggle-right">
<i class="bx bx-detail toggle-right"></i>
</button>
</template>
Basically, I dont want to use this button, instead, I want to click the row itself. Every row's rightbar information will be uniqe, my function does that. I just dont know how to use these 2 functions inside #row-clicked
Thanks in advance.
The row-clicked event will pass 3 parameters to your function.
The first being the item specific to the row that was clicked. The second will be the index of the row, and the third is a native click event.
This means you can use the arguments keyword to get the index and pass it to your function.
#row-clicked="toggleRightBar(); changeRightBarContent(arguments[1])".
Alternatively you can create a third method which will call the other two.
<b-table #row-clicked="onRowClicked" />
{
onRowClicked(item, index, event) {
this.toggleRightBar();
this.changeRightBarContent(index);
}
}
You can read more about the #row-clicked event on the docs component reference section.
https://bootstrap-vue.org/docs/components/table#comp-ref-b-table-events

Using inner component in a loop in Shopware 6 does not persist the values uniquely for each looped component

I am using a v-for over a custom component and passing the item as a prop. But the issue is that each component instance in the loop takes the same item prop. For e.g in the 1st loop a component field has text "abc", then the second looped component also will have the same "abc" text. If I change the text in the 2nd one, it changes in the 1st component too. Is there a way to make the prop unique for each loop ?
For e.g this is the code which calls the inner component:
<template v-for="(businesscase, index) in businessCase.fields">
<custom-case-freetext-field #field-changed="updateFields"
:key="index"
#field-removed="removeFields"
:fields="businessCase.fields"
:index="index">
</custom-case-freetext-field>
</template>
and inside this component I have a basic form
<sw-field :label="$tc('rma.modules.case.freetext.nameLabel')"
:placeholder="$tc('rma.modules.case.freetext.nameLabel')"
required
v-model="fields[index].name">
</sw-field>
<sw-single-select
labelValue="label"
valueProperty="label"
:options="fieldTypes"
:label="$tc('rma.modules.case.freetext.fieldType')"
:placeholder="$tc('rma.modules.case.freetext.fieldType')"
v-model="fields[index].type"
#input="changeType"
required>
</sw-single-select>
If I do :value instead of v-model, the entered value disappears as soon as the element loses focus.
If I use v-model, the data stays there, but then both (or as many are there in the loop) component instances, have data binding between them, so it defeats the purpose of having a loop for multiple components. As seen in the screenshot, I am typing in the 2nd component, but it changes the text for the first one too.
In the above example I am sending the whole array as prop, but I have also tried with individual field element instead of fields
Your are not using the businesscase variable inside your components. And since every component always works on the upper scope property, they will all change the same. Use the innerscope property. If you have problems with reactivity, because you try to mutate props directly work with events emitting the key and the changed value to the upperscope component.

Why input is broken when value is the same?

I want to have a controlled input, and set keep its value unchanged on any input. The problem is: it works only when I type in for the first time (i.e. it's set to 1). But then it stops working and you can type in any value. Why?
<input :value="message" #input="message = 1" />
Sandbox: https://codesandbox.io/s/unruffled-fire-in9yn?file=/index.html:162-209
If all you want to do is prevent the user from changing the <input> value, you can do that with simple HTML. You don't need Vue at all.
<input value="1" readonly>
I don't recommend doing this, but this would achieve your expected behavior:
<input v-model="message" #input="message = 1" />
This works because it is a "2-way binding" using v-model, which means changes to the input's value are propagated automatically, so a state change is triggered, because the new value of input is propagated (in the state) and then message = 1 get triggered afterwards and triggers a state change which updates the input element.
The original using :value=message is one-way, so changes in value to the input box are not automatically propagated to your component's state, and so Vue just sees a component with the same value bound to the message prop and does not update.

VueJS vee-validate issue when passed validation as props to input component

I'm building an input component to work with vee-validate.
for more convenience, I want to use validation rules as a props for this.
Every thing is ok when I use v-model directive on parent. but, with value property; after writing in the field and validating, input value reset to it's parent.
This is logical? if not, how can I solve this problem without v-model?
Note that:
1) - Validations events are 'input' and 'blur'
2) - I never want to set v-on:input event on parent
See This Fiddle
This is logical.
#input="$emit('input', $event.target.value)" is useless here because you don't listen to the input event.
When your input is invalid, component is re-render again. value of input component has never change changed when you input. When it re-render, it will display correct value which is passed from parent.
https://jsfiddle.net/787g7q0e/

valueUpdate: 'afterkeydown' for input type="numeric" in Knockoutjs 2.0

[see fiddle for illustration]
I set up a value bind to an input of type number, and want the bound observable to immediately reflect changes to the value of the field. to do that I set the afterkeydown valueUpdate binding. This works well for changing the number input using the arrow up and arrow down keys. However, if I change the number using the browser-generated (tested in chrome) increment/decrement control the change is only reflected upon changing focus to a different element. I assume this reflects the default update upon change event.
My question is whether there is any way to set the update to occur for both changes using the up down keyboard errors and browser-generated up/down error controls?
The valueUpdate additional binding can take an array of events. It looks like the oninput event is fired when clicking on the up/down arrows.
So, you can bind it like:
<input type="number" data-bind="value: y, valueUpdate: ['afterkeydown', 'input']"/>
http://jsfiddle.net/rniemeyer/hY5T2/9/