We create a Booking application with Webix UI

Webix UI
Webix UI

This article is intended for those who value their time and do not want to spend many months on a meticulous study of native web development technologies. It is certainly useful to know and understand them, but in the modern world technologies are developing so rapidly that keeping track of all the subtleties is not an easy task. In order not to waste away over the talmuds of boring documents that will change tomorrow, you can use ready-made solutions.





One of the best solutions is offered to us by the Webix team . We will look at their library of UI components in this article. 





For clarity, we will create our own application for searching and booking air tickets. The summer vacation season is just around the corner, so this choice is more relevant than ever. 





The code of the finished application can be found here .





A little about Webix and its capabilities

Webix UI — JavaScript , . UI , , , Report Manager, . , . , , , , . . .





UI

. , , . .





, , , ( webix-). , zip-. . “license.txt”, “readme.txt” “whatsnew.txt”, , . , “samples” ,   Webix UI.





“codebase”, , : “webix.js” “webix.css”. , Webix- , index.html :





<!DOCTYPE html>
<html>
    <head>
      	<title>Webix Booking</title>
      	<meta charset="utf-8">
      	<link rel="stylesheet" type="text/css" href="codebase/webix.css">
      	<script type="text/javascript" src="codebase/webix.js"></script>
    </head>
    <body>
			<script type="text/javascript">
			...
			</script>
    </body>
</html>
      
      



<script>...</script>, .





, . CDN. :





<link rel="stylesheet" type="text/css" href="http://cdn.webix.com/edge/webix.css">
<script type="text/javascript" src="http://cdn.webix.com/edge/webix.js"></script>
      
      



Webix.





Webix- webix.ui(). , HTML . webix.ready(function(){}). :





webix.ready(function(){
	webix.ui({
	    /* */
	});
});
      
      



index.html , Booking . .





Booking

:

















  • .





,   index.html. , . , .





, JSON. .





, rows cols, , . , .





2 . rows:





webix.ui({
    rows: [
        { template:"Row One" },
        { template:"Row Two" }
    ]
});

      
      



:





template:"Row One" , HTML-.





. 2 :









  • .





2 . , . cols:





webix.ui({
  rows: [
          { template:"Toolbar", height:50},
          {
              cols:[
                { template:"Search Form" },
                { template:"Data Table" }
              ]
          }
  ]
});

      
      



:





, . . , 2 . , , CSS width height.





2 . , . , ? : ,   , . , spacer, . , “ ”, .  





cols. , cols rows . . Webix type:





webix.ui({
  rows: [
    { template:"Toolbar", height:50 },
    {
      type:"clean", // -
      cols:[
        { template:"Order Form" },
        {}
      ]
    }
  ]
});
      
      



  :





. . , Webix . multiview .





cells id. , , , , , . 





:





webix.ui({
  rows:[
    { template:"Toolbar", height:50 },
    {
      cells:[
        {	
          id:"flight_search",
          cols:[
            {template:"Search Form"},
            {template:"Data Table"},
          ]
        },
        {
          id:"flight_booking",
          type:"clean",
          cols:[
            {template:"Order Form"},
            {},
          ]
        }
      ]
    }
  ]
});
      
      



, . .





— . . .





toolbar.js :





const toolbar = { view:"toolbar" };
      
      



, , .





, view. toolbar.  :





{
  view:"toolbar"
  css:"webix_dark", //
  cols:[
    {
      id:"label", // id  
      view:"label",
      label:"Flight Search", //
    }
  ]
}
      
      



, rows cols. label cols toolbar.





id . . , . 





. , toolbar.js index.html rows {template:“Toolbar”} :





webix.ui({
	rows: [
    toolbar,
    {
      cells:[
        ...
      ]
    }
	]
});
      
      



:





. . 2 :









  • .





.





. , .





<form>, . . .





Webix . . 





search_form.js form:





const search_form = { view:form };
      
      



, . elements:





{
  view:form,
  ...
  elements:[ 
    { /* */ },
    { /* */ },
    ...
  ]
  ...
}
      
      



, elements. , json . , Webix .





Webix . , . name . . .





, . , . . . “One Way” “Return”. . . , “Reset” “Search”. :





.









, . radio:





{
  view:"radio",
  label:"Trip",
  name:"trip_type",
  value:1,
  options:[
    { id:1, value:"One-Way" },
    { id:2, value:"Return" }
  ]
}
      
      



options. , label, , , name. , value









, . combo:





{
    view:"combo",
    id:"from",
    clear:"replace",
    ...
    placeholder:"Select departure point",
    options:cities_data
}

      
      



, . placeholder. , . , , , . clear replace. , , , ( ).





. . options . Webix. , URL, .





, , . Webix , DataCollection. URL, . . ./data/cities.json. :





const cities_data = new webix.DataCollection({
  url:"./data/cities.json"
});
      
      



.





. , , , .









— ­­ - . . . , datepicker:





{
  view:"datepicker",
  name:"departure_date",
  ...
  format:"%d %M %Y"
}
      
      



