在动态创建的select2元素上操作样式和工具提示

时间:2017-07-31 09:30:40

标签: jquery jquery-select2 tooltipster

我有一个部分动态创建的页面,其中一些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>'

1 个答案:

答案 0 :(得分: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);
    }
  }