v-treeview #input calling method twice - javascript

I have added a treeview in my vue component and on the selecting node it should update an array and then show the checkbox as selected. Currently, I am stuck in a situation where I am selecting elements from the tree (which is a folder containing an item) and then going to another folder to select different items. When I am opening the folder I previously selected, it will remove all the selected elements.
Here is my code:
<v-treeview
:items="patchItemsTreeList"
v-model="selectedPatchItemUUIDs"
#input="onChangeOfPatchSelection"
:name="'patchItemsTree'"
:open="openParentNode"
:item-text="'text'"
:key="fold"
:open-all="openParentNode.length === 0"
:selection-type="selectionType"
selectable
open-on-click
dense
#input=onChangeOfPatchSelection
This method is called twice interrupting my logic and deleting my selected items from the array.

Try switching from #input to either #update:active or #update:open. In your case I believe that you need #update:active
<v-treeview
:items="patchItemsTreeList"
v-model="selectedPatchItemUUIDs"
#update:active="onChangeOfPatchSelection"
:name="'patchItemsTree'"
:open="openParentNode"
:item-text="'text'"
:key="fold"
:open-all="openParentNode.length === 0"
:selection-type="selectionType"
selectable
open-on-click
dense
/>
What this will do is instead of emitting the array of selected items, it will emit the open items instead.

Related

Retrieve updated array values when the same array is updated with different condition

I want to display a dropdown value based on selection of type in another dropdown in angular
Basically I have an array of values which I will filer it on the based on type selected which is working fine. below is the code of filtering.
filterMethod(){
if(type === 'P'){
this.filteredArray = this.relationArray.filter(ele=> this.personValue.includes(ele.name));
} else{
this.filteredArray = this.relationArray.filter(ele=> this.orgValue.includes(ele.name));
}
}
And in HTML I'm looping it.
<mat-select formControlName="relation" aria-owns="relationshipSelect">
<mat-option *ngFor="let rel of filteredArray" [value]="relation.name">
{{rel.value}}
............
This above HTML is basically a child component where user can multiple dropdown when clicked new button. i.e., another dropdown will come next to it and so on...
Here what is happening is after selecting the relation dropdown when user click new button another relation dropdown is coming but the existing relation dropdown value is vanished. If user fires the filterMethod() method the vanished value will come.
I suspect it is because of calling new button new instance will be created and array will be set to its original state.

Making use of the key attribute in React JS

I have an array of values coming from an API, it contains the list of values. I am mapping all these values in an array of cards (as mentioned in the code below). I need to extract the id of the selected element, it is stored in the key attribute. Is there a way to use/reference the value of the key attribute?
{data.map((item) => (
<Card key={item[0]} element={item} />
))}
I am developing a KaiOS app and hence cursor interactions (onClick or onHover) are restricted. There is a nav-focus attribute (maintained using a custom hook) which is used to determine if the current element is selected and used CSS to highlight it (as shown in the image below) on that basis. I don't want to maintain a state of the selected element as it would be updated every time I navigate amongst the cards.
I would like to know if there is a way to use the key attribute of the selected item
I don't want to maintain a state of the selected element as it would be updated every time I navigate amongst the cards.
State is the correct way, why the want for not using state.
Keys should be used for uniquely identifying items rendered as a list, e.g. using map() and shouldn't really be used as other props would be.
Use a key in the html. It will solve the problem you suggested. and it will get the selected item as an attribute by the getAttribute property.
<div>
<select onChange = {this.onSelect}>
<option key="1" language="english">English</option>
<option key="2" language="espanol">Espanol</option>
</select>
</div>
Now onSelect function which will console log the selected language:
onSelect=(event)=> {
const selectedIndex = event.target.options.selectedIndex;
console.log(event.target.options[selectedIndex].getAttribute('language'));
}

how to change other siblings value to in vue?

