Hotel Room Reservation System

Simplest reservation SPA sample

by Ilia Tretiakov

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap-theme.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>
<div style="height:4px"></div>
<div class="container">
  <div class="row">
    <div class="col-xs-12">
      <div class="panel panel-default">
        <!-- Default panel contents -->
        <div class="panel-heading">
          <div class="form-inline">
            <div class="input-group">
              <div class="input-group-addon">From</div>
              <input data-bind="datepicker: dateFrom, datepickerOptions: { dateFormat: 'dd.mm.yy', minDate: new Date() }"
                class="form-control"/>
            </div>
            <div class="input-group">
              <div class="input-group-addon">To</div>
              <input data-bind="
                  datepicker: dateTo,
                  datepickerOptions: { dateFormat: 'dd.mm.yy', minDate: new Date() }"
                class="form-control"/>
            </div>
            <div class="input-group">
      ...

CSS

input[data-bind^='datepicker']{width: 110px !important;}

JavaScript

var viewModel = function () {
		"use strict"
  
    var self = this;
    
    self.rooms = ko.observableArray([
    	{id:1, name:'Room 1', beds:1},
    	{id:2, name:'Room 2', beds:1},
    	{id:3, name:'Room 3', beds:2},
    	{id:4, name:'Room 4', beds:2},
    	{id:5, name:'Room 5', beds:2},
    	{id:6, name:'Room 6', beds:3},
    	{id:7, name:'Room 7', beds:3},
    	{id:8, name:'Room 8', beds:3},
    	{id:9, name:'Room 9', beds:3},
    	{id:10, name:'Room 10', beds:4},
    	{id:11, name:'Room 11', beds:4},
    	{id:12, name:'Room 12', beds:4},
    	{id:13, name:'Room 13', beds:4},
    	{id:14, name:'Room 14', beds:4},
    ]);
    
 		self.bedAmounts = ko.observableArray([null,1,2,3,4]);
    
    self.dateFrom = ko.observable();
    self.dateTo = ko.observable();
    self.bedsRequested = ko.observable();
    
    self.booked = {};
    
    self.increaseDateTo = ko.computed(function() {
    	// TODO.it3xl.ru: replace by ko.validation (have no time to do it right now).
    	
      var fromDate = self.dateFrom();
      var toDate = self.dateTo();

      if(toDate < fromDate){
      	self.dateTo(null);
      }
    }, this);
    self.bookAllowed = function(room) {
      var fromDate = self.dateFrom();
      var toDate = self.dateTo();
      var bedsReq = self.bedsRequested();
      
      if(bedsReq !== room.beds){
      	return false;
      }
      
      if(!fromDate || !toDate){
      	return false;
      }
      
      var current = moment(fromDate);
      var days = daysToBook(current, toDate);
      for(var i = 0; i < days; i++){
      	current.add(1, 'days');
        var key = getBookedKey(current);
        var day = self.booked[key];
        if(!day){
        	continue;
        }
        if(day[room.id]){
        	return false;
        }
      }

      return true;
    };
    
    self.bookNow = function(room){
      var fromDate = self.dateFrom();
      var toDate = self.dateTo();
      var bedsReq = self.bedsRequested();
      
      // Will prvent a firing...