Jump to content
  • 0

Мини-конкурс


s0rr0w
 Share

Question

Цель мини-конкурса проста - по-новому посмотреть на привычные вещи. Звучит странно? Отнюдь! При промышленном производстве кода остается очень мало времени на развитие. И не всегда хватает времени на то, чтобы посидеть и подумать над тем, как что-то реализовать так, чтобы это было более-менее правильно.

Этот конкурс с довольно странным призом, но получить его могут многие. Если точнее, то призом будет бесценный опыт в решениях подобных задач и проблем. Хотите больше опыта? Просто принимайте участие. Согласен, что тяжелее всего будет самому первому смельчаку, который отважится на создание первого прототипа, но никто не запрещает делать несколько прототипов, постоянно улучшая свой или чужой код.

Правила просты. Я создаю некое подобие ТЗ. Это неточная формулировка какой-либо задачи (добавим чуток реализма, в жизни в 95% отсутствует не только ТЗ, но и понимание того, что хочет получить заказчик на выходе). Вы решаете эту задачу так, как вы бы ее решили, и выкладываете код в виде файла или текста сообщения. Мы коллективно исследуем код, задаем вопросы, подсказываем как надо решить. А потом выбираем победителя конкурса.

Разрешено улучшать чужой код. Мало того, это даже приветствуется. Разрешено использовать фреймворки и библиотеки.

Запрещено корчить из себя умника без адекватного подтверждения своих слов.

Ну что, попробуем?

Задача №1.

Создаем приложение.

Есть таблица на n строк. В какой-либо ячейке таблицы может стоять "переключатель", который создает или убирает контейнер под строкой таблицы, в которой и содержится переключатель. Нужно каким-либо способом передать некий идентификатор строки таблицы в показываемый контейнер.

Link to comment
Share on other sites

Recommended Posts

  • 0

Интересно, просто у некоторых нет времени, а некоторые не представляют как) вот например я ща попробую сделатль, если выйдет, отпишу)

Хм, а количество ячеек известно? или тоже n?

Edited by Vindex10
Link to comment
Share on other sites

  • 0

Если правильно понял задачу, самое тривиальное решение:

<script>
function insMe(obj)
{
var bBox = document.getElementById('bBox');
bBox.style.display == 'block' ? bBox.style.display = 'none' : bBox.style.display = 'block';
bBox.value = obj.parentNode.parentNode.id;
}
</script>

<table border=1>
<tr id='zxc1'>
<td><input type='button' value='1' onClick='insMe(this)'></td>
<td>sdf</td>
<td>sdf</td>
</tr>
<tr id='zxc2'>
<td><input type='button' value='2' onClick='insMe(this)'></td>
<td>sdf</td>
<td>sdf</td>
</tr>
</table>

<input type='text' id='bBox' style='display: none'>

Edited by XAOPT
Link to comment
Share on other sites

  • 0
Интересно, просто у некоторых нет времени, а некоторые не представляют как) вот например я ща попробую сделатль, если выйдет, отпишу)

Хм, а количество ячеек известно? или тоже n?

n много, пусть будет m :)

Link to comment
Share on other sites

  • 0
Если правильно понял задачу, самое тривиальное решение:

XAOPT, спасибо за решение!

Давай теперь посмотрим на твои ошибки. Самая первая ошибка - ты начал делать что-то, но ты был не сильно уверен, правильно ты ты что-то делаешь, или нет. Что я ждал от тебя - вопросы. Много много вопросов. Особенно одного - а зачем все это нужно?

Уточняю ТЗ.

| switch 1 | cell 2 | cell 3 | ... | cell n |
——————————————-
| контейнер |
——————————————-
| switch 2 | cell 2 | cell 3 | ... | cell n |
| switch 3 | cell 2 | cell 3 | ... | cell n |

Выглядеть должно примерно так.

Теперь по коду.

Почему ты используешь идентификатор TR в качестве идентификатора строки?

obj.parentNode.parentNode.id;

При изменении кода HTML придется перерабатывать и JS код. Если тебе нравится из-за одной правки искать еще 250 мест, где это нужно поправить, то ты можешь и дальше пользоваться такими приемами, но, скорее всего, ты будешь неэффективным кодером в команде. Такой код - верный путь к багам. Заказчики будут не рады.

bBox.style.display == 'block' ? bBox.style.display = 'none' : bBox.style.display = 'block';

А что, если это будет не блочный элемент, а, например, TD? Ты понимаешь последствия такого прямого присвоения? На этом форуме несколько раз было показано правильное решение.

