Monday, 27 May 2019

Server-sent event

Server sent event supports the server push from server to browser only.

In Javascript

var sse = null;

function runNow() {
    if (!sse) {
        sse = new EventSource('/sse_stream');

        sse.addEventListener('message',
            function (e) {
                document.getElementById('lbl1').innerText = e.data;
            });

    }
}

function stop() {
    if (sse) {
        sse.close();
        sse = null;
    }
}


Reference:

https://www.html5rocks.com/en/tutorials/eventsource/basics/
https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events

Web worker

Summary of web worker

  • Every web worker is a thread on it's own!! Instantiate too many worker instances might degrade your computer performance.
  • The worker will not be able to access the HTML page.
  • All data exchange/communication must be done through postMessage().
  • With web worker, the communication between the HTML/JS and the worker will be more complex.
  • Good thing is that process in the web worker won't affect the HTML page update/redraw.


The JavaScript to that create a web worker 

This script will be added to the HTML page like a normal JS file.

var w;
var lbl1;

function onStart() {
    if (w) {
        return;
    }

    w = new Worker('demo_worker.js');

    lbl1 = $('#lbl1');

    w.onmessage = function (e) {
        if (e.data.t == 'number') {
            lbl1.text('running value=' + e.data.i);
        }
        else {
            console.log(e.data)
        }
    }
}


function onStop() {
    if (w != null) {
        w.terminate();
        w = null;
    }
}

function onSayHelo() {
    if (w) {
        w.postMessage('helo from tab...' + (new Date()));
    }
}

The web worker Javascript file "demo_worker.js"

  • This file will run in it's own thread. 
  • All data exchange must be done through postMessage().
  • The worker is able to execute AJAX call.
  • The worker will not be able to access the HTML page.

var i = 0;

function timedCount() {
    i = i + 1;

    postMessage({
        t: 'number',
        i: '<b>'+ i + '</b>',
        ts: new Date()
    });

    setTimeout("timedCount()", 1000);   
}

function testAjax() {
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function (e) {
        if (xhr.readyState == 4 && xhr.status == 200) {
            // upon loaded succesfully, pass it to the HTML page.
            postMessage({
                t: 'data',
                data: xhr.response
            });
        }
    }

    xhr.open('get', 'test-data.txt');
    xhr.send();   
}

// message from the HTML page.
self.onmessage = function (e) {
    console.log('worker...', e.data)
}

timedCount();
setTimeout(testAjax, 3000)

Monday, 29 October 2018

Print the call stack in console

Here's the code in printing the call stack in console:

var stack = new Error().stack;   
console.log(stack);

Tuesday, 21 November 2017

CSS fill pattern

To create the fill pattern image, check out the following website:

     http://www.patternify.com/

/*dots*/

.inactive_cell2 {
    background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAEklEQVQImWNgYGD4z0AswK4SAFXuAf8EPy+xAAAAAElFTkSuQmCC");
    background-repeat: repeat;
}

To create strips without using any image data,

    https://css-tricks.com/stripes-css/

/*stripes*/
.inactive_cell {   
    background: repeating-linear-gradient( 48deg, #fefefe, #e0e0e1 5px, #eaeaea 5px, #eaeaea 10px );
}

Friday, 17 November 2017

Simple pie chart & doughnut chart with SVG + CSS

You can draw a simple pie chart & doughnut chart with SVG + CSS. This is quite simple and straight forward. But the limitation is that it is able to show 2 sections only.

To change the value of the section, look for stroke-dasharray and change the first value.

.pie2 {
        fill: yellow;
        stroke: green;

        /* max=50 (radius x 2) */
        stroke-width: 50;

        /* 158 = (radius x 2) x 3.142 = 25 x 2 x 3.142 */
        stroke-dasharray: 40 158;

    }
    .chart2 {
        background-color: yellow;
        border-radius: 50%;

        -webkit-transform: rotate(-90deg);
                transform: rotate(-90deg);
    }


    <svg width="100" height="100" class="chart2">    
        <circle r="25" cx="50" cy="50" class="pie2"/>  

    </svg>

To draw a doughnut chart,  

    .doghnut {
        fill: yellow;
        stroke: green;

        stroke-width: 20;
        stroke-dasharray: 180 251;

    }
    .doghnut_chart {
        background-color: yellow;
        border-radius: 50%;

        -webkit-transform: rotate(-90deg);
                transform: rotate(-90deg);
    }

    <svg width="100" height="100" class="doghnut_chart">    
        <circle r="40" cx="50" cy="50" class="doghnut"/>  
    </svg>

Wednesday, 15 November 2017

Javascript that prevents double click on submit button

This is what happening:
  • The user loves "double clicking" on any button even though single click will trigger the action.
  • The Internet connection slows down and the user thought that he did not click on the correct button. So, he decided to click it again even though the waiting time is lesser than 1 second (?!).
To solve this, you need the following JavaScript to ensure that the submit is working with single click only. Note: you may adjust the value of "500" (ms) to whatever value that you want.

var _prev_save_click_ts = null;

function beforeSubmit() {

    if (_prev_save_click_ts != null) {
        var ts = new Date();

        if (ts - _prev_save_click_ts < 500) {
            // user is double clicking.
            return false;
        }
    }

    _prev_save_click_ts = new Date();
    return true;
}

Thursday, 9 November 2017

Easiest way to search without using loop

If you have two sets of data and one set is referencing the other set, you will need to do a "double loop" to iterating through the data. But, there is a way to eliminate one loop and shorten the code.

For example, set 1 is the list of employees and set 2 is the list of working shift.

If you are using FOR loop, your codes will look similar to the following:

var employees = [];
employees.push({name: 'Mike', shift_id:'A'});
employees.push({name: 'Micky', shift_id:'B'});
employees.push({name: 'Mini', shift_id:'C'});

var shifts = [];
shifts.push({id: 'A', start_time: '08:00', end_time: '17:00'});
shifts.push({id: 'B', start_time: '09:00', end_time: '18:00'});

var s;

for (var i = 0; i < employees.length; i++) {
    s = null;

    // look for the shift:
    for (var j = 0; j < shifts.length; j++) {
         if (shifts[j].id == employees[i].shift_id) {
            s = shifts[j];
            break;
        }
    }

     if (s != null){
           console.log(employees[i].name, s.start_time);
     } else {
           console.log(employees[i].name, 'Cannot find the shift record');
     }
}

The JavaScript object is a key value collection:

   o = {};
   o['a'] = 'Apple';
   o['b'] = 'Banana';

And you can access the value:

   console.log(o['b']);

Below is the code that uses the key value collection to store the shift information and it will save us from writing one FOR loop.

var employees = [];
employees.push({name: 'Mike', shift_id:'A'});
employees.push({name: 'Micky', shift_id:'B'});
employees.push({name: 'Mini', shift_id:'C'});

var shifts = {};
shifts['A'] = {id: 'A', start_time: '08:00', end_time: '17:00'};
shifts['B'] = {id: 'B', start_time: '09:00', end_time: '18:00'};

var s;

for (var i = 0; i < employees.length; i++) {
    s = null;

    // look for the shift:
    if (shifts.hasOwnProperty(employees[i].shift_id)) {
            s = shifts[employees[i].shift_id];
           console.log(employees[i].name, s.start_time);
     } else {
           console.log(employees[i].name, 'Cannot find the shift record');
     }
}

We are moving

We are moving this blog to our new blog site: https://ciysys.com/blog/nodejs.htm