Skip to main content

Working with HTML5 Date and Number Inputs in Angularjs with MySQL and PHP


Angularjs provide an directive for the Date and Number input elements. We may be in a problem while handling the form having these as input from the user. There is always a type miss match between the value provided or accepted by these input and and the value accepted by the MySQL database.

In Angular, we send and receive data in a JSON format to prevent the page reload. JSON are provided into a string form, we need to process the JSON string at client side. Date , Integer and Float values are provided into string format so, we need to process the these values.

To show how to tackle this type mismatch, I have created an simple app that take one text, one float, one integer and one date value from the user and send it to server for storing into the database and return the inserted data item back to the user into JSON format.

Before going into the app, it should be noted that.
  • HTML5 date input takes and provide Date object
  • HTML5 number input takes number value (i.e. like 20, 22.2 | not like '20', '22.2') and provide number value
I have used twitter bootstrap for awesome look of the app. Here is first look of the app:

On clicking the "Place Order" button the form data will be send to server for storing and the stored data is returned as response. Let's see the HTML code for the our app:

HTML code (index.php):
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <title>Place an Order</title>
   <link rel="stylesheet" href="../css/bootstrap.min.css">
 </head>
<body ng-app="myApp" ng-controller="myAppCtrl">
  <div class="container-fluid">
   <div class="row">
    <div class="col-sm-4 col-sm-push-4">
     <h2 class="text-center text-primary">ORDER ITEM</h2>
     <form name="orderForm" novalidate>
      <div class="form-group">
       <label for="name">Item Name:</label>
       <input ng-model="item.name" type="text" id="name" name="name" class="form-control" placeholder="Item Name" required>
      </div>
      <div class="form-group">
       <label for="cost">Cost Per Unit:</label>
       <input ng-model="item.cost" type="number" class="form-control" id="cost" name="cost" placeholder="cost" required>
      </div>
      <div class="form-group">
       <label for="cost">Quantity:</label>
       <input ng-model="item.quantity" type="number" class="form-control" id="quantity" name="quantity" placeholder="quantity" required>
      </div>
      <div class="form-group">
       <label for="order_date">Order Date:</label>
       <input ng-model="item.order_date" type="date" id="order_date" name="order_date" class="form-control" placeholder="Order Date" required>
      </div>
      <input type="submit" ng-click="placeOrder()" ng-disabled="orderForm.$invalid" class="btn btn-primary" value="Place Order"></input>
   </form>
  </div> 
 </div>
 <div class="row"><hr>
   <div class="col-sm-4">
    <h4>Order Details</h4>
    <pre>{{item | json}}</pre>
   </div>
   <div class="col-sm-4">
    <h4>Raw response from server <button class="btn btn-xs btn-danger" ng-click="edit(rawResponse)">Edit 1</button></h4>
    <pre>{{rawResponse | json}}</pre>
   </div>
   <div class="col-sm-4">
    <h4>Processed response <button class="btn btn-xs btn-info" ng-click="edit(processedResponse)">Edit 2</button></h4>
    <pre>{{processedResponse | json}}</pre>
   </div>
  </div>
 </div>
 <script src="../js/angular.min.js"></script>
 <script src="script.js"></script>
</body>
</html>

Here, I have coded four input for Item name, Cost, Quantity and Order date. As the name suggest, the Cost and Quantity input are number input and Order date input is date input. Some angular directive like ng-app, ng-controller, ng-model and ng-click are used. We will not go into them. Let us see the JavaScript code for our app:

JavaScript code (script.js):

var app = angular.module('myApp',[]);

app.controller('myAppCtrl', function($scope, $http, dateFilter, $httpParamSerializerJQLike){
  $scope.item = {};
  $scope.processedResponse = {};//used for processed raw response
  $scope.rawResponse = {}; // raw response from server into json

  $scope.placeOrder = function(){
    var item = angular.copy($scope.item);
    item.order_date = dateFilter(item.order_date, 'yyyy-MM-dd');
    $http({
      method : 'POST',
      url : 'process.php',
      data : $httpParamSerializerJQLike(item),
      headers : {'Content-Type':'application/x-www-form-urlencoded'}
    })
      .then(
        function(response){
          var data = response.data;
          $scope.rawResponse = angular.copy(data);
          data.order_date = new Date(data.order_date);
          data.cost = parseFloat(data.cost);
          data.quantity = parseInt(data.quantity);
          $scope.processedResponse = data;
          $scope.item = {};
      });
  };

  $scope.edit = function(item){
    $scope.item = item;
  };

});
Here we have used 3 $scope variables:
  • item : To hold the form data
  • rawResponse : Used to hold the response data from the server. This object contains the missmatched data from the user form. We will see how it create problem below.
  • processedResponse : Used to hold the processed response data. This object contains the matched datatype as in user form.
