Upload file along with other input fields – Node JS

So we are going to teach you how you can upload the file from HTML form along with other input fields in Node JS. We will be using NPM’s formidable, fs (file system) and EJS modules. We will create an input type file to select a file from computer and input type text, the file will be store in server with the name I enter in text box.

Let’s get started

Open command prompt in your project’s root folder and run the following command to install necessary modules:

npm install express http formidable fs ejs
  • Express and HTTP will be used to start the server
  • formidable will be used to handle the input file
  • fs (file system) will be used to save the file
  • EJS will be used to render the HTML page

Now create a file named index.js and paste the following code in it:

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var formidable = require("formidable");
var fs = require("fs");

app.set("view engine", "ejs");

http.listen(4000, function () {
	app.get("/", function (request, result) {
		result.render("index");
	});
});

It will start the server at port number 4000 and creates a default route which when access will render the index.ejs page. We will create that file in a moment. We are setting the default template engine to EJS, don’t worry if you are using any other engine, the core login will remain the same.

Start the server

To start the server, simply run the following command in your command prompt which should be opened in your project’s root folder:

npm install -g nodemon
nodemon index.js

Now you can access your server by running the following URL in your browser:
http://localhost:4000/

Display input type file

Now create a folder in your project named “views”. Your all HTML files should be placed inside this folder and all files must end with an extension .ejs. Create a file named index.ejs inside this views folder. The name of the file must be the same as in render function above, along with .ejs extension at the end. Paste the following code in that file. It will create a form with an input field to select a file and an input field to enter text. We will save the uploaded file with the name entered in text box.

<form method="POST" action="/upload" enctype="multipart/form-data">
	<input type="file" name="file">
	<input type="text" name="fileName" placeholder="File name">

	<input type="submit">
</form>

Save file on server

Make sure the method is POST and encoding type must be attached, otherwise, the file will not be sent. Action attribute will specify the route where data should be sent. So paste the following code in your index.js file right below the “/” route:

app.post("/upload", function (request, result) {
	var formData = new formidable.IncomingForm();
	formData.parse(request, function (error, fields, files) {
		var extension = files.file.name.substr(files.file.name.lastIndexOf("."));
		var newPath = "uploads/" + fields.fileName + extension;
		fs.rename(files.file.path, newPath, function (errorRename) {
			result.send("File saved = " + newPath);
		});
	});
});

Now you just need to create a folder named “uploads” and when you select the file. Enter the name, the file will be saved with the name you enter in the text field. That’s how you can upload a file on Node JS server.

[wpdm_package id=’245′]

PHP – Subscribe to Newsletter and send Bulk Emails using PHPMailer

A newsletter is a printed or electronic report containing news concerning the activities of a business or an organization that is sent to its members, customers, employees or subscribers. Newsletters generally contain one main topic of interest to its recipients. In this article, we will discuss you how can send bulk emails using the PHP Mailer library.

Newsletter

Newsletters in websites are used in the form of E-mails and they are the most common type of emails in email marketing. They often contain news and updates, aiming to keep the audience engaged. At the same time, they are also designed to gently push users towards the conversion.

We are going to create a form that will help users to subscribe to the newsletter on your website and you will be able to send bulk emails to all those users. You can send promotional emails to promote your product or you can mail to them whenever you have a new post or news regarding your business, organization or website.

<form onsubmit="return doSubscribe();">
	<input type="email" id="subscriberEmail" placeholder="Subscribe to newsletter" required>

	<input type="submit" value="Subscribe">
	<p id="subscribe-message"></p>
</form>

This will create a form with an input field to type email and a submit button which when clicked will submit the form. We are preventing the default behavior of form submission by attaching an event listener called “onsubmit”. This function will be called when the user hits the submit button. We need to prevent the form from submitting and call our AJAX function to save this email in the MySQL database using PHP. At the end we have a paragraph, it will be used to display a message when the email has successfully been stored in the database.

Send an ajax request

<script type="text/javascript">
	function doSubscribe() {
		var subscriberEmail = document.getElementById("subscriberEmail").value;
		
		var ajax = new XMLHttpRequest();
		ajax.open("POST", "subscribe-newsletter.php", true);
		ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		
		ajax.onreadystatechange = function () {
			if (this.readyState == 4 && this.status == 200) {
				document.getElementById("subscribe-message").innerHTML = "You have been subscribed to our newsletter.";
			}
		};

		ajax.send("subscriberEmail=" + subscriberEmail);
		return false;
	}
</script>

Here first we have created a Javascript function and we are returning false from it, this will prevent the form from submitting. We are getting the input field value for email using the input field’s unique ID. Then we have created an AJAX object that can be used to send an asynchronous AJAX request. Next, we are calling open function and setting method to “POST”, the second parameter is the name of the file where data needs to be sent and the third parameter is whether the request is asynchronous.

Asynchronous

All modern browsers support asynchronous, so we are setting this to true. As the request is POST, so we also have to attach headers to this request. For application/x-www-form-urlencoded, the body of the HTTP message sent to the server is essentially one giant query string — name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=).

Before actually sending the request, we are attaching an event listener which will be called when a response is successfully been received from the server. The request is successful if the readyState is 4 and status has a value of 200. When the request is completed, we are simply displaying a message in the paragraph so the user can know that his email has been added in the subscriber’s list.

Save email in MySQL using PHP

Next, we need to create a PHP file that will store this email in MySQL database. First, create a table in your MySQL database and name it “subscribers”. It will have 1 column as auto-increment primary key whose value be unique for each subscriber and its data type should be an integer. It will also have another column for email whose value will be subscriber’s email and its data type should be text.

Save data in MySQL database

Create a new file named “subscribe-newsletter.php” and paste the following code in it. Make sure to change the database credentials as per your database.

<?php

	$conn = mysqli_connect("localhost:8889", "root", "root", "tutorials");
	$subscriberEmail = $_POST["subscriberEmail"];

	mysqli_query($conn, "INSERT INTO subscribers (email) VALUES ('$subscriberEmail')");

?>

Send bulk emails using PHP Mailer

Many PHP developers need to send email from their code. The only PHP function that supports this is mail(). However, it does not provide any assistance for making use of popular features such as encryption, authentication, HTML messages, and attachments.

The PHP mail() function usually sends via a local mail server, typically fronted by a Sendmail binary on Linux, BSD, and macOS platforms, however, Windows usually doesn’t include a local mail server; PHPMailer’s integrated SMTP implementation allows email sending on Windows platforms without a local mail server.

Install PHPMailer

Open command prompt (Windows) or Terminal (Mac OS) in your project’s root folder and run the following command:

composer require phpmailer/phpmailer

It will install the PHPMailer library in your project. You will see a folder named “vendor” will be created at the root folder of your project. Open the file from where you want to send emails to all your subscribers. And paste the following code in it:

<?php

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$conn = mysqli_connect("localhost:8889", "root", "root", "tutorials");

$result = mysqli_query($conn, "SELECT * FROM subscribers");
while ($row = mysqli_fetch_object($result))
{
	$mail = new PHPMailer(true);

	try {
	    $mail->SMTPDebug = 0;
	    $mail->isSMTP();
	    $mail->Host       = 'smtp.gmail.com';
	    $mail->SMTPAuth   = true;
	    $mail->Username   = 'adnan@gmail.com';
	    $mail->Password   = '';
	    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
	    $mail->Port       = 587;

	    $mail->setFrom('adnan@gmail.com', 'Adnan');
	    $mail->addAddress($row->email);     // Add a recipient
	    $mail->addReplyTo('adnan@gmail.com', 'Adnan');

	    // Content
	    $mail->isHTML(true);
	    $mail->Subject = 'Here is the subject';
	    $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
	    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

	    $mail->send();
	    echo '<p>Message has been sent to ' . $row->email . '</p>';
	} catch (Exception $e) {
	    echo "<p>Message could not be sent. Mailer Error: {$mail->ErrorInfo}</p>";
	}
}

Here first we are importing PHPMailer library files. Then we are including our “autoload.php” file, it should be automatically created when the composer command is executed. Then we are connecting with the database and fetching all the subscribers from the table. In each loop iteration, we are creating an object of PHPMailer class. Setting the host as Gmail and username and password as one of our Gmail account’s credentials. You need to enter the correct email and password of one of your Gmail account.

Enable google less secure apps

Make sure to enable “less secure apps” for your corresponding Gmail account. You can do that from this link or by tapping the screenshot below.

Set the port number to “587” it is the default for Gmail. Set your email address from where the email should be sent. And the recipient address which we will be receiving from the database. Then we are setting the subject and body of email, the body of the email can contain HTML content. But you can also specify non-HTML content in “AltBody” if the user switches to simple text format. Or if the user has a slow internet connection. Finally, we send the mail and display a confirmation message that an email has been sent. If there is any error, it will be handled in the catch block. We are also displaying an error message if there is any problem in sending en E-mail.

Apply CSS on form

Although your subscription form design will be different for everyone else as per your website’s existing design. But for the sake of simplicity, we are applying some CSS styles just to make it look a little bit good. First, change your form layout and enclose your input field and submit button inside div tag having class as “container”. We will apply styles based on this class.

<form onsubmit="return doSubscribe();">
	<div class="container">
		<h2>Subscribe to our Newsletter</h2>
		<p>Lorem ipsum..</p>
	</div>

	<div class="container" style="background-color:white">
		<input type="email" id="subscriberEmail" placeholder="Subscribe to newsletter" required>
	</div>

	<div class="container">
		<input type="submit" value="Subscribe">
	</div>

	<p id="subscribe-message"></p>
</form>

Next we are going to use the CSS to apply styles on those divs and classes.

<style type="text/css">
	/* Style the form element with a border around it */
	form {
		border: 4px solid #f1f1f1;
	}

	/* Add some padding and a grey background color to containers */
	.container {
		padding: 20px;
		background-color: #f1f1f1;
	}

	/* Style the input elements and the submit button */
	input[type=text], input[type=email], input[type=submit] {
		width: 100%;
		padding: 12px;
		margin: 8px 0;
		display: inline-block;
		border: 1px solid #ccc;
		box-sizing: border-box;
	}

	/* Add margins to the checkbox */
	input[type=checkbox] {
		margin-top: 16px;
	}

	/* Style the submit button */
	input[type=submit] {
		background-color: #4CAF50;
		color: white;
		border: none;
		cursor: pointer;
	}

	input[type=submit]:hover {
		opacity: 0.8;
	}
</style>

Now you have learned how you can send bulk emails using PHP Mailer library. You can also learn how to send email with attachments in PHP from here.

[wpdm_package id=’243′]

PHP – Add Dynamic Rows in Table Tag

Learn how to add dynamic rows in a table tag in HTML and Javascript. And also save the data in MySQL database using PHP.

Introduction

Suppose you are trying to generate an invoice for your customers. You wanted to have a functionality where you will be able to add multiple items in an invoice. A simple table tag will be created from where the user will be able to add multiple items. You have added a button labeled as “Add Item” which when clicked will create a new row to add an item.

Now it might sound easy but technically you have to create rows dynamically. Whenever a user clicks on the “Add Item” button, a new row inside table tag should be created and it must be an array as items can be multiple. Then these arrays should be stored in the database using a loop iteration. Following this tutorial, you will be able to do so.

We will be creating 2 tables, although to explain this tutorial only 1 table would be enough but teaching with 2 will help to understand better when you are working on existing projects. We will have 1 table for storing invoices basic data, for example, customer name, etc, and the second table for storing items in that invoice.

“invoices” table

Our first table name is “invoices” and it will have just 2 fields, unique auto-increment ID and customer name. And the second table will be named “items” and have the product name, quantity, etc and also a foreign key that reference for invoice ID.

To add dynamic rows, we are using a <table> tag that will create a table layout so we will add rows in <tbody> tag. As discussed earlier, all rows will be in an array that needs to be stored in the database, so we will create a <form> tag that will help to do this. We are setting the method to POST as the data might be sensitive and long, and action attribute as current file name, you can change this if you want to send data to a different page.

Customer field

We are creating a simple input field for customer name that will be stored in the “invoices” table, you can place your other fields here. Then we are creating a <table> tag and inside it, we will be displaying the number of items, item name, and item quantity. Make sure to give <tbody> tag a unique ID so we can append new rows in it using Javascript.

Below them, we are creating a button which when clicked will call a Javascript function from where we can add a new row inside that table. And finally, a submit button which when clicked will submit the form and we have to save that data in database.

<form method="POST" action="index.php">
	<input type="text" name="customerName" placeholder="Enter customer name" required>

	<table>
		<tr>
			<th>#</th>
			<th>Item Name</th>
			<th>Item Quantity</th>
		</tr>
		<tbody id="tbody"></tbody>
	</table>

	<button type="button" onclick="addItem();">Add Item</button>
	<input type="submit" name="addInvoice" value="Add Invoice">
</form>

Add/delete row

Now we need to create a function which when clicked will add a new node in the <tbody> tag. We have created a variable for the number of items and we are incrementing it on each click. Whenever this function called we are creating a <tr> tag and adding input fields for name and quantity in <td> tags. Notice the “[]” with the input name attribute, this tells that this field will be an array. Lastly, we are creating a new row using tbody function called insertRow() and appending the <tr> HTML in it.