, . , , . format.





, hidden. “Return”, .









, , . , . . counter. . , . min, 1 (, ). :





{ view:"counter", name:"tickets", label:"Tickets", min:1 }
      
      







. , .





“Search” “Reset”. button.  value,   css. , . "webix_primary" “Search”. .





:





{
  cols:[
    { view:"button", value:"Reset" },
    { view:"button", value:"Search", css:"webix_primary" }
  ]
}
      
      



. - ? , , search_form.js index.html. search_form, :





[
  toolbar,
  {
    cells:[
      {
        id:"flight_search",
        cols:[
          search_form,
          { template:"Data Table" }
        ]
      }, ...
    ]
  },
]	
      
      



:





, “Search” . , . 





Webix . , , PDF Excel. , , , .





datatable.js datatable:





const flight_table = { 
  view:"datatable",
  url:flights_data
};
      
      



. ./data/flights_data.json. Webix , , , . .





url. flights_data





, . , Webix autoConfig. true, .





, . , . . 





  columns:





columns:[
  { /* */ },
  { /* */ },
  ...
]
      
      



, id, , . 





, - — “”. header.





, , . , Webix . format. 





, . , . . 





.





, "2021-03-26". , — ( ). , JS Date . scheme ( id) Date :





scheme:{
  $init:function(obj){
    obj.date = webix.Date.strToDate("%Y-%m-%d")(obj.date);
  }
}
      
      



“Date” , . . . . format webix.i18n.longDateFormatStr. Date format 26 March 2021. .





, , . , . — ? . id - value, id . id, collection. 





, , cities_data. , 1 .





, collection cities_data id, . - . .





. , , “Search” ( , ). ? , . ?





, . . , .





, .





.





(10, 100 ), . . , - , . 





search:





const search_bar = { view:"search" };
      
      



“”.





, . :





[
   toolbar,
   {
     cells:[
       {
         id:"flight_search",
         cols:[
           search_form,
           { 
             rows:{
               search_bar,
               flight_table
             }
           }
         ]
       }, ...
     ]
   },
]	
      
      



-. :





. . . “Book” . :





, , form :





const order_form = {
  view:"form",
  elements:[
    ...
  ]
};
      
      



.









. , .





text :





elements:[
  { view:"text", name:"first_name", …, invalidMessage:"First Name can not be empty" },
  { view:"text", name:"last_name", …, invalidMessage:"Last Name can not be empty" },
  { view:"text", name:"email", …, invalidMessage:"Incorrect email address" },
  ...
]	
      
      



.   — , , . , . ? , . 





Webix rules . , , , , , , . , , ( name) rules:





{
  elements:[ … ],
  rules:{
    first_name:webix.rules.isNotEmpty, //    
    last_name:webix.rules.isNotEmpty, 
    email:webix.rules.isEmail //     email
  }
}
      
      



, . , . . , , , . 





Webix invalidMessage. , :





{ ..., invalidMessage:"First Name can not be empty", ... }
      
      



, Webix . , UI , - .









“Book” . , . 2 ( ), . . 





counter. , , . . , :





{ view:"counter", id:"tickets_counter", name:"tickets", label:"Tickets", min:1 }
      
      







, , , . , , . , .





2 “Checked-in Baggage” “Food” , , . checkbox:





[
  { view:"checkbox", name:"baggage", label:"Checked-in Baggage", checkValue:15 },
  { view:"checkbox", name:"food", label:"Food", checkValue:10 }
]
      
      



checkValue . 15 10 .









.  “Economy” “Business”. radio:





{ 
  view:"radio", name:"class", label:"Class",
  options:[
    { id:1, value:"Economy" },
    { id:2, value:"Business" }
  ]
}
      
      



“Economy” , “Business” . , .









— . . . label:





{ view:"label", id:"order_price" }
      
      



“Book” . . . 





“Go Back” “Make Order”





- . . “Go Back” “Make Order” button:





{ 
  cols:[
    { view:"button", value:"Go Back" },
    { view:"button", value:"Make Order" }
  ] 
}
      
      



. , :





[
  toolbar,
  {
    cells:[
      {...},
      {
        id:"flight_booking",
        type:"clean",								
        cols:[
           order_form, 
           {}
        ]
  		}
		]
	}
]	
      
      



:





. .





Webix UI. . . , , . , Webix .









, “One-Way”, , “Return”, . ? , . . on, . :





{
  view:"radio",
  ...
  on:{
    onChange:function(newv){
      if(newv == 2){
        $$("return_date").show(); //   
      }else{
        $$("return_date").hide(); //   
      }
    }
  }
}
      
      



. show() hide(), . $$(id) , id .









. , . ? , . , . .





, , , . :





...
{
  options:cities_data,
  on:{
    onShow:function(v){
      optionsData("from","to");
    }
  }
}
      
      



on, . onShow. optionsData(), , . :





function optionsData(first_id, second_id){
  const options = $$(first_id).getList(); //   
  const exception = $$(second_id).getValue(); //  
  options.filter(obj => obj.id != exception); // 
}
      
      



