Reset hidden fields in HTML form using Javascript

As normal, the clear button is intended for clearing user input, and since hidden inputs are not directly accessible by the user, it doesn’t make sense to allow the user to reset the hidden input’s value. So, the clear form action remains the hidden input values if it varies.

But, in some rare cases, we still need to reset the value of those hidden fields.

Below is several methods I thought of.

1. Cache hidden fields to a safe place

I created a supporter module to support us caching the hidden fields in a form. This requires jQuery to work.

var hiddenResetSupporter = (function() {
    var _form;
    var _initForm = function(formSelector) {
        _form = $(formSelector);
    };
    var _fallbackHiddenFieldsWithTextbox = function() {
        _form.find('input[type=hidden]').each(function() {
            var fallbackTextbox = $('<input>')
                .prop('type', 'hidden')
                .prop('id', 'fallback_textbox_' + $(this).prop('name'))
                .val($(this).val());

            _form.after(fallbackTextbox);
        });
    };

    return {
        setup: function(formSelector) {
            _initForm(formSelector);
            _fallbackHiddenFieldsWithTextbox();
        },
        registerResetEvent: function(callback) {
            var resetPerformElement = _form.find('[type=reset]');
            if (resetPerformElement === undefined) return;

            resetPerformElement.click(function(e) {
                _form.trigger('reset');
                hiddenResetSupporter.resetHiddenFields();
                if (callback) callback();

                e.preventDefault();
            });
        },
        resetHiddenFields: function() {
            _form.find('input[type=hidden]').each(function() {
                $(this).val($('#fallback_textbox_' + $(this).prop('name')).val());
            });
        }
    }
})();

For using example, I created a jsfiddle: https://jsfiddle.net/ducfilan/dbptztsd/

2. Serialize hidden fields to sessionStorage and restore them back in time

Because sessionStorage are widely supported in almost all browsers (for example, even the fastidious bad boy IE supports it in IE versions from 8), you can have a reference here.

So in common situations, you can use sessionStorage as an option here. This is a link to know how it works.

Below is a simple module I created to illustrate how it is done, it still contains several problems of the serialization process.

var hiddenFieldSerializer = (function(){
	var _form;
	var _serializedData;
	var _keyName;

	return {
		setup: function(formSelector, keyName){
			_form = $(formSelector);
			_keyName = keyName;
			_serializedData = [];
		},
		serialize: function(keyName){
			_form.find("input[type='hidden']").each(function() {
				if ($(this).attr('name') ) {
					_serializedData.push($(this).attr('name') + ':' + $(this).val());
				}
			});
			sessionStorage.setItem(_keyName, _serializedData.join());
			return true;
		},
		deserialize: function(){
            if (!sessionStorage.getItem(_keyName)) return;

            var formData = sessionStorage.getItem(_keyName).split(',');

            $.each(formData, function(i, item) {
                var s = item.split(':');
                var elem = _form.find('[name="' + s[0] + '"]');
				elem.val(s[1]);
            });

			return true;
        }
	}
})();

So, you can refer above 2 approaches or what you think of when you need to reset hidden fields in a form.

How to access the web server in VMWare Fusion on its host machine

Currently, I am in a team developing a web application that supports IEs. My development environment runs under Centos.

Some UI problems appear on IE but not other browsers. This situation leads me to be in need of reproducing those problems on my development environment to confirm if my issues are fixed. I tried to install IE on Centos using Wine, but it doesn’t work properly.

So, I think if I could access the web server on the virtual machine in its host?

Below steps are what I did to make it works.

1. Set the Virtual Machine’s Network Adapter to Bridged:

2017-05-22_171609

2. Get the IP V4 of the virtual machine using the below command in Terminal:

ifconfig
eth1 Link encap:Ethernet HWaddr 00:0C:29:11:C1:E8 
inet addr:192.168.0.178 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe11:c1e8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:536823 errors:0 dropped:0 overruns:0 frame:0
TX packets:241377 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000 
RX bytes:537011299 (512.1 MiB) TX bytes:27427710 (26.1 MiB)

