I am using tagsinput with bootstrap4. I want the user to click on deleting a tag (the 'x' button), then ajax the tag-delete request to the server which checks if user is allowed to do it. Server responds yes or no (and deletes the tag in DB if yes). And tagsinput should be notified to delete the tag from the input element and its internal state (on client side).
From what I understand, I add the beforeItemRemove
event to the tagsinput-element and use the event.cancel=true;
to cancel deletion of tag. Like this:
$(inputel).on('beforeItemRemove', function(event) {
ajaxreq(..., onSuccess(r){}, onError(e,m){ event.cancel = true; });
});
But as you would have guessed the event.cancel is set too late because the event is long processed and exits before the ajax request is completed!
What I ended doing is this:
event.cancel = true; // we cancel the deletion by default
$(inputel).on('beforeItemRemove', function(event) {
ajaxreq(..., onSuccess(r){
// ajax succeeded and server allowed to delete, let's also delete from inputel
$(inputel).tagsinput('remove', event.item, {preventPost: true});
}, onError(e,m){});
});
// the event is returning much earlier than ajax completing
// but with event.cancel=true it does nothing until we call the 'remove'
Is this the right solution?
EDIT: relevant documentation here: https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/ (search e.g. for beforeItemRemove
)
EDIT2: I have just confirmed that this works in the case where the user is not allowed to delete a tag and the server via ajax refuses to delete it. And indeed nothing gets deleted in the input element. However, in the case where the user can and does delete the tag, the event is fired repeatedly (despite the preventPost: true
which I only speculate that it removes without firing remove-event) and bombs the db.
Cloning and patching the JS file
bootstrap-tagsinput.js
from https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/ was my last resort and it did work. So this in not ideal at all. Plus, there are lots of bootstrap "tagsinput" JS files out there which makes this a very bad solution.The edits were in 3 places.
1) at registering the functions
add
andremove
so that they accept a 3rd parameter, their signature shows they take 3 params in (the last one is the options as an object with keys like preventPost) but the registration below does not pass the 3rd arg! (mind you arg1 is function name like "add" or "remove"):2) modify the "add" function to NOT trigger events when options arg contains
preventPost: true
3) The same modification as above but for the "remove" function:
The idea is simple and better to follow the idea to 1) allow
add
andremove
functions to take a 3rd parameter as options so that you can pass add(item, dontpushval, {preventPost: true}); 2) modify said functions to actually read the options parameter (as their signatures already show, misleadingly, that they accept anoptions
parameter) and whenever thepreventPost
exists and is set to true, to block triggering thebeforeItemAdd
andbeforeItemRemove
This just shows how broken the "web" is and how billions worth of businesses excelling out there are founded on rotten, clay legs.
bw, bliako
p.s. I am astonished on the lack of any SO troll arriving instantly to declare this question irrelevant, off-topic, vague, already-solved or one of their "computer-says-no" excuse of the day. Perhaps they are all busy in a "community" meeting to make SO "greater".