Push won't show the new changes to a @track attribute. You need to actually assign a new value to the @track attribute. Here is a demo I wrote for you.
import { LightningElement, track, api } from 'lwc';
export default class App extends LightningElement {
@track optionList = [{label:'-- none --',value:''}];
@track value;
newValue;
newLabel;
setNewValue(event) {
this.newValue = event.target.value;
}
setNewLabel(event) {
this.newLabel = event.target.value;
}
addNewOption() {
this.optionList = [...this.optionList, {label: this.newLabel+'', value: this.newValue+''}];
this.newValue = '';
this.newLabel = '';
if(this.optionList.length===1) {
this.value = this.optionList[0].value;
}
}
}
<template>
<lightning-input
label="New Value"
name="new-value"
onchange={setNewValue}>
</lightning-input>
<lightning-input
label="New Label"
name="new-label"
onchange={setNewLabel}>
</lightning-input>
<lightning-button label="Add" onclick={addNewOption}>
</lightning-button>
<hr></hr>
<lightning-combobox
label="Choose One"
name="options"
placeholder="Choose One"
options={optionList}
value={value}>
</lightning-combobox>
</template>
Here, we use the spread syntax to copy the array (...this.optionList
) and add the new element. This allows us to trip the @track decorator and allow the UI to update.
Your not setting the value attribute for your options, it should be below format
[{ value: "abc", label: "ABC" },{ value: "xyz", label: "XYZ" }]
your Name value is not existing in to your options that's why it's not selected default, in your below Json data Acme is not existing options(Acme not equal abc/xyz).
{
"data": {"Name": "Acme","Age": "34","State": "TX"}, //Acme is
"Names": [{"label": "ABC"},{"label": "XYZ"}],
"RecordTypeName": "Manager"
}
i would recommend go through lightning combo box , you need to use onchange
event like like onchange="{! c.handleChange }"
to update the datalist with selected value.
---Update with onchange Event-- i don't recommenced to use UI
controls because UI name space going to be retired in summer 21 . i added onchange event componenet level not in tr
level. here is tested code
after change
cmp:
<aura:attribute name="dataList" type="List"/>
<aura:attribute name="changedrow" type="List"/>
<!--<aura:handler name="change" value="{!v.dataList}" action="{!c.handleDataListChange}"/>-->
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<div class="slds-is-relative slds-scrollable" >
<!-- MARKUP for the datatable-->
<table class="slds-table slds-table--bordered " role="grid">
<thead>
<tr>
<th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
<span class="slds-truncate" title="SegmentChannelName">Name</span>
<span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
</th>
<th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
<span class="slds-truncate" title="Creative">Age</span>
<span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
</th>
<th class="slds-is-sortable slds-is-resizable slds-text-title_caps" scope="col">
<span class="slds-truncate" title="Channel Start">State</span>
<span class="slds-assistive-text" aria-live="assertive" aria-atomic="true"></span>
</th>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.dataList}" var="row" indexVar="index">
<tr>
<td role="gridcell">
<lightning:combobox aura:id="Nameid"
label="Names"
required="true"
name="{!'' +'Nameid=>'+index}"
variant="label-hidden"
value="{!row.data.Name}"
options="{!row.Names}"
onchange="{!c.rowaction}"/>
</td>
<td role="gridcell">
<lightning:input aura:id="ageid" class="slds-cell-wrap" name="{!'' +'Ageid=>'+index}" value="{!row.data.Age}" onchange="{!c.rowaction}"/>
</td>
<td role="gridcell">
<lightning:input class="slds-cell-wrap" aura:id="stateid" name="{!'' +'Stateid=>'+index}" value="{!row.data.State}" onchange="{!c.rowaction}"/>
</td>
</tr>
</aura:iteration>
</tbody>
</table>
<lightning:card title="changed row">
<aura:iteration items="{!v.changedrow}" var="row" indexVar="index">
<p><lightning:formattedText value="{!row.data.Name}"/></p>
<p><lightning:formattedText value="{!row.data.Age}"/></p>
<p><lightning:formattedText value="{!row.data.State}"/></p>
</aura:iteration>
</lightning:card>
</div>
controller:
doInit : function(component, event, helper) {
const json = '[{"data": {"Name": "Acme","Age": "34","State": "TX"},"Names": [{"label": "Acme","value": "Acme"},{"label": "ABC","value": "abc"},{"label": "XYZ","value": "XYZ"}],"RecordTypeName": "Manager"},{"data": {"Name": "John","Age": "21","State": "NY"},"Names": [{"label": "MNM","value": "MNM"},{"label": "TTT","value": "TTT"},{"label": "John","value": "John"}],"RecordTypeName": "Employee"},{"data": {"Name": "Mark","Age": "23","State": "CA"},"Names": [{"label": "Mark","value": "Mark"},{"label": "CD","value": "CD"},{"label": "BD","value": "BD"}],"RecordTypeName": "Employee"}]';
const obj = JSON.parse(json);
component.set('v.dataList', obj);
console.log('dataList === ' + JSON.stringify(component.get('v.dataList')));
},
rowaction: function(component, event, helper){
var index = event.getSource().get("v.name");
var idAndindex = event.getSource().get("v.name").split("=>"),
datalist = component.get('v.dataList'),
changedvalue = event.getSource().get("v.value"),
currentrow = datalist[idAndindex[1]];
switch (idAndindex[0]){
case 'Nameid':
currentrow.Name = changedvalue;
break;
case 'Ageid':
currentrow.Age = changedvalue;
break;
case 'Stateid':
currentrow.State = changedvalue;
break;
}
var changedrows = [].concat(currentrow);
component.set("v.changedrow",changedrows);
datalist.splice(idAndindex[1] ,1, currentrow);
component.set("v.dataList",datalist);
},
Best Answer
This cannot be achieved through wired property. You should be using wired function as below:
For sorting, you can do custom sort as follows while assigning:
Note: You should remove
placeholder
from combobox