Now you can browse your VM’s localhost outside of the virtual machine (your host machine) by replacing “localhost” by “192.168.0.178“.

Absolute position table with padding

Today, I have a task of widening the tables to match 100% browser width to view more contents while keeping other elements stay the as they were.

pjimage

The problem is, I have so many tables to do (about 20 pages including that kind of table). I am too lazy to edit all of those pages. It really takes time and potential to introduce bugs.

So, I choose javascript and CSS to help me out.

Firstly, those tables have the class named “table_wide”.

We will use the CSS absolute position’s power of ignorance. We can make the table to be absolute with 100% percent width. But the problem is, it also ignores padding or margin. So our table will be stuck to the left and right edges.

Well, challenge accepted.

Absolute position ignores everything but it has top, right, bottom and left instead. However, top, right, bottom and left are not adapted to its width. So we cannot use padding properly.

We will use what we have to acquire what we want.


$(".table_wide").each(function(){
var paddingInPx = 10;
var windowWidthInPx = $(window).width();

// Calculate the width of table.
var thisWidthInPercent = 100 - (100/windowWidthInPx*2*paddingInPx);

// Create an empty div to fill up the space the absolute table occupied in the past.
$(this).after('<div style="height: ' + this.offsetHeight + 'px;"></div>');
$(this).wrap('<div style="position: absolute; width: ' + thisWidthInPercent + '%; left: ' + paddingInPx + 'px"></div>');
});

.table_wide {
    display: block;
    overflow: auto;
}

Well done! Challenge accomplished.

Jsfiddle: https://jsfiddle.net/ducfilan/p961moLd/

How to debug/inspect your mobile web page on a real mobile device (with or without real device)

When developing web apps for with mobile support, we usually use Device toolbar (Ctrl + Shift + M) on Google Chrome Developer Tools. But, the problem is that sometimes our layout or javascript code work on Device toolbar but not a real device and there is no dev tool on mobile browsers.

Luckily, Chrome Developer Tools provides us a really useful tool to debug our web page on a real android device on our desktop totally like what we do on desktop web pages.

Installation and interacting with Remote debugging are described here.

In case you don’t have an Android device in hand. You could use an Emulator. It works perfectly with me.

I use Genymotion, it’s really fast and stable.

You can use any mobile browser and be able to debug your web pages on that browser.

You can install browsers to the Genymotion Emulator by drag and drop your .apk file to the emulator screen.

Or you can install Google Play Store and get them downloaded just like a normal device.

The processes are described here.

Goodluck!

How to deploy your hubot to Heroku and why your bot is not working after deploying

After completing the development of my Hubot, I decided to deploy it to Heroku.

I followed the tutorial on Github’s Hubot guideline as here.

For, short:

$ cd [path-to-your-hubot-folder]
$ heroku login

# Setup git (if not yet).
$ git init
$ git add .
$ git commit -m "Initial commit"

# Create a new heroku application.
$ heroku create

# Push to heroku master.
$ git push heroku master

# Set Slack token for heroku (Can be found at
# https://[your-slack-channel].slack.com/home 
# and under your Hubot app config).
$ heroku config:set HUBOT_SLACK_TOKEN=[xoxb-YOUR-TOKEN]

# Set heroku keep alive url (To keep your bot active).
$ heroku config:set HUBOT_HEROKU_KEEPALIVE_URL=$(heroku apps:info -s  | grep web-url | cut -d= -f2)

But my bot is not working at all, it keeps sleeping on the new Heroku’s bed and not responded to any of my commands.

I checked the build log on Heroku dashboard, it shows a lot of node modules are lack.

I viewed the .git_ignore file and its content:

node_modules
.DS_Store*
.hubot_history

So entire node_modules is ignored during commit and pushing to Heroku. So I think that it’s the reason why my bot is not working after deploying.

