Xpoint
   [напомнить пароль]

Оптимальная стратегия взаимодействия со сложными формами

Метки: [без меток]
2012-12-20 12:38:09 [обр] zx9r[досье]

Здравствуйте!

В моей практике крайне редко возникает необходимость в обработке сложных многостраничных html форм ввода. Пока было только два таких случая. Оба раза я решал задачу особо не задумываясь, "в лоб". Получались монстры, накапливающие в обычных переменных и массивах данные и передающие их по цепочке страниц многостраничных форм. Но во втором случае неожиданно для меня потребовалось активное наращивание функциональности и я быстро исчерпал модификационный потенциал решения. Соответственно, сейчас мне предстоит определиться с оптимальной стратегией взаимодействия с многостраничными формами ввода.

Прикладная задача, которая решается при помощи многостраничной формы заключается в наполнении БД сведениями о свойствах однотипных товаров (электродвигателей). У каждой модели электродвигателя есть несколько вариантов исполнения. Т.е. каждый электродвигатель представлен в БД одним общим для всех исполнений модели набором свойств (габариты, диаметр вала и т.п.) и секциями, в которых описаны специфичные для каждого исполнения характеристики (напряжение питания, ток потребления и т.п.). При заполнении формы оператор сначала вводит название модели двигателя и одинаковые для всех исполнений характеристики (те самые габариты, диаметр вала и т.п.). Характеристики конкретных исполнений вводятся на следующем этапе обработки формы (или в любое другое время независимо от ввода общих характеристик). Плюс, есть разные модели двигателей, но очень похожие по характеристикам. Поэтому важно иметь возможность сперва клонировать запись об уже имеющейся в БД модели и, изменив название и пару других характеристик, записать в БД.

На первый взгляд, решение лежит в плоскости использования ООП. В свойствах объекта накапливаем данные форм, расположенных на разных страницах. Параллельно, методами объекта осуществляем взаимодействие с БД для записи уже накопленных данных. Как-то так. По крайней мере, клонирование сводится к использованию существующих механизмов ООП.

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

Спасибо.

спустя 9 часов [обр] Филипп Ткачев(20/112)[досье]
C технологической точки зрения вам хорошо подходят документно-ориентированные БД вроде CouchDB, MongoDB или технология ORM.
Еще можно пойти и обычным реляционным путем, но не делая широких таблиц.
У меня был опыт работы с большими формами (40-50 полей). После длительной работы с ними и общения с операторами, пришел к выводу, что лучше полотно длинной в 3 страницы, чем 3 шага по одной странице. В первую очередь, пользователей больше всего напрягает возврат к редактированию и они хотят видеть все сразу перед отправкой.
Далее, вы простите, но я вынужден критиковать решение с многочисленными массивами, хранящимися в сессии и т.п.
В первую очередь, это удар по пользователю. Мне лично приходилось заполнять большие формы, на которые уходило почти по часу времени. Итак, у формы должно быть промежуточное сохранение. Идеально - скрытый ajax c сохранением состояния полей в базу и пометкой записи как "редактируется". Худший, но допустимый вариант, использовать Local Storage.
Как быть с тем, что много похожих форм? Используйте для форм шаблоны. Дальше напишите обвертку, которая будет читать эти шаблоны и динамически строить нужную форму.
Методы работы с полями достаточно тривиальны: восстановление, валидация, сохранение, вывод ошибки (подсказки), реакция - например заполнение зависимого select'a.
Обязательная валидация на сервере и грамотная на клиенте. Никаких принудительных установок фокуса при ошибке в поле. Оператор может туда по ошибке или просто механически нажимая Tab.
Чтобы обеспечить гибкость обработки - можете в шаблоне описывать сразу валидирующие и фильтрующие функции (точнее их имена). А сами реализации держать в отдельном файле.
Для вывода формы можете использовать пресловутый Smarty, создав нужные элементы формы на все случаи жизни.
спустя 1 день 15 часов [обр] zx9r[досье]
У меня был опыт работы с большими формами (40-50 полей). После длительной работы с ними и общения с операторами, пришел к выводу, что лучше полотно длинной в 3 страницы, чем 3 шага по одной странице. В первую очередь, пользователей больше всего напрягает возврат к редактированию и они хотят видеть все сразу перед отправкой.

