Monday, September 11, 2017

How to Validate and Submit Form Using VueJs and PHP?

Client-side validation using JavaScript enhances user experience by giving feedback immediately to the user rather than having them complete a round-trip through the server. Before we begin, you must understand that this type of data input validation is no substitute for server-side validation. Without server-side validation, you are trusting the user and whatever tools they are using to make sure input is valid. Client-side validation with Vue.js (or any other JavaScript library/framework) should be used in addition to, not instead of it.

I'll also mention that many modern browsers have client-side validation built-in by using HTML attributes such as (but not limited to) required and maxlength="10". However, not all browsers support this and all of them behave differently. Let’s look at how to build our own form validation using Vue.js so it behaves the same in all modern browsers.

Scenario
We want to build a form with 4 inputs:
• Name
• Number between 1 and 10
• Email
• Message

All inputs are required. The number input should only allow numbers between 1 and 10 & email input should have a valid format.

Setup
Start with a basic HTML file with the Bootstrap 3 stylesheet and Vue.js.
<!DOCTYPE html>
<html>
 <head>
    <meta charset="utf-8">
    <title>Form Validation</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"/>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha256-eZrrJcwDc/3uDhsdt61sL2oOBY362qM3lon1gyExkL0=" crossorigin="anonymous" />
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
</body>
</html>
Our form will go in the content area. Just to get a prettier layout, we’ll put it inside a single col, inside a single row, inside a single container. Each of these elements have classes that position them nicely.
<!div class="container">
  <!div class="row justify-content-center">
    <!div class="col-md-6">
      <!form>
       <!!-- form elements go here -->
      <!/form>
    <!/div><!!-- /col -->
  <!/div><!!-- /row -->
<!/div><!!-- /container -->
Now, our 4 input elements and submit button will go inside the form. Bootstrap provides validation classes. Let’s add those as well.
  <div class="form-group">
      <label class="control-label" for="name">Name </label>
      <input id="name" name="name" class="form-control" type="text" v-model="name">
      <span id="helpBlock" class="help-block">This field is required. </span>
    </div>
    
    <div class="form-group">
      <label class="control-label" for="number">Enter a number between 1 and 10 </label>
      <input id="number" name="number" class="form-control" type="text" v-model="number">
      <span id="helpBlock" class="help-block">Make sure this is a number between 1 and 10. </span>
    </div>

    <div class="form-group">
      <label class="control-label" for="name"Email</label>
      <input id="email" name="email" class="form-control" type="text" v-model="email">
      <span id="helpBlock" class="help-block">Email is invalid. </span>
    </div>

    <div class="form-group">
      <label class="control-label" for="message">Enter a Message </label>
      <textarea  name="message" class="form-control" type="text" v-model="message"> </textarea>
      <span id="helpBlock" class="help-block">This field is required. </span>
    </div>                 
    
    <button class="btn btn-primary">Submit </button>

Right now, the feedback elements will always be displayed. Later, we'll make sure they’re only shown if validation fails.

Building the Vue App
With the HTML in place, now we'll jump into main.js and start coding the logic for our form.
var form = new Vue({
  el: '#form',
  data: {
    name: '',
    email: '',
    message: '',
    number: '',
    attemptSubmit: false,
    postStatus: false
  },
  computed: {
    missingName: function () {},
    wrongNumber: function () {},
    missingEmail: function () {},
    missingMessage: function () {}
  },
  methods: {
    isNumeric: function () {},
    isEmail: function () {},
    validateForm: function () {},
    onSubmit () {}
  },
});


In our data object, there are 6 variables:
1. name — Will hold the value of the name input
2. email — Will hold the value of the email input
3. message — Will hold the value of the message input
4. number — Will hold the value of the number input
5. attemptSubmit — A boolean that indicates whether the user has attempted to submit the form. We can use this to hide validation warnings until after the user has tried to submit the form.
6. postStatus - A boolean that indicates whether the form has been submitted. We can use this to hide the form after the submission.

There are also a 4 computed variables here:
1. missingName — Will return true if name is empty
2. wrongNumber — Will return true if number is not between 1 and 10
3. missingEmail — Will return true if email is empty or invalid
4. missingMessage — Will return true if message is empty

