How to Create Forms with Webix JavaScript
Tags: javascript, webdev, programming, html
Published: 2021-08-12 08:57:50

The daily routine of a typical programmer consists of monotonous keystrokes and coffee breaks. A good programmer can reach the desired result with fewer keystrokes. And I don't mean the &quot;*Ctrl+C / Ctrl+V*&quot; combination, as you might think :) In this article, I want to tell you how to save precious time and nerves if you need to create a beautiful and functional form.

There are many libraries that provide a large number of features for working with forms. But today we will consider only one of the most convenient and multifunctional tools for building app interfaces of any complexity. It is about the Webix library and its capabilities.

To prove that these are not empty words, we will create a small app for bookselling and see how to implement an **order form** using Webix components.

You can find the full source code and live demo <a href="https://github.com/serhiipylypchuk1991/book-store-service" target="_blank" >here</a>. 

<h1>Webix and Its Capabilities</h1>

Webix UI is a <a href="https://webix.com/">JavaScript library</a> that allows you to create a responsive design without worrying about the app's performance. The range of possibilities is represented by UI components of varying complexity. It can be a simple button and a complex solution. Each widget includes a whole set of methods and properties for flexible configuring and controlling. Besides, the library has extra tools. For example, event handling, methods of working with data, interaction with the server, styling themes and much more. You can find out more information about capabilities in the <a href="https://docs.webix.com/">documentation</a>. Now it is time to move on to the practice.

<h1>Main Preparations</h1>

In order to use the Webix library, we need to include it in the main index.html file. It is worth mentioning here that the library is distributed in 2 versions: the basic <a href="https://webix.com/get-webix-gpl/">GPL</a> and extended <a href="https://webix.com/download/">Pro</a> version. The GPL version is free and provides a wide set of features that cover 97.26% of our day-to-day needs. But for working with forms, which are the main topic of this article, we will need some special features of the advanced version. I will mention them in the process. Based on this, we will use the extended Pro trial version to get the most impact.

To get the trial version of the library, we need to visit the <a href="https://webix.com/download/">download page</a>, enter the necessary data and get a link for downloading the coveted archive.

