Just another site

Category Archives: JavaScript

Javascript drawing on an image inside a canvas

I just finished a task: load an image inside a popup canvas then draw lines on the canvas and save the image data. I had a couple issues during the development, but luckily I managed to find answers on google.

  1. How to draw on canvas on mobile devices.
    I found a good article which give all the details Using Touch Events with the HTML5 Canvas.  You should be aware of the difference code for IOS,Android and canvas in browser. The touch devices use “touchmove”,”touchstart” while the browswer uses “mousemove”,”mousedown”..etc
  2. We need to stop page scrolling when user are ready for drawing.
    stopScroll = (ev) ->
    $page.on("popupbeforeposition","#popupPanel", (event,ui) ->
    $page.on("popupafterclose","#popupPanel",(event,ui) ->
  3. How to improve image quality.
    When loading the photo to canvas, you may get a blurry image. The following code improve the quality of image

    canvastx = popupCanvas.getContext("2d");
    canvastx.webkitImageSmoothingEnabled = false;
    canvastx.mozImageSmoothingEnabled = false;
    canvastx.imageSmoothingEnabled = false;
  4. Don’t resize canvas, you should always create new one.
    Make sure you create new canvas after reading the image info. This way you know the image demision, then you could create new canvas with the same width/height ratio.  If you draw on a resized canvas,  everything(x,y point) on that canvas will be scaled.  You will have to do some calculation to get the orginal point. That’s why I prefer creating a new canvas with the right size.

JQuery notes

  1. How to add listener for html content loaded by ajax call?

    Bind on a non-dynamic parent container using .on()

    $('.some-parent-class').on('click', '.element', function() {
      // DO STUFF!
  2. AddClass function

      AddClass function always check exisitng classes before adding new one, so we don’t need to check duplicate classes

     3. Find function

       The .find() and .children() methods are similar, except that the latter only travels a single level down the DOM tree

     4. text() and textarea

       The .text() method cannot be used on form inputs or scripts. To set or get the text value of input or textarea elements, use the .val() method

      5. checkbox and prop

$('.myCheckbox').prop('checked', true);
$('.myCheckbox').prop('checked', false);

      6. toggle

Quick way to switch show/hide, checked/unchecked state

$('#checkBoxId').click(function() {

       7. event.preventDefault()

Cancel the default action (navigation) of the click, this is used when we only want to trigger a js function but don’t want the page navagation.


access javascript object property using variable

I want to assign data to a js object as a property, but the new property name is dynamic.

The bracket notation should be used here:

var apiDynamicString = "dynamicStringFromOtherFunction";

var apiDynamicData ="somedata...";[apiDynamicString] = apiDynamicData ;

Then you can access the property this way:


OR (if you know the variable value)


javascript onclick event not working in chrome

The onclick event for select option is not triggered in chrome. We need to fire the onchange event on the select component.

<select class="select-one-group-select">
 <option class="select-one-group-option" value="option1">option 1</option>
 <option class="select-one-group-option"  value="option2">option 2</option>
 <option class="select-one-group-option"  value="option3">option 3</option>

This doesn’t work:

	$(".select-one-group-option").click(function() {


This solve the problem:

	$(".select-one-group-select").change(function() {

Read photo taken date from image

For Java, I use metadata-extractor:

Metadata metadata = ImageMetadataReader.readMetadata( item.getInputStream());
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
if(date != null){

For front end, I use exif-js:

window.resolveLocalFileSystemURL(attachmentInfo.fileSource, (fileEntry) ->
                fileEntry.file((file) ->
                    EXIF.getData(file, ->
                        galleryPhotoTakenDate = EXIF.getTag(this,"DateTimeOriginal");
                        cameraPhotoTakenDate = this.lastModifiedDate;

                        if photoFromCamera
                            if typeof cameraPhotoTakenDate != 'undefined'
                                #photo taken from camera
                                attachmentInfo.photoTakenDate = moment(cameraPhotoTakenDate).format("YYYY:MM:DD HH:mm:SS")
                            if typeof galleryPhotoTakenDate != 'undefined'
                                #photo taken from gallery
                                attachmentInfo.photoTakenDate = galleryPhotoTakenDate 

debug JQuery script loaded by getscript function

When loading js function with JQuery getScript function, we can’t debug it becuase it’s not in DOM. The following js function add the loaded js function into DOM and solve the problem.

var loadScript = function (path) {
    var result = $.Deferred(),
        script = document.createElement("script");
    script.async = "async";
    script.type = "text/javascript";
    script.src = path;
    script.onload = script.onreadystatechange = function(_, isAbort) {
        if (!script.readyState || /loaded|complete/.test(script.readyState)) {
            if (isAbort)
    script.onerror = function () { result.reject(); };
    return result.promise();

ref from :

Multiple Canvas only draw the last one

I have five canvas on the page, The following code is supposed to read the image data from hidden input field and draw image to the correspoding canvas. but it only draw the last one.

$('.signatureField').each(function() {					   
		canvas = $(this).children('canvas').get(0);
		ctx = canvas.getContext('2d');
		testImage = new Image();


Adding “var” to ctx solves the problem.What that does is to declare ctx as local variable in each loop, so they don’t share the same convas context.

$('.signatureField').each(function() {					   
		var canvas = $(this).children('canvas').get(0);
		var ctx = canvas.getContext('2d');
		var testImage = new Image();


Then I have the following code in CoffeeScript, unfortunately, it only draw the last canvas. Here I use apostrophe to declare canvas context as local variable. Also added an empty return at the end of the function to avoid CoffeeScript implicit return.

checklist.loadExistingSignature = (fields) ->
    for field in fields
        if field.type='signature' and field.value.length>0
            `var fieldCanvas = $('#' +`
            `var canvastx = fieldCanvas.getContext('2d')`
            `var testImage = new Image()`
            testImage.onload = ->
            testImage.src = "data:image/png;base64," + field.value;

To solve this problem, we need to add a javascript closure. In CoffeeScript , it’s the do function

checklist.loadExistingSignature = (fields) ->
    for field in fields
        if field.type='signature' and field.value.length>0
            `var fieldCanvas = $('#' +`
            `var canvastx = fieldCanvas.getContext('2d')`
            `var testImage = new Image()`
            do (canvastx, testImage) ->
            	testImage.onload = ->
            testImage.src = "data:image/png;base64," + field.value;

And the javascript version:

for (var i = 1; i < 5; i++) {
    var ctx = document.getElementById('canvas-' + i).getContext('2d'),
        image = new Image();
    (function(ctx, image) {
        image.onload = function() {
            ctx.drawImage(image, 0, 0);
        image.src = images[(i - 1)];
    })(ctx, image);

ref for javascript closure in loop:

JSF execute javascript after ajax call

To Execute js script after the f:ajax call

<h:selectOneMenu id="checklist" value="#{checklistReportAction.checklist}" required="true">
      <s:selectItems value="#{checklistReportAction.checklists}" var="_checklist"
        label="#{}" noSelectionLabel="Select Checklist..."/>
        <s:convertEntity />							 	
	<f:ajax  render="filterPanel checklistFieldPanel" listener="#{checklistReportAction.selectListener}" event="change" execute="@this" onevent="showCheckBox"/>

The above code will call showCheckbox function after user change value for the dropdown list

CDATA and javascript

&& are not valid characters in XML so they are also not valid for Facelets as well.
Use script in CDATA to get full javascript support in Facelets . CDATA is used like this :


function check(){
if (isCondition1 &&  !isCondition2){
alert(“Please input a valid number!”)

WebRemote and Seam

Step 1: add webremote annotation for the specific method in local interface

public interface ProspectController extends StatefulController {

public String createNewProspect();


Step 2:  create the javascript function

function showProspectPopUp(modelPanel,id){
Seam.Remoting.getContext().setConversationId(id);   //this is important: make sure the remote call is in the same conversation

Step 3:  in jsf page, add the following:

<ui:define name=”js”>
<s:remote include=”prospectController”/>
<onepl:javascript src=”/js/main.js” cachebusting=”true”/>   //where the javascript function locates

<h:outputLink onclick=”showProspectPopUp(‘prospPanel’,#{});return false;”  value=””>test </h:outputLink>