Load AngularJS, dependencies script files and the script file angular-reservation.min.js in your index.html.
<!-- Angular reservation dependencies --> <script type="text/javascript" src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script> <script type="text/javascript" src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script> <script type="text/javascript" src="bower_components/angular-translate/angular-translate.min.js"></script> <script src="bower_components/angular-messages/angular-messages.min.js"></script> <!-- Angular reservation minified --> <script type="text/javascript" src="bower_components/angular-reservation/dist/angular-reservation.min.js"></script>Load styles
Load bootstrap css and angular-reservation.min.css in your index.html.
<!-- Compiled and minified Bootstrap CSS --> <link rel="stylesheet" href="components/bootstrap/bootstrap.min.css"> <!-- Angular reservation minified css --> <link rel="stylesheet" href="bower_components/angular-reservation/dist/angular-reservation.min.css">Add module dependency
Add 'hm.reservation' to the list of module dependencies.
angular.module('myApp', [ 'hm.reservation' ])HTML Markup
Add angular-reservation directive in an html page.
<!-- angular-reservation directive --> <reservation></reservation>Setup
//Configuration of reservation module angular.module('myApp').config(function (reservationConfigProvider) { var config = { getAvailableHoursAPIUrl: "http://API-URL/availableHours", //API url endpoint to load list of available hours reserveAPIUrl: "http://API-URL/reserve", //API url endpoint to do a reserve }; reservationConfigProvider.set(config); });
You can configure angular-reservation module during config phase passing configuration options.
//Configuration of reservation module angular.module('myApp').config(function (reservationConfigProvider) { var config = { getAvailableDatesFromAPI: false, getAvailableDatesAPIUrl: "http://api-url/api/availableDates", getAvailableHoursAPIUrl: "http://api-url/api/availableHours", reserveAPIUrl: "http://api-url/api/reserve", language: "es", dateFormat: "dd/MM/yyyy", showConfirmationModal: false, datepickerTemplate: "partials/datepicker.html", availableHoursTemplate: "partials/availableHours.html", noAvailableHoursTemplate: "partials/noAvailableHours.html" clientFormTemplate: "partials/clientFormTemplate.html", confirmationModalTemplate: "partials/confirmModal.html" }; reservationConfigProvider.set(config); });Loading available dates from a REST API
//Configuration of reservation module angular.module('myApp').config(function (reservationConfigProvider) { var config = { getAvailableDatesFromAPI: true, getAvailableDatesAPIUrl: "http://my-api-url/availableDates", ... }; reservationConfigProvider.set(config); });Overriding datepicker template
<h3 class="text-center">Select an available date</h3> <div style="width: 50%; margin: 0 auto"> <p class="input-group"> <input type="text" class="form-control" uib-datepicker-popup ng-model="reservationCtrl.selectedDate" is-open="isOpen" datepicker-options="reservationCtrl.datepickerOptions" ng-change="reservationCtrl.onSelectDate()"/> <span class="input-group-btn"> <button type="button" class="btn btn-default" ng-click="isOpen = !isOpen"><i class="glyphicon glyphicon-calendar"></i></button> </span> </p> </div>Overriding available hours template
<h3 class="text-center">Select an available hour</h3> <div ng-repeat="hour in reservationCtrl.availableHours" ng-click="reservationCtrl.selectHour(hour)"> <div ng-class="{'selected': reservationCtrl.selectedHour == hour}" class="hour"> <span>{{hour}}</span> </div> </div> <style> .hour{ border: 1px solid black; border-radius: 4px; text-align: center; padding: 1em 1em; margin: 1em 1em; cursor: pointer; } </style>Overriding no available hours template
<div> <h3 class="text-justify" style="padding: 2em 2em;">Oh no! There is no available hours for selected date, try another date!</h3> </div>Overriding client form template
<div class="form-group col-md-12"> <label class="col-md-4 control-label" for="name">Name</label> <div class="col-md-8"> <input id="name" name="name" class="form-control" placeholder="{{'name' | translate}}" type="text" ng-model="reservationCtrl.userData.name" autofocus="true" ng-pattern="/^[\w\s\-\x7f-\xff]*$/" ng-minlength="2" ng-maxlength="100" required> <div class="help-block" ng-messages="reserveForm.name.$error" ng-if="reserveForm.$submitted"> <p ng-message="minlength" class="text-danger">{{"minLength" | translate: '{minLength: "2"}'}}</p> <p ng-message="maxlength" class="text-danger">{{"maxLength" | translate: '{maxLength: "100"}'}}</p> <p ng-message="pattern" class="text-danger">{{"invalidCharacters" | translate}}</p> <p ng-message="required" class="text-danger">{{"required" | translate}}</p> </div> </div> </div> <div class="form-group col-md-12"> <label class="col-md-4 control-label">Gender</label> <div class="col-md-8"> <div class="radio"> <label> <input type="radio" name="gender" id="option1" value="Male" ng-model="reservationCtrl.userData.gender"> Male </label> </div> <div class="radio"> <label> <input type="radio" name="gender" id="option2" value="Female" ng-model="reservationCtrl.userData.gender"> Female </label> </div> <div class="help-block" ng-messages="reserveForm.gender.$error" ng-if="reserveForm.$submitted"> <p ng-message="required" class="text-danger">{{"required" | translate}}</p> </div> </div> </div> <div class="form-group col-md-12"> <label class="col-md-4 control-label" for="phone">Phone</label> <div class="col-md-8"> <input id="phone" name="phone" class="form-control" placeholder="{{'phone' | translate}}" type="tel" ng-model="reservationCtrl.userData.phone" ng-pattern="/^[0-9]*$/" ng-minlength="5" ng-maxlength="15" required> <div class="help-block" ng-messages="reserveForm.phone.$error" ng-if="reserveForm.$submitted"> <p ng-message="minlength" class="text-danger">{{"minLength" | translate: '{minLength: "5"}'}}</p> <p ng-message="maxlength" class="text-danger">{{"maxLength" | translate: '{maxLength: "15"}'}}</p> <p ng-message="pattern" class="text-danger">{{"invalidPhone" | translate}}</p> <p ng-message="required" class="text-danger">{{"required" | translate}}</p> </div> </div> </div> <div class="form-group col-md-12"> <label class="col-md-4 control-label" for="age">Age</label> <div class="col-md-8"> <select id="age" name="age" class="form-control" ng-model="reservationCtrl.userData.age" required> <option value="18-25">Between 18 and 25</option> <option value="25-40">Between 25 and 40</option> <option value="40-65">Between 40 and 65</option> <option value="+65">>65/option> </select> <div class="help-block" ng-messages="reserveForm.age.$error" ng-if="reserveForm.$submitted"> <p ng-message="required" class="text-danger">{{"required" | translate}}</p> </div> </div> </div> <div class="form-group"> <div class="col-md-12"> <button id="reserve" type="submit" name="reserve" class="btn btn-success">{{"reserve" | translate}}</button> </div> </div>Overriding confirmation modal template
<div class="modal-header"> <h3 class="modal-title">Confirm amazing stuff</h3> </div> <div class="modal-body"> <h4>Are you really really sure of what you are doing??</h4> <h5>Let's the party started!!!</h5> </div> <div class="modal-footer"> <button class="btn btn-danger" type="button" ng-click="$dismiss()">Oh, no!</button> <button class="btn btn-success" type="button" ng-click="$close()">Hell, yes!</button> </div>
You can pass datepicker options to angular-reservation directive to configure datepicker based on your needs. Datepicker option documentation can be found here.
HTML Markup<reservation datepicker-options="myCtrl.datepickerOptions"></reservation>Controller
//Controller angular.module('myApp').controller('MyCtrl', function () { var vm = this; //Datepicker options vm.datepickerOptions = { minDate: new Date(), //Disabled date selection before today showWeeks: false, //Don't show weeks startingDay: 1, //Starting day at Monday dateDisabled: myDisabledDates //Disabled dates } //Disabled dates function myDisabledDates(dateAndMode) { var date = dateAndMode.date; var mode = dateAndMode.mode; var day = date.getDate(); var dayOfWeek = date.getDay(); var month = date.getMonth(); //Disable dates on Sundays and from 1 to 15 of August return (mode === 'day' && (dayOfWeek === 0) || (month === 7 && day in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])); } });
There are some callbacks available at reservationService that can be use to do some business logic. Open browser console to see callback logging for demo.
angular.module('myApp').controller('MyCtrl', function ($q, reservationService) { var vm = this; //Reservation module callbacks reservationService.onBeforeGetAvailableHours = function(selectedDate) { console.log("Before get available hours! Selected date: " + selectedDate); var deferred = $q.defer(); deferred.resolve(); return deferred.promise; } reservationService.onCompletedGetAvailableHours = function(statusLevel, message, selectedDate) { console.log("Completed get available hours! Status level: " + statusLevel + ", message: " + message + ", selected date: " + selectedDate); } reservationService.onSuccessfulGetAvailableHours = function(statusLevel, message, selectedDate, availableHours) { console.log("Successful get available hours! Status level: " + statusLevel + ", message: " + message + ", selected date: " + selectedDate + ", availableHours: " + availableHours); } reservationService.onErrorGetAvailableHours = function(statusLevel, message, selectedDate) { console.log("Error get available hours! Status level: " + statusLevel + ", message: " + message + ", selected date: " + selectedDate); } reservationService.onBeforeReserve = function(selectedDate, selectedHour, userData) { console.log("Before reserve! Selected date: " + selectedDate + ", selected hour: " + selectedHour + ", userData: " + JSON.stringify(userData)); var deferred = $q.defer(); deferred.resolve(); return deferred.promise; } reservationService.onCompletedReserve = function(statusLevel, message, selectedDate, selectedHour, userData) { console.log("Completed reserve! Status level: " + statusLevel + ", message: " + message + ", selected date: " + selectedDate + ", selectedHour: " + selectedHour + ", userData: " + JSON.stringify(userData)); } reservationService.onSuccessfulReserve = function(statusLevel, message, reservedDate, reservedHour, userData) { console.log("Success reserve! Status level: " + statusLevel + ", message: " + message + ", reserved date: " + reservedDate + ", reserved hour: " + reservedHour + ", userData: " + JSON.stringify(userData)); } reservationService.onErrorReserve = function(statusLevel, message, selectedDate, selectedHour, userData) { console.log("Error reserve! Status level: " + statusLevel + ", message: " + message + ", selected date: " + selectedDate + ", selected hour: " + selectedHour + ", userData: " + JSON.stringify(userData)); } });