Finally, there are a 4 methods:
1. isNumeric — A utility function that checks to see if an input is a number
2. isEmail — A utility function that checks to see if an input has valid email
3. validateForm — The main function that will be called when trying to submit
4. onSubmit - If the validation is passed, that will be called

I mentioned above that there are 4 variables that hold the value of the inputs. We can wire those up with Vue models. Back in the HTML…
  <input id="name" name="name" class="form-control" type="text" v-model="name">
  <input id="number" name="number" class="form-control" type="text" v-model="number">
  <input id="email" name="email" class="form-control" type="text" v-model="email">
  <textarea  name="message" class="form-control" type="text" v-model="message"></textarea>
With our models wired up, we can use the computed variables to determine the status of each input. missingName and missingMessage are easy. Return true if value is empty:
  missingName: function () { return this.name === ''; },
  missingMessage: function () { return this.message === ''; },
wrongNumber is a little more complex, but not bad at all. Return true if the value is not a number or it’s less than 1 or it’s greater than 10. missingEmail return true if the value has not a valid format or null.
 wrongNumber: function () {
  return (
    this.isNumeric(this.number) === false ||
    this.number < 1 ||
    this.number > 10
  )
},

missingEmail: function () {
   return (
     this.isEmail(this.email) === null)
},
Oops, we’re calling isNumeric() and isEmail() but we haven’t coded it, yet. Here’s what it looks like:
isNumeric: function (n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
},
isEmail: ( str ) => {      
   let regexp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/     
   return str.match(regexp);
}
We're actually done with the JavaScript except for the actual validateForm() and onSubmit function. For that one, we just want to tell our app the user attempted to submit the form and prevent it from submitting if missingName, missingEmail, missingMessage or wrongNumber are true. If all the values are validated, we call onSubmit method.
validateForm: function (event) {
   this.attemptSubmit = true;
   if (this.missingName || this.wrongNumber || this.missingMessage || this.missingEmail) {
       event.preventDefault();
   } else {
       this.onSubmit();
   }       
Done with JavaScript. Back in the HTML, we need to fire the validateForm() function when the form is submitted.

  <form id="form" method="post" v-on:submit.prevent="validateForm">


Then, add the (Bootstrap) has-warning class for each input. We only want to add this class if BOTH:
1. The user has attempted to submit the form, and 2. The value is not valid
<div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingName }">
...
<div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && wrongNumber }">
...
<div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingEmail }">
...
<div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingMessage }">

Finally, we only want the feedback elements to appear under those same circumstances:
 <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingName">This field is required.</span>
.....
 <span id="helpBlock" class="help-block" v-if="attemptSubmit && wrongNumber">Make sure this is a number between 1 and 10.</span>
......
 <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingEmail">Email is invalid.</span>
......
 <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingMessage">This field is required.</span>
That’s it! On load, the form looks like…
If you try to submit with an empty fields, a warning appears.
The nice part is that, the way we’ve coded it, when the user corrects their mistake, the warning goes away immediately.

Form Submission
After the validation is successful, we will submit using PHP. In order to submit the POST values we are going to use. Axios. Axios is a promise-based HTTP client that works both in the browser and in a node.js environment. It basically provides a single API for dealing with XMLHttpRequests and node’s http interface.

Before using axios, you first need to install it. Adding Axios to your project is easy. There are two options:
1. Install Axios with Node Package Manager as follows:
  $ npm install axios
2. The easiest way is to include Axios by using a Content Delivery Network, e.g. by including the following <script> tag in your index.html file:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Simply import axios or require it as you do with any other dependency in node as below (if you are using nodeJs and webpack only):

import axios from 'axios';

or

var axios = require('axios');

A frequently overlooked but very useful capability Axios provides is the ability to create a base instance that allows you to share a common base URL and configuration across all calls to the instance.

onSubmit () {
    
     if (process.env.NODE_ENV === 'development') {
            axios.defaults.baseURL = 'http://localhost:8888/your-project-name/php'
      }

      axios.post('post.php', {
                'name': this.name,
                'email': this.email,
                'message': this.message,
                'number': this.number               
        }).then(response => {
            if (response.data.error) {
                    console.log('error', response.data.error)
           } else {
                this.postStatus = true
                console.log('success', response.data.message)                   
           }
        }).catch(error => {
              console.log(error.response)
     }); 
}