Что будет, если объект bBox будет трагически убит другим скриптом? Пользователи будут не рады увидеть сообщение об ошибке.

Давай избавимся от недостатков, и сделаем скрипт немного гибче. И вернемся в рамки ТЗ. :)

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

Link to comment
Share on other sites

  • 0

Можно было бы вместо id передавать указатель типа [object] на строку, или индекс строки.

А вот про display:block было бы интересно услышать более правильное решение.

Этот контейнер, кстати, будет создаваться динамически при нажатии на switch, скажем, или он будет создан статически под каждой строкой?

Edited by Ogalig
Link to comment
Share on other sites

  • 0
Можно было бы вместо id передавать указатель типа [object] на строку, или индекс строки.

А что дает ссылка на ноду? А индекс строки?

Представьте, что таблица наполняется из базы. В ячейку записывается ф.и.о., нужно получить детальную информацию о человеке путем нажатия на соответсвующую кнопку.

А вот про display:block было бы интересно услышать более правильное решение.

http://forum.htmlbook.ru/index.php?showtopic=11543

Вот тут есть более правильное решение.

Этот контейнер, кстати, будет создаваться динамически при нажатии на switch, скажем, или он будет создан статически под каждой строкой?

Хороший вопрос. Но наиболее подходящий ответ на него нужно будет найти вам самим. Проанализируйте оба варианта, и найдите правильное решение.

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

В коллективе нужно будет быстро находить аргументацию, почему вы должны сделать именно так, а не по-другому.

Link to comment
Share on other sites

  • 0

Этот контейнер, кстати, будет создаваться динамически при нажатии на switch, скажем, или он будет создан статически под каждой строкой?

Можно по-моему его один раз создать (хоть где) и просто аппендить в нужное место.

Link to comment
Share on other sites

  • 0
Можно по-моему его один раз создать (хоть где) и просто аппендить в нужное место.

Решение хорошее, но только на половину. Нельзя использовать в двух, трех, n местах одновременно, как правильно подметил ZoNT. Но, как я уже сказал, есть позитивные стороны этого решения.

Link to comment
Share on other sites

  • 0

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

Link to comment
Share on other sites

  • 0
Ну если он динамически создается, то можно прямо при создании загружать в него все необходимые данные из строки. Прочитать на переключатель какой строки нажали не проблема, даже можно вообще не использовать никаких ID-в.

Ок, скрипт можно увидеть?

Link to comment
Share on other sites

  • 0

Просто выходные были :) .

Примерно так.

КСС:

.ForRow
{
height:110px;
position:relative;
}

.ForRow td
{
vertical-align:top;
}

.ForDiv
{
border:Solid 1px Orange;
background-color:#ddd;
height:80px;
width:150px;
position:absolute;
top:30px;
left:5px;
}

Джава:

function onClick(elem) // Вызывается по событию клика на переключателe
{
var row = elem.parentNode.parentNode;
row.className="ForRow";

var subCell=document.createElement("TD");
row.appendChild(subCell);

var div = document.createElement("DIV");
div.className="ForDiv";

//Вот тут мы и присваиваем нужные атрибуты создаваемому списку
for(i=1;i<row.cells.length;i++)div.innerHTML=div.innerHTML+" "+row.cells[i].innerHTML;

subCell.appendChild(div);
}

Пример таблицы:

<table>
<tr><td><input type="button" value="CH" onclick="onClick(this)" /></td><td>Первая строка</td><td>dgdfgdfg</td></tr>
<tr><td><input type="button" value="CH" onclick="onClick(this)" /></td><td>Вторая строка</td><td>dgdfgdfg</td></tr>
<tr><td><input type="button" value="CH" onclick="onClick(this)" /></td><td>Еще одна строка</td><td>dgdfgdfg</td></tr>
<tr><td><input type="button" value="CH" onclick="onClick(this)" /></td><td>Последняя строка</td><td>dgdfgdfg</td></tr>
</table>

Единственное что под не ИЕ ее карежит, пока не разобрался почему.

Индексация строк в таблице не нарушается, айдишники нигде не используются.

Какие именно данные передавать из задания я пока не понял, поэтому просто передаю содержимое ячеек без селектора. Но модернизировать под необходимые значения не сложно. Передавать индефикатор строки или указатель на нее не имеет смысла, т.к. сам контейнер находиться в этой строке.

Так же нет функции закрытия всплывающей подсказки, но если потребуется допишу.