I forced to add the folder with -f parameter in git add command (or you can just remove the line in .git_ignore folder), then commit and push again to Heroku.

And finally… the monster awakens.

How to debug Github’s Hubot script?

First of all, Hubot is a complete Node.js application itself. And for Node.js applications in general, node-inspector is a celebrity out there as a debugger based on Blink Developer Tools.

If you did not install node-inspector yet, install it as a global package and under root.

$sudo npm install -g node-inspector

Wait for a few seconds till the installation process is done.

Inside your hubot project folder, start the debugger:

$node-inspector --no-preload --web-port 8123

When the following message appears, it means that our debug session is ready.

Node Inspector v1.0.0
Visit http://127.0.0.1:8123/?port=5858 to start debugging.

Now we need to start our bot, in a different way than the old ‘bin/hubot’ command and remember to put your bot name corresponding to your application:

$coffee --nodejs --debug node_modules/.bin/hubot --name "[your_bot_name]"

And to set a breakpoint, put debugger to any line of your code, like:

2017-04-04_174110

In Chrome, visit http://127.0.0.1:8123/?port=5858 to start your debugging session, debug like any of your web applications.

 

zsh cannot execute global npm packages

Today, I installed a npm package globally, no problem here.

Screen Shot 2017-03-11 at 2.01.37 PM.png

But, when I execute the package, there comes an error:

~  yo
zsh: command not found: yo

So, it means that the system doesn’t reallize the path to my package. I confirm by using:

~/W/C/htnmaruko  echo $PATH
/Users/duchoang/.rbenv/shims:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

So that, we need to export the path to where my package is lying in.

Because I installed by -g parameter, so it is lying in global npm. In my case it is being in ~/.npm-global.

Steps:

1. Export your path in ~/.zshrc (in case of using zsh, otherwise using ~/.bashrc) by  print it to your ~/.zshrc or ~/.bashrc file:

~/.n/bin  printf "\nexport PATH=\"\$PATH\":%s\n" ~/.npm-global/bin >> ~/.zshrc

Or just editing with nano:

~  nano /Users/duchoang/.zshrc

2. Now, fire up the changes:

~  . ~/.zshrc

3. And finally, the problem gets solved, the result we have:

Screen Shot 2017-03-11 at 2.03.28 PM

Now we can get back to our work.

The git error: “gpg failed to sign the data”

Today, I need to commit some pieces of stuff to my GitHub repository, but somehow this error comes I don’t know.

It’s really painful.

error: gpg failed to sign the data
fatal: failed to write commit object

