Я начинающий front-end разработчик. Сейчас я учусь и стажируюсь в одной минской IT компании. Изучение основ web-ui проходит на примере JS библиотеки Webix и я хочу поделиться своим скромным опытом и сохранить его в виде небольшого учебного пособия по этой интересной UI библиотеки.

Вторая задача


В прошлом задании я создавал страницу при помощи библиотеки Webix. А сейчас мне необходимо задать следующую логику взаимодействия пользователя с формой:


Основной виджет с которым будет работа в статье — форма. Дополнительно по нему можно узнать.

Скачать исходники можно по ссылке.

С демо-версией туториала можно ознакомиться тут.

Шаг 1. Добавление новых данных в таблицу.


Для удобства чтения кода и разделения проекта на логические блоки, я создам файл functions.js и укажу к нему путь в файле index.html. В нем я буду задавать функции отвечающие за поведение приложения.

<body>
    <script src="data.js"></script>
    <script src="functions.js"></script>
    <script src="script.js"></script>
</body>

В новом файле создаю функцию addItem, добавляющую новые данные в таблицу:

const addItem = () =>{                                                       
    var item_data = $$("film_form").getValues();
    $$("film_list").add(item_data);
}

Для обращения к элементу по id в библиотеке Webix используется метод $$, в который передается id элемента. В указанном выше коде обращение к форме осуществляется при помощи конструкции — $$("film_form").
Функция addItem работает так: Получаю текущие данные из формы через ее метод getValues и записываю в переменную item_data. Используя эти данные, создаю новую запись в листе методом add.

Для вызова функции по клику в виджет "button" со значением "Add new" я устанавливаю свойство click.

margin:10,
cols:[
    { view:"button", id:"btn_add", value:"Add new", css:"webix_primary",
    click:addItem},
    { view:"button", id:"btn_clear", value:"Clear"}
 ]

В результате, в таблицу должны добавляться  данные из формы:


Шаг 2. Валидация формы. Всплывающее сообщение


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

Простое сообщение в Webix создается функцией webix.message(), которая в качестве параметра принимает текст сообщения. Сообщение появится в правом верхнем углу.

const addItem = () =>{        
    if($$("film_form").validate()){                                               
        var item_data = $$("film_form").getValues();
        $$("film_list").add(item_data);    
        webix.message("Validation is successful!");
    }
}

Функция работает так. Условие If обращается к форме и вызывает метод validate(). Если условие проверки равно true, код выполняется дальше. После добавления данных в таблицу, вызывается функция с сообщением — "Validation is successful!".

Всплывающее сообщение:


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

Условия для успешной валидации будут следующие:
  • поле Title не должно быть пустым;
  • поле Year не должно быть меньше 1970 и больше действующего года;
  • поле Rating не должно быть нулем;
  • поле Votes должно быть больше 1 и меньше 1000000.

Тогда, исходный код виджета «форма» с правилами валидации будет таким:

view:"form",
id:'film_form',
width: 350,
elements:[
    { type:"section", template:"EDIT FILMS"},
    { view:"text", name:"title", label:"Title", 
    invalidMessage:"Must be filled in"},
    { view:"text", name:"year", label:"Year", 
    invalidMessage:"Should be between 1970 and current" },
    { view:"text", name:"rating", label:"Rating",
    invalidMessage:"Cannot be empty or 0" },
    { view:"text", name:"votes", label:"Votes", 
    invalidMessage:"Must be less than 100000" }, 
    {
        margin:10, cols:[
            { view:"button", id:"btn_add", value:"Add new", 
            css:"webix_primary", click:addItem},
            { view:"button", id:"btn_clear", value:"Clear", 
            click:clearForm}
        ]
    },
    {}
],
rules:{
    title: webix.rules.isNotEmpty,
    rating:function(value){
        if(webix.rules.isNumber(value)!=0){
            return true;
        }
    },
    votes: function(value){
        return webix.rules.isNumber(value) < 1000000 && 
        webix.rules.isNumber(value) >= 1;
    },
    year: function(value){
        return value>=1970 && value <= new Date();
    }
}

Свойства объекта rules должны совпадать со значениями свойств name: "…" элементов массива elements. В свойствах title, rating и votes установлены предопределенные правила webix.rules.isNotEmpty и webix.rules.isNumber, в year стоит функция, определяющая пользовательские правила.

Правила должны возвращать true в случае успеха и false при ошибке. Форма пройдет валидацию тогда, когда все свойства объекта rules возвратят true. В противном случае поля не прошедшие валидацию будут подсвечены красным.

Результат проверки:


Шаг 3. Сообщение об ошибке


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

У полей может быть задано свойство invalidMessage, его значение — текст с сообщением об ошибке. Это сообщение появится под полем, если валидация не пройдена.

Код:
elements:[
    { type:"section", template:"EDIT FILMS"},
    { view:"text", name:"title", label:"Title", 
    invalidMessage:"Must be filled in"},
    { view:"text", name:"year", label:"Year", 
    invalidMessage:"Should be between 1970 and current" },
    { view:"text", name:"rating", label:"Rating", 
    invalidMessage:"Cannot be empty or 0" },
    { view:"text", name:"votes", label:"Votes", 
    invalidMessage:"Must be less than 100000" }, 
    {
        margin:10, cols:[
            { view:"button", id:"btn_add", value:"Add new", 
            css:"webix_primary", click:addItem},
            { view:"button", id:"btn_clear", value:"Clear", 
            click:clearForm}
        ]
    },
    {}
]

Результат:


Шаг 4. Очистка формы


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

Предупреждающее сообщение:


Назову функцию clearForm и запишу в ней следующий код:

function clearForm(){
    webix.confirm({
        title:"All data will be lost!",
        text:"Are you sure?"
    }).then(
        function(){
            $$("film_form").clear();
            $$("film_form").clearValidation();
        }
)};

Для окна подтверждения используется callback-метод webix.confirm({…}), который принимает следующие параметры: обязательный — text и необязательный title. Так как метод возвращает promise, я могу использовать обработчик .then. В случае если ответ будет положительным, в обработчике .then я вызову два метода: clear() — для очистки полей формы, и clearValidation(), убирающий метки ошибок валидации.

Заключающим действием нужно привязать вызов функции к кнопке "Clear".

margin:10, cols:[
    { view:"button", id:"btn_add", value:"Add new", 
    css:"webix_primary", click:addItem},
    { view:"button", id:"btn_clear", value:"Clear",
    click:clearForm}
]

Код и демо можно посмотреть тут — snippet.webix.com/17w1dodb.

Обобщение


По исходнику было видно, что код предыдущей статьи достаточно простой, но с развитием проекта постепенно усложняется, а его количество увеличивается. Чтобы не потеряться в бесконечности строк кода, становится важно сохранить легкость в его чтении и простоту в структуре. Пример взаимодействия с формой описывает лишь базовые методы, но и из них заметно, что для придания странице динамики webix предлагает небольшой, читаемый и интуитивно понятный код. Если сравнивать с чистым JavaScript, его объем в лучшем случае увеличился бы вдвое.