<script>
	var items = 0;
	function addItem() {
		items++;

		var html = "<tr>";
			html += "<td>" + items + "</td>";
			html += "<td><input type='text' name='itemName[]'></td>";
			html += "<td><input type='number' name='itemQuantity[]'></td>";
            html += "<td><button type='button' onclick='deleteRow(this);'>Delete</button></td>"
		html += "</tr>";

		var row = document.getElementById("tbody").insertRow();
		row.innerHTML = html;
	}

function deleteRow(button) {
    items--
    button.parentElement.parentElement.remove();
    // first parentElement will be td and second will be tr.
}
</script>

Style the table

Now we are going to apply some styles on our table just to make it look a little bit good.

<style type="text/css">
	table {
		width: 100%;
		border-collapse: collapse;
	}
	table tr td,
	table tr th {
		border: 1px solid black;
		padding: 25px;
	}
</style>

Add record in database

Now we just need to store this data in our database. The following code must be put at the top of your file. Our database name is “tutorials” but it will be different in your case, make sure to change the DB name accordingly. Next, check if the form is submitted, the if block will only run after the user submits the form. Get the customer name and insert that in the “invoices” table, it is rather simple.

Remember we added “invoiceId” as a foreign key in “items” table. So, we have to get the newly inserted AUTO-INCREMENT ID. Then we are looping through all the added items. You can either use the “itemName” input field or “itemQuantity” and insert them in “items” table with same invoice ID.

<?php

	$conn = mysqli_connect("localhost:8889", "root", "root", "tutorials");

	if (isset($_POST["addInvoice"]))
	{
		$customerName = $_POST["customerName"];

		$sql = "INSERT INTO invoices (customerName) VALUES ('$customerName')";
		mysqli_query($conn, $sql);
		$invoiceId = mysqli_insert_id($conn);

		for ($a = 0; $a < count($_POST["itemName"]); $a++)
		{
			$sql = "INSERT INTO items (invoiceId, itemName, itemQuantity) VALUES ('$invoiceId', '" . $_POST["itemName"][$a] . "', '" . $_POST["itemQuantity"][$a] . "')";
			mysqli_query($conn, $sql);
		}

		echo "<p>Invoice has been added.</p>";
	}

?>

That’s it, the job is done. At this point, you will be able to select multiple items. And add dynamic rows in table tag and inserting them in the database as well. Complete source file along with SQL exported file which will help you to understand the structure of database.

[wpdm_package id=’239′]

Custom auto complete view – Vanilla Javascript

Learn how to create a custom auto complete view in vanilla Javascript. Auto complete view is a feature in which an input field predicts the rest of a word a user is typing. In most frequently fields like city names, users can typically enter some words. And wait for seeing the suggestions to accept one of several cities.

Auto complete view speeds up human-computer interactions. It correctly predicts the word a user intends to enter after only a few characters have been typed into a text input field. It works best in domains with a limited number of possible words (such as in command-line interpreters). When some words are much more common (such as when addressing an e-mail), or writing structured and predictable text (as in source code editors).

Google

In search engines like Google, auto complete view provide users with suggested queries or results as they type their query in the search box. This is also commonly called autosuggest or incremental search. This type of search often relies on matching algorithms that forgive entry errors. Such as phonetic Soundex algorithms or the language-independent Levenshtein algorithm. The challenge remains to search large indices or popular query lists in under a few milliseconds. So, that the user sees results pop up while typing.

Nothing gives you more control than writing code by yourself.

Unknown

Auto complete view can have an adverse effect on individuals and businesses when negative search terms are suggested. Autocomplete has now become a part of reputation management as companies linked to negative search terms such as scam, complaints and fraud seek to alter the results. Google in particular have listed some of the aspects that affect how their algorithm works. But this is an area that is open to manipulation.

Example

Suppose you have a list of values that you want to populate in an input field as user types. Give users an ability to select an item from that list and store the data. For example, if you have a list of products, you can display product title. But once any value is selected, you can send the product ID in database. Although there are many libraries on the internet to do this job. But they are limited in customizations and you have to remember their function names and parameters and options etc.

Lets get started

First we are going to create an input field that will have an ability to call a Javascript function as soon as user types something in it. We are attaching the “onkeyup” attribute on that field which will be called for every key pressed by the user. We are also giving this field an ID and name attribute:

  • ID will be use in Javascript to populate suggestions based on this field value.
  • Name will be use in PHP where form data will be sent. You can handle this as per your project.

Form’s method and action attribute depends on your project, you can adjust them as per your needs. We have also created a hidden field which will set the ID of selected product. So we will be displaying product title in suggestions. Also, when user select one product, it’s ID will be put in this hidden field. Lastly, we have a div where all suggested products will be displayed.

<form method="POST" action="send-data.php">
    <input type="text" id="product" name="product" onkeyup="onKeyUp();">
    <input type="hidden" id="productCode" name="productCode">
    <div id="products-list"></div>
</form>

Send HTTP request

First we will create a function for “onkeyup” event that we attached on previous step. In this function, we are getting value from product’s input field. We will get the suggested products only if the input field has at-least 3 words in it. Because sending HTTP request on each word would be very costly and it does not make sense at all. When you search for some product you already know first 4 or 5 characters of it. Even in case of cities, most people know at-least 3-4 characters of what they want to search. Displaying suggestions on each word would be really annoying for users.

Then in div where we wanted to show the suggested products, we will first show a loading message. So that the user knows that it is searching for products and the location where suggested products will be displayed. Then we are sending an AJAX request, the request method is GE. So it does not require any headers in the request.

URL of AJAX request

Second parameter in open function is the name of file, we will create that file in next step. In same parameter, we are sending user entered words in the URL so we can get them in that PHP file. At the end of this function we are sending the request. But before sending, we are attaching an event which will be called when the response is successfully received from server.

From get-products.php file which we will create in next step, we will receive all the suggested products based on value of input field. The response sent from PHP to Javascript will be in JSON string format, so we have to convert (parse) that string to Javascript objects and arrays. Then we will loop through all the suggested products and display them in paragraph. A separate variable is created which will store all the HTML content of the autocomplete view. Finally, we are setting this HTML variable value to div using its unique ID.

<script>
    function onKeyUp() {
        var product = document.getElementById("product");

        if (product.value.length >= 3) {
            document.getElementById("products-list").innerHTML = "Loading...";

            var ajax = new XMLHttpRequest();
            ajax.open("GET", "get-products.php?product=" + product.value, true);

            ajax.onreadystatechange = function () {
                if (this.readyState == 4 && this.status == 200) {
                    var data = JSON.parse(this.responseText);
                    var html = "";

                    for (var a = 0; a < data.length; a++) {
                        html += "<p>" + data[a].productName + "</p>";
                    }

                    document.getElementById("products-list").innerHTML = html;
                }
            };

            ajax.send();
        }
    }
</script>

Get suggested products

