2017-02-20 5 views
2

Im загружает подробную информацию о строках в таблице начальной загрузки через вызов Ajax с идентификатором в качестве параметров.
Эта информация отображается в складной строке с помощью кнопки значка глифа.Строка строки таблицы бутстрапа - данные ajax

Однако, нажав на кнопку, чтобы свернуть строку, в результате искажения дисплея.
Я изо всех сил пытался найти исправление, хотя код кажется правильным.
Может вам найти jsFiddle here

var parentsData = { 
 
    "success": true, 
 
    "parents": [{ 
 
    "id": 1531, 
 
    "Firstname": "Austin", 
 
    "Surname": "Ana\u00eblle", 
 
    "schoolId": "046039", 
 
    "schoolName": "ARCAMBAL", 
 
    "commune": "ARCAMBAL" 
 
    }, { 
 
    "id": 2032, 
 
    "Firstname": "Ramos", 
 
    "Surname": "L\u00e8i", 
 
    "schoolId": "046043", 
 
    "schoolName": "J CALVET", 
 
    "commune": "CAHORS" 
 
    }, { 
 
    "id": 3036, 
 
    "Firstname": "Baker", 
 
    "Surname": "Salom\u00e9", 
 
    "schoolId": "046043", 
 
    "schoolName": "Z LAFAGE", 
 
    "commune": "CAHORS" 
 
    }, { 
 
    "id": 1724, 
 
    "Firstname": "Berry", 
 
    "Surname": "Marl\u00e8ne", 
 
    "schoolId": "046044", 
 
    "schoolName": "J CALVET", 
 
    "commune": "CAHORS" 
 
    }] 
 
}; 
 

 
var $table = $('.js-table'); 
 
