bootstrap4 tagsinput, удалить тег: как проверить с помощью ajax, а затем отменить - PullRequest
0 голосов
/ 28 мая 2020

Я использую ввод тегов с bootstrap4. Я хочу, чтобы пользователь щелкнул по удалению тега (кнопка «x»), а затем ajax запрос на удаление тега на сервер, который проверяет, разрешено ли пользователю это делать. Сервер отвечает да или нет (и удаляет тег в БД, если да). И tagsinput должен быть уведомлен об удалении тега из элемента ввода и его внутреннего состояния (на стороне клиента).

Насколько я понимаю, я добавляю событие beforeItemRemove к тегу input-element и использую event.cancel=true; для отмены удаления тега. Примерно так:

$(inputel).on('beforeItemRemove', function(event) {
  ajaxreq(..., onSuccess(r){}, onError(e,m){ event.cancel = true; });
});

Но, как вы уже догадались, event.cancel установлен слишком поздно, потому что событие долго обрабатывается и завершается до завершения запроса ajax!

Что Я закончил делать следующее:

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'

Это правильное решение?

EDIT: соответствующая документация здесь: https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/ (поиск, например, beforeItemRemove)

EDIT2: Я только что подтвердил, что это работает в том случае, когда пользователю не разрешено удалять тег, а сервер через ajax отказывается удалить его. И действительно, в элементе ввода ничего не удаляется. Однако в случае, когда пользователь может удалить и действительно удаляет тег, событие запускается повторно (несмотря на preventPost: true, которое я только предполагаю, что он удаляет без запуска remove-event) и бомбардирует db.

1 Ответ

0 голосов
/ 30 мая 2020

Клонирование и исправление JS файла bootstrap-tagsinput.js из https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/ было моим последним средством, и оно действительно сработало. Так что это совсем не идеально. Кроме того, существует множество файлов bootstrap "tagsinput" JS, что делает это очень плохим решением.

Изменения были внесены в 3 места.

1) при регистрации функции add и remove, так что они принимают 3-й параметр, их подпись показывает, что они принимают 3 параметра (последний - это параметры в качестве объекта с такими ключами, как preventPost), но регистрация ниже не передает 3-й аргумент! (имейте в виду, что arg1 - это имя функции, такое как «добавить» или «удалить»):

  /**
   * Register JQuery plugin
   */


   /* bliako modifies: add arg4 at the end, after arg3: */
  $.fn.tagsinput = function(arg1, arg2, arg3, arg4) {
    var results = [];

    this.each(function() {
...
      } else if(tagsinput[arg1] !== undefined) {
          // Invoke function on existing tags input
/* bliako modifies: */
var retVal = tagsinput[arg1](arg2, arg3, arg4);
/* bliako modifies: and comment out the following - which may introduce side-effects, the problem is that I can't see how these functions get an "options" 3rd arg without arg4 (arg1 is the function name, e.g."add") 
So this hopefully passes an options={preventPost: true} back to the add() and remove() functions.
*/
/*            if(tagsinput[arg1].length === 3 && arg3 !== undefined){
               var retVal = tagsinput[arg1](arg2, null, arg3);
            }else{
               var retVal = tagsinput[arg1](arg2);
            }
*/

2) измените функцию «добавить», чтобы НЕ запускать события, когда параметры arg содержат preventPost: true

      // if length greater than limit
      if (self.items().toString().length + item.length + 1 > self.options.maxInputLength)
        return;

      // raise beforeItemAdd arg
/* bliako modifies: don't trigger the &*Q&* event if preventPost == true */
if( (options == null) || ! options.hasOwnProperty('preventPost') || ! options.preventPost ){
      var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false, options: options});
      self.$element.trigger(beforeItemAddEvent);
      if (beforeItemAddEvent.cancel)
        return;
} else { console.log("tags/remove() : blocked beforeItemRemoveEvent"); }

3) Та же модификация, что и выше, но для функции «удалить»:

        if (typeof item === "object")
          item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) ==  self.optio$
        else
          item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) ==  item; } );

        item = item[item.length-1];
      }

      if (item) {
/* bliako modifies: don't trigger the @*&*Q& event if preventPost == true */
if( (options==null) || ! options.hasOwnProperty('preventPost') || ! options.preventPost ){
        var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false, options: options $
        self.$element.trigger(beforeItemRemoveEvent);
        if (beforeItemRemoveEvent.cancel)
          return;
} else { console.log("tags/remove() : blocked beforeItemRemoveEvent"); }

Идея проста, и лучше следовать идее 1) разрешить функции add и remove принять третий параметр в качестве параметров, чтобы можно было передать add (item, dontpushval, {preventPost: true}); 2) изменить указанные функции так, чтобы они фактически считывали параметр параметров (поскольку их сигнатуры уже показывают, вводя в заблуждение, что они принимают параметр options), и всякий раз, когда preventPost существует и имеет значение true, блокировать запуск beforeItemAdd и beforeItemRemove

Это просто показывает, насколько разорвана «паутина» и как миллиарды успешных предприятий основаны на гнилых, глиняных ногах. * ps Я удивлен отсутствием какого-либо ТАКОГО тролля, который бы сразу же объявил этот вопрос неуместным, неуместным, неясным, уже решенным или одним из их оправданий дня «компьютер говорит-нет». Возможно, все они заняты собранием «сообщества», чтобы сделать ТАК «большим».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...