Multiselect "Input Value Change" event - Add and Remove items

When building an app with retool, we are trying to use the Multiselect component.
We need to send "insert" or "delete" requests for items that are added to the multiselect list.
We do not see any documentation regarding the "Input Value Change" event, in regards to the item added or removed.

We expected to have something like this:
{{ multiselect.data.deletedItem.my_object.Id }}

But we do not see any documentation on the subject.

We don't want to go over ALL the list of selected items, and figure out what's new or what's missing. We expect to have that coming from somewhere in retool, and specifically from the "Input Value Change" event.

Where can we see a working example for "Add" and "Remove" Input Value Change events for a multiselect component ?

Thanks in advance

2 Likes

@berkovori Welcome to the forum!
Can you share a bit more information (screenshot) and more specifics?
Are you asking to figure out when the value of a multi-select field is changed for there to be some notification?

ScottR, as mentioned in the question - when the value of a multiselect is changed, we would like to send an Insert or Delete request. We want to know which item was added or subtracted from the list.

This is how the component commonly looks like, if you are not familiar with it:
image

As you can see - there are X buttons on every item.

When the X is clicked, there should be an event firing from the component. We would like to know WHICH item was deleted from the list.

Accordingly, when an item is ADDED - the event is fired, and we would like to know WHICH item was added.

Yes this can be done. However, I don’t have time to write it out at the moment. It will be a combination of using a transformer and temp states - I will post again as soon as I can. Or maybe someone else can chime in before I get back.

Hey @berkovori (and Scott) :slight_smile: Quick question, how are you populating your multiselect?

I too am looking for a solution to this.

I have done this using a temp state:
Editing the field directly and / or adding to it like the following:

Screenshot 2023-05-22 at 1.13.31 PM
Screenshot 2023-05-22 at 1.13.23 PM


Screenshot 2023-05-22 at 1.15.37 PM
Screenshot 2023-05-22 at 1.16.06 PM

@ScottR Thanks for your reply but I didn't quit understand it.

Regardless, I ended up getting this to working using a blur event handler on the multiselect calling the following JS Code:

const tags_old = task_tags.data.tgs_id;
const tags_new = tags_selection2.value;
const tags_to_insert = [];
const tags_to_delete = [];
let updated = 0;
tags_selection2.setDisabled(true);

// Loop through existing tags to DELETE tags that were removed
for (const tag of tags_old) {
  // was tag deleted?
  if (!tags_new.includes(tag)) {
    tags_to_delete.push(tag);
  }
}
// Loop through new tags to INSERT tags that were added
for (const tag of tags_new) {
  // was tag added?
  if (!tags_old.includes(tag)) {
    tags_to_insert.push(tag);
  }
}

const refresh_task_tags = function() {
  updated++;
  if(updated === tags_to_insert.length + tags_to_delete.length) {
    task_tags.trigger(); //ensures that we are only triggering a refresh once all queued work is done
    tags_selection2.setDisabled(false);
  }
}

for (const tag of tags_to_delete) {
  task_tags_delete.trigger({
    additionalScope: {
      tgs_id: tag,
      tsk_id: tsk_id_updating.value,
    },
    onSuccess: refresh_task_tags,
    onFailure: refresh_task_tags
  });
}

for (const tag of tags_to_insert) {
  task_tags_insert.trigger({
    additionalScope: {
      tgs_id: tag,
      tsk_id: tsk_id_updating.value,
    },
    onSuccess: refresh_task_tags,
    onFailure: refresh_task_tags
  });
}