The archive includes the ***webix/codebase/*** folder with two sacred files, namely: *webix.js* and *webix.css*. In order for the Webix magic to start working, we need to move this folder into the root of our project and include the library source files in the *index.html* file:

{% gist https://gist.github.com/serhiipylypchuk1991/d80a15055dcdc78ae2a874d706b9ef32 %}

It's worth noting that these files are also available via the CDN at the following links:

{% gist https://gist.github.com/serhiipylypchuk1991/025a13fd4bae64870548685f92210727 %}

We'll use local files, as they work faster and do not need Internet access (sometimes it happens). The *index.html* file looks like this:

{% gist https://gist.github.com/serhiipylypchuk1991/467837888a652333323ec971fc43330c %}

We have created a basic *index.html* file and included all the necessary tools. Let's start with making an overview of our app.

<h1>Application Overview</h1>

We have a small bookselling app. It consists of a toolbar and two replaceable modules, namely:

* module with a catalog of books
* module with a book description and order form.

The module with the catalog consists of small blocks, 2 items in one row. Each block contains a short description of the product and button to order. It is worth clarifying here that we use the **<a href="https://docs.webix.com/desktop__dataview.html">dataview</a>** widget for creating this module. In the browser, we will see the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xu2qk4w6hikm0tuxlviv.png" >

When clicking on the "**Buy now**" button, the user will see the module with a detailed description of the product. For its creation we use the **<a href="https://docs.webix.com/desktop__template.html">template</a>** widget. Next to the product description we will place the module with our form, which this article is devoted to. In the browser, we will see the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6i1r65310u3ubtb3h746.png" >

And now our task is to add a module with a form, where the user can enter all the necessary data for ordering. As you may know, the purpose of any form is collecting information from users. In our case, we are going to collect the following data:

* information about the order and its delivery
* information about the user
* information about the payment.


Each form should contain input fields and various controls, namely: checkboxes, radiobuttons, selectors, buttons and much more. Considering the data we need to collect, our form will be large enough.

If we don't want to scare off the user with a large number of fields and controls, let's divide the form into semantic groups mentioned above. Each group will deal with each particular order step. Group will be placed in a separate tab and the user will be able to navigate back and forth through them. There will be 3 tabs:

* the first one includes an order form with the possibility to choose between the *pick-up* and *delivery* options. If the user chooses *delivery*, the app will display some extra fields for entering the desired delivery address
* the second one includes a form for user's personal data
* the last tab includes a form to collect information about the user's credit card. 

The interface of each form will be created in a separate file and saved to a variable. These variables will be used for building the layout in the *index.html* file.

<h1>Layout for Module with Forms</h1>

In this article, we will not dive into the details of building the entire app layout. If you would like to study this topic more deeply, read the <a href="https://webix-ui.medium.com/creating-a-booking-application-with-webix-ui-32e1ee42e799">Creating a Booking App with Webix UI</a> article. You can also refer to the **<a href="https://docs.webix.com/desktop__layout.html">layout</a>** documentation. There you will find an exhaustive description of all properties and methods with corresponding samples.

Here we are interested in only the part of the layout containing the tabs with forms. These tabs will be switched by the user dynamically. For such cases, Webix provides a special **<a href="https://docs.webix.com/api__refs__ui.multiview.html">multiview</a>** component. The needed modules (in our case it is the forms) have to be placed in the array of the ***cells*** property. When initial loading, the first element of this array will be displayed. To navigate between modules, we need to set them a unique **ID**. The code of layout looks like this:

{% gist https://gist.github.com/serhiipylypchuk1991/4397b878561ad9dd21bb7524c134dcd3 %}

We have created the layout with forms. Now let's get down to the forms directly. And we start with the order form.

<h1>Order Form</h1>

The order form will consist of two logical parts. The first part will contain the fields for information about the order itself, and the second one - about its delivery.

Initially, the form will be displayed only with the "**Order Information**" section:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9eqbn0qwd4nryx87mh2j.png" >

The second one "**Delivery Information**" section will be hidden by default. We will show it only if the user selects the corresponding option of the **radio** control. The order form with 2 sections will look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzhe3s1mvd7f7k2rh7hw.png" >

To navigate through the tabs with forms, we will use the &quot;**Back**&quot; and &quot;**Next**&quot; buttons. The former button returns us to the catalog of goods, and the latter displays the next form.

Now let's take a look at how to implement all of this in code.

To collect data from users, Webix provides a special <a href="https://docs.webix.com/desktop__form.html">**form**</a> widget and a number of related <a href="https://docs.webix.com/desktop__controls.html">**controls**</a>. The form organisation is similar to the <a href="https://docs.webix.com/desktop__layout.html">**layout**</a> component. We can divide form into rows and columns, putting the necessary controls into the corresponding containers.

We create a form in the *order_form.js* file and save it to the **order_form** variable:

{% gist https://gist.github.com/serhiipylypchuk1991/c2e9cab9ea8484d854f4aa394ef42d04 %}

Here we also need to define the form layout mentioned above. For doing this, the widget has dedicated <a href="https://docs.webix.com/api__link__ui.form_cols_config.html">***cols***</a>, <a href="https://docs.webix.com/api__link__ui.form_rows_config.html">***rows***</a> and <a href="https://docs.webix.com/api__link__ui.form_elements_config.html">***elements***</a> properties. The first two properties allow us to divide the component interface into columns and rows. The ***elements*** property we are going to use, allows us to place the form elements as rows. All we need to do is to place two sections with the desired fields into the array of this property. Now let's tackle these sections.

<h2>The "Order Information" Section</h2>

To group the form fields into sections, we use the <a href="https://docs.webix.com/api__refs__ui.fieldset.html">**fieldset**</a> component. The first section is &quot;**Order Information**&quot;. It combines several inputs for collecting the order data. The name of this section is defined via the ***label*** property. The desired controls will be described in the object of the ***body*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/3ca644fab9c1f653d76ce2ff0392932c %}

All the fields within this section will be arranged in rows. For this, we need to put them inside the array of the ***rows*** property. Now let's create these fields.

<h3>Special Field for Order Name</h3>

Let's start with the field that contains the order name. It doesn't need any data entry, since its value is set dynamically. To create this field, we can use 2 label components and arrange them as columns. The first component will contain the field name, and the second one will contain the name of the selected item (in our case it is the book title).

{% gist https://gist.github.com/serhiipylypchuk1991/def3b3cc1a2bf7897995b74b358a83fd %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3817e11u5mm86i4377jd.png" >

For the second label we need to set the ***name*** property to the ***order_name*** value. The unique name is required to access corresponding form elements. The reason is that the value of this control will be set and read dynamically via the form API. We also need to specify the unique names for other fields, the values ​​of which we are going to set or read.

<h3>Control for Goods Amount Setting</h3>

In this section we need to give the user an ability to indicate the desired number of goods. To do this, let's use the special <a href="https://docs.webix.com/desktop__counter.html">**counter**</a> tool and specify its label and unique name. We can also define the min and max values via the dedicated ***min*** and ***max*** properties.

{% gist https://gist.github.com/serhiipylypchuk1991/1999e4965efccffdb9b70aae47daa3ff %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3s5phx5y3trmhms0lh93.png" >

<h3>Input Field for Gift Card</h3>

Now let's create a field where the user can enter a gift card number. It is best to use the <a href="https://docs.webix.com/desktop__text.html">**text**</a> control here. Besides the name and label, we can set a placeholder via the ***placeholder*** property and a special icon on the right part of the field via the ***clear*** property. The icon will appear when the user enters data in the field. When he clicks on this icon, the entered data will be deleted and the icon will disappear.

{% gist https://gist.github.com/serhiipylypchuk1991/0ec8e6997d4a8f31deb5abe69a7d9895 %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khit0sf4bq5du8yj7j28.png" >

<h3>Special Field for Order Price</h3>

Next, we have a field for displaying the order price. The price, as well as the order name, is set dynamically via the form's API and changes depending on the selected parameters. Here we do the same as with the order name field: use 2 <a href="https://docs.webix.com/desktop__label.html">**label**</a> components, place them as columns and set the name to the second one through its ***name*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/7fe7ca77a0629a057a921dd5c1ce701c %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x2kwtzqgdhde58dxtdr9.png" >

<h3>Control for Order Receiving Method</h3>

In this section, we have to implement the field where the user can select the receiving order method: pick-up or delivery. We can do this via the <a href="https://docs.webix.com/desktop__radio.html">**radio**</a> control with two options. The label of this control will be empty, because the radio button names are informative enough. The options data for the radio buttons are set via the ***options*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/0c63345af8b6120d805918fe1cafb7dd %}

Now let's make it so that if the user switches between the &quot;*Delivery*&quot; and &quot;*Pick-up*&quot; options, the "**Delivery Information**" section will be displayed or hidden correspondingly. Let me remind you that the &quot;*Pick-up*&quot; option is selected by default, and the section itself is hidden.

To handle the desired event, we need to specify the special ***on*** property into the constructor of the **radio** control. In the object of this property, we also need to specify the required event (in our case, it is *onChange*) and set to it the desired handler.

{% gist https://gist.github.com/serhiipylypchuk1991/d6dbf88ec41baf929468ab1cf0fc6b65 %}

First, we get the current value of the **radio** control via its `getValue()` method. If the value is 1 (the &quot;*pick-up*&quot; option is selected), we will hide the "**Delivery Information**" section via its `hide()` method.

If the value is 2 (the "*delivery*" option is selected), we will display the "**Delivery Information**" section via its `show()` method.

The whole section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yktlnysgpne0oos8yauh.png" >

<h2>The "Delivery Information" Section</h2>

Now let's move on to the "**Delivery Information**" section. It combines the fields for entering the delivery address. We create it in the same way as the previous "**Order Information**" section. As mentioned above, this section is hidden by default. To do this, we need to set its ***hidden*** property to *true*.

{% gist https://gist.github.com/serhiipylypchuk1991/c51e9799adccf3470c4344683657fe67 %}

To ship the order, we need to get a delivery address. For this, we will create special fields in which the user can enter the following parameters:

- country
- address within the country:
   * region
   * city
   * street and house
   * zip code
- desired shipping date
- additional instructions.

Besides, we will provide the user with the ability to insure the delivery. And as a nice bonus, the user will be able to choose the desired packaging color, which I personally attach great importance to :) Now let's start implementing our plan.
<h3>Control for Country Selection</h3>
Let's make it so that the user doesn&rsquo;t enter the country name but selects it from the drop-down list. For creating this field we can use the <a href="https://docs.webix.com/desktop__combo.html">**combo**</a> tool of the Webix library. In addition to the standard set of properties ( *label, name, clear and placeholder* ), we need to parse data for the drop-down list options. This is done via the ***options*** property. The data can be set either as an array with data (if they are on the client) or as the path to the data on the server. The data schema should be as follows:


```json
[
	{ "id":1, "value":"Canada" },
	{ "id":2, "value":"United Kingdom" },
	...
]
```

The library allows us to make the fields required for filling. To do this, we need to set the ***required*** property to *true*. As a result, we will see a special red marker at the top right corner of the label. Looking ahead, if the user leaves such a field empty and runs validation, it will turn in red and the data will not be sent.

{% gist https://gist.github.com/serhiipylypchuk1991/4ede8be31160f4cc4e02195fa84d189f %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jdba24k0chtqdzxyp5c.png" >

<h3>Input Fields for Delivery Address</h3>

All the fields for addresses within the country will contain the same settings. To create them, we use the well-known **text** control and a set of basic properties: *label, name, clear, placeholder and required*.

{% gist https://gist.github.com/serhiipylypchuk1991/c275e90be8be0be8d6d3d413d1169762 %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4gsuuj9o2tj89xez1agr.png" >

<h3>Control for Shipping Date Selection</h3>

We can ask the user about the desired shipping date of the order. And here, instead of the usual input field, Webix provides us with a special <a href="https://docs.webix.com/desktop__datepicker.html">**datepicker**</a> widget. When the user clicks on it, the component will display a compact calendar, in which he can select the required shipping date. In addition to the basic properties mentioned above, we can specify the format for displaying the date via the ***format*** property. To read more about all capabilities of this widget, visit its <a href="https://docs.webix.com/api__refs__ui.datepicker.html">documentation</a> page.

{% gist https://gist.github.com/serhiipylypchuk1991/458cfcbd3d827241c3378206353c37d8 %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpoz4t5p3a06deppyfsx.png">

<h3>Field for Additional Instructions</h3>

It is difficult to foresee the fields for each specific situation. Sometimes it happens that the user wants to specify the additional delivery instructions. For example, he wants the order to be left on the porch of the house or packed in additional packaging. Let's give the user such ability in our form.

The <a href="https://docs.webix.com/desktop__textarea.html">**textarea**</a> component is the best decision for such an issue. If you have worked with plain HTML forms, you should be familiar with this element. In addition to the standard settings of this widget, we will set a fixed height via its ***height*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/862961c0d014b3a047a8d70354616d1a %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z4z9b8h0ndzwjgrj3vtf.png" >

<h3>Control for Applying Insurance</h3>

Let's provide our users with the ability to insure order delivery.

To apply for insurance, we will use the <a href="https://docs.webix.com/desktop__switch.html">**switch**</a> control. It is a toggle button that allows the user to switch between two opposite values ​​(0 and 1). Besides the label and name, we can specify 2 inside labels for active and passive states. This can be done via its ***onLabel*** and ***offLabel*** properties.

{% gist https://gist.github.com/serhiipylypchuk1991/9ac3572c5547f8afbb57adaa237e9033 %}

<h3>Control for Сolor Selection</h3>

As mentioned above, we will give users the ability to choose the packaging color. For this, the Webix library provides several widgets, namely: <a href="https://docs.webix.com/desktop__colorpicker.html">**colorpicker**</a>, <a href="https://docs.webix.com/desktop__colorselector.html">**colorselect**</a> and <a href="https://docs.webix.com/desktop__colorboard.html">**colorboard**</a>.

Since we only have 4 types of color packages, the best option would be the **colorboard** widget with a limited palette.

We can specify the palette colors via the ***palette*** property and the default color via the ***value*** property. Let's also set fixed dimensions for each palette box via the corresponding ***width*** and ***height*** properties, and remove the border around the component using its ***borderless*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/672af47b9ebefeaf66de159541800d1c %}

The whole section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gq5vf6jzsmar9vhv7fpz.png" >

<h2>Buttons for Navigation</h2>

For the order form we have to implement one more important part. It is about buttons for switching to the next form and back to the trade list. For creating these buttons we will use the <a href="https://docs.webix.com/desktop__button.html">**button**</a> component.

To apply built-in styling, we need to set the css property to the corresponding webix class. In our case, it is about the *webix_secondary* and *webix_primary* classes.

The button name is set via its ***label*** property. For completeness, it is worth noting that along with the label of each button, we will place a small arrow to indicate the button's purpose. The left arrow for going back (in this case, to the goods list), and the right one for going forward to the next form. To define built-in webix icons, we need to use dedicated css classes.

Both these buttons will be displayed as columns. For this, we need to put them into the array of the ***cols*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/493f9fb6d92f3b5aa393353cffa24e2a %}

The buttons look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fdli8kquu97ffqk3takf.png" >

The order form interface is ready. Now we need to include the *order_form.js* file into *index.html* and put the **order_form** variable into the layout code. In the browser, we will see the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx67ackf8tl2cpo8593r.png" >

<h2>User Form</h2>

After the user has entered the necessary information about the order, we need to get his personal data. It is required for identifying the user when he comes to pick up his order or receives it through the delivery service.

Let's create a separate form with fields for entering the following personal data:

- first and last name
- age
- gender
- contact information:
   * email
   * phone number.

The user form will look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx67ackf8tl2cpo8593r.png" >

Let's see how to implement this in the code.

We create a form in the *user_form.js* file and save it to the **user_form** variable. After this we define the "**User Information**" section with the fields mentioned above.

<h3>Input Fields for First and Last Name</h3>

Now let's move on to the fields in which the user can enter its first and last name. To create them, we can use the well-known **text** control. As in the previous form, for these controls we also specify a standard set of properties, namely: *label, name, placeholder, clear and required*.

{% gist https://gist.github.com/serhiipylypchuk1991/6b25d5b41c905adcfb90d19d033f3fa6 %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8mdqq4q7vjrsmhkixni.png" >

<h3>Controls for Age and Gender</h3>

Next, we have 2 optional fields. It is about a counter with which the user can indicate his age and radio buttons for choosing a gender.

**Counter**

To get the user age, we can use the **counter** control. We have already used it to define the number of goods.

The age of our customer should be in the range from 18 to 100. These parameters can be set via the ***min*** and ***max*** properties.

**Radio**

To get the user gender, we can use the **radio** control. We have also used it to select the method of the order receiving. The widget will consist of 2 options, namely: *Male* and *Female*.

{% gist https://gist.github.com/serhiipylypchuk1991/726c1f588ca8bfd3a2a1c42246d9cfbb %}

Now the section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aoc02kvbdx4b78sziub8.png" >

<h3>Input Fields for Contact Information</h3>

To contact the user for clarifying any additional information and notifying about the order readiness or its dispatch, we need to get its contact information.

Let's create 2 fields in which the user can enter his email and phone number. For this, we use the **text** control and specify the set of standard properties (*label, name, placeholder, clear and required*).

A special emphasis should be placed on the phone number field. Here we can apply a special mask for entering a phone number. To do this we need to set the ***pattern*** property to the built-in `webix.patterns.phone` value. It is worth mentioning here that this is one of those features that are available only in the PRO version. In <a href="https://docs.webix.com/desktop__formatted_text_inputs.html">this</a> article, you can find more information about the input field formatting.

The mask allows users to enter only 11 characters of the phone number, adds a "+" sign at the beginning of the number and encloses the telephone operator code in parentheses. Other characters will be ignored.

Let's give a little hint for filling this field and add a short message at the bottom of the input. For this, we can use the ***bottomLabel*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/40e04fb9803640d1c9f86ce3c4f682c1 %}

The whole section looks like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5nd27n3xtagesnwlr81.png" >

For this form, we also need to add navigation buttons. Here we don't have to bother too much and just copy the similar code from the previous form. The differences will only be visible when we make these buttons workable.

The user form interface is ready. Now we just need to include the *user_form.js* file into *index.html* and put the **user_form** variable into layout code. In the browser, we will see the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3r4grx1wpceubhqohloc.png" >

<h1>Payment form</h1>

After the user has entered personal data, we need to get his credit card information for paying the order through a special service.

Let's create a separate form for payment information and collect the following data:

* card number
* cardholder's name
* expiration date
* CVV code.

The payment form will look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8vn1go5qxq3l8igiwww.png" >

We create a form in the *payment_form.js* file and save it to the **payment_form** variable. After this, we define the "**Payment Information**" section with the fields mentioned above.

The first field is intended for the card number. Besides the standard properties of the **text** control (*label, name, placeholder, clear and required*), we also specify a built-in mask for entering the card number: `pattern: webix.patterns.card`. It means that the user can enter only 16 digits indicated on the front of his card. Other characters will be ignored. I would like to remind you that masks are only available in the Pro version.

Next, we need to create a field for entering the name of the cardholder. The **text** control of this field will also include the standard set of properties mentioned above.

The controls for selecting card expiration date deserve more attention. Here we can use 2 <a href="https://docs.webix.com/desktop__richselect.html">**richselect**</a> components. When the user clicks on it, the widget will display a drop-down list with options. The data for these options are set via the ***options*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/678a6b97c6a69d899ff9b01464113688 %}

Now we move on to the field for entering the CVV code. Here the user needs to enter 3 secret digits indicated on the back of the card. The **text** control of this field will also include a standard set of properties. Besides, we can set the ***type*** property to the `password` value, to define the type of the field. It will display asterisks instead of the entered data. We will also specify a custom mask via the ***pattern*** property. So now the user can enter only 3 digits of the CVV code.

{% gist https://gist.github.com/serhiipylypchuk1991/10b5d7590b69438f4379968c46a6d2a7 %}

Let's add some control for saving the entered data in the browser settings. If the user enters data and checks this control, he can reuse payment data the next time. For this, we use the <a href="https://docs.webix.com/desktop__checkbox.html">**checkbox**</a> control with the ***name*** and ***labelRight*** properties. The second property will display the label on the right part of the control

{% gist https://gist.github.com/serhiipylypchuk1991/17f914564de00a076e79f2766eeab02c %}

For this form, we also need to add corresponding buttons for going back and making the order. Here we just copy the similar code from the previous form and rename the second button to "**Make order**".

The payment form interface is ready. Now we just need to include the *payment_form.js* file into index.html and put the **payment_form** variable into layout code. In the browser, we will see the following result:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iw7i62kp45gwd3kufw8r.png" >

<h1>How to Get the App Working</h1>

Above we have described the layout and interface of our forms. But this is only half the way. Now let's get them to work. And for this, Webix has all the necessary tools.

<h3>The List of Goods</h3>

And we will start from the main page, where the list of goods is displayed. Each block on this page consists of a short description and the "**Buy now**" button.

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/igyyjs2wzyd3hnrn3d1d.png" >

When the user clicks on this button, we need to:

* show the module with the order form
* fill out the order form with the data of the selected book.

To implement the mentioned above, we need to handle the button **click** event. This can be done via the corresponding ***onClick*** property of the **dataview** widget. Inside the object of this property, we specify the *css* class of our button and set a handler to it as a value.

{% gist https://gist.github.com/serhiipylypchuk1991/a19e67f1a6820e744704cd8fac2f89af %}

To fill out the order form fields, we can use its `setValues()` method and pass the object with the needed data as a parameter.

As you remember, we have set the name for all form fields via the ***name*** property. In the data object, we use these names as the keys and set them to the corresponding values.

If we pass only the data object to the method, it will remove all the form values ​​and set new values specified in the object. In this case, the delivery information will also be cleared and the user will need to enter the address again.

To avoid this inconvenience, we can pass the `true` value to the method as the second parameter. So now the method will change only the values passed in the object.

After all the data manipulation, we can switch the **multiview** component to the next module using its `show()` method.

<h3>How to Calculate the Order Price</h3>

Now we need to calculate the order price and update it every time when the user changes the number of goods or applies the insurance control.

To listen to any change in the form fields, we need to use the ***on*** property. In the object of this property, we can specify the desired event and its handler.

{% gist https://gist.github.com/serhiipylypchuk1991/0c90aaa32d9da380d6b9f209cc87f12c %}

So now we need to create this handler. And it will look like this:

{% gist https://gist.github.com/serhiipylypchuk1991/1adad114df77337ac1b33a109e3446ad %}

Here we get an object with the form values ​​via its `getValues()` method. It is worth noting that this object will include only the fields value with the ***name*** property.

The price variable stores the total goods price. It depends on the initial price (set in the hidden *initial_price* field) and the goods count.

Next, we need to check the insurance that can be applied in the "**Delivery Information**" section and will affect the order price. For this, we check the visibility of the "**Delivery Information**" section using the `isVisible()` method. It returns *true* if the section is visible and *false* if not.

If the section is visible, we need to check the state of the **switch** control (if enabled - value `1`, if disabled - value `0`) and generate the final order cost. If the insurance is applied, we will increase the cost by 20%.

When the final order price is ready, we need to update it in the corresponding **Price** field. To do this, we can use the `setValues​​()` method and update only the field we need.

Now the order price is updated dynamically when the user changes the number of goods and applies the insurance.

<h3>How to Navigate Between Forms</h3>

In each form of our application, we have created the "**Back**" and "**Next**" buttons to navigate between tabs.

The "**Back**" button will switch the **multiview** component to the previous module, and the "**Next**" button to the next one. To get the buttons to work, we need to catch the click events and set the appropriate handlers.

To handle the click event, the **button** control has a special ***click*** property.

{% gist https://gist.github.com/serhiipylypchuk1991/df4ad3481f5caa66434c044d1108e799 %}

In the handler of the "**Back**" button of the user form, we go back to the trade list via its `show()` method.


```javascript
function goBackCustomHandler(){
	$$("trade_list").show(); //go to the trade list
}
```

In the same handlers of two other forms, we go to the previous module via the `back()` method of the **multiview** widget, which contains the tabs with the forms.


```javascript
function goBackCustomHandler(){
	$$("form_multiview").back(); //go to the previous module
}
```

In the handler of the "**Next**" button, we also use the `show()` method to display the desired module, included in the **multiview** component.


```javascript
function goNextCustomHandler(){
	$$("id_of_next_form").show();
}
```

In this way we will change tabs dynamically.

<h3>How to Validate the Forms</h3>

When the user clicks on the "**Next**" button and before switching to the next form, we need to validate the current form. This can be done in the "**Next**" button handler:


```javascript
function goNextCustomHandler(){
	if($$("id_of_current_form").validate()){
		$$("id_of_next_form").show();
	}
}
```

Here we run the validation of the current form via its `validate()` method. It will return true if the validation is successful, and false if not. It should be noted here that the method checks only those form fields for which we applied the rules. Webix allows setting these rules for a separate field via its <a href="https://docs.webix.com/api__ui.text_required_config.html">***required***</a> and <a href="https://docs.webix.com/api__ui.text_validate_config.html">***validate***</a> properties, and for the whole form via its <a href="https://docs.webix.com/api__link__ui.form_rules_config.html">***rules***</a> property.

I hope you still remember that for the required fields we defined the required property. This property adds a red asterisk to the labels of the required fields. By default, such fields are validated by the built-in `webix.rules.isNotEmpty` rule and must be filled. If at least one of these fields is not filled in, the validation method will return an error and the fields will be highlighted in red.

The unvalidated order form will look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mll6xgmudyzujgq06tvg.png" >

If all the required fields of this form are filled in, or the "Delivery Information" section is hidden, the multiview will be switched to the next form.

Besides the ***required*** property with the default validation rule, we can apply other built-in rules or define our own. Let's set such rules for checking the email and phone number in the user form. And this can be done in the object of the ***rules*** property of the form.

{% gist https://gist.github.com/serhiipylypchuk1991/e2f8409fcbba8b16b85eb1772dc98f70 %}

To check the email address, we use the built-in `webix.rules.isEmail` rule, and for the phone number we use our own condition. Since the phone number consists of 11 digits, we will return an error if the entered value length is less than the required one.

To make the field validation more informative, let's add a hint that will be displayed if the validation method returns an error. For the required fields, we need to specify the ***invalidMessage*** property and set it to the error message.

The unvalidated user form will look like this:

<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1f28uq7e9bygo85x4vv7.png" >

In case the user navigates to the previous form and then comes back, let's clear the validation markers of the current form. To do this, we can use the `clearValidation()` method of the form and call it in the "**Back**" button handler.

<h3>How to Make Order</h3>

In the last payment form, we have created the "**Make order**" button instead of the "**Next**" button. This button runs validation and, if successful, collects data from all three forms, clears the current form and displays the main page with the goods list. The handler code will look like this:

{% gist https://gist.github.com/serhiipylypchuk1991/98be67d05ee8907a7132210df9b7a124 %}

In a real example, the collected data needs to be sent to the server for further processing. But this is the topic of another article.

<h1>Conclusion</h1>

You can find the full source code and live demo <a href="https://github.com/serhiipylypchuk1991/book-store-service">here</a>.

In this article, we have detailed how to create forms using the Webix library, and now we know:

* how to connect the library
* how to describe UI components using JSON syntax
* how to use component methods
* how to set the event handlers.

And most importantly, we have learned how to work with Webix forms, apply various controls and use methods for managing the form (collecting and setting data, validation, etc.).

As you can see, the widget names, their methods and properties are intuitive and easy to use. In fact, this is only a small part of everything that the library can offer. For more detailed information, you can go to the <a href="https://docs.webix.com/">documentation</a>, which contains a detailed description of all the possibilities with examples.