WordPress textbox autocomplete using Ajax/jQuery

This tutorial is absolutely for beginner which contains demo source code, wordy explanation. At the end, you will be able to write up a WordPress Plugin that can load data from custom database table and serve it as data source. If you learn faster by reading source code, please feel free to jump in to my github repository.

In this article, I am going to cover below topics

  1. WordPress custom database table
  2. Enqueue or load required scripts (js)
  3. Textbox autocomplete


Getting started

Before we deep dive into detail, here is couple of things that we need to do

  1. Create a folder in “\wp-content\plugins\” called “ajax-autocomplete”
  2. Create “ajax-autocomplete.php” inside above folder, this file should have below header. Check out this official document for more options

    * Plugin Name: Ajax Autocomplete
    * Plugin URI: https://www.vndeveloper.com/
    * Description: DEMO WordPress Ajax jQuery textbox autocomplete, data source from custom table.
    * Version: 0.1
    * Author: Hien D. Nguyen
    * Author URI: https://www.vndeveloper.com/
    * License: GPL2+

  3. I recommend below file folder structure. If you already have your style, keep using it.

WordPress custom database table

We will create a custom table name “testing_table” and insert some test data upon Plugin activation

register_activation_hook(basename(dirname(__FILE__)) . ‘/’ . basename( __FILE__ ), ‘activate’);
function activate() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’);