Combo, getList() getValue(). , — . filter() ( getValue).





“Reset” “Search”.





“Search”





, “Search” . , . . :





function lookForFlights(){
	const vals = $$("search_form").getValues(); //     
	const table = $$("flight_table"); //    
	table.filter(function(obj){ /*  */ });
}
      
      



Webix , . getValues(), . filter(), .   , , , . , JS.





, , . click:





{ view:"button", value:"Search", ... click: lookForFlights }
      
      



“Reset”





, , , . , “Reset”.





:





function resetForm(){
	const form = $$("search_form"); 
	form.clear(); // 
	form.setValues({trip_type:1}); //    
	$$("flight_table").filter(); //    
}
      
      



clear(), . ( ) . setValues(). , . 





filter() , . , , . . . . , , :





{ view:"button", value:"Reset", ... click:resetForm }
      
      



. .





, , . 





, , . :





function searchFlight(){
  //   
	const value = $$("search").getValue().toLowerCase(); 
	const table = $$("flight_table");
  //   
	const res = table.find(function(obj){ /* */ }); 
	table.clearCss("marker", true);  //  
	for(let i = 0; i < res.length; i++){
		table.addCss(res[i].id, "marker", true); //  css  marker
	}
	table.refresh(); // 
}
      
      



getValue() . find(), . , , css “marker” ( css ). , refresh(), css . 





onTimedKeyPress, . on. :





{
  view:"search",
  id:"search",
  ...
  on:{
    onTimedKeyPress:function(){ //   
      searchFlight(); //     
    },
    onChange:function(){ //     “”
      if(!this.getValue()){
        $$("flight_table").clearCss("marker"); // 
      }
    }
  }
}
      
      



, onChange. “”, clear, .





, . 





, “Book”, . , .









“Book” . , , multiview. cells, id:





cells:[
  {	
    id:"flight_search", ...
  },
  {
    id:"flight_booking", ...
  }
]
      
      



multiview show() , . $$(id). id :





$$("flight_booking").show(); //  
      
      



. :





function bookFlight(id){
	//   
	const required_tickets = $$("search_form").getValues().tickets;
	//   
	const available_places = flight_table.getItem(id).places;
	//    	
	$$("tickets_counter").define("max", available_places); 
	//      
	$$("flight_booking_form").setValues({
		//        
		tickets:required_tickets <= available_places ? required_tickets : available_places,
		//      
		price:flight_table.getItem(id).price,
		// ""   
		class:1
	});
	$$("flight_booking").show(); //  
	...
}
      
      



, , . 





, getItem(). , “Book”. . id .





, , . . define() refresh(). 





define() , refresh() :





$$("label").define("label", "Flight Booking"); //   
$$("label").refresh(); //  

      
      



“Book”. , “webix_button” . Webix onClick, , css :





{
  columns:[ … ],
  onClick:{
    "webix_button":function(e,id){
      bookFlight(id);
    }
  }
}
      
      



.





“Book” . , . , . .





“Book” . . . , on, onChange ( ) onValues ( “Book”):





on:{
	onChange:function(){
		orderPrice(this.getValues());
	},
	onValues:function(){
		orderPrice(this.getValues());
	}
}
      
      



:





function orderPrice(vals){
	//  
	const tickets = vals.tickets; 
	//       
	const price = vals.price*1*vals.class*tickets; 
	//   
	const baggage = vals.baggage * tickets;
	//   
	const food = vals.food * tickets; 
	//  
	const total = price+baggage+food; 
	//  
	$$("order_price").setValue(total+"$"); 
}
      
      



- getValues(),   “Price”   setValue(). setValues(), , setValue() , .





. , . 





, “Make Order”. , , :





function makeOrder(){
	const order_form = $$("flight_booking_form"); //   
	if(order_form.validate()){ //  
		webix.alert({ //       
			title: "Order",
			text: "We will send you an information to confirm your Order"
		}).then(function(){
			goBack(); //      
		});
	}
}
      
      



validate(). , rules. , true. false, , . , invalidMessage.





. , Webix . webix.alert(), , “OK” ( goBack()):





webix.alert({
  title: "Order is successfull",
  text: "We will send you an information to confirm your Order"
}).then(function(){
  goBack();
});
      
      



goBack() “Go Back”. clearValidation(), , :





function goBack(){
	const order_form = $$("flight_booking_form"); //   
	const label = $$("label"); //     

	order_form.clearValidation(); // 

	label.define("label", "Flight Search"); //  
	label.refresh(); // 

	$$("flight_search").show(); //       
}
      
      



.





In this article, we have detailed how to create an application using Webix. We learned how to create layouts and describe UI components using json syntax. We indirectly touched upon some of the methods that allow you to work with data. As you can see, the components and methods are intuitive and easy to use. In fact, this is only a small fraction of everything that the library has to offer us. For a more detailed acquaintance, you can go to the documentation , which contains a detailed description of all the possibilities with illustrative examples.








All Articles