-
[LWC] 실습 2) lightning-datatable에 picklist field 표시하기 - How to display picklist field in datatableLWC 2024. 9. 11. 10:17
실습 계획
이번시간은 실습 2) custom lightning-datatable에 picklist field 표시하기
실습 1) lightning-datatable 생성하기
실습 2) custom lightning-datatable에 picklist field 표시하기
실습 3) custom lightning-datatable에 lookup field 표시하기
실습 4) custom datatable에 lookup 필드와 picklist 필드 함께 표시하기
실습 5) datatable 설정 Tip 및 issue 공유
0. 기본 Setup 및 개념
- 기회제품 개체에 선택목록 필드 추가
- 추가한 선택목록 필드 조회해 오도록 apex 컨트롤러에서 sql문 수정
- 선택목록 필드를 보여주기 위한 lwc 컴포넌트 생성
- 기본으로 제공되는 lightning-datatable에서는 선택목록 필드를 보여줄 수 없어서
- 1. datatable을 extends한 lwc 컴포넌트를 생성하고
- 2. 해당 컴포넌트(=datatable 컴포넌트)에 custom type 추가하여
- 3. 선택목록 필드 편집화면 처럼 보여주도록 구현
- 기본으로 제공되는 lightning-datatable에서는 선택목록 필드를 보여줄 수 없어서
1. 추가한 선택목록 필드(=제품 등급) 조회해 오도록 apex 컨트롤러에서 sql문 수정
- OppItemManagementController.cls
- oppItems 가져오는 부분에서 testSelectList__c 필드 가져오도록 추가
public with sharing class OppItemManagementController {public OppItemManagementController() {}//기존 기회 제품 리스트 반환@AuraEnabledpublic static List<OpportunityLineItem> getOppItems(String oppId){
List<OpportunityLineItem> oppItems = new List<OpportunityLineItem>();try {//testSelectList__c 선택목록 필드 추가 함oppItems = [SELECT Id, OpportunityId, Product2Id, Product2.Name, PricebookEntryId, PricebookEntry.Name, Quantity, UnitPrice, Description, SortOrder, testSelectList__cFROM OpportunityLineItemWHERE OpportunityId = :oppIdORDER BY SortOrder, Id];
return oppItems;
} catch (Exception e) {throw new AuraHandledException(e.getMessage());}}}2. 선택목록 필드를 보여줄 lwc 컴포넌트 - customDatatableType.cmp 생성
- Custom Datatable 컴포넌트이다.
2-1 : customDatatableType.html
- 해당 컴포넌트(customDatatableType.cmp)는 extends LightningDatatable한 데이터테이블 컴포넌트이다.
- 따라서 html 파일에 코드를 입력하지 않아도 datatable 형식으로 표시된다.
- 코드를 입력해도 화면에 나타나지 않는다.
<template></template>2-2 : picklistColumn.html
<template><lightning-comboboxname="picklist"data-inputable="true"label={typeAttributes.label}value={editedValue}placeholder={typeAttributes.placeholder}options={typeAttributes.options}variant='label-hidden'dropdown-alignment="auto"></lightning-combobox></template>2-3 : pickliststatic.html
<template><span class="slds-truncate" title={value}>{value}</span></template>2-4 : customDatatableType.js
import { LightningElement } from 'lwc';import LightningDatatable from 'lightning/datatable';import picklistColumn from './picklistColumn.html';import pickliststatic from './pickliststatic.html';
export default class CustomDatatableType extends LightningDatatable {static customTypes = {picklistColumn: {template: pickliststatic,editTemplate: picklistColumn,standardCellLayout: true,typeAttributes: ['label', 'placeholder', 'options', 'value', 'context', 'variant', 'name']}}}2-5 : customDatatableType.xml
<?xml version="1.0" encoding="UTF-8"?><apiVersion>61.0</apiVersion><isExposed>false</isExposed></LightningComponentBundle>3. custom datatable을 화면에 보여주도록 부모 컴포넌트의 html 파일 수정
- 부모 컴포넌트(데이터 테이블 및 main화면 보여줄 컴포넌트) : oppItemManagementEdit.cmp
- 자식 컴포넌트(커스텀 데이터테이블 컴포넌트) : customDatatableType
- 컴포넌트 호출 시에는 c- 로 시작하며 이름에 대문자가 있는 경우 케밥케이스 형식으로 표시
- customDatatableType.cmp 호출 시 <c-custom-datatable-type>
<template>
<section role="dialog" tabindex="-1" aria-modal="true" aria-labelledby="modal-heading-01" class="slds-modal slds-fade-in-open slds-modal_large"><div class="slds-modal__container">
<lightning-button-icon icon-name="utility:close" onclick={fnCloseModal} alternative-text="close" variant="bare-inverse" class="slds-modal__close" ></lightning-button-icon>
<!-- 모달 헤드 --><div class="slds-modal__header"><h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">기회제품 편집</h2></div>
<div style="background-color: white; "><div class="datatable-container" onitemregister={handleRegisterItem}><c-custom-datatable-typekey-field="Id"data={data}columns={columns}></c-custom-datatable-type></div></div>
<!-- 모달 푸터 --><div class="slds-modal__footer"><lightning-button name="close" label="닫기" class="slds-float_right" onclick={fnCloseModal}></lightning-button></div>
</div><!--modal container--></section>
<div class="slds-backdrop slds-backdrop_open" role="presentation"></div>
</template>
4. custom datatable을 호출하도록 부모 컴포넌트의 js 파일 수정- 부모 컴포넌트(데이터 테이블 및 main화면 보여줄 컴포넌트) : oppItemManagementEdit.cmp
- 자식 컴포넌트(커스텀 데이터테이블 컴포넌트) : customDatatableType
4-1 : 선택목록 필드를 column에 추가
- label → 필드 레이블
- fieldName → 필드 api명
- type → 내가 생성한 커스텀 타입명
- editable → 수정 가능여부
- typeAttributes → 해당 필드 타입의 추가적인 정보
const columns=[{ label: '제품 Id', fieldName : 'Product2Id', type: 'text', hideDefaultActions : "true", editable: true, },{ label: '제품명', fieldName : 'Product2.Name', type: 'text', hideDefaultActions : "true", editable: true, },{ label: '수량', fieldName : 'Quantity', type: 'decimal', hideDefaultActions : "true", editable: true, cellAttributes:{ class: { fieldName: 'quantityCellClass' } }},{ label: '판매가격', fieldName : 'UnitPrice', type: 'currency', hideDefaultActions : "true", editable: true, typeAttributes: { currencyCode: 'KRW', style: 'currency', minimumFractionDigits: 0 } },{ label: '설명', fieldName : 'Description', type: 'text', hideDefaultActions : "true", editable: true, },{label: '제품 등급',fieldName: 'testSelectList__c',type: 'picklistColumn',editable: true,typeAttributes: {placeholder: '== 선택 ==',options: { fieldName: 'pickListOptions' },value: { fieldName: 'testSelectList__c' },context: { fieldName: 'Id' }},hideDefaultActions : "true"}];export default class OppItemManagementEdit extends NavigationMixin(LightningElement) {columns = columns;}4-2 : 선택목록 필드의 option 값 가져오기
@wire(getPicklistValues) 호출 시
- 개체의 recordTypeId가 있다면 recordTypeId를 전달해주어야 하며
- 개체의 recordTypeId가 없다면 " 012000000000000AAA"를 전달해 주면 된다.
import { getPicklistValues } from 'lightning/uiObjectInfoApi';import FIELD_testSelecteList from '@salesforce/schema/OpportunityLineItem.testSelectList__c';export default class OppItemManagementEdit extends NavigationMixin(LightningElement) {//매입상태 선택목록 필드 option 값 세팅- ( recordTypeId 전달 값 체크 )@track pickListOptions;@wire(getPicklistValues, { recordTypeId: "012000000000000AAA", fieldApiName: FIELD_testSelecteList })wirePickList({ error, data }) {if (data) {this.pickListOptions = data.values;// oppId가 설정된 경우 기회 항목을 가져옴if (this.oppId) {this.fetchOppItems();}} else if (error) {console.error(error);}}}4-3 : 제품별(row별) 선택목록 option값 세팅 해주기
- apex controller 메서드를 통해 기회제품 list를 가져오고
- 이를 데이터테이블에서 활용할 data로 세팅해 줄 때 제품별(row별)로 선택목록 option값 세팅 해주기
import getOppItems from '@salesforce/apex/OppItemManagementController.getOppItems';export default class OppItemManagementEdit extends NavigationMixin(LightningElement) {//기회제품 가져오기fetchOppItems() {console.log('save시 fetchOppItems 동작 == ');if (this.oppId && this.pickListOptions ) { <------- oppId와 pickListOptions이 모두 랜더링되었을 때 동작하도록 설정getOppItems({ oppId: this.oppId }).then(result => {this.data = JSON.parse(JSON.stringify(result));if (this.data) {this.data.forEach(ele => {ele.pickListOptions = this.pickListOptions; <------- 기회제품 list의 각 제품별로 pickListOption값 세팅});}}).catch(error => {console.error(error);this.data = undefined;});}}}4-4 : js파일 전체 코드 확인
- OppItemManagementEdit.js
import { LightningElement, track, wire, api } from 'lwc';import getOppItems from '@salesforce/apex/OppItemManagementController.getOppItems';import { CurrentPageReference, NavigationMixin } from 'lightning/navigation';
//4-2import { getPicklistValues } from 'lightning/uiObjectInfoApi';import FIELD_testSelecteList from '@salesforce/schema/OpportunityLineItem.testSelectList__c';
//4-1 : 선택목록 필드 columns에 추가const columns=[{ label: '제품 Id', fieldName : 'Product2Id', type: 'text', hideDefaultActions : "true", editable: true, },{ label: '제품명', fieldName : 'Product2.Name', type: 'text', hideDefaultActions : "true", editable: true, },{ label: '수량', fieldName : 'Quantity', type: 'decimal', hideDefaultActions : "true", editable: true, cellAttributes:{ class: { fieldName: 'quantityCellClass' } }},{ label: '판매가격', fieldName : 'UnitPrice', type: 'currency', hideDefaultActions : "true", editable: true, typeAttributes: { currencyCode: 'KRW', style: 'currency', minimumFractionDigits: 0 } },{ label: '설명', fieldName : 'Description', type: 'text', hideDefaultActions : "true", editable: true, },{label: '제품 등급',fieldName: 'testSelectList__c',type: 'picklistColumn',editable: true,typeAttributes: {placeholder: '== 선택 ==',options: { fieldName: 'pickListOptions' },value: { fieldName: 'testSelectList__c' },context: { fieldName: 'Id' }},hideDefaultActions : "true"}];
export default class OppItemManagementEdit extends NavigationMixin(LightningElement) {columns = columns;@track data = [];@track oppItemList;@track draftValues = [];@api oppId;//4-2 : 제품 등급 선택목록 필드 option 값 가져오기@track pickListOptions;@wire(getPicklistValues, { recordTypeId: "012000000000000AAA", fieldApiName: FIELD_testSelecteList })wirePickList({ error, data }) {if (data) {this.pickListOptions = data.values;// oppId가 설정된 경우 기회 항목을 가져옴if (this.oppId) {this.fetchOppItems();}} else if (error) {console.error(error);}}
//lwc를 호출한 url에서 파라미터 값 가져오기@wire(CurrentPageReference)setCurrentPageReference(currentPageReference) {if (currentPageReference) {const state = currentPageReference.state;const newOppId = state.c__oppId;if (newOppId !== this.oppId) {this.oppId = newOppId;this.fetchOppItems();}}}//4-3 : 기회제품 가져오기 및 제품 별 선택목록 option 값 세팅해주기fetchOppItems() {if (this.oppId && this.pickListOptions ) { <- oppId와 pickListOptions값이 세팅되었을때 기회제품 list 가져오기getOppItems({ oppId: this.oppId }).then(result => {this.data = JSON.parse(JSON.stringify(result));if (this.data) {this.data.forEach(ele => {ele.pickListOptions = this.pickListOptions;});}}).catch(error => {console.error(error);this.data = undefined;});}}
//기본 실행connectedCallback() {}
fnCloseModal(){this[NavigationMixin.Navigate]({type: 'standard__recordPage',attributes: {recordId: this.oppId,objectApiName: 'Opportunity',actionName: 'view'}});}
}5. 화면 확인
선택한 값으로 제품의 정보가 실제 저장되도록하려면
datatable에 draft-values와 oncellchange 속성부여가 필요하다.
이번 실습에서는 보여주는 것이 목표
해당 기능은 실습5번에서 포스팅할 예정
반응형