- Click on the pen
- Choose value
- Use scroll bar to go down The whole field with values is moving down, it is not on the row. How can I set it in CSS? or maybe HTML?
lWCDatatableWithPicklist.css
.cardSpinner{
position: relative;;
}
lWCDatatableWithPicklist.js
import { LightningElement, track, wire } from 'lwc';
import fetchAccounts from '@salesforce/apex/AccountDataController.fetchAccounts';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import Customer_Segment__c_FIELD from '@salesforce/schema/Account.Customer_Segment__c';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { refreshApex } from '@salesforce/apex';
import { getPicklistValues, getObjectInfo } from 'lightning/uiObjectInfoApi';
const columns = [
{ label: 'Name', fieldName: 'Name', editable: true },
{ label: 'Phone', fieldName: 'Phone', type: 'phone', editable: true },
{
label: 'Type', fieldName: 'Customer_Segment__c', type: 'picklistColumn', editable: false, typeAttributes: {
placeholder: 'Choose Type', options: { fieldName: 'pickListOptions' },
value: { fieldName: 'Customer_Segment__c' }, // default value for picklist,
context: { fieldName: 'Id' } // binding account Id with context variable to be returned back
}
}
]
export default class CustomDatatableDemo extends LightningElement {
columns = columns;
showSpinner = false;
@track data = [];
@track accountData;
@track draftValues = [];
lastSavedData = [];
@track pickListOptions;
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
objectInfo;
//fetch picklist options
@wire(getPicklistValues, {
recordTypeId: "$objectInfo.data.defaultRecordTypeId",
fieldApiName: Customer_Segment__c_FIELD
})
wirePickList({ error, data }) {
if (data) {
this.pickListOptions = data.values;
} else if (error) {
console.log(error);
}
}
//here I pass picklist option so that this wire method call after above method
@wire(fetchAccounts, { pickList: '$pickListOptions' })
accountData(result) {
this.accountData = result;
if (result.data) {
this.data = JSON.parse(JSON.stringify(result.data));
this.data.forEach(ele => {
ele.pickListOptions = this.pickListOptions;
})
this.lastSavedData = JSON.parse(JSON.stringify(this.data));
} else if (result.error) {
this.data = undefined;
}
};
updateDataValues(updateItem) {
let copyData = JSON.parse(JSON.stringify(this.data));
copyData.forEach(item => {
if (item.Id === updateItem.Id) {
for (let field in updateItem) {
item[field] = updateItem[field];
}
}
});
//write changes back to original data
this.data = [...copyData];
}
updateDraftValues(updateItem) {
let draftValueChanged = false;
let copyDraftValues = [...this.draftValues];
//store changed value to do operations
//on save. This will enable inline editing &
//show standard cancel & save button
copyDraftValues.forEach(item => {
if (item.Id === updateItem.Id) {
for (let field in updateItem) {
item[field] = updateItem[field];
}
draftValueChanged = true;
}
});
if (draftValueChanged) {
this.draftValues = [...copyDraftValues];
} else {
this.draftValues = [...copyDraftValues, updateItem];
}
}
//listener handler to get the context and data
//updates datatable
picklistChanged(event) {
event.stopPropagation();
let dataRecieved = event.detail.data;
let updatedItem = { Id: dataRecieved.context, Type: dataRecieved.value };
console.log(updatedItem);
this.updateDraftValues(updatedItem);
this.updateDataValues(updatedItem);
}
//handler to handle cell changes & update values in draft values
handleCellChange(event) {
this.updateDraftValues(event.detail.draftValues[0]);
}
handleSave(event) {
this.showSpinner = true;
this.saveDraftValues = this.draftValues;
const recordInputs = this.saveDraftValues.slice().map(draft => {
const fields = Object.assign({}, draft);
return { fields };
});
// Updateing the records using the UiRecordAPi
const promises = recordInputs.map(recordInput => updateRecord(recordInput));
Promise.all(promises).then(res => {
this.showToast('Success', 'Records Updated Successfully!', 'success', 'dismissable');
this.draftValues = [];
return this.refresh();
}).catch(error => {
console.log(error);
this.showToast('Error', 'An Error Occured!!', 'error', 'dismissable');
}).finally(() => {
this.draftValues = [];
this.showSpinner = false;
});
}
handleCancel(event) {
//remove draftValues & revert data changes
this.data = JSON.parse(JSON.stringify(this.lastSavedData));
this.draftValues = [];
}
showToast(title, message, variant, mode) {
const evt = new ShowToastEvent({
title: title,
message: message,
variant: variant,
mode: mode
});
this.dispatchEvent(evt);
}
// This function is used to refresh the table once data updated
async refresh() {
await refreshApex(this.accountData);
}
}
lWCDatatableWithPicklist.html
<template>
<!-- header -->
<div class="slds-tabs_card">
<div class="slds-page-header">
<div class="slds-page-header__row">
<div class="slds-page-header__col-title">
<div class="slds-media">
<div class="slds-media__figure">
<span class="slds-icon_container slds-icon-standard-opportunity">
<lightning-icon icon-name="standard:recipe" alternative-text="recipe" title="recipe"></lightning-icon>
</span>
</div>
<div class="slds-media__body">
<div class="slds-page-header__name">
<div class="slds-page-header__name-title">
<h1>
<span>PickList In LWC Inline Datatable Edit</span>
<span class="slds-page-header__title slds-truncate" title="Recently Viewed">TechDicer</span>
</h1>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> <br/>
<!-- /header -->
<!-- create folder card -->
<lightning-card variant="Narrow" title="PickList In LWC Inline Datatable Edit" icon-name="standard:folder" class="cardSpinner">
<!-- loader -->
<div if:true={showSpinner}>
<lightning-spinner
alternative-text="Loading..." variant="brand">
</lightning-spinner>
</div>
<!-----/loader-------->
<div class="slds-var-p-around_small">
<template if:true={data}>
<c-l-w-c-custom-datatable-type
key-field="Id"
data={data}
columns={columns}
onpicklistchanged={picklistChanged}
onvalueselect={handleSelection}
draft-values={draftValues}
oncellchange={handleCellChange}
onsave={handleSave}
oncancel={handleCancel}
hide-checkbox-column>
</c-l-w-c-custom-datatable-type>
</template>
</div>
</lightning-card>
</template>
picklistColumn.css
.picklist-section{
margin-top: -1rem;
margin-left: -0.5rem;
position: fixed !important;
min-width: 10%;
z-index: 99999999999999999999999999;
}
.picklist-section .slds-dropdown{
position: fixed !important;
max-height: 120px;
max-width: fit-content;
overflow: auto;
}
picklistColumn.html
<template>
<div class="picklistSection" id="picklist">
<div if:true={showPicklist} class="picklist-section">
<lightning-combobox name="picklist" label={label} value={value} placeholder={placeholder} options={options} variant='label-hidden'
onchange={handleChange} onblur={closePicklist} class="slds-popover slds-popover_edit slds-popover__body" dropdown-alignment="auto"></lightning-combobox>
</div>
<div if:false={showPicklist} class="slds-table_edit_container slds-is-relative">
<span class="slds-grid slds-grid_align-spread slds-cell-edit">
<span class="slds-truncate" title={value}>{value}</span>
<button data-id={context} class="slds-button slds-button_icon slds-cell-edit__button slds-m-left_x-small" tabindex="-1" title="Edit" name="tes"
onclick={handleClick} data-name="myButtonName" >
<svg class="slds-button__icon slds-button__icon_hint slds-button__icon_lock slds-button__icon_small slds-button__icon_edit slds-icon slds-icon-text-default slds-icon_xx-small"
aria-hidden="true">
<use xlink:href="/_slds/icons/utility-sprite/svg/symbols.svg?cache=9.37.1#edit"></use>
</svg>
<span class="slds-assistive-text">Edit</span>
</button>
</span>
</div>
</div>
</template>
picklistColumn.js
import { LightningElement, api, track } from 'lwc';
import { loadStyle } from 'lightning/platformResourceLoader';
import LWCDatatablePicklist from '@salesforce/resourceUrl/LWCDatatablePicklist';
export default class PicklistColumn extends LightningElement {
@api label;
@api placeholder;
@api options;
@api value;
@api context;
@track showPicklist = false;
renderedCallback() {
Promise.all([
loadStyle(this, LWCDatatablePicklist),
]).then(() => { });
this.template.querySelector("lightning-combobox")?.focus();
}
closePicklist() {
this.showPicklist = false;
}
handleChange(event) {
//show the selected value on UI
this.value = event.detail.value;
//fire event to send context and selected value to the data table
this.dispatchEvent(new CustomEvent('picklistchanged', {
composed: true,
bubbles: true,
cancelable: true,
detail: {
data: { context: this.context, value: this.value }
}
}));
}
handleClick(event) {
this.showPicklist = true;
}
}
lWCCustomDatatableType.js
import LightningDatatable from 'lightning/datatable';
import picklistColumn from './picklistColumn.html';
export default class LWCCustomDatatableType extends LightningDatatable {
static customTypes = {
picklistColumn: {
template: picklistColumn,
standardCellLayout: true,
typeAttributes: ['label', 'placeholder', 'options', 'value', 'context', 'variant','name']
}
};
}
picklistColumn.html in lWCCustomDatatableType
<template>
<c-picklist-column label={typeAttributes.label} value={typeAttributes.value}
placeholder={typeAttributes.placeholder} options={typeAttributes.options} context={typeAttributes.context}>
</c-picklist-column>
</template>