Friday, 13 September 2019

Vertical scrollbar causing column width different between header and cell in spreadsheet

Vertical scrollbar causing column width different between header and cell in spreadsheet. This is a common issue when the HTML page that display on a computer. Whereas, it won't have issue if it is on Android or iOS because the scrollbar is floating on top of the content.

To explain this issue, let says we have a spreadsheet (or "table" view) built with DIV which looks like below:

<style>
.header {
  display:flex;
  flex-direction:row;
}

.item {
  display:flex;
  flex-direction:row;
}

.c1 {
  width:50%;
}

.item-list {
  overflow: hidden;
  overflow-y: scroll;
  height: 80px;
}
</style>

<div class="my-table">

<div class="header">
  <div class="c1">Date</div>
  <div class="c1">Ref #</div> 
</div> 
<div class="item-list">
  <div class="item">
    <div class="c1">1 Sep 2019</div>
    <div class="c1">0001</div> 
  </div>
  <div class="item">
    <div class="c1">1 Sep 2019</div>
    <div class="c1">0002</div> 
  </div>
  <div class="item">
    <div class="c1">1 Sep 2019</div>
    <div class="c1">0003</div> 
  </div>
  <div class="item">
    <div class="c1">1 Sep 2019</div>
    <div class="c1">0004</div>
  </div>
  <div class="item">
    <div class="c1">1 Sep 2019</div>
    <div class="c1">0005</div>
  </div>
</div>
</div>


With the CSS for item-list, a vertical scrollbar will appear once the number of items increased.

The problem with this CSS is that the date and reference number column in the header will have a different width if you compared it with the column in the items.

To solve this, you need to use this style:

(1) you have to use "sticky:

.header{
  position: sticky;
  top: 0;
  left: 0;
  background-color: white;
}

(2) Move the overflow attribute for "item-list" to "my-table":

.my-table {
  position:relative;
  overflow: hidden;
  overflow-y: scroll;
  height: 80px;
}

And that solves the column width issue when there is a vertical scrollbar.


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)

We are moving

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