$table.find('.js-view-parents').on('click', function(e) { 
 
    e.preventDefault(); 
 
    if (!$(this).closest('tr').next('tr').hasClass('expand-child')) { 
 

 
    $(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open'); 
 

 
    $(".expand-child").slideUp(); 
 
    var $this = $(this).closest('tr'); 
 
    var rowId = $(this).data('id'); 
 

 
    var newRow = '<tr class="expand-child">' + '<td colspan="12" id="collapse' + rowId + 
 
     '">' + 
 
     '<table class="table table-condensed table-bordered" width=100% >' + 
 
     '<thead>' + 
 
     '<tr>' + 
 
     '<th>Surname</th>' + 
 
     '<th >FirstName</th>' + 
 
     '<th >School Id</th>' + 
 
     '<th >School name</th>' + 
 
     '</tr>' + 
 
     '</thead>' + 
 
     '<tbody>'; 
 

 
    $.ajax({ 
 
     url: '/echo/json/', 
 
     dataType: "json", 
 
     data: parentsData, 
 
     success: function(parentsData) { 
 
     if (parentsData.parents) { 
 
      var parents = parentsData.parents; 
 
      $.each(parents, function(i, parent) { 
 
      newRow = newRow + '<tr scope="row">' + 
 
       '<td>' + parent.Firstname + '</td>' + 
 
       '<td>' + parent.Surname + '</td>' + 
 
       '<td>' + parent.schoolId + '</td>' + 
 
       '<td>' + parent.schoolName + ' ' + parent.commune + 
 
       '</td>' + 
 
       '</tr>'; 
 
      }); 
 
      newRow = newRow + '</tbody></table></td></tr>'; 
 
     } 
 
     $(newRow).insertAfter($this); 
 
     } 
 
    }); 
 
    } else { 
 
    $(this).closest('tr').slideToggle(); 
 
    var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child'); 
 
    $detailRow.style.visibility.toggle('table-row collapse'); 
 
    $(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open'); 
 
    } 
 
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> 
 
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet" /> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 
 
<container> 
 
    <table class="table table-striped table-hover js-table"> 
 
    <thead> 
 
     <tr> 
 
     <th>Training</th> 
 
     <th>Title</th> 
 
     <th>Date</th> 
 
     <th>End date</th> 
 
     <th>Description</th> 
 
     <th>nb of Applicants</th> 
 
     <th>Actions</th> 
 
     </tr> 
 
    </thead> 
 
    <tr data-toggle="collapse" data-target="#collapse4039" class="clickable"> 
 
     <td>Activités nautiques</td> 
 
     <td>Activités nautiques - 16/10/2016</td> 
 
     <td>16/oct./2016</td> 
 
     <td>13/oct./2016</td> 
 
     <td>Sequelae of viral hepatitis</td> 
 
     <td>15</td> 
 
     <td> 
 
     <div class="btn-group btn-group-sm" role="group" aria-label="..."> 
 
      <div class="btn-group " role="group" aria-label="Voir le detail"> 
 
      <a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits"> 
 
       <span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 

 
      <div class="btn-group " role="group" aria-label="Valider les candidats"> 
 
      <a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats"> 
 
       <span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
      <div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation"> 
 
      <a href="/edsa-AgrementEPS/app_dev.php/formation/4039/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants"> 
 
       <span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
     </div> 
 
     </td> 
 
    </tr> 
 
    <tr data-toggle="collapse" data-target="#collapse4095" class="clickable"> 
 
     <td>Activités nautiques</td> 
 
     <td> Activités nautiques - 24/10/2016</td> 
 
     <td>24/oct./2016</td> 
 
     <td>21/oct./2016</td> 
 
     <td>Severe pre-eclampsia, third trimester</td> 
 
     <td>0</td> 
 
     <td> 
 
     <div class="btn-group btn-group-sm" role="group" aria-label="..."> 
 
      <div class="btn-group hidden" role="group" aria-label="Voir le detail"> 
 
      <a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4095 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits"> 
 
       <span class="glyphicon " aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 

 
      <div class="btn-group hidden" role="group" aria-label="Valider les candidats"> 
 
      <a href="/valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats"> 
 
       <span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
      <div class="btn-group hidden" role="group" aria-label="Imprimer la liste d'emargement pour cette formation"> 
 
      <a href="/print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 24/10/2016" title="Download PDF list of applicants"> 
 
       <span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
     </div> 
 
     </td> 
 
    </tr> 
 
    <tr data-toggle="collapse" data-target="#collapse3188" class="clickable"> 
 
     <td>Activités nautiques</td> 
 
     <td>Activités nautiques - 29/10/2016</td> 
 
     <td>29/oct./2016</td> 
 
     <td>26/oct./2016</td> 
 
     <td>Other secondary chronic gout</td> 
 
     <td>0</td> 
 
     <td> 
 
     <div class="btn-group btn-group-sm" role="group" aria-label="..."> 
 
      <div class="btn-group " role="group" aria-label="Voir le detail"> 
 
      <a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits"> 
 
       <span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 

 
      <div class="btn-group " role="group" aria-label="Valider les candidats"> 
 
      <a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats"> 
 
       <span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
      <div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation"> 
 
      <a href="/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants"> 
 
       <span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span> 
 
      </a> 
 
      </div> 
 
     </div> 
 
     </td> 
 
    </tr> 
 

 
    </table> 
 
</container>

+0

Строка '$ detailRow.style.visibility.toggle ('coll-row collapse');' не имеет абсолютно никакого смысла, чего вы пытаетесь достичь там? – Connum

ответ

2

Основная проблема заключается в том, что вы прикрепляли идентификатор для свертывания на неправильном элементе. Он должен быть прикреплен к элементу tr.expand-child, а не к элементу .expand-child td.

Я бы построил строку .expand-child целиком только после того, как у вас есть ответ AJAX.

И это хорошая привычка кэшировать элементы, которые вы будете повторно использовать.

Вот как я бы пересмотреть свой код:

var $table = $('.js-table'); 

$table.find('.js-view-parents').on('click', function(e) { 
    e.preventDefault(); 
    // cache elements 
    var $btn = $(e.target), $row = $btn.closest('tr'), 
     // find next immediate .expand-child 
     $nextRow = $row.next('tr.expand-child'); 
    // toggle button 
    $btn.toggleClass('glyphicon-eye-close glyphicon-eye-open'); 
    // if .expand-child row exist already, toggle 
    if ($nextRow.length) { 
     // show or hide .expand-child row if eye button is open or not, respectively 
     $nextRow.toggle($btn.hasClass('glyphicon-eye-open')); 
    // if not, create .expand-child row 
    } else { 
     $.ajax({ 
      url: '/echo/json/', 
      dataType: "json", 
      data: parentsData, 
      success: function (parentsData) { 
       var newRow = '<tr class="expand-child" id="collapse' + $btn.data('id') + '">' + 
        '<td colspan="12">' + 
        '<table class="table table-condensed table-bordered" width=100% >' + 
        '<thead>' + 
        '<tr>' + 
        '<th>Surname</th>' + 
        '<th>FirstName</th>' + 
        '<th>School Id</th>' + 
        '<th>School name</th>' + 
        '</tr>' + 
        '</thead>' + 
        '<tbody>'; 
       if (parentsData.parents) { 
        $.each(parentsData.parents, function(i, parent) { 
         newRow += '<tr>' + 
         '<td>' + parent.Firstname + '</td>' + 
         '<td>' + parent.Surname + '</td>' + 
         '<td>' + parent.schoolId + '</td>' + 
         '<td>' + parent.schoolName + ' ' + parent.commune + '</td>' + 
         '</tr>'; 
        }); 
       } 
       newRow += '</tbody></table></td></tr>'; 
       $row.after(newRow); 
      } 
     }); 
    } 
}); 

Demo

Для демонстрационных целей я закомментировать вызов AJAX.

+0

Спасибо @Mikey за дополнительный бит (рефакторинг, кеширование и т. Д.). –

2

Есть несколько вещей неправильно в вашем else блоке. Прежде всего,

$(this).closest('tr').slideToggle(); 

будет скользить вверх вашу родительскую строку, которая не то, что вы хотите - вы хотите, чтобы скрыть дочернюю строку.

var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child'); 

hasClass() возвращает логическое значение, вы не можете использовать его для фильтрации коллекции JQuery. То, что вы пытаетесь сделать, это выбрать следующий <tr>, который имеет класс .expand-child, например:

var $detailRow = $(this).closest('tr').next('tr.expand-child'); 

Следующая строка не имеет абсолютно никакого смысла.

$detailRow.style.visibility.toggle('table-row collapse'); 

Я предполагаю, что вы хотите, чтобы переключить классы этой строки вместо:

$detailRow.toggleClass('table-row collapse'); 

Эти изменения сделают первый показ/скрытие работы. Но есть проблема в вашем if блоке, а также:

$(".expand-child").slideUp(); 

Это позволит выбрать все элементы с классом .expand-child в DOM. Но вы, вероятно, захотите только выбрать дочернюю строку текущей родительской строки. Я, однако, не собираюсь отлаживать весь этот код для вас. Я думаю, что я сделал некоторые из основных проблем ясными (см. Эту обновленную скрипку: https://jsfiddle.net/r7sgL7vy/2/), и вы, надеюсь, сможете продолжить здесь.

Еще один пример: для производительности храните коллекции jQuery, которые вы используете более одного раза в переменных вместо того, чтобы запрашивать их каждый раз, когда они вам понадобятся. Вы уже делаете это с $detailRow, например, и с $this = ... - но он не используется поэтому. Почему бы не выбрать и не объявить все необходимые элементы dom в начале обработчика событий click, а затем использовать их везде? Помимо коэффициента производительности, он также делает ваш код намного чище, проще в понимании (для вас и для других) и облегчает выявление любых ошибок в вашей логике.

+0

Спасибо @Connum за подробные объяснения. Хотел бы я отметить как правильный ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^