$table = $wpdb->prefix . ‘testing_table’;
$query = “CREATE TABLE IF NOT EXISTS {$table} (
name VARCHAR(128),

$wpdb->insert($table, array(‘name’=>’LogiTech’));
$wpdb->insert($table, array(‘name’=>’Apple’));
$wpdb->insert($table, array(‘name’=>’Dell’));
$wpdb->insert($table, array(‘name’=>’Google’));

Enqueue or load required scripts (js)

You might know that AutoComplete needs jQuery. You also might think that you need to download jQuery libraries and place it in your plugin, then enqueue it.

For demo purpose, we don’t have any specific requirement for jQuery version. Therefore, we are going to use “built-in” jQuery that shipped along with WordPress. You can also check out all built-in scripts or libraries such as backbone, jquery-effects-transfer…at here.

add_action(‘wp_enqueue_scripts’, ‘mysite_js’);
function mysite_js() {
$wp_scripts = wp_scripts();
wp_enqueue_script(‘mysitejs’, plugins_url(‘/assets/js/frontend.js’, __FILE__), array(‘jquery’, ‘jquery-ui-core’, ‘jquery-ui-autocomplete’));
wp_localize_script(‘mysitejs’, ‘ajax_object’, array(‘ajax_url’ => admin_url( ‘admin-ajax.php’)));

// Autocomplete style
wp_enqueue_style(‘plugin_name-admin-ui-css’,’http://ajax.googleapis.com/ajax/libs/jqueryui/’ . $wp_scripts->registered[‘jquery-ui-core’]->ver . ‘/themes/flick/jquery-ui.css’);

// If your plugin needs its own style
wp_register_style(‘mysitecss’, plugins_url(‘/assets/css/frontend.css’, __FILE__));
wp_enqueue_style(‘mysitecss’ );

Keep in mind that we’ll need to send ajax request to query data from custom database table (testing_table). That’s why we need to call wp_localize_script so that our script (JavaScript) can understand variable “ajax_url”. Basically, to send an ajax request, we send a POST request to “wp-admin/admin-ajax.php”. I personally find this article perfectly explains Ajax as well as how it handles data submission.

We also load “themes/flick/jquery-ui.css” for styling our textbox autocomplete. You can check out other styles at here.

Textbox autocomplete

First thing first, we need a textbox. In this tutorial, we’ll use shortcode called “test-form” so later on we can place it in any page or post or even widget.

add_shortcode(‘test-form’, ‘test_form’);
function test_form($args, $content=”){
include(plugin_dir_path(__FILE__) . ‘includes/forms/test-form.php’);
return ob_get_clean();

In our “test-form.php”, just create a form with a textbox with “name” attribute as “testing”. In our JavaScript, we can make use of this attribute to locate this target textbox.

<form >
<input type=”text” name=”testing”>

In our loaded script (“/assets/js/frontend.js”), it looks this

jQuery(document).ready(function($) {
source: function(request, response){
type: “POST”,
url: ajax_object.ajax_url,
data: {
action: ‘myautocomplete’,
keyword: $(‘input[name=testing]’).val(),
success:function(data) {
response(JSON.parse( data ));
error: function(errorThrown){

For further options, please check out this article. Whenever user types in, an ajax request will be sent to (url: ajax_object.ajax_url) which is “wp-admin/admin-ajax.php”, then callback action “myautocomplete” will handle this request and send a response.

add_action(‘wp_ajax_nopriv_myautocomplete’, ‘ajax_autocomplete’);
add_action(‘wp_ajax_myautocomplete’, ‘ajax_autocomplete’);
function ajax_autocomplete() {
global $wpdb;
$table = $wpdb->prefix . ‘testing_table’;
$results = $wpdb->get_results(“SELECT name FROM ” . $table . ” WHERE name LIKE ‘%” . $_POST[‘keyword’] . “%'”);
$items = array();
if ( !empty( $results) ) {
foreach ( $results as $result ) {
$items[] = $result->name;
echo json_encode($items);

Final thought

That’s it. We finished creating a WordPress Plugin that has a “testing-form” short-code. This short-code contains a form with single textbox. When user types in “l”, this textbox will load data from custom table and suggest possible value.

Technical side, we covered

  1. Creating custom table upon WordPress Plugin activation, also add some testing data
  2. Load built-in jQuery and custom scripts, styles
  3. Using Ajax/jQuery for textbox autocomplete

Please share if you find this tutorial helpful and don’t forget to leave a comment.

Where is Software Testing Heading?

Just like other vibrant industries, software testing is changing every day. As a tester, what should you learn to stay on top of your game? Below are some trends you might want to take a look at in 2018. Sharpen the saw!

  • Blockchain app testing: Unless you’ve been living under a rock for the past few years, you’d probably have heard of buzzwords like Bitcoin, Ethereum and Blockchain. Blockchain is taking the world by storm. More and more investments are made on developing Blockchain-based applications, translated: more software testing needed.
    Tip: “Mastering Bitcoin: Unlocking Digital Cryptocurrencies” of Andreas Antonopoulos is a very good start. This book provides basic understanding about Bitcoin and Blockchain through very good examples.
  • Smart product testing: Devices equipped with sensors (think smart toys like Anki Overdrive), voice-based & AI-powered devices (think Amazon Alexa) are taking the center stage. Millions of Amazon Echo and Google Home devices have been sold. Gartner predicts that the market for voice-based wireless speakers will reach $2 billion by 2020. Testers nowadays face a wildly different problem that requires a wildly different skill set.
    Tip: Learn how to program an Alexa “skill” (another name for “apps” on Alexa Marketplace). You just need to sign up for an AWS account (free) and start writing a Lambda function (guide).
  • More test automation: Manual testers have found themselves in a shrinking job market. The industry demands more technical skills like the ability to churn out automated tests, preferably platform-agnostic.
    Tip: If you’re a manual tester, it’s still not too late to learn test automation. Here’s a general guideline: http://qr.ae/TbSswT
  • Wiring automated tests into the pipelines: In today’s DevOps world, bug fixes & new product increments are directly pushed out to end-users, in the continuous fashion. Shit hits the fan if those pieces of code are continuously untested. But the path to Continuous Testing is not always straightforward. Unexpected plumbing landmines are always lurking around the corner.
    Tip: You or your colleagues won’t need to be coding experts to wire automated tests to your pipelines. Almost all ALM tools provide a command-line interface.
  • Service-oriented testing: This is absolutely not a brand new trend in 2018. The trend started long ago: the number of API-level tests keeps growing while UI-level tests keep shrinking. API tests obviously dig deeper, run faster & more reliably (think Fowler pyramid).
    Tip: Learn how to use REST endpoints via tools like POSTMAN and curl first. Then you can write API tests using RestAssured.
  • Involvement of non-engineering testers: More and more non-engineering testers (or some might call “test analysts” or “domain experts”) are taking part in software testing although they don’t possess a strong technical background. This trend calls for an effective scripting language that is readable & writable for non-technical testers, yet executable for the test runners.
    Tip: Focus on the business flows and business logics of your app instead of code. Leave the coding / test implementation to automation engineers. Besides, it’s really useful to get acquainted to the Keyword-Driven method, a solution for non-technical testers to collaborate effectively with technical ones.

Obviously these trends will pivot as the industry progresses. To stay up to date, I’d recommend keeping up-to-date via several information channels below. It’s only my personal ranking / preferences so don’t shoot the messenger.

  1. Automation Awesomeness
  2. Software Development & Testing Insights | TechWell
  3. LogiGear Magazine
  4. StickyMinds
  5. Community Articles | SoftwareTestPro
  6. SD Times – Software Development News
  7. DevOps.com
  8. James Bach – Satisfice, Inc.
  9. Asktester Blog
  10. Testing Excellence

Some testable smart products:
testable smart products

Install MariaDB / MySQL on Raspbian / Debian

Install MariaDB (or MySQL) on Raspbian / Debian is pretty easy with the supported package:
sudo apt-get install mariadb-server (or mysql-server)

And you can set password for the root account as well as configure others by one simple command:
sudo mysql_secure_installation (for both MariaDB and MySQL)

But the problem is that you can’t connect to the database from any system. You’ll get the “Access denied” error all the time. The only way to access is from the terminal of that server:
sudo mysql -u root -p

I don’t know why the authors make them to be difficult to use at the first time. To remove the restrictions, it requires many steps:

1. Login from terminal:
sudo mysql -u root -p

2. The plugin of the root account in the mysql.user table is set to ‘unix_socket’, which means you can only access using the terminal. Use the following commands to remove it:
USE mysql;
UPDATE user SET unix_socket = '' WHERE User='root';

3. Now you can use any SQL tool (phpMyAdmin, SQL Workbench…) to access the database. But that tool must be used on the same server because the Host field of root account in mysql.user is ‘localhost’. So you may need to remove it.
UPDATE user SET Host = '' WHERE User='root';

4. Now, try to access again. You still can’t access the database from another machine. Why? Because the database socket doesn’t bind to an IP address. This setting is missing from the config file. Let’s find the config file first:
sudo find / -name my.cnf

The file is usually located at: /etc/mysql/my.cnf. Open it to modify using nano:
sudo nano /etc/mysql/my.cnf

Add to that file a new section:

5. That’s it. Restart the services and enjoy it.
sudo service mysqld restart
sudo service mysql restart

Leave a comment or contact me if you have any questions or suggestions

Install PHP 7 from source on Raspbian/Debian

This tutorial cover Raspbian PHP 7 installation as well as Apache 2 configuration.

Prerequisite: Apache 2 installation exists

1. Download PHP source code from http://php.net/downloads.php and then decompressed it to have a PHP folder contains source code

2. On the terminal, install the libxml2:
sudo apt-get install libxml2-dev

3. Inside the PHP folder at step #1,configure the build:
./configure ––with-apxs2=/usr/local/apache2/bin/apxs ––with-mysqli ––enable-mbstring

  • apxs was installed when installing Apache 2. In this example, the Apache 2 was installed at /usr/local/apache2.
  • The default location of php.ini is /usr/local/lib/. Use ––with-config-file-path=<path> if you need to put the php.ini file at somewhere else.
  • ––with-mysql was removed, use ––with-mysqli instead (https://github.com/php-build/php-build/issues/348)
  • ––enable-mbstring is required for using phpMyAdmin

4. Install:
sudo make
sudo make install

5. Verify:
php -v

Here are a few more steps to configure Apache 2 to support PHP:

1. Open the httpd.conf to edit:
sudo nano /usr/local/apache2/conf/httpd.conf

2. Make sure the following line exists and not commented:
LoadModule php7_module modules/libphp7.so

3. Add the following lines to let Apache parse PHP files:
<FilesMatch “\.phps$”>
        SetHandler application/x-httpd-php-source

4. Enable mod_rewrite:
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On

5. Save and close Nano by pressing Ctrl+X and Y

6. Restart Apache 2:
sudo /usr/local/apache2/bin/apachectl restart

Also, check out Install MariaDB / MySQL on Raspbian / Debian

Install Apache 2 web server from source on Raspbian

Image credit: http://www.apache.org/

This guideline is for working on Raspbian – a Linux distro for Raspberry Pi, but other Linux operating systems have similar steps.

  1. Download source from https://httpd.apache.org/download.cgi. It should be in a compressed file, e.g.: httpd-2.4.28.tar.bz2. After decompressing it, we have a httpd-<version> folder.
  2. Install PCRE library from the terminal:
    sudo apt-get install libpcre3-dev
  3. Download source of APR and APR-util from https://apr.apache.org/download.cgi. They’re all in compressed files, e.g.:  apr-1.6.2.tar.gzapr-util-1.6.0.tar.gz. After decompressing them, we have the following folders: apr-<version>, apr-util-<version>. Rename them accordingly to apr and apr-util and then move them into the folder at step #1 to this path: httpd-<version>/srclib/.
    The folder structure should be like this:
  4. Open the terminal and issue the following commands in the httpd-<version> folder to build and install Apache 2:
    ./configure –prefix=/usr/local/apache2 –with-included-apr –enable-so
    sudo make
    sudo make install
  5. Check its version:
    apache2 -v

Also check out “Install MariaDB / MySQL on Raspbian / Debian” and “Install PHP 7 from source on Raspbian/Debian

How To Unlock Desktop Screen After Remote Access Disconnected

Remote Desktop to VM to check out, investigate issues, deploy things are very common, especially when you are in CI/CD, Agile, DevOps environment. The demand to unlock desktop screen remotely is crucial for automation tests to run. A friend of mine says he struggled with this for 2 weeks. Therefore I am going to put simple and short answer right below.

How To Unlock Desktop Screen Remotely

Please note that you need to run these commands with administrative rights on remote machine.

Below command should work for Windows 7, Windows 8, Windows 8.1, Windows 10

tscon [RDC Session ID] /dest:console
Ex. tscon 1 /dest:console

Session ID can be retrieve by issuing below command

query session

Or simply use below single command

for /f "skip=1 tokens=2" %%s in ('query user %USERNAME%') do (
    tscon.exe %%s /dest:console


Below command should work on Windows Server

tscon %sessionname% /dest:console

If you have PowerShell installed on your remote machine, try this one

tscon ((quser $env:_TFSLab | select -Skip 1) -split '\s+')[2] /dest:console

Wrapping Up

That’s it. It’s simple when you know it and it can take you weeks if you don’t (like my friend’s case). Please share if you have any inputs or comment if these work for you.