Ti trovi qui:
Configurazione di una modalità colonna in un modello di griglia di immissione regalo nell'istruzione
Personalizzare l'esperienza di immissione regalo configurando le modali delle colonne interattive. È possibile incorporare insiemi di campi standard o componenti Web Lightning personalizzati (LWC) direttamente nella griglia per acquisire dettagli di donatori complessi senza uscire dal flusso di lavoro principale.
Versioni (Edition) richieste
| EDIZIONI RICHIESTE |
|---|
| Disponibile in: Lightning Experience |
Disponibile in: Enterprise Edition, Performance Edition, Unlimited Edition e Developer Edition con Education Cloud Disponibile nelle versioni: Enterprise Edition, Unlimited Edition e Developer Edition con Nonprofit Cloud |
| Autorizzazioni utente necessarie | |
|---|---|
| Per configurare una finestra modale colonna: | Insieme di autorizzazioni FundraisingAccess O Insieme di autorizzazioni Accesso completo a Education Cloud |
- In Visualizza colonne, per la colonna che si desidera configurare, fare clic su Modifica colonna.
- Fare clic su Modale.
-
Selezionare Componenti Web Lightning come tipo modale.
È possibile utilizzare un LWC esistente creato o installato da un pacchetto gestito. In alternativa, è possibile selezionare i campi da visualizzare selezionando
$GiftEntryGrid.FieldsModal
LWC standard e quindi l'aggiunta di campi nella sezione Imposta campi modali. - Selezionare il componente Web Lightning come nome del componente Web Lightning.
- Immettere un'etichetta modale.
-
Immettere un'icona da visualizzare per la finestra modale (l'impostazione predefinita è utility:expand_alt).
L'icona predefinita è utility:expand_alt, ma è possibile sceglierne altre dalla SLDS Icon Library.
-
Se si desidera, aggiungere un'etichetta alternativa per la finestra modale.
Se vengono soddisfatti i criteri per visualizzare l'alternativa, verrà visualizzata al posto del valore Etichetta modale.
Componente modale griglia di ingresso regalo di esempio
Questo snippet di codice componente Web Lightning di esempio mostra un processore di carte di credito e può essere configurato come finestra modale per il campo Metodo di pagamento.
| EDIZIONI RICHIESTE |
|---|
| Disponibile in: Lightning Experience |
Disponibile in: Enterprise Edition, Performance Edition, Unlimited Edition e Developer Edition con Education Cloud Disponibile nelle versioni: Enterprise Edition, Unlimited Edition e Developer Edition con Nonprofit Cloud |
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();
}
}

