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

问题描述:

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

我想要做的是在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(); 
     } 
    }); 
} 

在服务器端,会产生一些标记来渲染选择2元素:

$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>' 

解决此问题的一种方法是通过两个父母遍历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); 
    } 
    }