Nonprofit의 Gift Entry Grid 템플릿에서 열 모달 구성
대화형 열 모달을 구성하여 선물 항목 환경을 사용자 정의합니다. 표준 필드 집합 또는 사용자 지정 Lightning 웹 구성 요소(LWC)를 그리드에 직접 내장하여 기본 워크플로를 떠나지 않고 복잡한 기부자 세부 사항을 캡처할 수 있습니다.
필수 Edition
| 필수 Edition |
|---|
| 지원 제품: Lightning Experience |
지원 제품: Education Cloud를 사용하는 Enterprise, Performance, Unlimited 및 Developer Edition 지원 제품: Nonprofit Cloud를 사용하는 Enterprise, Unlimited 및 Developer Edition |
| 필요한 사용자 권한 | |
|---|---|
| 열 모달 구성: | FundraisingAccess 권한 집합 OR Education Cloud 전체 액세스 권한 집합 |
- 열 표시에서 구성할 열에 대해 열 편집을 클릭합니다.
- 모달을 클릭합니다.
-
모달 유형으로 Lightning 웹 구성 요소를 선택합니다.
관리 패키지에서 생성하거나 설치한 기존 LWC를 사용할 수 있습니다. 또는 표시할 필드를 선택하여 표시할 필드를 선택할 수 있습니다.
$GiftEntryGrid.FieldsModal
표준 LWC 및 모달의 필드 설정 섹션에서 필드를 추가합니다. - Lightning 웹 구성 요소 이름으로 Lightning 웹 구성 요소를 선택합니다.
- 모달 레이블을 입력합니다.
-
모달에 표시할 아이콘을 입력합니다(기본값: utility:expand_alt).
기본 아이콘은 utility:expand_alt이지만, SLDS 아이콘 라이브러리에서 다른 아이콘을 선택할 수 있습니다.
-
경우에 따라 모달에 대한 대체 레이블을 추가합니다.
대체자를 표시하기 위한 기준을 충족하면 모달 레이블 값 대신 표시됩니다.
샘플 기프트 항목 그리드 모달 구성 요소
이 샘플 Lightning 웹 구성 요소 코드 조각은 신용 카드 처리기를 보여주며 결제 방법 필드의 모달로 구성할 수 있습니다.
| 필수 Edition |
|---|
| 지원 제품: Lightning Experience |
지원 제품: Education Cloud를 사용하는 Enterprise, Performance, Unlimited 및 Developer Edition 지원 제품: Nonprofit Cloud를 사용하는 Enterprise, Unlimited 및 Developer Edition |
giftEntryGridPaymentAuthModal.html
<template>
<!--
Sample Gift Entry Grid Modal Component
There are no implementation requirements for this component, however the modal portal size is limited.
-->
<lightning-card title="Credit Card Authorization">
<div class="slds-p-around_medium">
<form onsubmit={handleSubmit} class="slds-form">
<!-- Row 1: PaymentMethod GiftEntry field -->
<lightning-record-edit-form object-api-name="GiftEntry" onsuccess={handleSuccess} class="slds-m-bottom_medium">
<div class="slds-grid">
<div class="slds-col slds-size_1-of-1">
<lightning-input-field
field-name="PaymentMethod"
value={paymentMethod}
onchange={handleInputChange}
required
></lightning-input-field>
</div>
</div>
</lightning-record-edit-form>
<!-- Only show credit card fields if needed -->
<template if:true={showCreditCardFields}>
<!-- Row 2: NameOnCard and CardNumber -->
<div class="slds-grid slds-gutters slds-m-bottom_medium">
<div class="slds-col slds-size_1-of-2">
<lightning-input
name="NameOnCard"
label="Name on Card"
value={nameOnCard}
onchange={handleInputChange}
required
></lightning-input>
</div>
<div class="slds-col slds-size_1-of-2">
<lightning-input
name="CreditCardNumber"
label="Credit Card Number"
value={creditCardNumber}
placeholder="XXXX-XXXX-XXXX-XXXX"
maxlength="19"
inputmode="numeric"
pattern="(?:\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}|\d{3}[-\s]?\d{6}[-\s]?\d{5}|\d{16}|\d{15})"
message-when-pattern-mismatch="Enter a valid credit card number."
onchange={handleInputChange}
required
></lightning-input>
</div>
</div>
<!-- Row 3: ExpiryMonth, ExpiryYear, CVV -->
<div class="slds-grid slds-gutters">
<div class="slds-col slds-size_1-of-3">
<lightning-input
name="ExpiryMonth"
label="Expiration Month"
value={expiryMonth}
onchange={handleInputChange}
inputmode="numeric"
pattern="\d{2}"
required
></lightning-input>
</div>
<div class="slds-col slds-size_1-of-3">
<lightning-input
name="ExpiryYear"
label="Expiration Year"
value={expiryYear}
onchange={handleInputChange}
inputmode="numeric"
pattern="\d{2}|\d{4}"
required
></lightning-input>
</div>
<div class="slds-col slds-size_1-of-3">
<lightning-input
name="Cvv"
label="CVV"
value={cvv}
onchange={handleInputChange}
inputmode="numeric"
pattern="\d{3,4}"
required
></lightning-input>
</div>
</div>
</template>
</form>
</div>
<template if:true={showCreditCardFields}>
<div class="slds-grid slds-grid_align-end slds-m-top_medium">
<lightning-button
variant="brand"
label="Charge Card"
onclick={handleChargeCardClick}
class="slds-m-right_none"
disabled={isChargeCardDisabled}
></lightning-button>
</div>
</template>
</lightning-card>
</template>
giftEntryGridPaymentAuthModal.js
import { LightningElement, api, track } from 'lwc';
const CONSTANTS = {
CREDIT_CARD: 'Credit Card',
ACH: 'ACH'
}
/**
* Sample Gift Entry Grid Modal Component
*/
export default class giftEntryGridPaymentAuthModal extends LightningElement {
/**
* Required input property.
* Not generally used within a custom component
*/
@api
set modalFields(value) {
this._modalFields = value || [];
this.initializeFields();
}
get modalFields() {
return this._modalFields;
}
/**
* Required input property.
* Contains all the data for the row.
*/
@api
set rowData(value) {
this._rowData = value || {};
this.initializeFields();
}
get rowData() {
return this._rowData;
}
// ------------------------------------------------------------
// Required Exposed API Functions for GiftEntryGrid
// ------------------------------------------------------------
/**
* Validates the component fields.
* @returns {Object} An object with properties for isValid (boolean) and an invalidFields collection with errors
* - isValid: true if the component fields are valid, false otherwise.
* - invalidFields: A Set of field names and errors to render
*/
@api
validate() {
let isValid = true;
let invalidFields = new Set();
if (!this.paymentMethod) {
isValid = false;
invalidFields.add('PaymentMethod');
}
if (this.showCreditCardFields) {
if (!this.chargeCardClicked) {
isValid = false;
invalidFields.add('ChargeCard');
}
if (!this.creditCardNumber || !this.validateCreditCardNumber()) {
isValid = false;
invalidFields.add('CreditCardNumber is invalid');
}
if (!this.nameOnCard) {
isValid = false;
invalidFields.add('NameOnCard is missing');
}
if (!this.expiryMonth || !this.validateExpiryMonth()) {
isValid = false;
invalidFields.add('ExpiryMonth is not valid');
}
if (!this.expiryYear || !this.validateExpiryYear()) {
isValid = false;
invalidFields.add('ExpiryYear is not valid');
}
if (!this.cvv || !this.validateCVV()) {
isValid = false;
invalidFields.add('CVV is not valid');
}
}
return { isValid, invalidFields };
}
/**
* Returns values to be saved to the row. These are directly applied to the rowData object within the Grid
* Properties in this object do not need to be actual GiftEntry fields. Dummy properties are allowed, but
* they will not persist to the GiftEntry row when the record is saved.
* @returns {Object} An object with the values that represent GiftEntry fields.
*/
@api
getComponentValues() {
let result = {}
result['PaymentMethod'] = this.paymentMethod;
if (this.showCreditCardFields) {
result['Last4'] = this.creditCardNumber ? this.creditCardNumber.slice(-4) : null;
result['ExpiryMonth'] = this.expiryMonth;
result['ExpiryYear'] = this.expiryYear;
result['CCAuthCode__c'] = this.generateRandomString(16);
result['NameOnCard__c'] = this.nameOnCard;
result['Card_CVV__c'] = this.cvv;
result['GatewayTransactionFee__c'] = 0.12345;
result['GatewayReference__c'] = this.creditCardNumber;
} else {
result['Last4'] = null;
result['ExpiryMonth'] = null;
result['ExpiryYear'] = null;
result['CCAuthCode__c'] = null;
result['NameOnCard__c'] = null;
result['Card_CVV__c'] = null;
result['GatewayTransactionFee__c'] = null;
result['GatewayReference__c'] = null;
}
return result;
}
// ------------------------------------------------------------
// Everything below this is generic custom code to illustrate the component behavior
// ------------------------------------------------------------
_modalFields = [];
_rowData = {};
@track paymentMethod = CONSTANTS.CREDIT_CARD;
@track creditCardNumber = '';
@track nameOnCard = '';
@track expiryMonth = '';
@track expiryYear = '';
@track cvv = '';
@track gatewaytransactionfee = null;
@track gatewayreference = null;
@track chargeCardClicked = false;
connectedCallback() {
this.initializeFields();
}
initializeFields() {
this.paymentMethod = this._rowData['PaymentMethod'] || '';
this.creditCardNumber = (this._rowData['Last4'] ? "****-****-****-" + this._rowData['Last4'] : '');
if (this._rowData['NameOnCard__c']) {
this.nameOnCard = this._rowData['NameOnCard__c'];
} else if (this._rowData['FirstName'] && this._rowData['LastName']) {
this.nameOnCard = this._rowData['FirstName'] + ' ' + this._rowData['LastName'];
} else {
this.nameOnCard = '';
}
this.expiryMonth = this._rowData['ExpiryMonth'] || '';
this.expiryYear = this._rowData['ExpiryYear'] || '';
this.cvv = this._rowData['Card_CVV__c'] || '';
this.gatewayTransactionFee = this._rowData['GatewayTransactionFee__c'] || null;
this.gatewayReference = this._rowData['GatewayReference__c'] || null;
}
handleInputChange(event) {
let fieldName = event?.target?.fieldName || event?.target?.name;
if (fieldName) {
fieldName = fieldName.charAt(0).toLowerCase() + fieldName.slice(1);
}
const fieldValue = event?.target?.value;
this[fieldName] = fieldValue;
if (fieldName === 'paymentMethod') {
if (!this.showCreditCardFields) {
this.creditCardNumber = '';
this.nameOnCard = '';
this.expiryMonth = '';
this.expiryYear = '';
this.cvv = '';
}
}
if (fieldName === 'creditCardNumber') {
this.validateCreditCardNumber();
}
if (fieldName === 'expiryMonth') {
this.validateExpiryMonth();
}
if (fieldName === 'expiryYear') {
this.validateExpiryYear();
}
}
handleChargeCardClick() {
this.chargeCardClicked = true;
}
canChargeCard() {
if (this.chargeCardClicked) return false;
if (!this.showCreditCardFields) return false;
return (
!!this.creditCardNumber && this.validateCreditCardNumber() &&
!!this.nameOnCard &&
!!this.expiryMonth && this.validateExpiryMonth() &&
!!this.expiryYear && this.validateExpiryYear() &&
!!this.cvv && this.validateCVV()
);
}
validateCreditCardNumber() {
const regex = /^(?:\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}|\d{3}[-\s]?\d{6}[-\s]?\d{5}|\d{16}|\d{15})$/;
return this.creditCardNumber === '' || regex.test(this.creditCardNumber);
}
validateExpiryMonth() {
const month = parseInt(this.expiryMonth, 10);
return this.expiryMonth === '' || (month >= 1 && month <= 12);
}
validateExpiryYear() {
let year = parseInt(this.expiryYear, 10);
year = year < 99 ? 2000 + year : year;
const currentYear = new Date().getFullYear();
return this.expiryYear === '' || (year >= currentYear && year <= currentYear + 10);
}
validateCVV() {
return this.cvv === '' || /^\d{2}|\d{4}/.test(this.cvv);
}
generateRandomString(length) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
get showCreditCardFields() {
return this.paymentMethod === CONSTANTS.CREDIT_CARD || this.paymentMethod === CONSTANTS.ACH;
}
get minExpiryYear() {
return new Date().getFullYear();
}
get maxExpiryYear() {
return new Date().getFullYear() + 10;
}
get isChargeCardDisabled() {
return !this.canChargeCard();
}
}
이 기사를 통해 문제를 해결했습니까?
개선을 위한 의견을 보내주세요.

