【问题标题】:Actioning styling and a tooltipster on a dynamically created select2 element在动态创建的 select2 元素上执行样式和工具提示
【发布时间】:2017-07-31 09:30:39
【问题描述】:

我有一个部分动态创建的页面,其中一些 select2 元素从 ajax 调用返回。然后我需要对它做一些 jquery 来操作它。该页面有点复杂,因为它在表格中显示表格,每一行都是一个表格。

我想要做的是在 select2 元素中没有输入数据时呈现红色边框和工具提示器。 select2 字段是必需的,它应该显示用户错误消息,因为没有输入数据。页面上有几个这样的 select2 元素,它们都没有显示任何工具提示。其他非 select2 字段会显示它们的工具提示。

使用一些控制台记录器,我可以看到要提供给工具提示器的错误消息数据是从表单提交中返回的。我还可以看到 jquery 看到了 tooltipster 对象。但它不会显示,也不会变成红色。

在ajax调用成功的属性中保存一行数据:

if ($.isEmptyObject(result['messages']['success'])) {
  if (!$.isEmptyObject(result['messages']['client_id'])) {
    var html = '';
    $.each(result['messages']['client_id'], function( index, value ) {
      html += ' ' + value;
    });
    displayError('#clients[' + maxLevel + ']-' + id, html);
    displayError('#client_id-' + id, html);
  }
  for (j = 0; j <= maxLevel; j++) {
    if (!$.isEmptyObject(result['messages']['clients[' + j + ']'])) {
      var html = '';
      $.each(result['messages']['clients[' + j + ']'], function( index, value ) {
        html += ' ' + value;
      });
console.log($('[name^="clients[' + j + ']-'+id+'"]'));
console.log(html);
      displayError('[name^="clients[' + j + ']-'+id+'"]', html);
      displayError('#clients[' + j + ']-' + id, html);
      displayError('#client_id-' + id, html);
    }
  }

显示错误的函数:

function displayError(id, html) {
   $(id).css('border-color', 'red');
   $(id).attr('title', html);
   displayTooltipster(id);
}

function displayTooltipster(id) {
  if (!$(id).hasClass("tooltipstered")) {
    $(id).tooltipster({
      position: 'top-left',
      contentAsHTML: 'true',
      theme: '.tooltipster-default',
      animation: 'grow'
    });
  } else {
    $(id).tooltipster('enable');
  }
}

控制台记录器有这样的显示:

[input#clients[0]-212713.form-control.input-small.tooltipster.select2-offscreen, prevObject: init(1), context: document, selector: "[name^="clients[0]-212713"]"]
vehicule-realocate:554  Une valeur est requise et ne peut être vide
vehicule-realocate:553 
[input#clients[1]-212713.form-control.input-small.tooltipster.select2-offscreen, prevObject: init(1), context: document, selector: "[name^="clients[1]-212713"]"]
vehicule-realocate:554  Une valeur est requise et ne peut être vide
vehicule-realocate:553

在每一行上,有几个 select2 字段;每个都以链式方式显示,下一个替换前一个,允许选择树中的节点。这工作得很好,让我可以浏览节点树:

function handleSelect2Fields() {
    for (var i=0; i <= maxLevel; i++) {
        var el = $('[name^="clients[' + i + ']"]');
        el.data('level', i);
        el.select2({
            width: 'element',
            ajax: {
                url: '<?php echo $this->url('users/get-client-options'); ?>',
                type: 'post',
                dataType: 'json',
                data: function(term, page) {
                    var level = parseInt(this.data('level'));
                    if (level > 0) {
                        var sameRowClients = $(this).parent().parent();
                        var oneClientFromSameRow = sameRowClients.find('[name^="clients[' + (level-1) + ']"]');
                        var el = oneClientFromSameRow;
                        return {client_id : el.val(), term : term}
                    }
                },
                results: function(data, page) {
                    data.datas.push({'id':0, 'text':'[Retour]'});
                    return {results : data.datas, more : false}
                }
            },
            initSelection : function (element, callback) {
            }
        });
        el.on('change', function(e) {
          var selectedValue = e.val;
            var level = parseInt($(this).data('level'));
            if (selectedValue == 0) {
              if (level > 0) {
                level -= 1;
              }
            } else {
              level += 1;
            }
            for (var i=0; i <= maxLevel; i++) {
                var sameRowClients = $(this).parent().parent();
                var oneClientFromSameRow = sameRowClients.find('[name^="clients[' + i + ']"]');
                var el = oneClientFromSameRow;
                if (i == level) {
                  oneClientFromSameRow.parent().show();
                    el.select2("val", '');
                    el.select2("readonly", false);
                    el.select2("open");
                } else if (i < level && level <= maxLevel) {
                  oneClientFromSameRow.parent().hide();
                } else if (i > level) {
                  oneClientFromSameRow.parent().hide();
                    el.select2("readonly", true);
                    el.select2("val", '');
                }
            }
            var id_suffix = oneClientFromSameRow.attr('id').split('-')[1];
            if (level > maxLevel) {
                $('[name=client_id-' + id_suffix + ']').val($(this).val());
            } else {
                $('[name=client_id-' + id_suffix + ']').val('');
            }
            $('[name=client_id-' + id_suffix + ']').val($(this).val());
        });
        if (i != 0) {
            if (! el.val()) {
              el.select2("readonly", true);
              $('[name^="clients[' + i + ']"]').parent().hide();
            }
        }
    }

function loadItems() {
    $.ajax({
        url: "<?php echo $this->url('ajax', array('action' => 'get-vehicules-to-realocate'));?>",
        data: {'maxLevel': maxLevel},
        type: 'post',
        success: function(items) {
            $.each(items['html'], function(id, contentHtml) {
                $('#list-items').append(contentHtml);
            });

            $('#nb_items').html(items['total']);
            $('#header').html(items['header']);

            $(".datepicker").datepicker({ 'dateFormat': 'yy-mm-dd'});

            handleSelect2Fields();
        }
    });
}

在服务器端,会生成一些标记来呈现 select2 元素:

$client = '<input type="hidden" name="client_id-' . $id . '" id="client_id-' . $id . '" value="" class="tooltipster">';
for ($j = 0; $j <= $maxLevel; $j++) {
  $client .= '<span><input type="hidden" name="clients[' . $j . ']-' . $id . '" id="clients[' . $j . ']-' . $id . '" value="" class="form-control input-small tooltipster" required></span>';
}

客户端字段位于引导表中:

$html[$i] = '<div class="row" id="bloc-' . $id . '">'
    . '<div class="span1" style="text-align:center; white-space:nowrap;">' . $client . '</div>'

【问题讨论】:

    标签: jquery jquery-select2 tooltipster


    【解决方案1】:

    解决此问题的一种方法是通过两个父级遍历 DOM 树,以到达某个封闭的 div。

    用于显示错误消息的方法现在使用两个 parent() 调用:

    function displaySelect2Error(id, html) {
       $(id).parent().parent().css('border', 'solid 1px');
       $(id).parent().parent().css('border-color', 'red');
       $(id).parent().parent().attr('title', html);
       displayTooltipster($(id).parent().parent());
    }
    

    它被称为:

    if ($.isEmptyObject(result['messages']['success'])) {
      for (j = 0; j <= maxLevel; j++) {
        if (!$.isEmptyObject(result['messages']['clients[' + j + ']'])) {
          var html = '';
          $.each(result['messages']['clients[' + j + ']'], function( index, value ) {
            html += ' ' + value;
          });
          displaySelect2Error('#client_id-' + id, html);
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2021-08-08
      • 2011-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多