IMPORTANT!! User Confirmation Before Deleting Item from MultiLookup

Hi,

In Contact Object, there is a multiselect field 'Affiliation' where I add any no of item from list.

Source Code:

 

Query: Whenever user click on 'x' icon to delete an item from multiselect field, Creatio should pop up a confirmation box i.e. 'Do you want to remove Item' & then delete item if user agree.

 

 

Like 0

Like

5 comments

Hi Team,

I need assistance & guidance on it.

souresh khandelwal,

Hello,

First of all point us to the addon you installed to your application to add this multiselect dropdown (or how it was added?). And next: have you checked which handlers are triggered when the value is removed from this field?

 

Hi Oleg,

I followed an article on CustomerFX: Using the new Multiselect Control in Creatio 8.2.1 and Higher | Customer FX

      
Steps:

  1. Created an Object UsrContactSBURelationship to store data as 1: many relationship
  2. Create 2 lookup: UsrContact, UsrSBU
  3. Add the multiselect control to the page and plug in the correct lookup/object

 

I used 'crt.HandleViewModelAttributeChangeRequest' Handler Method to see which attribute is called when item is removed from multiselect lookup.

Handler: Change In Model Attr

 

souresh khandelwal,

Theoretically this is possible to implement, but you will need to continue the investigation from your end. I can give you the start code that you can then modify.

 

  1. Create 3 parameters: one will store the originally loaded values in the lookup, the second parameter will control if the initial values were loaded and the third one will control if rollback is in progress (let's say the parameters are PageParameters_UsrBooleanParameter1_62tb9kv to control the inital values loaded state (true\false), PageParameters_UsrTextParameter1_3yzslqj - will store the original values, PageParameters_UsrRollbackInProgress - controls if rollback is in progress (true\false).
  2. Create a separate module where all the logic will be storred (call it like UsrContactsFormPageUtilities) and connect it to the Contacts_FormPage (or whatever page you want this logic to have)

    define("Contacts_FormPage", /**SCHEMA_DEPS*/["UsrContactsFormPageUtilities"]/**SCHEMA_DEPS*/, function/**SCHEMA_ARGS*/(contactFormPageFunc)/**SCHEMA_ARGS*/ {

     

  3. Add the following code in the UsrContactsFormPageUtilities:

     define("UsrContactsFormPageUtilities", ["@creatio-devkit/common"], function(sdk){
    	 return {
    		 handleInitialValues: async function(request) {
    			 let initialValues = [];
    			 const multiLookupValues = await request.value;
    			 for (item of multiLookupValues) {
    				 const retrievedItem = await item.Name;
    				 initialValues.push(retrievedItem);
    			 }
    			 request.$context.PageParameters_UsrTextParameter1_3yzslqj = initialValues;
    			 request.$context.PageParameters_UsrValuesOnDelete = Object.assign({}, await request.$context.MultiSelect_lwnwdk0_Items);
    			 console.log(`Initial values are ${await request.$context.PageParameters_UsrTextParameter1_3yzslqj}`);
    			 request.$context.PageParameters_UsrBooleanParameter1_62tb9kv = true;
    		 },
     
    		 handleModification: async function(request) {
    			 let modifiedValues = [];
    			 const newValues = await request.value;
    			 for (item of newValues) {
    				 const retrievedItem = await item.Name;
    				 modifiedValues.push(retrievedItem);
    			 }
    			 console.log(`value: ${modifiedValues}`);
    			 await this.handleCompareInitialModifiedValues(request, modifiedValues);
    		 },
     
    		 handleCompareInitialModifiedValues: async function(request, modifiedValues) {
    			 const initialValues = await request.$context.PageParameters_UsrTextParameter1_3yzslqj;
    			 if(initialValues.sort().join(',') !== modifiedValues.sort().join(',')) {
    				 await this.handleConfirmation(request);
    			 } 
    		 },
     
    		 handleConfirmation: async function(request) {
    			 const dialogService = new sdk.DialogService();
    			 const deleteResult = await dialogService.open({
    				 message: "Are you sure you want to delete the item?",
    				 actions: [
    					 {
    						 key: 'true',
    						 config: {
    							 color: 'primary',
    							 caption: 'YES',
    						 }
    					 },
    					 {
    						 key: 'false',
    						 config: {
    							 color: 'default',
    							 caption: 'NO',
    						 }
    					 }
    				 ]
    			 });
    			 this.handleDeleteResult(request, deleteResult);
    		 },
     
    		 handleDeleteResult: async function(request, deleteResult) {
    			 if (/false/.test(deleteResult)
    ) {
    				 await this.performRollback(request);
    			 } else {
    				 await this.performDelete(request); 
    			 }
    		 },
     
    		 performRollback: async function(request) {
    			 const originalValues = await request.$context.PageParameters_UsrValuesOnDelete;
    			 const currentValues = await request.$context.MultiSelect_lwnwdk0_Items;
     
    			 const origValuesKeys = Object.keys(originalValues).filter(item => !isNaN(item))
    ;
    			 const currentValuesKeys = Object.keys(currentValues).filter(item => !isNaN(item))
    ;
     
    			 let originalValuesArray = [];
    			 let currentValuesArray = [];
     
    			 for (key in origValuesKeys) {
    				 const originalValueName = await originalValues[key].Name;
    				 originalValuesArray.push(originalValueName);
    			 }
     
    			 for (key in currentValuesKeys) {
    				 const currentValueName = await currentValues[key].Name;
    				 currentValuesArray.push(currentValueName);
    			 }
     
    			 const missingValue = await this.valuesComparator(originalValuesArray, currentValuesArray);
    			 const config = {
    				 originalValues: originalValues,
    				 origValuesKeys: origValuesKeys,
    				 missingValue: missingValue
    			 };
    			 const missingValueInOrigValues = await this.findMissingValueInOriginalValues(config);
    			 request.$context.MultiSelect_lwnwdk0_Items.__zone_symbol__value.push(missingValueInOrigValues);
    			 request.$context.PageParameters_UsrRollbackInProgress = true;
    		 },
     
    		 performDelete: async function(request) {
     
    		 },
     
    		 valuesComparator: async function(originalValues, currentValues) {
    			 const originalValuesSet = new Set(originalValues);
    			 return currentValues.filter(item => !originalValuesSet.has(item));
    		 },
     
    		 findMissingValueInOriginalValues: async function(config) {
    			 const { originalValues, origValuesKeys, missingValue } = config;
    			 let missingValueKey = 0;
    			 for (let i = 0; i < origValuesKeys.length; i++) {
    				 if (await originalValues[i].Name == missingValue) {
    					 missingValueKey = i;
    				 }
    			 }
    			 return await originalValues[missingValueKey];
    		 }
    	 };
     });
  4. Add the following handler to the Contacts_FormPage:

    {
    				request: "crt.HandleViewModelAttributeChangeRequest",
    				handler: async (request, next) => {
    					if (request.attributeName == "MultiSelect_lwnwdk0_Items") {
    						const initialValueLoaded = await request.$context.PageParameters_UsrBooleanParameter1_62tb9kv;
    						const rollbackInProgress = await request.$context.PageParameters_UsrRollbackInProgress;
    						if (initialValueLoaded && !rollbackInProgress) {
    							await contactFormPageFunc.handleModification(request);
    						} else if(!initialValueLoaded) {
    							await contactFormPageFunc.handleInitialValues(request);
    						}
    						request.$context.PageParameters_UsrRollbackInProgress = false;
    					}
    					return next?.handle(request);
    				}
    			}

    So the logic I was trying to implement was simple: check if the user selects the option to remove records or no. If user doesn't want to remove the record - call the rollback function to add the deleted value back (deleted value is retrieved from the originally loaded values). If user selects "Yes" - we need to remove the deleted value also from the originaly loaded values.

Also there is another approach that may work. Add the "disableManualSave" attribute to the multilookup element in the source code and set the value of "true" for it and test the result after that.

Show all comments