Create a folder 'php' and create a file 'post.php' under it.
/* php/post.php */

<?php
header('Content-type: application/json');
header('Access-Control-Allow-Headers: Content-Type');
header("Access-Control-Allow-Origin: *");

$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);

$name = $input['name'];
$email = $input['email'];
$message = $input['message'];
$number = $input['number'];


$result['message'] = '';
$result['error']  = false;

if($name){
  $result['message']  = "Posted Values => ".$name."-".$email."-".$message."-".$number;
  $result['error']  = false;
}
else {
  $result['error']  = 'Form submission failed.';
}


echo json_encode($result);

file_get_contents(php://input) - gets the raw POST data and this is useful if the POSTed data is a JSON encoded structure, which is often the case for an AJAX POST request. The PHP superglobal $_POST, only is supposed to wrap data that is either
1. application/x-www-form-urlencoded (standard content type for simple form-posts) or
2. multipart/form-data-encoded (mostly used for file uploads)

This is because these are the only content types that must be supported by user agents. So the server and PHP traditionally don't expect to receive any other content type (which doesn't mean they couldn't). But if you are working with Ajax a lot, this probably also includes exchanging more complex data with types (string, int, bool) and structures (arrays, objects), so in most cases JSON is the best choice. The content would now be 'application/json' (or at least none of the above mentioned), so PHP's $_POST-wrapper doesn't know how to handle that (yet). The data is still there, you just can't access it through the wrapper. So you need to fetch it yourself in raw format with file_get_contents('php://input') (as long as it's not multipart/form-data-encoded).

After the form is submitted, you will see confirmation message as below.
I have created a component called 'Form.Vue' with above pieces. Here is the complete source code.

//Form.Vue

<template>  
    <div id="app" class="container">
      <div class="row justify-content-center">
        <div class="col-md-6" v-if="!postStatus">
          <form id="form" method="post" v-on:submit.prevent="validateForm">
            <div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingName }">
              <label class="control-label" for="name">Name</label>
              <input id="name" name="name" class="form-control" type="text" v-model="name">
              <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingName">This field is required.</span>
            </div>
            
            <div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && wrongNumber }">
              <label class="control-label" for="number">Enter a number between 1 and 10</label>
              <input id="number" name="number" class="form-control" type="text" v-model="number">
              <span id="helpBlock" class="help-block" v-if="attemptSubmit && wrongNumber">Make sure this is a number between 1 and 10.</span>
            </div>

             <div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingEmail }">
              <label class="control-label" for="name">Email</label>
              <input id="email" name="email" class="form-control" type="text" v-model="email">
              <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingEmail">Email is invalid.</span>
            </div>

             <div class="form-group" v-bind:class="{ 'has-warning': attemptSubmit && missingMessage }">
              <label class="control-label" for="message">Enter a Message</label>
              <textarea  name="message" class="form-control" type="text" v-model="message"></textarea>
              <span id="helpBlock" class="help-block" v-if="attemptSubmit && missingMessage">This field is required.</span>
            </div>                 
            
            <button class="btn btn-primary">Submit</button>
          </form>
        </div><!-- /col -->

         <div class="col-md-8" v-if="postStatus">

           <h1>The form is submitted successfully.</h1>

         </div> 
      </div><!-- /row -->

    </div><!-- /container -->
</template>

<script>

import axios from 'axios'
  
  export default {   
    data () {
      return {
        name: '',
        email: '',
        message: '',
        number: '',
        attemptSubmit: false,
        postStatus: false
      }
    },
    computed: {
        missingName: function () { return this.name === '' },
        missingMessage: function () { return this.message === '' },
        missingEmail: function () {
          return (
            this.isEmail(this.email) === null)
        },
        wrongNumber: function () {
          return (
            this.isNumeric(this.number) === false ||
            this.number < 1 ||
            this.number > 10
          )
      },
  },
  methods: {
     isNumeric: function (n) {
      return !isNaN(parseFloat(n)) && isFinite(n);
    },
    isEmail: ( str ) => {      
      let regexp = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/     
      return str.match(regexp);
    },       
    validateForm: function (event) {
      this.attemptSubmit = true;
      if (this.missingName || this.wrongNumber || this.missingMessage || this.missingEmail) {
          event.preventDefault();
      } else {
         this.onSubmit();
      }       
    },
    onSubmit () {
    
       if (process.env.NODE_ENV === 'development') {
                axios.defaults.baseURL = 'http://localhost:8888/your-project-name/php'
        }

       axios.post('post.php', {
                'name': this.name,
                'email': this.email,
                'message': this.message,
                'number': this.number               
            }).then(response => {
                if (response.data.error) {
                    console.log('error', response.data.error)
                } else {
                    this.postStatus = true
                    console.log('success', response.data.message)                   
                }
            }).catch(error => {
                console.log(error.response)
            }); 
      }
  }   
}
</script>