В моем случае информация о каждом двигателе представлена в иерархическом виде. На вершине пирамиды - название модели и другие общие параметры. Каждая модель подразумевает наличие нескольких модификаций - это средний уровень пирамиды. У каждой модификации может быть несколько исполнений - это основание пирамиды. Количество полей в каждой ячейке пирамиды может доходить до 30..50 (иногда это отдельные поля, иногда - таблицы значений). Прошу прощения, что скомкано осветил это в предыдущем своем сообщении - я не предполагал, что будем это обсуждать.
Предполагается, что заранее неизвестно максимальное количество модификаций одной модели и максимальное количество исполнений одной модификации. Если попытаться изобразить все это на одной странице, то при росте количества модификаций и исполнений получится не очень наглядно. Поэтому изначально я все реализовал с использованием карт данных. Каждый двигатель имеет карту данных с перечислением всех его модификаций и исполнений. Данные в карте отображаются в наглядном иерархическом виде. По клику на номере модификации или исполнения происходит переход к редактированию этой модификации/исполнения (в карте есть также кнопки "создать модификацию" и "создать исполнение").
В настоящее время все отлажено и исправно работает. По результатам разговоров с операторами модифицировал мелочи, на формат представления данных в виде карты нареканий нет (я об этом прямо спрашивал). Но, к сожалению, возникла необходимость ввода функционала клонирования записей. Как я выше писал, стали массово попадаться двигатели, различающиеся всего несколькими характеристиками. Возможность клонирования записей с последующей правкой названия модели и одной-двух характеристик открывает перспективу колоссальной экономии операторских человеко-часов. Но модификационный потенциал текущего решения исчерпан подчистую (и клонирование записей БД отдельным механизмом не спасет т.к. текущее решение не предполагает возможности правки данных, находящихся на вершине пирамиды). Получается, я изначально недооценил сложность задачи и недостаточно продумал решение. Теперь предстоит переписывание "с нуля". Вот от того и попросил помощи сообщества - жуть как не хочется через время опять понять что очередной велосипед сделан недостаточно хорошо.
Моя текущая задача - определиться с оптимальной структурой ядра решения. Пока думаю в сторону использования объекта для хранения в его свойствах всех характеристик двигателя. Т.е. во всех случаях сначала создаем объект и, если речь о редактировании данных, заполняем его свойства из соответствующей записи БД. Если инициируем создание в БД записи про новый двигатель, то оставляем свойства пустыми. Плюсом такого решения будет, в частности, относительная легкость клонирования при помощи штатных механизмов объекта.
Соответственно, интересно узнать две вещи:

  1. В правильном ли направлении двигаюсь? Или у кого-нибудь уже есть опыт такой работы и от описанного решения пришлось отказаться в пользу более эффективного и гибкого?
  2. Какие еще дополнительные нюансы и решения стоит учесть/использовать в дополнение к описанному объекту?
Далее, вы простите, но я вынужден критиковать решение с многочисленными массивами, хранящимися в сессии и т.п.

Видимо, я некорректно сформулировал. В сессии я ничего не храню. При нажатии кнопки "отправить" на любой из страниц формы данные пишутся в БД. При переходе к следующей форме, если требуется отобразить информацию введенную на предыдущем шаге, эта информация берется именно из БД, а не передается напрямую из механизма обработки предыдущей формы. Или Вы что-то другое имели в виду под хранением данных в сессии?

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

При переходе на следующий шаг заполнения формы (т.е. на следующую страницу) вся введенная на предыдущем шаге информация отображается вверху страницы (без возможности редактирования), а поля формы идут уже ниже этой информации. Причем, эта отображаемая информация считывается из БД, а не передается напрямую из предыдущей формы (я выше об этом уже написал). Таким образом страхуемся от риска некорректной записи в БД на предыдущем шаге. Операторы проинструктированы проверять именно эту информацию на корректность (а не по сто раз перепроверять содержимое полей ввода на этапе заполнения).

В первую очередь, это удар по пользователю. Мне лично приходилось заполнять большие формы, на которые уходило почти по часу времени. Итак, у формы должно быть промежуточное сохранение. Идеально - скрытый ajax c сохранением состояния полей в базу и пометкой записи как "редактируется".

Ваша мысль про промежуточное сохранение понятна. Скажите, а есть какие-нибудь готовые ajax-решения в части работы с формами с функцией промежуточного сохранениея? Имею в виду именно примитивные элементы (например, те же формы с ajax-сохранением), которые можно встроить в мое решение, а не какое-то сложное и полнофункциональное изделие. Сам я, к сожалению, на JS не пишу (я вырос вдали от клиентов - сложных пауков писал, в основном, и прочее серверное, не предполагающее взаимодействия с браузерами).

Еще можно пойти и обычным реляционным путем, но не делая широких таблиц.

Пожелание про отсутствие широких таблиц вызвано традиционными причинами (типа размера файла таблицы, скорости обработки и т.п.) или у моей задачи есть какие-то дополнительные специфичные нюансы?

спустя 20 часов [обр] Филипп Ткачев(20/112)[досье]
На мой взгляд, вы все делаете правильно.
Честно говоря, я не привык пользоваться готовыми решениями и тут совсем не советчик. Единственное, что могу посоветовать, это jQuery. Самая популярная на текущий момент библиотека. И пример ее использования.
Насчет таблиц, я думал, что у вас очень сильно разнится набор параметров от модификации к модификации. Но поскольку это не так, то существенного влияния это не окажет. Могу лишь предостеречь от всех стоблцов типа TEXT :)
спустя 5 дней [обр] zx9r[досье]
На мой взгляд, вы все делаете правильно.

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

Про jQuery много слышу со всех сторон, но пока еще не пробовал. Спасибо за ссылку на пример. По поводу готовых решений у меня аналогичное мнение - мой PHP-опыт показывает, что написанное самостоятельно работает, в большинстве случаев, корректнее. Правда, движок форума на сайте у меня, все же, покупной :)

P.S. С наступающим!

Powered by POEM™ Engine Copyright © 2002-2005