Playing aroud with vue with a todo list.
At this stage, I am able to show the list within and with an edit button, the text will be an input so I can edit the todo items. But for example if I have 10 items, and I clicked edit for item 2 and item 4 and item 5, then all these 3 items will change into input.
What I am thinking is if I click on item 4, item 2 will change back to text, so only one item will show input if edit clicked.
I have my template code as below
<td class="col-8">
<!-- if editable is false, show the checkbox and todo item -->
<div class="custom-control custom-checkbox" v-if="!editable">
{{ todo.item }}
</div>
<!-- if editable is true, turn item into an input so user can enter new value -->
<div v-else>
<input ref="editItem" type="text" class="form-control" :value="todo.item" #input="onInput">
</div>
</td>
<td class="col-2">
<button
class="btn btn-sm"
:class="editable ? 'btn-outline-success' : 'btn-outline-info'"
#click.prevent="editable ? onSave() : onEdit()">{{ editable ? 'save' : 'edit' }}
</button>
</td>
As I open up the vue inspect in chrome, I can see all items have their different data value.
How can I change others siblings' value?
Thanks in advance for any sugguestins and advices.
I wouldn't recommend you to change the value of another sibling, since you cannot be sure of the side-effects it can cause, obviously when you look at a todo list, it would feel like there are no side-effects but in general practice, a node should change elements that are below it in the parentage, neither above nor the siblings.
If you want to change elements above, its always drive via events. You let the parent know that something needs to be changed rather than changing it yourself.
This is what you can do here:
Rather using editable as a data property, use it as a prop to the TodoListItem component.
props: {
editable: {
type: Boolean,
default: false
},
}
When the Save/Edit button is clicked in the child component, rather than changing the value there itself, use events like so.
/** You should keep a deepCopy of the props if you are changing the state
of that object and then send the updated local data prop to the parent
as well for updation rather than changing the prop object.
NEVER CHANGE THE PROP OBJECT DIRECTLY. -> this.todoItem =
this.deepCopy(this.todo);
Do this in before mount hook of the child component.
**/
this.$emit('todo-item-action', action, todoItem);
Once this event is emitted, in the parent TodoList component, catch this event and change the state of the items like so:
<todo-list-item
v-for="todo in todos"
:key="todo['id']"
:todo="todo"
:editable="todo['editable']"
#todo-item-action="handleItemAction"
>
or if you don't want to mutate the todo object. here you can make sure editableItem is null if none is selected or only the active item ID is referred so that the prop will change and automatically other list item will become un-editable.
<todo-list-item
v-for="todo in todos"
:key="todo['id']"
:todo="todo"
:editable="editableItem === todo['id']"
#todo-item-action="handleItemAction"
>
The more you drive a component via events and props, the more re-usable it becomes. Always have an orchestrator component which manipulates these stateless components by handling events propogated by them and sending state via props.
This is the approach I have always followed and it always allow me to refactor cleanly and quickly.
Regards.

Can't load SelectTagHelper when using the multiple attribute

As a simple test I'm passing 2 lists to a javascript function, only the list without a multiple attribute populates, the second list does get the "select one or more items" option but not 1,2,3 and only after I lose focus from list2. Can anyone tell me how I can repopulate the multiselect?
<select id="lstTest"></select>
<select id="lstTest2" multiple="multiple"></select>
function TestList(obj) {
var x = $(obj);
x.append('<option value="">Select one or more items</option>');
x.append('<option value="1">1</option>');
x.append('<option value="2">2</option>');
x.append('<option value="3">3</option>');
}
Empty Lists
List 1 after javascript call
List 2 after javascript call
Turns out the select is referencing custom js to turn it into a checkbox list as a way of selecting the items instead of highlighting. I need to treat it as a checkbox list and not just a list of options, which I'm still not sure how to do, I need to clear and add new checkboxes.

How to select item(s) out of a FlatList?

I want to select items using FlatList like when you select multiple photos on your photo galery (in this case, I am using a flatlist with 2 rows like a grid of 2x10). I want to select (for example) 3 items using onLongPress.
Something like this, but with 2 rows.
What about this:
Every item rendered would have an onLongPress, and an isPicked property.
Initially, and in renderItem(), you would implement an if statement that either renders checked square or empty square every time an item executes executes; To indicate if the item is selected or not (based on isPicked).
onLongPress invokes isPicked and rerenders everything (to toggle the square). So if isPicked is true it becomes false, and if false becomes true. You can achieve that by simply doing this: this.item.isPicked = !this.item.isPicked
Finally on Submit, filter all your initial items (data) by the isPicked === true and hurrah, you will end up with the items that were selected !

Categories