Под конструктором обычно понимают систему вопросов, отвечая на которые, пользователь получает какой-то фрагмент кода. Здесь мы говорим о другом конструкторе, в котором один модуль программы задаёт вопросы другому модулю.

Конструктор HTML форм

Начнём с того, что конструктор форм, как и конструктор сайтов, есть вещь принципиально невозможная. Как, впрочем, и любой конструктор вообще. Конструктор – выражение фигуральное, метафорическое. В приложении к веб-разработке оно означает примерно следующее:

1) кто-то очень-очень умный создаёт непрозрачные кирпичи, небольшие блоки – чёрные ящики, которые можно использовать в строительстве сайта;

2) кто-то менее умный, кто не может (или не хочет) знать устройство кирпичей, пользуется кирпичами как данностью, работает с сайтом на уровне блоков, предложенных кем-то более умным;

3) проблема в следующем: Потребитель кирпичей, не желающий вникать во всякие тонкости, неизбежно будет создавать ситуации использования кирпичей не по назначению; Производитель кирпичей это предвидит (или получает в виде рекламаций от Потребителя) и начинает модифицировать кирпичи таким образом, чтобы они могли быть затычкой в каждой дырке.

Кирпичи становятся многогранными, умными, саморазрастающимися, как амёбы, – и вес каждого такого кирпича очень скоро приближается к тонне.

Эффективно пользоваться хорошим конструктором с оптимальными (а не весящими тонну!) кирпичами может только создатель конструктора. Конструкторы, которые делаются «на экспорт», – обман. В наиболее наглом и неприкрытом виде этот обман сформулирован, например, в рекламе CMS Битрикс, заявляющей, что сайты с помощью этой системы может легко создавать любой человек, не являющийся специалистом в веб-разработке.

Каждый программист, однако, всегда делает для себя целую кучу маленьких «конструкторов» – фрагментов кода, позволяющих сокращать рутинные операции. Вопрос, как сильно может вырасти такой небольшой «вспомогательный конструктор», насколько он может стать универсальным. Попробуем рассмотреть это на примере конструктора HTML форм.

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

Логику приложения формализовать достаточно просто: серверному скрипту для работы требуется входящий именованный массив (GET, POST...) – вот список этих имён (полей) и является главным требованием логики приложения для изготовленной конструктором формы. Предметная логика не всегда очевидна. Пример. Для выбора цвета картриджа (для принтера) существуют четыре латинские буквы: CMYK. Можно дать список этих букв пользователю в виде выпадающего списка (select), а можно в виде radioButton'а. Тут нет никакой логики, это произвольное решение дизайнера (что красивее, или уместнее, по размеру и по форме больше подходит).

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

Логика Конструктора HTML формы

Что внутри? Форма – это набор HTML элементов, следующих друг за другом или вложенных друг в друга. Поэтому первой функцией конструктора, очевидно, будет функция создания HTML-элемента. Такая функция реализована в любом браузере (createElement), почему же нельзя использовать встроенную, готовую? Потому что у элементов могут быть разные атрибуты. То есть наша функция должна будет принимать в качестве параметров наименование элемента и набор атрибутов, и выглядеть примерно так:

Понятно, что атрибуты должны будут передаваться не отдельными параметрами, а в виде именованного массива (объекта javascript).

Лирическое отступление. Тут у любого нормального человека уже должен будет возникнуть вопрос: а нафига вообще такие сложности, и почему нельзя просто написать:

– а обязательно нужно выёживаться со всякими «конструкторами»? Какова причина, что заставляет разработчиков так всё усложнять? ("– Вот всё у вас как на параде, – заговорил он, – салфетку – туда, галстук – сюда, да «извините», да «пожалуйста-мерси», а так, чтобы по-настоящему, – это нет. Мучаете сами себя, как при царском режиме").

Называемая причина чаще всего формулируется как «Повторное использование кода»: если мы напишем руками сразу готовый HTML, в другой форме нам придётся писать другой HTML, с другими наименованиями полей. Если же у нас будет «конструктор», мы можем передать ему только наименования полей «в чистом виде», а HTML-код конструктор сгенерирует сам (причём, не очень даже принципиально, на javascript или на сервере).

Использование конструктора заставляет нас отделять вычисления от данных. Данными в нашем случае являются описания полей, и они могут (и должны!) храниться совершенно отдельно от кода конструктора. И это правильно (и удобно). Вопрос «где именно должны храниться описания полей?» приведёт нас ко второй причине использования конструктора – точнее, к более глубокой причине всех этих танцев. Эта причина логически возникает раньше требования «отделять данные от кода».