After some researches on Google, I know that Github has implemented something called GPG to sign and verify work from trusted collaborators, using public-secret key mechanism. (refer: https://help.github.com/articles/signing-commits-with-gpg/)

My below guide is used on MacOS. For other platforms, please refer this link for Windows and this link for Linux.

So, to solve the problem, I have to config gpg to be able to sign commits. Note that from now, I will use brew to manage my installations. To know more about brew, you could find so much information on Google or its homepage: https://brew.sh

1. We need pinentry to read passphrases and PIN numbers in a secure manner. (For more information: https://www.gnupg.org/related_software/pinentry/index.en.html)

~/W/G/TalentHub-solutions brew install pinentry-mac

2. We need gpg of course, I use gpg2

~/W/G/TalentHub-solutions ❯ brew install gpg2

3. Now we are ready to generate our secret key, I chose all by default.

~/W/G/TalentHub-solutions  gpg2 --gen-key

Screen Shot 2017-03-10 at 10.35.20 PM

4. Once you have a private key to sign with, you can configure Git to use it for signing things by setting the user.signingkey config setting.

4.1. Get your secret key:

~/W/G/TalentHub-solutions  gpg2 --list-secret-keys

You will see something like:

Screen Shot 2017-03-10 at 10.40.35 PM

Then, B069A034 is your secret key.

4.2. Config your signing key:

~/W/G/TalentHub-solutions  git config --global user.signingkey B069A034
~/W/G/TalentHub-solutions  git config --global gpg.program $(which gpg2)
~/W/G/TalentHub-solutions  git config --global commit.gpgsign true
~/W/G/TalentHub-solutions ❯❯❯ echo "no-tty" >> ~/.gnupg/gpg.conf

5. Point out the pinentry program to gpg-agent.conf:

~/W/G/TalentHub-solutions  touch  ~/.gnupg/gpg-agent.conf
~/W/G/TalentHub-solutions  echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf

Now you will be able to commit to your git repository.

An example of how Excel can boost your coding productivity

During my working time in software companies, there are ton of cases which the support of Excel helps alot.
Today for an example.

I have to add rules to validate many fields with the similar name like below:

  • open1post
  • open1person
  • open2corp
  • open2post
  • open2person
  • open3corp
  • …and so on…

I need to create some code lines like below:

  • $val->add(‘open1corp’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open1post’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open1person’, $multi_lang_items[‘lbl’][23])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2corp’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2post’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open2person’, $multi_lang_items[‘lbl’][24])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • $val->add(‘open3corp’, $multi_lang_items[‘lbl’][25])
    ->add_rule(‘match_pattern’, ‘/^[0-9]*$/’);
  • …and so on…

So, in excel:

  1. First column, I store a list of fields, name it “Form control name”.
  2. Because, a label is provided to 3 fields, for example: “open1corp”, “open1post”, “open1person” use the same lbl 23.

So that, we have to calculate the same number for each open[x][post_fix]. In order to achieve that, I used the magic of mod like below formula.

Note that, 19 is the row number of the first open[x][post_fix] item.

=CONCATENATE("$val->add('",[@[Form control name]],"', $multi_lang_items['lbl'][",ROW()-MOD(ROW()-1,3)+4-2*(FLOOR.MATH((ROW()-19)/3)),"])
 ->add_rule('match_pattern', '/^[0-9]*$/');")

And the result we get:
Excel productivity
That’s it, now we can copy those code to our IDE.

How to auto compile sass/scss files in Eclipse

First of all, sass/scss compilation needs Ruby to work with.

So, ok, we will install it.

But, we need to use system wide Ruby, ’cause I tried with rvm but there comes some problems:

/usr/bin/env: ruby_executable_hooks: No such file or directory

So if you use rvm, switch it back to:

rvm use system

Now go to:

https://www.ruby-lang.org/en/documentation/installation/

Then to make sure that Ruby is successfully installed:

ruby -v

It should have some information like:

[ducfilan@localhost]$ ruby -v
 ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-linux]

Now come to sass:

gem install sass
# su in case of permission errors

Once again to make sure:

sass -v

Some information like this means we’ve successfully installed it:

[ducfilan@localhost]$ sass -v
Sass 3.4.23 (Selective Steve)

Ok, preparation is done. Open your project in Eclipse.

Right click on it > Properties > Builder > New > Choose ‘Program’ then Ok.

2017-01-25_140725

We need to fill out some fields:

  1. Location
    • Get the location of sass using:
      • which sass
  1. Working Directory
    • Relative path to your folder, with ${workspace_loc:/…} as root. Use Browse workspace to make it ez.
  2. Arguments
    • --update ${workspace_loc:/QTEC-Web/public/sass}:${workspace_loc:/QTEC-Web/public/css} --sourcemap=none --style compressed
    • With:
      • –update: Means compiling when your sass file is changed.
      • ${workspace_loc:/QTEC-Web/public/sass}: Your sass folder
      • ${workspace_loc:/QTEC-Web/public/css}: Your output folder
      • –sourcemap=none: No generating .map file
      • –style compressed: Output style

For example in my case:

2017-01-25_141341.png

After that, don’t close the configuration screen.

Switch to Build options tab and check only following files, uncheck all others if they are pre-checked.

  1. Allocate Console
  2. During auto builds

Now you’re done, edit an .scss file and you will see the message of writing .css file in the output screen. If not, you’re doing it wrong.