Выбор строк и дочерних строк в таблицах данных

Я работаю над таблицей данных с дочерними строками (отмечены красным цветом), где можно выбрать только одну (основную) строку, щелкнув (отмечена синим цветом).

  1. Я хочу, чтобы основная строка оставалась выбранной, когда дочерняя строка снова разворачивается (красный знак минус) или складывается (зеленый знак плюс). Однако я не могу заставить его работать, как показано ниже.

  1. Кроме того, есть ли способ предотвратить выбор дочерних строк?

Вот функция Javascript, которую я реализовал до сих пор. Может ли кто-нибудь помочь мне с этими проблемами? Заранее большое спасибо!

// Text format of the displayed text in the child row
var format = function( d ) {  //
   return '<div class=\"child-row-abstract\"> ' + d[5] + '</div>';
};

// Column with index=0 is selectable per mouse
table.column(0).nodes().to$().css({cursor: 'pointer'});

// Open/close child row
table.on('click', 'td.details-control', function() {
   var td = $(this);
   var row = table.row(td.closest('tr'));
   if (!row.child.isShown()) {
      row.child(format(row.data())).show();
      td.html(", quote(symbol_minus), ");
   } else {
      row.child.hide();
      td.html(", quote(symbol_plus), ");
   }
});

Нам нужен полный фрагмент, чтобы помочь вам, пожалуйста, создайте его с помощью инструмента [<>]

Simone Rossaini 20.04.2023 14:31

Делает ли ваш код что-нибудь, как есть? Выдает ошибку? Нам также нужно увидеть html, чтобы понять, что происходит.

mykaf 20.04.2023 15:36

На самом деле, опубликованный код является частью блестящей программы, которая слишком велика, чтобы публиковать ее здесь. Я собираюсь разбить его на работающий пример, а затем опубликовать его.

Emil 20.04.2023 16:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
113
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я знаю, что вы ориентируетесь на приложение Shiny для этого, но вот ванильный подход DataTables, который вы сможете адаптировать к Shiny.

  1. Предотвратите работу выбора/отмены выбора строки, когда пользователь нажимает на первый столбец, содержащий кнопки открытия/закрытия.

  2. Для первого столбца включите выбор строки внутри кода прослушивателя событий открытия/закрытия.

  3. Убедитесь, что вы настроили стиль выбора как 'single'.


Шаг 1:

Это позволяет вам отделить функциональность открытия/закрытия от функциональности выбора/отмены выбора:

table.on( 'user-select', function ( e, dt, type, cell, originalEvent ) {
  if ( $(originalEvent.target).index() === 0 ) {
    e.preventDefault();
  }
} );

Ссылка.


Шаг 2:

Добавьте row.select(); в конец кода прослушивателя событий открытия/закрытия.

Ссылка.


Шаг 3:

Используйте стиль выделения одной строки.

select: {
  style: 'single'
}

Ссылка.


Базовая демонстрация:

Примечание: в демо нет значков + (открыть) и - (закрыть) — так что вам нужно их представить и просто щелкнуть по пустым ячейкам в первом столбце.

var dataSet = [{
    "id": "123",
    "name": "Tiger Nixon",
    "position": "System Architect",
    "salary": "$320,800",
    "start_date": "2011/04/25",
    "office": "Edinburgh",
    "extn": "5421"
  },
  {
    "id": "456",
    "name": "Donna Snider",
    "position": "Customer Support",
    "salary": "$112,000",
    "start_date": "2011/01/25",
    "office": "New York",
    "extn": "4226"
  },
  {
    "id": "567",
    "name": "Cedric Kelly",
    "position": "Senior Javascript Developer",
    "salary": "$433,060",
    "start_date": "2012/03/29",
    "office": "Edinburgh",
    "extn": "6224"
  },
  {
    "id": "432",
    "name": "Airi Satou",
    "position": "Accountant",
    "salary": "$162,700",
    "start_date": "2008/11/28",
    "office": "Tokyo",
    "extn": "5407"
  },
  {
    "id": "987",
    "name": "Brielle Williamson",
    "position": "Integration Specialist",
    "salary": "$372,000",
    "start_date": "2012/12/02",
    "office": "New York",
    "extn": "4804"
  }
];

/* Formatting function for row details - modify as you need */
function format(d) {
  // `d` is the original data object for the row
  return '<table class = "cell-border" cellpadding = "5" cellspacing = "0" border = "0" style = "padding-left:50px;">' +
    '<tr>' +
    '<td>Full name:</td>' +
    '<td>' + d.name + '</td>' +
    '</tr>' +
    '<tr>' +
    '<td>Extension number:</td>' +
    '<td>' + d.extn + '</td>' +
    '</tr>' +
    '<tr>' +
    '<td>Extra info:</td>' +
    '<td>And any further details here (images etc)...</td>' +
    '</tr>' +
    '</table>';
}

$(document).ready(function() {

  var table = $('#example').DataTable({
    select: {
      style: 'single'
    },
    data: dataSet,
    "columns": [{
        "className": 'details-control',
        "orderable": false,
        "data": null,
        "defaultContent": ''
      },
      {
        "data": "name"
      },
      {
        "data": "position"
      },
      {
        "data": "office"
      },
      {
        "data": "salary"
      }
    ],
    "order": [
      [1, 'asc']
    ]
  });



  // Add event listener for opening and closing details
  $('#example tbody').on('click', 'td.details-control', function() {
    var tr = $(this).closest('tr');
    var row = table.row(tr);

    if (row.child.isShown()) {
      // This row is already open - close it
      row.child.hide();
      tr.removeClass('shown');
    } else {
      // Open this row
      row.child(format(row.data())).show();
      tr.addClass('shown');
    }
    row.select();
  });


  table
    .on('user-select', function(e, dt, type, cell, originalEvent) {
      if ($(originalEvent.target).index() === 0) {
        e.preventDefault();
      }
    });




});
<!doctype html>
<html>

<head>
  <meta charset = "UTF-8">
  <title>Demo</title>
  <script src = "https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src = "https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
  <link rel = "stylesheet" type = "text/css" href = "https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">

  <link href = "https://cdn.datatables.net/select/1.6.2/css/select.dataTables.min.css" rel = "stylesheet" />
  <script src = "https://cdn.datatables.net/select/1.6.2/js/dataTables.select.min.js"></script>

  <link rel = "stylesheet" type = "text/css" href = "https://datatables.net/media/css/site-examples.css">

  <style>
    td.details-control {
      background: url('./resources/details_open.png') no-repeat center center;
      cursor: pointer;
    }
    
    tr.shown td.details-control {
      background: url('./resources/details_close.png') no-repeat center center;
    }
  </style>

</head>

<body>

  <div style = "margin: 20px;">

    <table id = "example" class = "display dataTable cell-border" style = "width:100%">
      <thead>
        <tr>
          <th></th>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Salary</th>
        </tr>
      </thead>
      <tfoot>
        <tr>
          <th></th>
          <th>Name</th>
          <th>Position</th>
          <th>Office</th>
          <th>Salary</th>
        </tr>
      </tfoot>
    </table>

  </div>



</body>

</html>

Кроме того, убедитесь, что вы включили пакет расширения "Выбрать", например, `DT::datatable(data = df, selection = "none", extensions = c("Buttons", "Select"), options = list( select = list(style = "single", items = "row")), callback = DT::JS(" ... "))' Еще раз большое спасибо!

Emil 25.04.2023 14:24

Другие вопросы по теме