- PVSM.RU - https://www.pvsm.ru -
Программист должен упрощать жизнь пользователю, а не себе.
(конечно, есть нюансы)
Автор статьи
Статья описывает идею визуального веб-контрола для выбора элемента из списка. Эта идея о том, как можно эволюционировать ComboBox (он же DropDown, он же select в html) для повышения удобства программного продукта для пользователя – чтобы контрол выбора стал намного удобнее и дружелюбнее при выборе сложных объектов из больших и не очень списков. Ведь задача программиста — в непрерывном улучшении и упрощении жизни пользователя.
Это идея, реализация которой есть только частичная и только для ASP.NET Web Forms в связке с devexpress [1] – поскольку у меня большой бекграунд именно на этой связке технологий.
Эта статья не для тех, кто хочет скопипастить код, нажать F5 и увидеть результат. Ее корректнее всего было бы отнести к документам, которые называют Функциональными Требованиями или даже Функциональным Дизайном. Поэтому, если вам интересен взгляд на эволюцию удобства, то, надеюсь, статья будет полезна.
Сначала приведу список удобных фич, которые уже есть в хороших реализациях визуальных контролов. В этом параграфе нет ничего нового, только описание функциональности, уже реализованной в передовых библиотеках визуальных контролов.
Например, у devexpress [2] фичи относительно select в html такие (в порядке, на мой взгляд, уменьшения необходимости, то есть сначала самое важное):

По мере введения символов в контрол список фильтруется. Тут замечания:
— По каким полям проверять вхождение введенной строки? Если проверять по тем, которые в контроле не отображаются, то пользователю может быть неочевидно поведение. Но иногда такое может требоваться. А если пользователь вводит строку, содержащую в себе границу при конкатенации полей? То есть, если выводится ФИО сотрудника, скажем, «Черняев Константин», а имя и фамилия хранятся в разных полях данных, и пользователь вводит «яев конс» (здесь и далее регистр символов не имеет значения – считаю, что при поиске текста это стандарт де-факто). Дружелюбно со стороны контрола было бы найти эту запись:

— Обычно сортировку делают по алфавиту. И когда пользователь вводит строку (скажем, «стол»), и такой элемент в списке есть, причем есть и такие элементы, которые эту строчку содержат, но не равны ей («столб», «апостол», «пистолет»), то получится, что пользователю приходится листать список, выбирая нужный (а порядок в этом примере будет такой: «апостол», «пистолет», «стол», «столб»). Причем уточнить запрос и сузить список невозможно. Если список большой, это большой минус к дружественности.
Решением этой проблемы будет сортировка по признаку «равенство/вхождение». То есть первыми должны идти записи, равные введенной строке, а потом остальные. Я бы даже пошел дальше – сначала равные, потом начинающиеся с этой строки, потом остальные.

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

В комбике на скриншоте убрана обычная кнопка-треугольник

, но добавлено три пользовательских.

ComboBox’а элемента из иерархического списка, но это другой контрол (DropDownEdit [3], хотя заголовок у него Tree List Lookup).
Пользуясь перечисленными возможностями, я постепенно приходил к тому, что не хватает дальнейшей эволюции ComboBox’а:
boolean-свойству контрола:
<comboBox showResetButton=”true” />
ComboBox’а, а вообще всех эдиторов.

Возможно, стоит добавить возможность откатить изменение в контроле редактирования. Как бы cntr+z.
Например, пользователь делает заказ и выбирает пункт самовывоза. И естественно захотеть при выборе, да и после выбора, получить полную информацию о выбранном пункте (адрес, как добраться, схема и фото) без лишних телодвижений. Один раз реализовав такую возможность, уже хочется, чтобы в любом комбике она была.
Самым удобным кажется рядом с визуальным контролом написать обычный тег
<a href='entity?id=...'>i</a>
Можно и сам текст выбранного значения сделать ссылкой, но не стоит – ведь при нажатии на комбик обычно открывается список выбора. Хотя так делают – тогда для открытия списка пользователю нужно нажать на кнопку треугольника
.
Пример реализации этих трех пунктов:

Звездочка означает, что значение было изменено (можно ее показывать как в caption, так и справа от контрола, это дело стиля конкретного проекта – обычно ведь звездочка означает, что значение обязательно для выбора), красный крестик – кнопка «Сбросить значение», i – ссылка на карточку выбранного филиала, кнопка с троеточием – для пункта 4.
ComboBox CatalogBox’ом – ComboBox’ом XXI века.
Например, выбирает пользователь клиента, чтобы подставить в договор и ComboBox ищет по выводимым данным (скажем, номер и название клиента), а пользователь не знает имени, только, например, ИНН, или телефон, или даже просто фамилию директора искомого юрлица. Тогда он открывает страницу-каталог клиентов, ищет нужного с помощью фильтров, копирует номер/код/название клиента, закрывает каталог, вставляет из буфера в ComboBox. Но наша задача — сделать пользователю удобнее (см эпиграф).
А для пользователя будет удобно каталог открывать в модальном окошке при нажатии на специальную кнопочку на CatalogBox’е (кнопка-троеточие
).
Пример страницы-каталога:

На скриншоте каталог открыт в модальном окошке после нажатия на кнопку-троеточие.
Но сама страница каталога не должна быть привязана к модальности – ее должно быть можно открывать как отдельно и независимо, так и в модальном окне. В модальном окне у грида должна появляться возможность выделить одну выбранную строку (или несколько), после чего становится активной кнопка «Выбрать» (на скриншоте она disabled, потому что выбор не сделан). При ее нажатии выбранное значение подставляется в ComboBox, то есть теперь CatalogBox.
CheckBoxList (картинки [4]), но раз уж есть CatalogBox и можно делать выбор с удобными фильтрами, то хочется множественный CatalogBox. Тут естественны функции: добавить, убрать. Иногда требуется ввести валидацию на количество выбранных элементов – расширение required.
Например, нужно в заказ добавлять товары и хочется дать возможность пользователю выбирать их сразу несколько, но CheckBoxList неудобен ввиду большого количества товаров. Тогда пользователю будет удобно в каталоге с помощью фильтров выбрать несколько товаров, нажать «Добавить», и потом, при необходимости, добавить еще.
Визуальный пример:

Как видно, в левом столбце грида стоит CheckBox – таким образом можно выбирать несколько элементов.
Эта возможность уже полностью ломает ComboBox – он не предназначен для хранения нескольких выбранных значений. Получаем для общего случая творческую изобретательскую задачу, вариативную в реализации.
Приведу визуальный пример сделанного выбора.
— Если выбран 1 элемент:

— Если выбрано 2 элемента:

— А так можно просмотреть список выбранных элементов и удалить ненужные:
ComboBox из разных списков.
Удобнее всего для пользователя этот выбор реализовать на одном контроле CatalogBox, но сделать 2 (или более) кнопочки, открывающие разные страницы-каталоги (разных сущностей). И как значение хранить не только выбранный объект, но и его сущность.
Пример:

В остальном все так же, как раньше – просто к кнопке-троеточию добавляются еще кнопки выбора.
Практически в любом веб-приложении очень нужны первые 4 пункта – кнопка «сбросить значение», выделение изменений, ссылка на страницу выбранного элемента и выбор с полноценными фильтрами. Остальные дополнения нужны далеко не всем проектам. Но для большой информационной системы кажется в любом случае необходимыми все пункты.
a. Возможность задать настройками, показывать или нет кнопку-треугольник.
Для больших списков кнопка «показать весь список» может не иметь большого значения, имеет значение только фильтрованный список. А выбирать критерий, большой это список или нет, должен архитектор интерфейса, а не сам контрол – поэтому нужна настройка.
b. Для разнородного выбора (выбора значения из двух списков) нужно либо делать более одной кнопки-треугольника, либо ни одной, если созданы кнопки-троеточия (открывающие модальную страницу-каталог).
c. Открывать ли список при нажатии на контрол.
d. Открывать ли список при фокусе на контрол.
a. Связана с валидацией. Если выбор обязателен – то крестика не должно быть.
b. Для множественного выбора – очистить полностью выбор. Стоит также сделать кнопку удаления одного выбранного значения.
Идеальным кажется такое поведение. Пользователь вводит текст, ищутся элементы, показываются найденные (с учетом авторизационного фильтра, заданного фильтра, фильтра от выбора значений в других контролах, настроек окна virtual scrolling). При потере фокуса выбирается:
— Ничего не найдено: выбор не меняется.
— Найден 1 элемент: выбирается он.
— Найдено больше 1: настройка: выбирается либо первый, либо выбранный до этого.
Выбор элемента мышкой, скролом, стрелками-ентером. Список либо полный, либо подкачивается по мере надобности (virtual scrolling).
Необходимые фильтры:
a. Заданный постоянный фильтр для этого инстанса контрола;
b. Продуцированный другими контролами страницы фильтр;
c. Авторизационный фильтр. Этот фильтр должен накладываться на серверной стороне – это правило безопасности.
Передача всех этих фильтров в страницу-каталог с указанием, что пользователю нельзя их менять.
a. Возможность табличного вида, шаблоны ячейкам, стили/форматы.
b. Выделение найденного текста в элементе.
js-аналога string.Format с указанием path’ов (например, «{Name} ({Id})»);js-функция; select, то возможны только текстовые варианты, а если разметка полностью кастомная, то простор для фантазии есть.title (всплывающей подсказке).Title или baloon для показа информации о выбранном элементе, не поместившейся в видимую область бокса.title.CatalogBox.CatalogBox’а. CatalogBox мог открыть свой каталог, в котором пользователь не смог бы выбрать ничего запрещенного.checkbox на каждый элемент.grid. Но может быть и list или tree.Для модального режима (то есть при связке с CatalogBox’ом):
target=”_blank”).disabled. Когда выбирается первый, становится активна. При нажатии каким-либо образом шлет выбранный элемент (или элементы) породившему CatalogBox’у.Коллеги, прошу вас, если знаете, где реализована похожая функциональность выбора объекта с помощью полнофункциональной страницы-каталога, пишите в коментах. Я нигде — по крайней мере, в веб-мире — не видел подобных реализаций.
Автор: Константин
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/interfejsy/268445
Ссылки в тексте:
[1] devexpress: https://www.devexpress.com/
[2] devexpress: https://demos.devexpress.com/ASPxEditorsDemos/ASPxComboBox/LargeDataSource.aspx
[3] DropDownEdit: https://demos.devexpress.com/ASPxEditorsDemos/ASPxDropDownEdit/DropDownEdit.aspx
[4] картинки: https://www.google.ru/search?q=checkboxlist&newwindow=1&tbm=isch&imgil=W-znIs1ZeRkJjM%253A%253B8lP1eewCUpO4uM%253Bhttps%25253A%25252F%25252Fwww.codeproject.com%25252FArticles%25252F18466%25252FTitleCheckBoxList-Adding-Column-Headers-Titles-to&source=iu&pf=m&fir=W-znIs1ZeRkJjM%253A%252C8lP1eewCUpO4uM%252C_&usg=__Tq9ZpkrEBwDn66DhPxRM3BX6Za4%3D&biw=1086&bih=779&ved=0ahUKEwi4sPOKgtXWAhVGQpoKHYdpAaMQyjcIRw&ei=9M3TWbjmEcaE6QSH04WYCg#imgrc=W-znIs1ZeRkJjM:
[5] Источник: https://habrahabr.ru/post/342184/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.