Source: Form Validation with Vue.js

Wednesday, August 16, 2017

How to Dockerize a Node.js app?

The goal of this example is to show you how to get a Node.js application into a Docker container. In this article we'll show you how to create a Docker image for an application written in Node.js.

Why should I dockerize my application
You might've heard about the whole Docker thing, but that still doesn't answer the question: "why bother?" Well, that's why:

1. You can launch a fully capable development environment on any computer supporting Docker; you don't have to install libraries, dependencies, download packages, mess with config files etc.
2. The working environment of the application remains consistent across the whole workflow. This means the app runs exactly the same for developer, tester, and client, be it on development, staging or production server.

In short, Docker is the counter-measure for the age-old response in the software development: "Strange, it works for me!"

Part 1: Create the Node.js app
In the first part of this guide we will create a simple web application in Node.js, then we will build a Docker image for that application, and lastly we will run the image as a container.

Install Node.js
If you've never worked with Node.js before, kick off with installing the npm manager: nodejs.org/en/download/package-manager

Install NPM and Express Framework
First, create a new directory 'helloworld' where all the files would live and initialize npm.
 $ mkdir helloworld 
 $ cd helloworld
 $ npm init
When asked for the details of the application (name, version, etc.), just confirm the default values with enter.

Npm will create a package.json that will hold the dependencies of the app. Let's add the Express Framework as the first dependency:
 $ npm install express --save
The file should look like this now:
{
  "name": "helloworld",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.15.2"
  }
}
With everything installed, we can create a server.js file that defines a web app using the Express.js framework with a simple HTTP server that will serve our Hello World website:
//Load express module with `require` directive
var express = require('express')
var app = express()

//Define request response in root URL (/)
app.get('/', function (req, res) {
  res.send('Hello World!')
})

//Launch listening server on port 8081
app.listen(8081, function () {
  console.log('app listening on port 8081!')
})
Run the app
The application is ready to launch:
  $ node server.js
Go to http://localhost:8081/ in your browser to view it.

Part 2: Dockerizing Node.js application
Every application requires a specific working environment: pre-installed applications, dependencies, data bases, everything in specific version. Docker containers allow you to create such environments. Contrary to VM, however, the container doesn't hold the whole operating system—just applications, dependencies, and configuration. This makes Docker containers much lighter and faster than regular VM's.

In this part of the article, we'll look at how you can run this app inside a Docker container using the official Docker image.

Install Docker
Docker allows you to package an application with all of its dependencies into a standardized unit, called a container, for software development. A container is a stripped-to-basics version of a Linux operating system. An image is software you load into a container.

Begin with installing Docker for your type of OS: Docker installation

Write Dockerfile
The Docker image is created with instructions written in the Dockerfile. Let's add Dockerfile to the directory with our application. Create an empty file called Dockerfile:
 touch Dockerfile
Open the Dockerfile in your favorite text editor. The first thing we need to do is define from what image we want to build from.
Line 1: Use another Docker image for the template of my image. We shall use the official Node.js image with Node v8.
 FROM node:8.3.0
Line 2: Set working dir in the container to /app. We shall use this directory to store files, run npm, and launch our application:
 # Create app directory
 WORKDIR /app
Line 3-5: Copy application to /app directory and install dependencies. If you add the package.json first and run npm install later, Docker won't have to install the dependencies again if you change the package.json file. Please note that if you are using npm version 5 or later you will also want to copy package-lock.json, which is generated once you run npm install. This results from the way the Docker image is being built (layers and cache), and this is what we should do:
 # Install app dependencies
 COPY package.json /app

 # For npm@5 or later, copy package-lock.json as well
 # COPY package.json package-lock.json /app

 RUN npm install