Это – устранение неявных зависимостей. Если мы напишем руками в HTML имя поля в форме, то ведь мы должны будем сначала откуда-то узнать это имя. «Мы» в данном случае – это какой-то человек, программист, который должен какое-то время что-то держать в голове (или извлечь из головы другого программиста). Очевидно, что это слабость проекта. Такие слабости нужно устранять.

Вспомним, что форма – это лишь часть цепочки. Набор именованных значений из формы передаётся на сервер, а там (чаще всего) значения вводятся в поля таблицы БД. Как синхронизировать набор полей БД и набор полей формы? Самое очевидное решение здесь – создать описание полей, которое будет являться источником и для таблицы БД, и для HTML формы. То есть, проектируя таблицу пользователей для сайта, мы сначала должны будем создать массив вида:

А потом на его основании уже создавать таблицу БД и HTML форму. Вот в последнем случае как раз и нужны будут какие-то более-менее общие функции для генерации HTML кода, и эти функции можно будет использовать для разных форм и на разных сайтах, при условии передачи им описания полей в оговорённом формате. Например, отсутствие значения для ключа 'html' в массиве будет означать, что поле в форме показывать не надо (оно не нужно пользователю для работы). То есть конструктор может быть только очень конкретным, достаточно жёстко привязанным к определённой структуре данных, получаемых им для обработки. Попытка «отвязать» его, сделать более универсальным, мгновенно приведёт к непомерному раздутию кода, о чём мы и говорили в начале.

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

PHP или javascript?

Почему форма иногда генерируется на сервере, а иногда на клиенте? Так быть не должно. То есть не должно быть равнозначного выбора, что-то должно перевешивать. Если нет, значит, разработчик чего-то не заметил, какого-то важного фактора.

Исторически первичным был серверный скрипт. Зачем понадобилось допиливать что-то на клиенте? Первое, что приходит в голову, – валидация, проверка значений, вводимых пользователем. Гораздо удобнее пользователю сразу видеть, что он делает что-то неправильно, чем получить отрицательный результат после отправки формы на сервер. Сейчас это уже является хорошим тоном, мало кто теперь заставляет пользователя заполнить все поля, нажать кнопку «Сохранить», дождаться ответа сервера и увидеть сообщение «Неправильно заполнено поле Адрес» или «Такой пользователь уже существует».

Потом идут сами поля. Если это обычное текстовое поле (например, «Наименование фирмы»), и оно однозначно и без затей соответствует полю БД (name_firm), логично генерировать его на сервере. Если это не совсем обычное, простое поле (например, русская дата) его тоже можно генерить на сервере, а в браузере цеплять к нему вспомогательный скрипт «Календарь». Но если у поля формы более сложные взаимоотношения с полем БД (например, выпадающий список, значения которого берутся вовсе не из БД, или какая-нибудь «Корзина»), проще отдать всю информацию о структуре Клиенту и забыть (на сервере), а потом уже работать только с javascript.

Такая логика отображает довольно слабую, нечёткую зависимость. Более сильным является правило (и его надо, видимо, признать более правильным): создавать на сервере только те формы, которые нельзя создать на javascript. И вообще-то не только формы... Мы показывали раньше (biglist2.aspx), что большие HTML-таблицы лучше полностью перестраивать в браузере с помощью javascript (для более удобного управления ими – сортировки, фильтрации данных). В идеале (для освобождения сервера от нагрузки) надо всегда «выплёвывать» содержимое клиенту в предельно простом виде, а верстать уже в браузере, на javascript.

Но такой радикализм не позволит ПС (на сегодняшний день) правильно индексировать страницы сайта, поэтому вёрстка основной части содержимого сайта пока остаётся за сервером. Формы же индексировать в ПС совершенно не нужно (и даже вредно), поэтому их следует делать только на javascript. Плюсом такого решения является гарантированная защита от спама (лучше всякой капчи), так как на сегодняшний день не только ПС, но и вообще любые роботы принципиально не работают с javascript.

Минус только один: «А если javascript в браузере отключён?..» Ну, тогда надо сообщить пользователю, что он попросту не сможет работать. Ни один современный движок сайта не может работать нормально без javascript, это такая же реальность, как и сложность javascript для индексации в ПС.

Ещё раз о конструкторе

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

Мы, разумеется, говорили здесь совершенно о другом конструкторе – не о визуальном, а о чисто программном. То есть все вопросы в этом случае один модуль программы (например, функция js) задаёт другому модулю (например, данным, полученным от Модели с сервера), а результирующий код генерируется и выводится в браузер уже без всякого участия программиста.

D.M., admin

Комментарии

Иван 11.11.2014 05:03:41

Я для себя выбрал вот этот конструктор html форм – http://formdesigner.ru. Как по мне очень удобный и много функциональный сервис. Рекомендую.