Жду конструктивной критики. :(

Edited by Ogalig
Link to comment
Share on other sites

  • 0
Какие именно данные передавать из задания я пока не понял, поэтому просто передаю содержимое ячеек без селектора.

Вот представь, у тебя есть массив данных

id: 11 | name: "Иванов Иван Иванович" | sex: 1 | email: "x@xx.com" 
id: 14 | name: "Иванова Мария Никитична" | sex: 0 | email: "y@yy.com"
id: 234 | name: "Петров Петр Петрович" | sex: 1 | email: "z@zz.com"

Тебе по кнопке надо показывать дополнительную информацию. Чтобы ее показать, нужно знать id записи.

Жду конструктивной критики. :)

Не дочитал задание. Кнопка должна включать и выключать дополнительный контейнер. Нажал - показался, нажал - убрался, нажал - показался, нажал - убрался...

Link to comment
Share on other sites

  • 0

Айдишник записи содержится в одной из ячеек таблицы? Тогда просто надо читать содержимое нужной ячейки. Я правильно понял? Обработка айдишника и поиск по нему в задание входит?

Сейчас допишу чтоб убирался.

Не могли бы пока помочь с тем что в мозиле так криво отображается?

Link to comment
Share on other sites

  • 0
Айдишник записи содержится в одной из ячеек таблицы?

Не обязательно. Его нужно передать одним из способов. Это может быть как прямая запись значения id при генерации таблицы ( onclick="foo( 11 );"), или записано в JS массив, к которому идет обращение при нажатии на кнопку.

Обработка айдишника и поиск по нему в задание входит?

Не входит. Это для понимания, что мы делаем, зачем это мы делаем

Не могли бы пока помочь с тем что в мозиле так криво отображается?

position: absolute

Link to comment
Share on other sites

  • 0

Примерно так тогда

КСС:

.ForRow
{
height:110px;

}

.ForRow td
{
vertical-align:top;
}

.ForDiv
{
border:Solid 1px Orange;
background-color:#ddd;
height:80px;
width:150px;
position:absolute;
top:2px;
}

.ForSubDiv
{
height:0px;
width:0px;
position:relative;
}

Скрипт:

function onClick(elem) // Вызывается по событию клика на переключателe
{
var row = elem.parentNode.parentNode;
if(elem.nextSibling && elem.nextSibling.tagName=="DIV" && elem.nextSibling.name=="subDiv")
{
elem.parentNode.removeChild(elem.nextSibling);
row.className="";
}

else
{
row.className="ForRow";

subDiv=document.createElement("DIV");
subDiv.className="ForSubDiv";
subDiv.name="subDiv";
elem.parentNode.appendChild(subDiv);

var div = document.createElement("DIV");
div.className="ForDiv";

//Вот тут мы и присваиваем нужные атрибуты создаваемому списку
//for(i=1;i<row.cells.length;i++)div.innerHTML=div.innerHTML+" "+row.cells[i].innerHTML;
div.innerHTML=row.rowIndex;//Тут по идее вызываеться ф-я которая ищет запись в массиве по индексу строки

subDiv.appendChild(div);
}
}

Единственное что пока недоработал так это то что переключатель должен находиться в первой колонке. Для исправления нужно просто скриптом высчитывать ширину колонок перед переключателе и выставлять координаты абсолютного позиционирования относительно этой ширины. Просто не было времени.

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

Link to comment
Share on other sites

  • 0
В иннерхтмл дива пока передается индекс строки, вместо этого должна вызываться функция которая по индексу строки ищет соответствующую запись в массиве. Но написание этой функции в задание уже не входит, насколько я понял.

Не входит.

Что будет с твоим скриптом, когда на него натравить функцию пересортировки таблицы по второй колонке?

И зачем тебе див с абсолютным позиционированием, которому будет высчитываться высота и так далее?

Почему ты не хочешь использовать примитивный до ужаса код

<table>
<tr>
<td>cell1</td>
<td>cell2</td>
<td>cell3</td>
</tr>
<tr>
<td colspan="100">
Sub container
</td>
</tr>
</table>

Пока что твой скрипт нереально использовать в качестве удобного компонента для сайта или приложения. Но, ты на вполне правильном пути и делаешь успехи. С каждым разом приближаешься ближе к первому месту в данном конкурсе.

Очень жаль, что таких как ты больше никого нет. Ребята, то, что я вам даю, не даст ни один преподаватель ни в одном вузе. Да и не во всех больших компаниях этому учат.

Link to comment
Share on other sites

  • 0

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

