У меня есть таблица, созданная обычным циклом 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
}
?>



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Сделайте это 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 этой функции, а результат - вашей функции переключения.
вы должны убедиться, что между <a> и <span> нет пробелов, иначе nextSibling <a> будет текстовым узлом
@tomhaigh - согласился. Обычно я бы использовал навигацию jQuery, которая автоматически пропускала бы текстовые узлы, но я не хотел предлагать использовать фреймворк. Вы также можете реализовать функцию, которая будет переходить к следующему нетекстовому родственнику и использовать его для получения DIV.
Просто используйте разные идентификаторы для каждой строки:
<?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>. Мне легче читать.
Кажется, что оба ответа работают, но этот я понимаю лучше. Могу ли я что-нибудь сделать в Javascript, чтобы он не выводил меня наверх страницы, когда он переключает скрытые данные?
Вместо использования # в качестве href используйте javascript: void (0) ИЛИ следуйте за переключателем в обработчике onclick с помощью "return false;"
Идеально. Вы, ребята, потрясающие. Огромное спасибо.
Просто чтобы вы знали, есть качественная разница между двумя решениями. Он будет искать в DOM каждый раз с самого начала именованный элемент. Мое решение начнется с данного элемента, используя следующий элемент. Наверное, это заметно на практике, только если страница очень сложная.
@tvanfosson Да, я это вижу. Как я уже упоминал, я бесполезен, когда дело доходит до JS, поэтому мне проще работать с ответом на PHP (этот) прямо сейчас, поэтому я его использую. Хотел бы я отметить оба как «ответы».
@Evan - для меня это не имеет значения, я просто хотел убедиться, что вы понимаете, что они похожи по функциям, но не эквивалентны.
Вот мое рекомендуемое (общее решение) использование 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>
Демо:
Рабочую демонстрацию этого можно найти здесь.
«использовать DOM-навигацию, чтобы показать / скрыть следующего брата (который должен быть SPAN)» Вы можете объяснить это немного подробнее?