So we are sending HTTP request after 3 words entered by the user. And sending those 3 words to the server to fetch suggested products that match their title with those 3 words. Now we need to create a file that will match the product’s title with those words and return them all as an array. So we are first connecting with the database, get the user input field from URL.

Search that value in the database based on the products table’s title field (it might be different as per your need). Executing that query will return a $result object. It will have all pieces of information about the result which is received from the database. For example, number of rows, columns in each row, each row’s content, etc.

mysqli_fetch_all

You can use the mysqli_fetch_all function to return all rows at once. But this function does not work in some PHP versions. So what we are going to do, is to loop through each record and push them in our created array one-by-one. We will be using while loop to continue loop until all rows are fetched. At the end, we will have a PHP array will all the suggested products.

But we need them in Javascript, so we need to convert that array into JSON string format and in Javascript we are already converting that string back to Javascript arrays and objects.

get-products.php

<?php

	$conn = mysqli_connect("localhost", "root", "root", "classicmodels");
	$product = $_GET["product"];

	$sql = "SELECT * FROM products WHERE productName LIKE '%" . $product . "%'";
	$result = mysqli_query($conn, $sql);

	$data = array();
	while ($row = mysqli_fetch_object($result))
	{
		array_push($data, $row);
	}
	echo json_encode($data);

?>

Select product from suggestions

At this point, as the user starts typing the input field, after 3 words a list of suggested products will be displayed. Now we need to give the user an ability to select a product from this suggested list. First, we need to attach on “onclick” listener to the product’s title in a suggestions list that will call a Javascript function whenever the user selects a product from the list.

In that function we are going to need a selected product ID, so we are adding a custom attribute data-id whose value will be the product ID that should be set in the hidden input field. In that function, we are getting the selected product ID and setting this in the hidden product code field. Also, we are emptying the div so the suggestions will be removed once an item is selected from the list.

Lastly, in input field we are setting product’s title as a value because the user has only entered 3 words, once he selects some item from the list, that value will be set in his input field.

function selectProduct(self) {
	var productCode = self.getAttribute("data-id");
	document.getElementById("productCode").value = productCode;
	document.getElementById("products-list").innerHTML = "";
	document.getElementById("product").value = self.innerHTML;
}

// Inside AJAX response
for (var a = 0; a < data.length; a++) {
	html += "<p onclick='selectProduct(this);' data-id='" + data[a].productCode + "'>" + data[a].productName + "</p>";
}

Applying styles

Although this part has nothing to do with functionality, but it is always good to do some work on the design and make it look good. Add a CSS class to suggested products single paragraph, and create a <style> tag anywhere in your file and use that CSS class to applying styles as per your needs.

// Inside the loop in AJAX response, give CSS class
html += "<p class='product-list-item' onclick='selectProduct(this);' data-id='" + data[a].productCode + "'>" + data[a].productName + "</p>";

<style>
    .product-list-item {
        background: darkgray;
        color: white;
        width: 200px;
        padding: 15px;
        border-radius: 5px;
        cursor: pointer;
    }
</style>

That’s how you can create a customized auto complete view in HTML and Javascript.

[wpdm_package id=’235′]

Show realtime website users counter – Node JS

In this article, we are going to show you how you can get realtime website users counter using Node JS. Paste the following code in page where you want to display the counter:

HTML

<div class="row">
	<div id="countdown">
		<div id='tiles'>
			<span>0</span>
			<span>0</span>
			<span>0</span>
			<span>0</span>
		</div>

		<div class="labels">
			<li>Registered users</li>
		</div>
	</div>
</div>

CSS