Кстати. А почему должен быть обязательно связанный массив? Не легче всю информацию, или хотя бы ссылки на нее грузить в невидимые столбцы той же строки?

Link to comment
Share on other sites

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

А почему? Индексация строк нам ничего не дает.

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

Если писать код только для того, чтобы один раз использовать, то при любом изменении задания вам придется постоянно его переписывать. Иногда кардинальным образом. А это время и деньги. Лучше потратить больше время на начальное создание скрипта, а потом тратить по 5 минут на каждую переделку, чем постоянно тратить день на каждую мелочь.

Поэтому, приняв ограничение в виде нерушимой индексации строк, этим серьезно ухудшается гибкость скрипта к будущим изменениям.

Кстати. А почему должен быть обязательно связанный массив? Не легче всю информацию, или хотя бы ссылки на нее грузить в невидимые столбцы той же строки?

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

<a href="#" onclick="switchButtonState( 11, this ); return false;">батон</a>

Link to comment
Share on other sites

  • 0

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

Как я понял основная проблема это где хранить данные или ссылку на данные? Если бы я создавал таблицу, то поместил бы их или в кнопку, как было предложено, или же вообще все данные поместил бы в таблицу и прятал столбцы, естественно если данных немного и это не сильно скажется, например, на трафике. В таком случае тягать их из этой же самой строки тоже не проблема. Собственно это уже в алгоритме и делается.

Баг с тем что кнопка должна находиться в первой ячейки строки я сейчас исправлю.

П.С, Может уже на "ты"? А то ты сам перескакиваешь с ты на вы от сообщения к сообщению. :angry:

Edited by Ogalig
Link to comment
Share on other sites

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

Может ты не в том направлении думаешь? :)

Смотри, давай перевернем все с ног на голову. Мы возьмем за константу не то, что HTML статичен, а что HTML динамичен и никогда не является константой.

Как такое может быть? Да очень просто.

Скрипт может работать не с DOM-структурой, а с некой абстрактной структурой, которая является логической надстройкой над DOM.

Теперь ближе к нашему примеру. Возьмем кнопку. Нужно узнать TR в которой она находится. Самый простой способ - через parentNode.parentNode

Как только кнопка будет помещена в <div>, скрипт перестанет работать. Можно написать функцию getParentByTagName( node, "TR" ), которая будет искать у ноды парента с заданным именем. Это спасает, но не сильно, так как при помещении ссылки еще в одну таблицу (вариант редкий, но случиться может), скрипт работать перестанет. И, можно присвоить нужной TR определенный класс, который будет выступать в роли идентификатора, и искать парента при помощи функции getParentWithClassName(node, "className"). Это вариант, которому пофиг структура HTML, главное, чтобы нужная нода имела определенное имя класса.

Таким образом можно развязать руки дизайнерам, им нужно будет следовать только общим правилам, и скрипт не нужно будет переписывать при каждом чихе заказчика.

Как я понял основная проблема это где хранить данные или ссылку на данные? Если бы я создавал таблицу, то поместил бы их или в кнопку, как было предложено, или же вообще все данные поместил бы в таблицу и прятал столбцы, естественно если данных немного и это не сильно скажется, например, на трафике. В таком случае тягать их из этой же самой строки тоже не проблема. Собственно это уже в алгоритме и делается.

Основная проблема в том, как построить скрипт, чтобы было все равно, где именно хранить данные. Методы построения таблицы вторичны.

П.С, Может уже на "ты"? А то ты сам перескакиваешь с ты на вы от сообщения к сообщению. :angry:

На вы я обращаюсь к множеству людей. С тобой на ты. :P

Link to comment
Share on other sites

  • 0

Подобную мысль я тоже рассматривал. К имени класса мне тоже не очень нравиться привязываться, т.к. я за динамичный ксс :) . Как лучшую альтернативу я так же рассматривал привязываться к атрибуту NAME, т.к. этот атрибут не обязательно должен быть уникальным. Весь вопрос сводиться в конечном счете к тому к чему привязываться.

Тоже хотел написать подобную функцию которая ищет родителя по атрибутам, но отложил ее на потом ) .

Link to comment
Share on other sites

  • 0
Подобную мысль я тоже рассматривал. К имени класса мне тоже не очень нравиться привязываться, т.к. я за динамичный ксс :) . Как лучшую альтернативу я так же рассматривал привязываться к атрибуту NAME, т.к. этот атрибут не обязательно должен быть уникальным. Весь вопрос сводиться в конечном счете к тому к чему привязываться.

Мысль про данамичный ксс не понял.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy