jQuery

индекс
283,92

jQuery.Tree

Товарищ caffeine искал плагин к jQuery, который делает дерево с чекбоксами, которые имеют три состояния — установленный, снятый и «чуть-чуть установленный». Не нашел, попросил меня написать. Я написал и делюсь со всеми желающими.

Страница проекта: code.google.com/p/jquery-tree/

Текущая версия: jquery-tree.googlecode.com/files/jquery-tree.tar.gz

Пример (на народе, потом, может быть, перенесу): max-at-work.narod.ru/jquery.tree.test.html
Пример с отключенным js: max-at-work.narod.ru/jquery.tree.test.nojs.html

Использование:

<head>
  <link rel="stylesheet" type="text/css" href="css/jQuery.Tree.css" />
</head>
<body>
  <ul id="tree">
    <li>
      <label><!-- Наличие лейбла критично -->
        <input type="checkbox" />Элемент с чекбоксом
      </label>
    </li>
    <li>
      <label>
        <input type="checkbox" />Категория
      </label>
      <ul>
        <li>
          <label>
            <input type="checkbox" />Элемент с чекбоксом
          </label>
        </li>
      </ul>
    </li>
  </ul>
  
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js">
  </script>

  <script type="text/javascript" src="jQuery.Tree.js">
  </script>
  
  <script type="text/javascript">
    $(document).ready(function(){
      $("#tree").Tree();
    });
  </script>
</body>


* This source code was highlighted with Source Code Highlighter.


Распространяется «как есть», работает в FF3.5, IE8, Chrome 4 (остальные не смотрел).

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

Как подсказывают 1x1 и Mikeprosoft, есть плагин с аналогичным функционалом jstree.com/. Главное отличие — мой позволяет отправить форму и без js.

_________
Текст подготовлен в ХабраРедакторе
+62
2 декабря 2009, 17:34
149

комментарии (54)

0
LeeMiller #
а примерчик можно?
+6
maxatwork #
Вот так примерно:
max-at-work.narod.ru/jquery.tree.test.html
+1
Mecid #
несколько дней назад искал что-то похожее, очень помогли спасибо
0
beos #
Пробывал на jQuery 1.6.4
чекбоксы работают не стабильно (то отмечаються то нет)
Исправилось путём удаления:

//Для IE вешаем обработчики на лейбл
.closest('label').click(function(){
labelClick(this);
checkCheckbox($('input:checkbox', this));
});
0
zelenoff #
Спасибо!!! очень нужная штука, осталось в вид под нормальное дерево сделать)
0
tzlom #
а почему у вас комментарии в utf-8 а html в 1251?
+2
maxatwork #
Это особенность народа — он отдает в 1251.
+1
alexeydg #
драг дропа не будет?
+2
maxatwork #
Будет время — сделаю.
Да, в гугл-коде можно добавлять фичреквесты, буду смотреть периодически туда.
+1
1x1 #
0
Stom #
это совсем другое, прочтите начало топика
+2
maxatwork #
Тут кагбэ не дерево само по себе важно. Тут важно, чтоб можно было в чекбоксы тыкать. Изначально нужно было для выбора регионов-областей-городов:
— выбрали один город — отметилась соотв. область и регион, как «частично выбранные».
— выбрали все города в области — пометилась область, как выбранная
— сняли все города в области — сняли отметку с области
— выбрали все области в регионе — выбрался регион

ну и т. д.
+4
Mikeprosoft #
А вот это http://jstree.com/demo/checkbox — разве не то же самое?
+1
maxatwork #
А это в форме не отправишь без js'а =)
0
ilyaagron #
эээ… вы как бы уже jQuery заставили юзера скачать и создали свое дерево с его помощью, в чем проблема использования JS..?
или это был сарказм?
или «типа круто, что форму, созданную JS'ом можно отправить уже без JS?»

вообще вещь понравилась
+2
maxatwork #
Нет. Дерево не создается скриптом, оно выводится в html как неупорядоченный список. Чекбоксы тоже есть в html.
Скрипты только добавляют более удобное-красивое отображение и расширяют функционал.

Посмотрите пример с отключенным js'ом — чекбоксы отметить можно, древовидная структура осталась. Нет кнопок «свернуть/развернуть» и поддерево нельзя выделить щелчком по родительскому чекбоксу.

max-at-work.narod.ru/jquery.tree.test.nojs.html
+1
Guria #
При отключенном JS не следует делать группу чекбоксом, как мне кажется, ибо поведение формы становится не очевидным.
0
maxatwork #
Да, тут вы, пожалуй, правы.
0
wpm1 #
а как добиться функционала чтобы «кликнул по родителю и потомки не стали отмеченными как „выбранные“? спасибо.
0
Stom #
а так, довольно симпатично получилось
+1
Sef4eg #
ниче, секси, пока надобности нет но в избранное не помешает
+9
nord_ua #
Может быть картинки checkbox-partial.png, checkbox-unchecked.png, checkbox-checked.png объеденить в одну?.. Как это называется, спрайт, чтоли.
У меня интернет временами медленный и при раскрытии дерева полностью отмеченная ветка долго была без чекбокса вообще.
0
SolarSoul #
Да, поддерживаю. СSS-спрайт тут точно нужен
0
nord_ua #
Ээээм. И еще такой вопрос: сначала надо выгнать HTML который потом оживится с помощью скрипта?
А в чем удобство такого подхода по сравнению с рендером дерева из JS?
0
nord_ua #
Если что — смотрел в исходники страницы max-at-work.narod.ru/jquery.tree.test.html
+1
kolpeex #
Очевидно, страница остаётся рабочей при отключённом Javascript
0
nord_ua #
Понял. Спасибо за пояснение.
0
linas #
То что нужно, спасибо.
0
maxatwork #
Да не за что ;-)
+1
pxx #
У обоих решений (Вашего и jstree.com) есть незначительный но недостаток — у «чекбоксов» нет фокуса, т.е. их нельзя пролистать/ткнуть с клавиатуры.
В Вашем случае это можно решить, т.к. есть закладка в коде (реальный чекбокс за границами видимости).
Достаточно прикрутить еще несколько событий и предусмотреть визуальную часть фокусного элемента.
Как-то так на псевдокоде:
— checkbox.onfocus => (parent label).focus();
— checkbox.onblur => (parent label).unfocus();
— checkbox.onchange => (parent label).change();
— label.onclick => (child checkbox).focus().change();

И было бы неплохо сделать подсвечивание «чекбокса» на onmouseover примерно так, как это сделано у jstree.com
0
maxatwork #
Да, про это тоже думал.
0
pxx #
Еще одно улучшение пришло на ум.
Если сделать все состояния чекбокса CSS-спрайтом, станет немного лучше:
— один запрос на сервер вместо трех;
— очень чуть-чуть, но меньше суммарный объем данных;
— и самое главное — не будет мигания при подгрузке другого состояния в процессе работы.
0
maxatwork #
Тоже думал про это, и к тому же чуть выше предложили уже =)
habrahabr.ru/blogs/jquery/77064/#comment_2244897
0
maxatwork #
На самом деле, тут больше, имхо, логика/разметка важна, т.к. стили все равно под каждый проект придется подгонять, соответственно, они там только в роли примера.
0
danilissimus #
какой браузер используете, уважаемый?
в опере все отлично
0
danilissimus #
0
pxx #
Опера — мой основной браузер для серфинга, поэтому в первую очередь я попробовал в ней (версия 10.10). Потом ФФ, ИЕ8, Хром. Ни в одном нет намека. Скорее всего такое можно увидеть в какой-то из 9-х версий. Там был такой паразитный фрейм на фокусе, кот которого в итоге Опера отказалась из-за многочисленных жалоб от юзеров и разработчиков сторонних JS-компонентов, ибо это было абсолютно не так, как в большинстве остальных браузеров, непредсказуемо, неудобно.
Если оно будет выглядет так, как на скриншоте, то лучше уж никак.
+1
danilissimus #
нажмите Shift, и потом управляйте фокусом стрелками.
ваш К.О.
0
pxx #
OMG! Век живи — век учись. Спасибо за просвещение.
Получается, я всех неосознанно обманул в прошлом комменте. Простите меня великодушно.
Но тем не менее, с другими браузерами вопрос остается открытым.
+1
VladimirAndreev #
кмк, при клике по категории было бы логичнее открывать список подкатегорий, а не выделять категорию и всех ее потомков.
0
maxatwork #
Спорно. При щелчке по лейблу чекбокса обычно ждут, что отметится чекбокс. Как вариант, можно одновременно с этим разворачивать поддерево, но в моем случае это было не нужно и даже наоборот (т.к. поддерево достаточно большое, и постоянное разворачивание начинает бесить через пару-тройку кликов).
+1
WebDev #
ajax/json?
0
IDMan #
Красиво сделано. Спасибо.
0
Cellard #
Вы хороший
–1
zeromodule #
Неплохо, но нужны нативные эвенты :)
0
kvf77 #
Немного дополнение к логике. Я думал облегчить себе жизнь этим компонентом, но не получилось. Проблема в том, что визуально, вы родителей как бы тоже отмечаете (квадратик), но при субмите — они не передаются, что несколько не логично, если я отметил детей, то и родитель должен быть отмечен в результирующем массиве на сервере. Можно это как-то реализовать?
0
maxatwork #
Ну, это не совсем баг, скорее наоборот.

В этом контроле есть три состояния у чекбокса:
— не отмеченный (галочка снята) — все дети не отмечены
— отмеченный (галочка установлена) — все дети отмечены
— «частично отмеченный» (серый квадратик) — некоторые из детей отмечены или «частично отмечены».

Т.к. я могу передать только два состояния на сервер (отмеченный и не отмеченный) — то третим пришлось пожертвовать. В моем случае было более логичным, когда «частично отмеченный» передается, как не отмеченный.

Возможно, стоит сделать переключатель, изменяющий поведение на предложенное вами.
0
kvf77 #
Просто если без такого переключателя, мне приходится на сервере делать N запросов на каждого ребенка, чтобы отметить в базе родителей, а это лишняя нагрузка.
0
wpm1 #
хранимая процедура поможет? или реорганизация дерева в виде MPTT алгоритма.
0
kvf77 #
Еще код немного не валидный, вы переделываете создание чекбоксов, и не валидно в xhtml надо чтобы вконце было />
0
maxatwork #
Гм, не могли бы вы описать подробнее? Скриптом я только добавляю <span /> перед лейблом каждой группы, и <div /> перед всем деревом. Сами чекбоксы я не трогаю.
0
kvf77 #
у меня в html выглядит так:
<input />

запускаем в браузере, смотрим «Показать сгенерированый код» получаем
<input>
0
maxatwork #
Понятно. Это, скорее всего, плагин что то неправильно отображает (см. скриншот). Какой браузер и какой плагин используете для просмотра сгенеренного html? =)



С другой стороны, после распарсивания html понятие «валидности» неприменимо, т.к. имеет смысл только до преобразования текста в DOM (цель процесса валидации — убедиться, что в исходном файле нет ошибок) =)
0
Ar2r #
Жаль, что нет готовой инструкции о том, как в процессе генерации развернуть все ветки…

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

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