I have a datatable that shows data from a record query on a specific object, it allows edits and it also has comboboxes for the multitude of picklists. Each combobox has the correct options for the picklists they represent...so that's not a problem. The problem is it shows all the comboboxes as blank, which is obvious as i haven't set a default value. By default value i mean the value which currently exists on the record, but how do i pass the field data from the datatable down to the combobox?
I know at the combobox level i have to have @api someVariable and then edit the extension to add that as an attribute...say 'currentvalue' as an attribute..
but take these two picklists turn editable combobox
{ label: 'EGM Config', fieldName: 'Machine_Configuration__c', type: 'picklist', editable: true, wrapText: true, typeAttributes: { fieldname :'Machine_Configuration__c', currentvalue 'what goes here?'} },
{ label: 'Denom', fieldName: 'To_Theme_Denom__c', type: 'picklist', editable: true,wrapText: true, typeAttributes: { fieldname :'To_Theme_Denom__c', currentvalue : 'what goes here?'} },
i'm not exactly sure how i'm supposed to pass the field value of that row into the combobox... but i'm guessing the data exists in config.data somewhere, but because it's multiple records stored in that i'm not sure how to get the value from config.data.thisDynamicRow.thisField then pass than as an attritube to the combobox
data table html:
<template>
<c-quote-line-items-table_ext
key-field="Id"
data={config.data}
columns={columns}
onsave={handleSave}
draft-values={draftValues}>
</c-quote-line-items-table_ext>
</template>
datatable js:
import { LightningElement, wire, api } from 'lwc';
import getConfig from '@salesforce/apex/quoteLineItemConfig_ctl.getConfigs';
import { refreshApex } from '@salesforce/apex';
import updateRecords from '@salesforce/apex/QuoteLineItemConfig_ctl.updateRecords';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getRecordNotifyChange } from 'lightning/uiRecordApi'
import getRowData from '@salesforce/apex/SObjectController2.getRowData';
const COLS = [
{ label: 'Cabinet', fieldName: 'Cabinet__c', editable: false },
{ label: 'Brand', fieldName: 'Brand__c', editable: false },
{ label: 'Theme', fieldName: 'To_Theme__c', editable: false },
{ label: 'Quantity', fieldName: 'Quantity__c', type: 'number', editable: true },
{ label: 'Incremental', fieldName: 'Incremental__c', type: 'boolean', editable: true },
{ label: 'Price', fieldName: 'Min_or_Flat_Fee_Amount__c', type: 'number', editable: true },
{ label: 'EGM Config', fieldName: 'Machine_Configuration__c', type: 'picklist', editable: true, wrapText: true, typeAttributes: { fieldname :'Machine_Configuration__c', value: {fieldName: 'Machine_Configuration__c'}, placeholder: {fieldName: 'Machine_Configuration__c'}}},
{ label: 'Denom', fieldName: 'To_Theme_Denom__c', type: 'picklist', editable: true, wrapText: true, typeAttributes: { fieldname :'To_Theme_Denom__c', value: {fieldName: 'To_Theme_Denom__c'}, placeholder: {fieldName: 'To_Theme_Denom__c'}}},
{ label: 'Form Factor', fieldName: 'Form_Factor__c', type: 'picklist', editable: true,wrapText: true, typeAttributes: { fieldname :'Form_Factor__c', value: {fieldName: 'Form_Factor__c'}, placeholder: {fieldName: 'Form_Factor__c'}}},
{ label: 'Sign?', fieldName: 'Sign__c', type: 'text', editable: false },
{ label: 'Merchandise', fieldName: 'Signage__c', type: 'text', editable: false},
{ label: 'Stand', fieldName: 'Stands__c', type: 'text', editable:false},
{ label: 'Seats', fieldName: 'Seats__c', type: 'text', editable: false },
{ label: 'Notes', fieldName: 'Notes__c', editable: true }
];
export default class quoteLineItemsTable extends LightningElement {
@api recordId;
columns = COLS;
draftValues = [];
@wire(getConfig, { recordId: '$recordId' })
config;
async handleSave(event) {
const updatedFields = event.detail.draftValues
const notifyChangeIds = updatedFields.map(row => {return { "recordId" : getRowData.Id}});
try {
const result = await updateRecords({data: updatedFields});
console.log(JSON.stringify('apex return ' + result));
this.dispatchEvent(
new ShowToastEvent({
title: 'Success',
messsage: 'Record Updated',
variant: 'succes'
})
);
getRecordNotifyChange(notifyChangeIds);
refreshApex(this.config).then(() => {
this.draftValues = [];
});
} catch (error) {
this.dispatchEvent(
new ShowToastEvent({
title: 'Error Updating or refreshing records',
message: 'error.body.message',
variant: 'error'
})
);
}
}
}
data table extension html
<template>
<c-quote-Dynamic-Combo record-id={value}
label={typeAttributes.label}
value={typeAttributes.value}
placeholder={typeAttributes.placeholder}
options={typeAttributes.options}
context={typeAttributes.context}
fieldname={typeAttributes.fieldname}
currentvalue={typeAttributes.currentvalue}>
</c-quote-Dynamic-Combo>
</template>
data table extension js
import LightningDatatable from 'lightning/datatable';
import dPicklist from './quoteCombo.html';
export default class quoteLineItemsTable_ext extends LightningDatatable {
static customTypes = {
picklist: {
template: dPicklist,
typeAttributes: ['label', 'placeholder', 'options', 'value', 'context','fieldname','currentvalue'],
},
};
}
the custom component aka a combobox html:
<template>
<lightning-combobox
label={Name}
placeholder="--none--"
value={value}
onchange={handleSelect}
options={pickVals}>
</lightning-combobox>
</template>
the js for the combobox
import { LightningElement,wire,api,track } from 'lwc';
import getPicklist from '@salesforce/apex/quoteLineItemConfig_ctl.getPicklist';
export default class quoteDynamicCombo extends LightningElement {
error;
@api fieldname;
@track choice;
@track pickVals;
@wire(getPicklist, { fieldname: '$fieldname'})
wiredpickList({ error, data }) {
if (data) {
this.pickVals = data.map((cls) => Object.assign({}, { label: cls.label, value: cls.value }));
} else if (error) {
this.error = error;
}
}
handleSelect(event) {
this.choice= event.detail.value;
}
}
the apex controller
public with sharing class quoteLineItemConfig_ctl {
Final Static String THEME_CONVERSION = 'Theme_Conversion__c';
public class customSelectOption {
public customSelectOption() {
this.value = '';
this.label = '';
}
public customSelectOption(String value, String label) {
this.value = value;
this.label = label;
}
@AuraEnabled
public String label { get;set; }
@AuraEnabled
public String value { get;set; }
}
@AuraEnabled (cacheable=true)
public static list <Theme_Conversion__c> getConfigs(string recordId){
return [SELECT Id, Cabinet__c, Brand__c, To_Theme__c, Quantity__c,Incremental__c,Min_or_Flat_Fee_Amount__c,To_Theme_Denom__c,Form_Factor__c, Machine_Configuration__c,Sign__c,Signage__c,Stands__c,Seats__c,Notes__c
FROM Theme_Conversion__c
WHERE Sales_Toolkit__c =: recordId];
}
@AuraEnabled
public static string updateRecords(Object data){
List<Theme_Conversion__c> configsForUpdate = (List<Theme_Conversion__c>) JSON.deserialize(
JSON.serialize(data),
List<Theme_Conversion__c>.class
);
try {
update configsForUpdate;
return 'Success: successfully updated';
}
catch(Exception e) {
return 'The following exception has occured: ' + e.getMessage();
}
}
@AuraEnabled(cacheable=true)
public static list<customSelectOption> getPicklist(string fieldname){
List<customSelectOption> options = new List<customSelectOption>();
String objectName = THEME_CONVERSION;
Schema.SObjectType sObjName = Schema.getGlobalDescribe().get(objectName);
Schema.DescribeSObjectResult SObjectDescribe = sObjName.getDescribe();
Map<String,Schema.SObjectField> fields = SObjectDescribe.fields.getMap() ;
Schema.DescribeFieldResult fieldResult = fields.get(fieldname).getDescribe();
List<Schema.PicklistEntry> ple = fieldResult.getPicklistValues();
for(schema.PicklistEntry plVal : ple){
options.add(new customSelectOption(plVal.getLabel(), plVal.getValue()));
}
return options;
}
}