Note that, rather than copying the entire working directory, we are only copying the package.json file. This allows us to take advantage of cached Docker layers.
To bundle your app's source code inside the Docker image, use the COPY instruction:
 # Bundle app source
 COPY . /app
Your app binds to port 8081 so you'll use the EXPOSE instruction to have it mapped by the docker daemon:
 EXPOSE 8081
Last but not least, define the command to run your app using CMD which defines your runtime. This line describes what should be executed when the Docker image is launching. What we want to do is to run our application:
 CMD node server.js
Summing up, the whole Dockerfile should look like this:
 FROM node:8.3.0

 # Create app directory
 WORKDIR /app

 # Install app dependencies
 COPY package.json /app

 # For npm@5 or later, copy package-lock.json as well
 # COPY package.json package-lock.json /app

 RUN npm install

 # Bundle app source
 COPY . /app

 EXPOSE 8081
 CMD node server.js

.dockerignore file
Create a .dockerignore file in the same directory as your Dockerfile with following content:
 node_modules
 npm-debug.log
This will prevent your local modules and debug logs from being copied onto your Docker image and possibly overwriting modules installed within your image.

Build Docker image
Go to the directory that has your Dockerfile and run the following command to build the Docker image. The -t flag lets you tag your image so it's easier to find later using the docker images command:
 $ docker build -t hello-world .
Run the image
The application has been baked into the image. Dinner time! Execute the following string to launch the container and publish it on the host with the same port 8081:
 $ docker run -p 8081:8081 hello-world
Running your image with -p flag redirects a public port to a private port inside the container.

Print the output of your app
# Get container ID
$ docker ps

# Print app output
$ docker logs 

# Example
  app listening on port 8081!

We hope this tutorial helped you get up and running a simple Node.js application on Docker.

Sources:
Dockerizing a Node.js web app
How to Dockerize a Node.js application

Thursday, July 6, 2017

How To Use jQuery Into Vue.js Using Webpack?

For global access to jQuery there exists several methods. In my most recent vue.js and webpack project, I wanted global access to jQuery so I added using the following method.

Suppose you have Vue.js project created with vue-cli and node. (e.g. vue init webpack my-project ).
Go to project dir and run
  npm install jquery --save-dev
Open file build/webpack.base.conf.js and add plugins :
var webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jquery: 'jquery',
      'window.jQuery': 'jquery',
      jQuery: 'jquery'
    })
  ],
  ....
Go to project dir and run
   npm run dev
This then means that jquery is accessible from within the JavaScript source code via global references $, jquery and jQuery. Now you are ready to go.

Friday, June 16, 2017

How To Calculate The Percentage Of A Number Using PHP?

This is a short guide on how to calculate the percentage of a given number in PHP. For example: What is 25% of 100? Or what is 10% of 728?

In this code snippet, I have put each calculation on its own separate line, just to make the math a little clearer:
<?php
 
//My number is 928.
$myNumber = 928;
 
//I want to get 25% of 928.
$percentToGet = 25;
 
//Convert our percentage value into a decimal.
$percentInDecimal = $percentToGet / 100;
 
//Get the result.
$percent = $percentInDecimal * $myNumber;
 
//Print it out - Result is 232.
echo $percent;
A quick summary of what we did:
1. We used the number 928 for example purposes.
2. We specified that we wanted to get 25% of 928.
3. We converted our percentage value into a decimal number by dividing it by 100. This turns 25 into 0.25.
4. We then multiplied 0.25 by 928.
5. The end result is 232, which means that 25% of 928 is 232.

Function
If you're looking for a simple PHP function to use in your projects, then you can use the following:
/**
 * A simple PHP function that calculates the percentage of a given number.
 * 
 * @param int $number The number you want a percentage of.
 * @param int $percent The percentage that you want to calculate.
 * @return int The final result.
 */
function getPercentOfNumber($number, $percent){
    return ($percent / 100) * $number;
}

echo getPercentOfNumber(928, 25); 

//output 232

Source: PHP: Calculate The Percentage Of A Number.