Переключить отображение данных внутри ячейки таблицы

У меня есть таблица, созданная обычным циклом PHP. Я хочу создать форму в первом столбце каждой строки, которая по умолчанию скрыта, но появляется, когда вы щелкаете ссылку переключения в этой строке.

Я могу сделать обычный div с возможностью переключения, создав идентификатор CSS с именем hidden и установив display: none;. К сожалению, я не могу продолжать создавать div с id=hidden, которые автоматически связываются с предыдущей ссылкой.

У меня довольно мало опыта работы с Javascript и CSS, поэтому я в основном пытался сделать это, исправляя примеры, но у меня ничего не вышло. Я читал в некоторых местах, что вы не можете помещать div внутри таблицы, так что, возможно, я ошибаюсь.

Вот пример того, что делает код и как бы я хотел, чтобы он работал, но, конечно, это не так.

<script language = "JavaScript" type = "text/javascript">
    function toggle(id) {
        var state = document.getElementById(id).style.display;
            if (state == 'block') {
                document.getElementById(id).style.display = 'none';
            } else {
                document.getElementById(id).style.display = 'block';
            }
        }
</script>


<?php

while($array = mysql_fetch_array($sql))
    {
?>
<tr>
    <td>
<?php
        echo $array['some_data'];
?>
        <a href = "#" onclick = "toggle('hidden');">Toggle</a>
        <div id = "hidden"><?php echo $array['hidden_thing']; ?></div>
    </td>
    <td>
        <?php echo $array['some_other_data']; ?>
    </td>
</tr>
<?php
    }
?>
Поведение ключевого слова "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
0
4 367
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Сделайте это span вместо DIV, поскольку я думаю, что некоторые браузеры не поддерживают div внутри элементов таблицы. Кроме того, вместо того, чтобы ссылаться на него по идентификатору, передайте this.nextSibling() переключателю, используя DOM-навигацию, чтобы получить следующего брата (которым должен быть SPAN) для отображения / скрытия.

  function toggle(ctl) {
      var state = ctl.style.display;
      if (state == 'block') {
          document.getElementById(id).style.display = 'none';
      } else {
          document.getElementById(id).style.display = 'block';
      }
  }


  <a href = "#" onclick = "toggle(this.nextSibling);">Toggle
  </a><div><?php echo $array['hidden_thing']; ?></div>

РЕДАКТИРОВАТЬ: как предлагает @tomhaigh (и как показано в примере), для того, чтобы это работало, вам нужно убедиться, что между привязкой и div нет текста / пробелов. Вы также можете написать функцию, которая, учитывая элемент DOM, выбирала бы следующий нетекстовый элемент DOM и возвращала бы его. Затем передайте this этой функции, а результат - вашей функции переключения.

«использовать DOM-навигацию, чтобы показать / скрыть следующего брата (который должен быть SPAN)» Вы можете объяснить это немного подробнее?

Evan 09.01.2009 14:22

вы должны убедиться, что между <a> и <span> нет пробелов, иначе nextSibling <a> будет текстовым узлом

Tom Haigh 09.01.2009 14:24

@tomhaigh - согласился. Обычно я бы использовал навигацию jQuery, которая автоматически пропускала бы текстовые узлы, но я не хотел предлагать использовать фреймворк. Вы также можете реализовать функцию, которая будет переходить к следующему нетекстовому родственнику и использовать его для получения DIV.

tvanfosson 09.01.2009 14:39
Ответ принят как подходящий

Просто используйте разные идентификаторы для каждой строки:

<?php
$count = 0;
while($array = mysql_fetch_array($sql)) {
  $id = 'hidden' . $count++;
  $data = $array['some_data'];
  $hidden = $array['hidden_thing'];
  $other_data = $array['other_data'];
  echo <<<END
<tr>
  <td>$data <a href = "#" onclick = "toggle('$id');>Toggle</a>
    <div id = "$id">$hidden_thing</div>
  </td>
  <td>$other_data</td>
</tr>

END;
}

Кстати, это чисто стилистическая проблема, но я предпочитаю синтаксис здесь-документа, который я разместил здесь, нескольким блокам <? Php>. Мне легче читать.

cletus 09.01.2009 14:34

Кажется, что оба ответа работают, но этот я понимаю лучше. Могу ли я что-нибудь сделать в Javascript, чтобы он не выводил меня наверх страницы, когда он переключает скрытые данные?

Evan 09.01.2009 14:39

Вместо использования # в качестве href используйте javascript: void (0) ИЛИ следуйте за переключателем в обработчике onclick с помощью "return false;"

tvanfosson 09.01.2009 14:45

Идеально. Вы, ребята, потрясающие. Огромное спасибо.

Evan 09.01.2009 14:47

Просто чтобы вы знали, есть качественная разница между двумя решениями. Он будет искать в DOM каждый раз с самого начала именованный элемент. Мое решение начнется с данного элемента, используя следующий элемент. Наверное, это заметно на практике, только если страница очень сложная.

tvanfosson 09.01.2009 14:51

@tvanfosson Да, я это вижу. Как я уже упоминал, я бесполезен, когда дело доходит до JS, поэтому мне проще работать с ответом на PHP (этот) прямо сейчас, поэтому я его использую. Хотел бы я отметить оба как «ответы».

Evan 09.01.2009 14:59

@Evan - для меня это не имеет значения, я просто хотел убедиться, что вы понимаете, что они похожи по функциям, но не эквивалентны.

tvanfosson 09.01.2009 17:34

Вот мое рекомендуемое (общее решение) использование jQuery для относительной ссылки на события вместо поддержания идентификаторов для каждой строки и формы. Это также позволяет вам легко скрывать неактивные формы строк, что является хорошей идеей, поскольку одновременно может быть отправлена ​​только одна форма.

HTML:

<table id = "tableForms" class = "table">
  <tr>
    <td class = "rowForm"><form><span>form1 content</span></form></td>
    <td class = "showRowForm">click on row to show its form</td>
    </tr>
  <tr>
    <td class = "rowForm"><form><span>form2 content</span></form></td>
    <td class = "showRowForm">click on row to show its form</td>
    </tr>
  <tr>
    <td class = "rowForm"><form><span>form3 content</span></form></td>
    <td class = "showRowForm">click on row to show its form</td>
    </tr>
</table>

Javascript:

<script type = "text/javascript" src = "/assets/js/jquery.min.js"></script>
<script type = "text/javascript">
//as soon as the DOM is ready, run this function to manipulate it
$(function() {
    // get all tr elements in the table 'tableForms' and bind a 
    // function to their click event
    $('#tableForms').find('tr').bind('click',function(e){
        // get all of this row's sibblings and hide their forms.
        $(this).siblings().not(this).find('td.rowForm form').hide();

        // now show the current row's form
        $(this).find('td.rowForm form').show();
    }).
    // now that the click event is bound, hide all of the forms in this table
    find('td.rowForm form').hide();
});
</script>

Демо:

Рабочую демонстрацию этого можно найти здесь.

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