Bart Simons

Creating HTML tables from JSON data in JavaScript

 •  Filed under json, data, html tables, javascript

A few weeks ago I have written a simple JavaScript library to convert JSON data to an HTML table, and vice versa if you need it. With that library comes even more functionality, like the ability to filter (search) through table rows and the ability to filter JSON data for a multi-page table layout.

You can find my project on GitHub.

This is the table and search box HTML code that I used for this article:

<div class="container">  
  <div class="row">
    <br>
    <input type="text" name="searchbox" id="searchbox" style="width: 100%;"><br><br>
  </div>

  <div class="row">
    <table id="userTable" class="table">
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>Bart</td>
       </tr>
        <tr>
          <td>2</td>
          <td>Nick</td>
        </tr>
        <tr>
          <td>3</td>
          <td>Jason</td>
        </tr>
        <tr>
          <td>4</td>
          <td>Fred</td>
        </tr>
        <tr>
          <td>5</td>
          <td>Ed</td>
        </tr>
        <tr>
          <td>6</td>
          <td>Peter</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>  



So let's dive deeper into some code examples that you can use to create your tables from JSON data:


Example 1: Convert an HTML table to JSON

$(document).ready(function()
{
  // Create a new JSONTable Object from the basicTable table.
  var jsonTable = new JSONTable($("#basicTable"))

  // Convert existing HTML table to a JSON object.
  var tableData = jsonTable.toJSON()
})



Example 2: Search through a table with the filter function

$(document).ready(function()
{
  // Create a new JSONTable Object from the basicTable table.
  var jsonTable = new JSONTable($("#basicTable"))

  // Convert existing HTML table to a JSON object.
  var tableData = jsonTable.toJSON()

  // Create a jQuery event handler on the searchbox.
  $("#searchbox").on('input', function(e) {
    jsonTable.filter($(this).val())
  })
})



Example 3: Create a new HTML table directly from JSON data

// Build a JSON object array with items which are to be included in the table.
var jsonData = [{"ID":"1","Name":"User1"},{"ID":"2","Name":"User2"},{"ID":"3","Name":"User3"},{"ID":"4","Name":"Admin1"},{"ID":"5","Name":"Admin2"}]

// Create a new table inside the body tag
$("body").append("<table id='testTable'></table>")

// Spawn a new JSONTable object on the newly created table
var jsonTable = new JSONTable($("#testTable"))

// Create HTML table (data)structure from JSON data
jsonTable.fromJSON(jsonTest)  



You should definitely try these examples. Good luck!

Detect and monitor DOM changes with MutationObserver

 •  Filed under monitor, javascript, detect, dom changes, mutationobserver

The MutationObserver JavaScript API allows a developer to actively watch for DOM changes, so that if something gets changed, added or removed within the boundaries of the specified DOM node, a callback function will be triggered.

Browser support for this API is pretty good as well. All major modern browsers do support MutationObserver, but please note that IE10 and lower are not supported unless you use some sort of shim or polyfill for this.

Getting started is very easy as well:

// Step 1: Create a new MutationObserver object
var observer = new MutationObserver( function(mutations) { // this is the callback function } )

// Step 2: Observe a DOM node with the observer as callback
observer.observe(document.querySelector("table"), { attributes: true, childList: true, attributeOldValue: true })  



As an example I have built up a table to watch out for DOM changes:

<table id="demoTable" class="table">  
  <thead>
    <tr>ID</tr>
    <tr>E-mail</tr>
  </thead>

  <tbody>
    <tr>
      <td>1</td>
      <td>todd@localhost</td>
    </tr>
    <tr>
      <td>2</td>
      <td>ted@localhost</td>
    </tr>
    <tr>
      <td>3</td>
      <td>root@localhost</td>
    </tr>
    <tr>
      <td>4</td>
      <td>bart@localhost</td>
    </tr>
  </tbody>
</table>  



And here is the JavaScript code that goes with this:

var observer = new MutationObserver(function(mutation) {  
console.log(mutation)  
})

var observerConfig = {  
  attributes: true,
  childList: true,
  attributeOldValue: true,
  characterData: true
}

const tableRows = document.querySelectorAll("#appUsers tr")

for (i = 0; i < tableRows.length; i++)  
{
  observer.observe(tableRows[i], observerConfig);
}



Try to destroy, add or recreate td elements inside the table and you will get an array of MutationRecord objects returned within your browsers' console. Please note that when you edit the node's innerHTML, nothing will get triggered. I don't know if this is a bug in Safari (I only tested this in Safari, FYI) or something by design.

Using MySQL in Swift with Perfect

 •  Filed under swift, mysql, perfect

So I recently got a chance to play around with Perfect - a "web app framework" for Swift that provides you with multiple building blocks to get your project going. One of the really neat things about this framework is that it contains anything you need to get stuff connected. I came across their MySQL library that can be used in projects with or without the other Perfect dependencies involved. You can't get any more modular than this!


My development environment

I tend to always use Linux for my projects, and this little project is no exception. My dev box is equipped with the following stuff:

  • Ubuntu Server 16.04 LTS
  • MySQL Server
  • Swift 3.0.2

You also need to install the libmysqlclient-dev package through apt-get in order to use and build the Swift MySQL package.


Creating a new project

Create a new directory for this project on your server. I called mine mysql-app. Change your current directory to that directory and run swift package init --type executable to generate a blank Swift project. If you have a Mac and plan to use Xcode for your project: you can initialize an Xcode project file with swift package generate-xcodeproj


Adding Perfect-MySQL to the project

Edit your Package.swift file and include Perfect-MySQL as a dependency, like this:

import PackageDescription

let package = Package(  
    name: "mysql-app",
    dependencies: [
        .Package(url: "https://github.com/PerfectlySoft/Perfect-MySQL.git", majorVersion: 2)
    ]
)

Now it's time to write some code!


The database structure


The code

Just put the following code inside Sources/main.swift:

import MySQL

let sqlHost     = "127.0.0.1"  
let sqlUser     = "app_authentication"  
let sqlPassword = "testing01"  
let sqlDB       = "app_authentication"

func fetchData()  
{
    let mysql   = MySQL()
    guard mysql.connect(host: sqlHost, user: sqlUser, password: sqlPassword, db: sqlDB) else
    {
        print(mysql.errorMessage())
        return
    }

    defer {
        mysql.close()
    }

    let theStatement = MySQLStmt(mysql)

    _ = theStatement.prepare(statement: "SELECT * FROM users")
    _ = theStatement.execute()

    let theResults = theStatement.results()

    print("\r\n")

    _ = theResults.forEachRow {
        e in

        for i in 0..<e.count {
            let theFieldName = theStatement.fieldInfo(index: i)!.name
            print("\(theFieldName): \(e[i]!)")
        }

        print("\r\n")
    }
}

fetchData()  


Build and run

Just run swift build to build your project and run .build/debug/mysql-app to run your application. It should return this as the output in your terminal:


Extra information

I made this small tutorial after I had to fiddle around with this library for one whole day. The documentation suggests to use mysql.query to run queries, but there's too little information available about running prepared statements. Not only in the documentation of Perfect, but also on the whole web. Then - a couple hours later - I discovered the MySQLStmt class, after digging into the Swift Tests available on their Github repo.

Another reason to only use the MySQLStmt class is because the class contains a function called fieldInfo which returns the name of a column by ID. mysql.query simply doesn't have that...

Oh well, at least I got some of my code fixed today. Enjoy programming in Swift!

Controlling iTunes via Swift using SBApplication

 •  Filed under swift, itunes, sbapplication, scriptingbridge

Since I took my hands down on Swift, I discovered SBApplication, Apple's take on making scriptable calls to the applications you already have on your computer. Want to get a list of currently opened tabs in Safari, and each of their titles? No problem!

I used tingraldi's SwiftScripting repository to generate Swift headers for any application that is scriptable. The generated headers give you full access to all the available calls you can make to a scriptable application.

I came up with an idea that might be great for demoing the purposes of the SBApplication class: a simple command-line application that controls and/or fetches information from and to iTunes. I uploaded my code as a Github repository, it should work for any Intel-based Mac.

https://github.com/bmsimons/itunescli

The how-to-use and build guide can be found inside the readme file on my repository.

Interactive website tracking with NodeJS - Proof of Concept

 •  Filed under node.js, node, interactive, website, tracking

Interactive website tracking is the future! Why do you want to aggregate static data if you can make your data dynamic? This mindset motivated me to make a small interesting proof of concept to show off the capabilities of dynamic tracking.

The development stack

I decided to make my small app in JavaScript, both for the server and client. Data transfer had to be effective, modern and bandwidth-effective, so I chose websockets over legacy AJAX technology.

I used this bootstrap form as an example:

<form>  
    <div class="form-group">
        <label for="exampleInputEmail1">Email address</label>
        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
    </div>
    <div class="form-group">
        <label for="exampleInputPassword1">Password</label>
        <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
    </div>
    <div class="form-group">
        <label for="exampleInputFile">File input</label>
        <input type="file" id="exampleInputFile">
        <p class="help-block">Example block-level help text here.</p>
    </div>
    <div class="checkbox">
        <label>
        <input type="checkbox"> Check me out
        </label>
    </div>
    <button type="submit" class="btn btn-default">Submit</button>
</form>  

And the page has this client-side code:

$(document).ready(function()
{
    new Fingerprint2().get(function(result, components)
    {
        var sessionidentifier = "ID"+Date.now().toString()

        const socket = new WebSocket("ws://formstream:8080")

        var interval = 750

        var eventarray = []

        setInterval(function()
        {
            if (eventarray.length != 0)
            {
                socket.send(JSON.stringify(eventarray))
                eventarray = []
            }
        }, interval)

        $('form').on("click textInput", function(e)
        {
            var eventroot = {}
            eventroot['session'] = sessionidentifier
            eventroot['event'] = e.type
            eventroot['id'] = e.target.id
            eventroot['value'] = e.target.value
            eventroot['timestamp'] = Date.now()
            eventarray.push(eventroot)
        })
    })
})

As shown in the code sample above, I used fingerprintjs2 to create a unique browser identifier. This identifier can not be used as a personal identifier, but rather a unique anonymous identifier that matches your 'specific browser'. After a fingerprint has been generated, the script continues to run a continuous loop defined as an interval, which can be set to your desired value in a variable.

A UNIX epoch timestamp is generated for every event taking place, linked to that is every bit of event information that matters:

  • The event itself
  • The DOM object ID
  • The object's value

All this information is stored inside a JSON object. Once an event takes place, the JSON object gets pushed to the eventarray array.

Once the script reaches the end of an interval, the JSON objects stored in the eventarray get stringified and pushed to the websocket server but only in the case where there are more than 0 JSON objects available in the array, just to prevent the script from sending empty data on every interval.

The server application
var ws = require('nodejs-websocket')

var server = ws.createServer(function (conn)  
{
        console.log("NEW CONNECTION!")
        conn.on("text", function (str)
        {
                console.log(str)
        })
        conn.on("close", function (code, reason)
        {
                console.log("CONNECTION CLOSED.")
        })
}).listen(8080)

The server application is quite simple, it runs on NodeJS and only requires the nodejs-websocket dependency. No big deal, as it only functions as a console application that prints the received data from the client.

Server-sided console output

Remember that this is just a proof-of-concept that just captures form events. In reality you could capture any possible event and put it in a server side database. I hope that this article was informative enough for you, stay tuned for more 👍🏽