#countdown{
    width: 465px;
    height: 170px;
    text-align: center;
    background: #222;
    background-image: -webkit-linear-gradient(top, #222, #333, #333, #222); 
    background-image:    -moz-linear-gradient(top, #222, #333, #333, #222);
    background-image:     -ms-linear-gradient(top, #222, #333, #333, #222);
    background-image:      -o-linear-gradient(top, #222, #333, #333, #222);
    border: 1px solid #111;
    border-radius: 5px;
    box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.6);
    margin: auto;
    padding: 24px 0;
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
}

#countdown:before{
    content:"";
    width: 8px;
    height: 65px;
    background: #444;
    background-image: -webkit-linear-gradient(top, #555, #444, #444, #555); 
    background-image:    -moz-linear-gradient(top, #555, #444, #444, #555);
    background-image:     -ms-linear-gradient(top, #555, #444, #444, #555);
    background-image:      -o-linear-gradient(top, #555, #444, #444, #555);
    border: 1px solid #111;
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
    display: block;
    position: absolute;
    top: 48px; left: -10px;
}

#countdown:after{
    content:"";
    width: 8px;
    height: 65px;
    background: #444;
    background-image: -webkit-linear-gradient(top, #555, #444, #444, #555); 
    background-image:    -moz-linear-gradient(top, #555, #444, #444, #555);
    background-image:     -ms-linear-gradient(top, #555, #444, #444, #555);
    background-image:      -o-linear-gradient(top, #555, #444, #444, #555);
    border: 1px solid #111;
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
    display: block;
    position: absolute;
    top: 48px; right: -10px;
}

#countdown #tiles{
    position: relative;
    z-index: 1;
}

#countdown #tiles > span{
    width: 92px;
    max-width: 92px;
    font: bold 48px 'Droid Sans', Arial, sans-serif;
    text-align: center;
    color: #111;
    background-color: #ddd;
    background-image: -webkit-linear-gradient(top, #bbb, #eee); 
    background-image:    -moz-linear-gradient(top, #bbb, #eee);
    background-image:     -ms-linear-gradient(top, #bbb, #eee);
    background-image:      -o-linear-gradient(top, #bbb, #eee);
    border-top: 1px solid #fff;
    border-radius: 3px;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.7);
    margin: 0 7px;
    padding: 18px 0;
    display: inline-block;
    position: relative;
}

#countdown #tiles > span:before{
    content:"";
    width: 100%;
    height: 13px;
    background: #111;
    display: block;
    padding: 0 3px;
    position: absolute;
    top: 41%; left: -3px;
    z-index: -1;
}

#countdown #tiles > span:after{
    content:"";
    width: 100%;
    height: 1px;
    background: #eee;
    border-top: 1px solid #333;
    display: block;
    position: absolute;
    top: 48%; left: 0;
}

#countdown .labels{
    width: 100%;
    height: 25px;
    text-align: center;
    position: absolute;
    bottom: 8px;
}

#countdown .labels li{
    /*width: 102px;*/
    font: bold 15px 'Droid Sans', Arial, sans-serif;
    color: #f47321;
    text-shadow: 1px 1px 0px #000;
    text-align: center;
    text-transform: uppercase;
    display: inline-block;
}

Display currently registered users

Paste the following code before the counter is displayed:

<?php
	$conn = mysqli_connect("localhost:8889", "root", "root", "classicmodels");
	$result = mysqli_query($conn, "SELECT COUNT(*) AS total_users FROM users");
	$row = mysqli_fetch_object($result);
	$total_users = $row->total_users;
	$total_users = substr("0000" . $total_users, -4);
?>

This will return the number of users in 4 digit format. For example, if your website has 275 users then substr(“0000” . $total_users, -4):

  • “0000” will print 4 zeroes.
  • $total_users will append 275, thus makes 0000275.
  • -4 will pick the last 4 characters, thus becomes 0275.

We need to display each character in 1 block, so we will loop through length of this digit and display single character in each iteration.

<?php for ($a = 0; $a < strlen($total_users); $a++) { ?>
	<span><?php echo $total_users[$a]; ?></span>
<?php } ?>

Setup Node JS

Download and install Node JS from here. After installation, create a new folder for Node JS and create a new file named “index.js”. Open command prompt in this folder and run the following command:

npm init

This will initialize the directory. Then you need to install 3 modules for this, you can install all 3 of them from single command:

npm install express http socket.io

When all above modules installs, open your index.js file and paste the following code in it:

var express = require("express");
var app = express();
var http = require("http").createServer(app);
var socketIO = require("socket.io")(http);

http.listen(3000, function () {
	socketIO.on("connection", function (socket) {
		socket.on("new_user", function () {
			socket.broadcast.emit("new_user");
		});
	});
});

And run the command in your command prompt:

node index.js

This will start the server and keep listen for incoming events for “new_user” event. As soon that event is received, it broadcast that event to all other connected clients. Broadcast means to send the event to all users except the one who sends it.

Send event when new user gets registered

So the server is listening for incoming events and sending to all other connected clients. Now we need to send event whenever new user gets registered. On registration form, attach an onsubmit event and call a function to send event to server. Make sure the function must returns true otherwise your action attribute will not work.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

<form action="your_action_page" onsubmit="return sendEvent();" method="POST">

JS

function sendEvent() {
	var socketIO = io("http://localhost:3000/");
	socketIO.emit("new_user");
	return true;
}

Receive event on counter page

So an event is sent from registration page to server, and sends it to all other connected clients. But there isn’t any client to receive it yet, so we will be listening to this event on our page where we want to display the counter. In this case, we are displaying counter on home page.

When the event is received we will increment the current users number and display it in 4 digit format, like we did for PHP. In order to increment the current number, we first must have the old number, so we have created an hidden field for it.

<input type="hidden" id="total_users" value="<?php echo $row->total_users; ?>">

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

JS

var socketIO = io("http://localhost:3000/");
socketIO.on("new_user", function () {
	var total_users = document.getElementById("total_users").value;
	total_users++;

	var totalUsers_Str = total_users + "";
	totalUsers_Str = totalUsers_Str.padStart(4, "0");

	var html = "";
	for (var a = 0; a < totalUsers_Str.length; a++) {
		html += "<span>" + totalUsers_Str[a] + "</span>";
	}

	document.getElementById("tiles").innerHTML = html;
	document.getElementById("total_users").value = total_users;
});

This tutorial is created in core PHP and vanilla Javascript, but may be you were working in Laravel or in any other framework, so you might face minor problems to integrate this in your scenario. If you face any issue, you can always contact us and we will help you out.

That’s how you can show realtime website users counter in your website using PHP and Node JS.

[wpdm_package id=’233′]

2 factor Login Authentication – PHP & Twilio SMS

In this tutorial, we are going to implement 2 factor login authentication. 2 factor login authentication means that user will be verified twice before login.

  1. 1st factor should be what they know, like password or some security question.
  2. 2nd factor will be what they have, like mobile or fingerprint.

Database structure

First create a table where all users data will be stored. You might already have that if you are working on existing project. You need to add a new field “phone” in your existing “users” table because we will be sending SMS to this field value. There should be an option to enable or disable this 2 factor authentication, so a boolean field named “is_tfa_enabled”. Also a pin number which will be sent as SMS.

users

  • id int(11) NOT NULL AUTO_INCREMENT
  • email text NOT NULL
  • password text NOT NULL
  • phone text NOT NULL
  • is_tfa_enabled tinyint(1) NOT NULL
  • pin text NOT NULL

User registration

During registration, we need to add a new field for phone number. Below is a sample registration form with password encryption.

Set default values to following fields:

  • “is_tfa_enabled” as false
  • “pin” as empty
<form method="POST" action="register.php">
	
	<input type="email" name="email">
	<input type="password" name="password">
	<input type="text" name="phone">
	
	<input type="submit" name="register">
</form>

register.php

<?php

	if (isset($_POST["register"]))
	{
		$email = $_POST["email"];
		$phone = $_POST["phone"];
		$password = $_POST["password"];
		$password = password_hash($password, PASSWORD_DEFAULT);

		$conn = mysqli_connect("localhost", "root", "", "tutorials");
		
		$sql = "INSERT INTO users (email, phone, password, is_tfa_enabled, pin) VALUES ('$email', '$phone', '$password', 0, '')";
		mysqli_query($conn, $sql);

		header("Location: login.php");
	}

?>

User login – Send OTP

There will be no extra field in login, it will have email/username and password or whatever fields you are using to login. The important thing is, we need to send an SMS if the user has enabled 2-factor authentication. Below is a typical login form:

<form method="POST" action="login.php" id="form-login">
	<input type="email" name="email">
	<input type="password" name="password">
	
	<input type="submit" name="login">
</form>

We will send an SMS using Twilio if user has enabled 2-factor authentication. First you need to include Twilio PHP library in your project using composer. Open terminal in your project root folder and run the following command to install Twilio:

composer require twilio/sdk

Create an account on Twilio from here. After creating account, you will be given a $15 balance to test the API. On your Twilio console dashboard you will find your “account SID” and “auth token”. You will need to place those on below variables accordingly:

Twilio console

login.php

<?php

	session_start();

	require_once "vendor/autoload.php";
	use Twilio\Rest\Client;

	$sid = "";
	$token = "";

	if (isset($_POST["login"]))
	{
		$email = $_POST["email"];
		$password = $_POST["password"];

		$conn = mysqli_connect("localhost", "root", "", "tutorials");
		
		$sql = "SELECT * FROM users WHERE email = '$email'";
		$result = mysqli_query($conn, $sql);

		if (mysqli_num_rows($result) > 0)
		{
			$row = mysqli_fetch_object($result);
			if (password_verify($password, $row->password))
			{
				if ($row->is_tfa_enabled)
				{
					$row->is_verified = false;
					$_SESSION["user"] = $row;

					$pin = rand(0, 9) . rand(0, 9) . rand(0, 9) . rand(0, 9) . rand(0, 9) . rand(0, 9);
					
					$sql = "UPDATE users SET pin = '$pin'  WHERE id = '" . $row->id . "'";
					mysqli_query($conn, $sql);

					$client = new Client($sid, $token);
					$client->messages->create(
						$row->phone, array(
							"from" => "",
							"body" => "Your adnan-tech.com 2-factor authentication code is: ". $pin
						)
					);

					header("Location: enter-pin.php");
				}
				else
				{
					$row->is_verified = true;
					$_SESSION["user"] = $row;

					header("Location: index.php");
				}
			}
			else
			{
				echo "Wrong password";
			}
		}
		else
		{
			echo "Not exists";
		}
	}

?>
  1. We need to call session_start() in order to use any $_SESSION variable.
  2. If the user has provided correct email and password, then we are checking if that user has enabled 2-factor authentication for his account.
  3. Then we are generating a random pin code of 6 digits and sending it to the user’s phone number.
  4. We are using “is_verified” field in $_SESSION to check if user account is pin verified or not.
  5. After SMS has been sent, you will be redirected to “enter-pin.php” where you need to enter the pin sent in SMS.

enter-pin.php

This file will only contain 1 field to enter pin code. User ID is already been stored in $_SESSION.

<form method="POST" action="enter-pin.php">
	<input type="text" name="pin">
	
	<input type="submit" name="enter_pin">
</form>

And when this form submits, we are simply going to check the entered pin with database and login the user. We also need to empty the pin from database so that it cannot be used again.

<?php

	session_start();

	if (isset($_POST["enter_pin"]))
	{
		$pin = $_POST["pin"];
		$user_id = $_SESSION["user"]->id;

		$conn = mysqli_connect("localhost", "root", "", "tutorials");
		
		$sql = "SELECT * FROM users WHERE id = '$user_id' AND pin = '$pin'";
		$result = mysqli_query($conn, $sql);

		if (mysqli_num_rows($result) > 0)
		{
			$sql = "UPDATE users SET pin = '' WHERE id = '$user_id'";
			mysqli_query($conn, $sql);

			$_SESSION["user"]->is_verified = true;
			header("Location: index.php");
		}
		else
		{
			echo "Wrong pin";
		}
	}

?>

Now after verification user will be redirected to “index.php” which is by default the home of every website. You might already have a check to prevent the user from entering this page without login. Just need to change few things,

  • Check if user is logged in and pin verified.
  • A switch to turn on/off 2-factor authentication.
  • A link to logout the user.

index.php

<?php

session_start();
$conn = mysqli_connect("localhost", "root", "", "tutorials");

if (isset($_SESSION["user"]) && $_SESSION["user"]->is_verified)
{

	$user_id = $_SESSION["user"]->id;

	if (isset($_POST["toggle_tfa"]))
	{
		$is_tfa_enabled = $_POST["is_tfa_enabled"];

		$sql = "UPDATE users SET is_tfa_enabled = '$is_tfa_enabled' WHERE id = '$user_id'";
		mysqli_query($conn, $sql);

		echo "Settings changed";
	}

	$sql = "SELECT * FROM users WHERE id = '$user_id'";
	$result = mysqli_query($conn, $sql);
	$row = mysqli_fetch_object($result);

	?>

	<form method="POST" action="index.php">
		<h1>Enable TFA</h1>

		<input type="radio" name="is_tfa_enabled" value="1" <?php echo $row->is_tfa_enabled ? "checked" : ""; ?>> Yes
		<input type="radio" name="is_tfa_enabled" value="0" <?php echo !$row->is_tfa_enabled ? "checked" : ""; ?>> No

		<input type="submit" name="toggle_tfa">
	</form>

	<a href="logout.php">
		Logout
	</a>

	<?php
}
else
{
	header("Location: login.php");
}

We are displaying 2 radio buttons and an ability to automatically select the radio based on enable or disability of 2-factor authentication. You can use the same condition on all pages which you want to show to only authenticated users. Now we just need to logout the user. We have created a link with text “Logout” which when clicked will redirect the user to “logout.php” page.

logout.php

<?php

session_start();
unset($_SESSION["user"]);
session_destroy();
header("Location: login.php");

?>

Re-send OTP after 30 seconds

If you want to resend the OTP after 30 seconds, first, we need to call a Javascript function using setTimeout method.

setTimeout(function () {
// [call AJAX here]
}, 30 * 1000)

Then we need to call an AJAX to resend the OTP. The following code goes in the [call AJAX here] section:

const form = document.getElementById("form-login")

const ajax = new XMLHttpRequest()
ajax.open("POST", "login", true)

ajax.onreadystatechange = function () {
	if (this.readyState == 4) {
		if (this.status == 200) {
			console.log(this.responseText)
		}
	}
}

const formData = new FormData(form)
ajax.send(formData)

Show timer

If you want to show the timer for 30 seconds. First, create a <div> where the timer text will be displayed.

<div id="timer"></div>

Then we need to call a setInterval function to call each second and decrement the value.

let seconds = 30

const timerInternval = setInterval(function () {
	seconds--
	document.getElementById("timer").innerHTML = seconds
	if (seconds <= 0) {
		stopInterval(timerInternval)
	}
}, 1000)

That’s how you can add 2 factor login authentication with a timer on your website. If you want to know how to add “reset password” feature in your website, check our free tutorial here.

https://drive.google.com/file/d/1NosW0DI4WBG6cFz9f0xzluNAnkBPma1H/view?usp=sharing

UICollectionview with search bar – Swift iOS

In this article, we are going to show you how you can create a UICollectionview with search bar in Swift for your iOS application.

First, we will create a collection view and populate the data in it. We are using a MySQL database for employees table and a PHP API to fetch all employees data from database. The output of API will be in JSON format. So, we will also learn how to encode JSON data in Swift. We will be displaying employee number and name in it.

Create UICollectionView using storyboard

  1. First goto your storyboard, search for collection view and drag in in your main view.
  2. Your collection view will have a cell inside it. Search for label for employee number and drag it inside collection view cell.
Select collection view cell and set a custom class
add an identifer

Now select collection view, goto outlets, and attach data source & delegate of collection view to your view controller class.

Create a class for single cell layout named SingleCellView.swift:

import UIKit

class SingleCellView: UICollectionViewCell {
	// drag label outlet here
}

Select label from storyboard and drag it inside SingleCellView class:

Note: To drag label from storyboard into SingleCellView class, oepn storyboard, goto “Navigate” in menu and select “Open in assistant editor”. Then select the class file from left sidebar and it will appear in second window.

Populate data in UI collection view

We are receiving an array of objects from the API. Each object has employeeNumber, firstName, lastName, email and other fields as displayed above. We need to display them in each collection view cell:

EmployeeModel.swift

import Foundation

class EmployeeModel: Decodable {
    public var employeeNumber: String!
    
    public var firstName: String!
}
  1. Create an outlet for collection view same as we did for collection view cell labels.
  2. Open viewcontroller file and extend it with UICollectionViewDataSource and UICollectionViewDelegate
  3. Implement 2 functions, first for total number of items in collection view, and second for populating data in collection view cell.
  4. Create an array of EmployeeModel objects and initialize it as an empty array.
  5. We will be using NSURLConnection.sendAsynchronousRequest to fetch data from API.
  6. When the response is received, we validate the data using guard statement to make sure it is not null.
  7. Decode the JSON string into EmployeeModel array.

ViewController.swift

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UISearchBarDelegate {
    
    private var data: [EmployeeModel]! = []
    private var realData: [EmployeeModel]! = []
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let url: URL = URL(string: "http://192.168.43.64/test/api.php")!
        var request: URLRequest = URLRequest(url: url)
        request.httpMethod = "GET"
        
        // if using POST
//        request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
//        let dataStr: String = "value=1&value=2"
//        let postData: Data = dataStr.data(using: .utf8)!
//        request.httpBody = postData
        
        NSURLConnection.sendAsynchronousRequest(request, queue: .main) { (response, data, error) in
            
            guard let data = data else {
                print(error)
                return
            }
            
            let responseString: String! = String(data: data, encoding: .utf8)
            
            do {
                
                let jsonDecoder: JSONDecoder = JSONDecoder()
                self.data = try jsonDecoder.decode([EmployeeModel].self, from: data)
                
                self.realData = self.data
                
                self.collectionView.reloadData()
            } catch {
                print(error.localizedDescription)
            }
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.data.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let singleCell: SingleCellView = collectionView.dequeueReusableCell(withReuseIdentifier: "singleCell", for: indexPath) as! SingleCellView
        
        singleCell.employeeNumber.text = self.data[indexPath.item].employeeNumber
        
        singleCell.firstName.text = self.data[indexPath.item].firstName
        
        return singleCell
    }
}

Add search bar in collection view

First select your collection view and enable section header. This will create a re-usable view inside collection view.

  1. Search for “Search bar” and drag it inside re-usable view. Also give it a identifier like we did for collection view cell.
  2. Set the custom class for re-usableview (in our case SearchBarView.swift), we will create that class in a moment.

SearchBarView.swift

import UIKit

class SearchBarView: UICollectionReusableView {
	// drag search bar outlet here same as we did for collection view cell
}
  1. Add delegate of search bar to our view controller same as we did for collection view delegate.
  2. Extend view controller class with UISearchBarDelegate and implement 2 more functions in this class.
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

	let searchView: UICollectionReusableView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "SearchBar", for: indexPath)
	return searchView
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
	self.data.removeAll()
        
	for item in self.realData {
		if (item.firstName.lowercased().contains(searchBar.text!.lowercased())) {
			self.data.append(item)
		}
	}
        
	if (searchBar.text!.isEmpty) {
		self.data = self.realData
	}
	self.collectionView.reloadData()
}

Now you will have a working UICollectionView with search bar in your iOS application.

Video tutorial:

Get realtime notification from contact us form to admin panel – Node JS

You can receive realtime notification on your admin panel for your website’s contact us form using simple Node JS script. You can download Node JS from here and install it in your system.

Above screenshot is the demo of what we are going to create. On left we have contact us page from where users can send a message to admin. And on right we have admin panel where admin will be able to view messages without refreshing the page.

Sending message from contact us form

Your typical contact us form might have the following fields:

<form action="#">
	<input type="text" id="name">
	<input type="text" id="email">
	<input type="text" id="subject">
	<textarea id="message"></textarea>

	<input type="button" onclick="sendMessage()" value="Send Message">
</form>

<script>
	function sendMessage() {
		//
	}
</script>

You might also have different fields too but it does not matter. The most important thing is, your form should:

  1. Have ID attribute to all fields.
  2. For submit button, input type must be “button”, not “submit”.
  3. The button needs to have an “onclick” listener.
  4. A function with same name must be created inside script tag.

Now we will be sending an event from socket. You can all an AJAX function too if you want to perform other actions too. First you need to include socket-io.js in your project, you can use the below CDN link to do that. Paste the following code anywhere in your contact us page:

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

Then you have to create an instance for IO object and in sendMessage() function, you have to emit an event using this IO object. Sending an event is commonly refer to as “Emitting an event”.

var socket = io("http://192.168.43.64:3000");

function sendMessage() {
	socket.emit("messageSent", {
		"name": document.getElementById("name").value,
		"email": document.getElementById("email").value,
		"subject": document.getElementById("subject").value,
		"message": document.getElementById("message").value
	});

	// Call an AJAX for further actions you want to perform (like saving in database etc.)
}

io constructor will receive an IP address and port number where Node JS server will be running. You can get your local IP address from terminal by running the command: ifconfig and search for line having “ipv4”, your local IP address will be right next to “ipv4”. You can run your Node JS project on any port number other than 8080 (default for apache) and 3306 (default for MySQL). It will return a socket object which can be used to send an receive events from server. To send an event, we will calling a function named emit(eventName, data), it has 2 argument:

  1. First argument is the name of event that needs to be send.
  2. Second will be the data that needs to be send with this event. Here you can place all your contact us fields using their IDs.

Node JS server

Now we need a medium which will listen to this event and respond accordingly. So we assume that you have installed Node JS in your computer.

  1. Create a folder named “nodejs-server” anywhere in your system. I am creating it at desktop.
  2. Open terminal in that folder (shift + right click) and run the following command one at a time:
npm init

This will initialize the folder as Node JS project.

npm install express

This will install the express module used to create a server.

npm install http

This module will be used to start the server at specific port (3000 in our case).

npm install socket.io

This module will be used to listen events from client, and emit events to clients.

server.js

Create a file named “server.js” in newly created folder (“nodejs-server” in our case) and paste the following code in it:

var express = require("express");
var app = express();

var http = require("http").createServer(app);
var io = require("socket.io")(http);

http.listen(3000, function () {
    console.log("Server connected");

    io.on("connection", function (socket) {
        console.log("User " + socket.id);

        socket.on("messageSent", function (message) {
            socket.broadcast.emit("messageSent", message);
        });
    });
});

Remeber this file is a Javascript file so it does not need a <script> tag in it. We will explain each later in a moment. To start the server, run the following command in terminal or command prompt in that folder:

node server.js
  • First we created an instance of express and initialize it, saved it in a variable named “app”.
  • Similarly, we created “http” and “socket.io” instances. Http is created from express module. And socket.io is created from Http.
  • Then we start the server using listen function. First parameter will be port number and second will be a call back function that will be called when the server started running.
io.on("connection", function (socket) {
  • This function will be called when a new client connected with Node JS server. Client is connected by calling io() function from web page.
  • Then we are listening to “messageSent” event from client. That function will be called when client emits that event (in our case, from contact us form).
  • Then we are sending this event to all other connected clients. Broadcast will send the event to all connected clients other than the one who sends it.

Receive realtime notification on admin panel

So we are emitting event from contact us form and broadcasting it to all other connected clients from Node JS app. But who are the “other clients” ?
The one who will be listening to that event. So we are going to make admins to listen to that event. Paste the following code in all files on admin panel where you want to receive realtime notifications. Or you can paste them in admin template’s header or footer file as that will be included in each file.

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/notify/0.4.2/notify.js"></script>

<script>
	var socket = io("http://192.168.43.64:3000");

	socket.on("messageSent", function (message) {
		$.notify("New Message\n" + message.message + "\n\nFrom: " + message.name, {
			autoHide: false,
			className: "success"
		});
	});
</script>

First we added socket IO and created an instance like we did for contact us page. We are using https://notifyjs.jpillora.com/ library to display a simple alert realtime notification but once you have attach an event listener, you can display the realtime notification as per you need. jQuery is also added for notify.js, otherwise you do not need jQuery for socket IO.

That’s how you can receive realtime notification from your contact us form in your admin panel. Learn how to create a realtime customer support chat widget from here.

Custom sort – jQuery UI, AJAX, PHP & MySQL

We are going to implement a custom sort using jQuery UI, which helps you to customize the order of data being displayed on your website. First, add CDN for jquery and jquery UI. Goto cdnjs.com to get CDN link for jQuery and visit this link to get CDN link for jQuery UI. Copy the JS link for jQuery, and CSS and JS links for jQuery UI. Create 2 script tags for jQuery and jQuery UI JS and one link tag for jQuery UI CSS.

index.php

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>

<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.min.js">
</script>

First you need to show all data from database. Here we are connecting with our sample database and displaying all products based on their product code.

<?php

    $conn = mysqli_connect("localhost", "root", "", "classicmodels");
    $result = mysqli_query($conn, "SELECT * FROM products ORDER BY productCode DESC");

?>
  1. Create a div container which will enclose all data.
  2. Create a while loop to run through all records in database.
  3. Inside this loop, create a div tag which will represent each product separately.
  4. Give it a class so it will group each product under same class.
  5. and give it a unique ID, now ID will be the value which will tell the order of all products in an array. In our database, unique ID of product is productCode, so we will use that. But you must use as per your database table.
<div id="myData">
    <?php while ($row = mysqli_fetch_object($result)) { ?>

        <div 
            class="item"
            id="<?php echo $row->productCode; ?>"
            style="margin-top: 0px; margin-bottom: 0px;">
                
            <img
                src="<?php echo $row->image; ?>"
                style="width: 200px;">

            <h3><?php echo $row->productName; ?></h3>

        </div>
    <?php } ?>
</div>

Now we need to find a way to able to drag them so we can move them. So,

  1. Create a script tag.
  2. Attach a listener which will be called when the page is fully loaded.
  3. Select the div container using ID.
  4. Call sortable function, it exists in jquery UI. Its constructor will receive an object where you can specify options.
<script>

    window.products = [];
    
    $(function () {
        $("#myData").sortable({
            "items": ".item",
            "opacity": 0.6,
            "cursor": "move",
            "update": function (event, ui) {
                var data = $("#myData").sortable("toArray");
                
                // if using table
                // data = data.filter( n => n );

                window.products = data;
            }
        });
    });
</script>

jQuery UI sortable options

  1. “items”: Selector of each individual item. So we will use the div inside loop having class class=”item”.
  2. “opacity”: Give it an opacity, so when we select some product it will be highlighted among others.
  3. “cursor”: A cursor which will be displayed on div only during dragging an item.
  4. “update”: A function which will be called when you finish dragging some item from one place to another.

The update function has 2 parameters, events and UI (although we are not going to use any of them but you might need them in your case). Inside this function, we will get the new order of items in a variable. Select the main div container tag using its ID selector and call sortable function same as above. And inside it pass the argument “toArray”. It will return all items unique ID in a sorted array.

If you are using tables instead of divs, you might receive first element of array as empty string. You can prevent this by calling filter function to this array. Passing n means to remove null or empty strings.

Save custom sequence in database

Now we will create a button which when clicked will save this data in selected sequence.

<button type="button" onclick="saveData();">Save</button>

Create a function inside script tag:

function saveData() {
    var ajax = new XMLHttpRequest();
    ajax.open("POST", "save.php", true);
    ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajax.send("data=" + JSON.stringify(window.products));

    ajax.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            console.log(this.responseText);
        }
    };
}
  1. First create an AJAX object.
  2. Call open method and set the request method to “POST”.
  3. Second parameter will be the name of file where data needs to be sent.
  4. Since this is a post request, so we also need to attach a header for content type.
  5. And send the data will be in name value pair separated by ampersand sign.
  6. Since we want to send an array so we need to convert that into JSON string.
  7. onreadystatechange event will be fired when the response has been received from server.

save.php

Create a new file named “save.php” which will handle the request. First make a connection with database. Create a new table in database which will hold the sequence of products, its structure will be as below:

Table name: product_order, columns:

id integer auto increment
product_id integer
order_number integer
Then in “save.php” paste the following code:

<?php

    $conn = mysqli_connect("localhost", "root", "", "classicmodels");

    $data = json_decode($_POST["data"]);

    mysqli_query($conn, "DELETE FROM product_order");

    $sql = "INSERT INTO product_order(product_id, order_number) VALUES";

    for ($a = 0; $a < count($data); $a++)
    {
        $sql .= " ('" . $data[$a] . "', '" . ($a + 1) . "')";

        if ($a < count($data) - 1)
        {
            $sql .= ",";
        }
    }

    mysqli_query($conn, $sql);
    echo "Done";

?>

First get all data that we are receiving in a separate variable, and since we are sending JSON string so we need to decode that JSON back in PHP array. First of all, whenever the sequence of products changes, we have to remove all the previous sequence from database. Then we will prepare an SQL query to insert the new sequence in product order table. So loop through each product ID. Product ID will be what we are receiving from AJAX. Order number must be starting from 1, to 2 3 and so on, that is why we are incrementing in variable $a.

Display data by custom sort

Now go back to index.php and change the SQL query to following:

<?php

$conn = mysqli_connect("localhost", "root", "", "classicmodels");

$result = mysqli_query($conn, "SELECT * FROM products INNER JOIN product_order ON products.productCode = product_order.product_id ORDER BY product_order.order_number ASC");

?>

So we just need to change this query to display products based on order number from product_order table. Inner join with product_order, based on productID. And order by order_number from product_order table. Ascending order will make it start from 1 to 2 and 3 and so on.

That’s how you can implement a custom sort in jQuery UI using AJAX, PHP and MySQL.

[wpdm_package id=’219′]