As we can see in $scope.placeOrder function, we are copying the $scope.item to 'item' variable to process the item.order_date (till now it is Date object having '2017-09-30T18:30:00.000Z' format) to match the datatype accepted by the MySQL (as mysql accept dates into 'yyyy-mm-dd' format). We used dateFilter to convert order_date to make it accepted my MySQL Database. Number input have no mismatch. Now the http request is sent to server one clicking the 'Post Order' button. Let's see the PHP code:

PHP code (process.php):
<?php
/*
$_POST array have following structure of data at this point
Array{
 "cost": "30.5",
 "order_date": "2017-10-20",
 "name": "Ice Cream",
 "quantity": "25"
}
*/

//Write your MySQL specific codes here

echo json_encode($_POST);
?>
The above code simply response the POSTed data into JSON format to the user. In the $http success function, we copied the JSON raw response from the server into $scope.rawResponse variable. And then process the dates and number to make it acceptable by the user.

$scope.rawResponse:

{
  "cost": "30.5",
  "name": "Ice Cream",
  "order_date": "2017-10-20",
  "quantity": "25"
}


We have-
  • converted the date string into Date object
  • converted the integer string into Integer value
  • converted the float string into Float value
After conversion, we have assign converted value into $scope.processedResponse variable.

$scope.processedResponse:

{
  "cost": 30.5,
  "name": "Ice Cream",
  "order_date": "2017-10-20T00:00:00.000Z", //a Date() object
  "quantity": 25
}
Let's look into our app. This will look like as below before 'Post Order' button clicked:

When the 'Post Order' Button is click;

When the Edit 1 button is clicked. It assign $scope.rawResponse value to form inputs variable $scope.item. It cause an error as shown below because it has mismatch datatypes:

When the Edit 2 button is clicked. It doesn't show any error as it is assigned after processing:

Comments

Post a Comment

Popular posts from this blog

Automatic Slashing the Date Input using Angularjs

We define a directive that will automatically slash the input field as user typein the date. The directive have following capabiltiy: The directive will append slash '/' when input field has 2 or 5 characters. The input will accept only 10 characters (dd/mm/yyyy). Validity of date provide will not be checked. When the backspace is pressed it will remove the last two character if last character is slash. Otherwise it will remove last character from the input field. The input will not accept characters other than numbers (0 to 9). Let's jump into the code. We will use bootstrap for awesome look: HTML Code: <div class="container" ng-app="myApp" ng-controller="myAppCtrl"> <div class="row"> <div class="col-sm-8 col-sm-offset-2"> <form class="form-horizontal"> <h4 class="bg-primary">Auto Slashing Date using Angularjs Directive</h4> <div class=...

Code Syntax Highlighting on Blogger using Prismjs

Prismjs is developed by Lea Verou. It is a lightweight, extensible syntax highlighter, built with modern web standards in mind. It’s used in thousands of websites, including some of those you visit daily.Today, we will see how to use the prismjs on blogger to highlight our codes. It very easy and step by step process to follow: Goto to this link and get the personalized links for prismjs or simply copy the links given below: <link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.6.0/themes/prism-coy.min.css" rel="stylesheet"></link> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.0/prism.min.js"></script> Goto Theme > Edit HTML and paste the links before the closing </head> section as shown below: Default prism.min.js file contain the functionality to highlight the code for only HTML, CSS and JS code. If you wish to use other language to highlight, you have to paste the link for that langu...

Conversion between Date String and Timestamp using Angularjs Directive

Let me ask you one question. Can a veiwValue and modelValue have same value into a different format? The answer is YES . Here we will see how it can be possible. We will see it through a simple example that converts date string (viewValue) into timestamp (modelValue). We will use a text box to enter a date string (dd/mm/yyyy) and convert it into timestamp that will be stored into model value. The trick is that we will use $parsers to convert the date string into the timestamp and $formatters to change the timestamp stored in modelValue to date string that will be shown on text input. Let's see the codes first: HTML Code: <h4>Date to Timestamp</h4> <div class="form-group"> <label for="date1" class="col-sm-3 control-label">Date1 VeiwValue:</label> <div class="col-sm-3"> <input type="text" id="date1" class="form-control" name="date1" ng-model="ob...