Javascript – Object watch (on all browsers)

Javascript’s object.watch is a function which tends to work only on Firefox.. How do we make it work on other browsers? Below is the code snippet to achieve this:-

 

Common JS Snippet for making object.watch to work on all browsers

if (!Object.prototype.watch) {
Object.defineProperty(Object.prototype, “watch”, {
enumerable: false
, configurable: true
, writable: false
, value: function (prop, handler) {
var
oldval = this[prop]
, newval = oldval
, getter = function () {
return newval;
}
, setter = function (val) {
oldval = newval;
return newval = handler.call(this, prop, oldval, val);
}
;

if (delete this[prop]) { // can’t watch constants
Object.defineProperty(this, prop, {
get: getter
, set: setter
, enumerable: true
, configurable: true
});
}
}
});
}

// object.unwatch
if (!Object.prototype.unwatch) {
Object.defineProperty(Object.prototype, “unwatch”, {
enumerable: false
, configurable: true
, writable: false
, value: function (prop) {
var val = this[prop];
delete this[prop]; // remove accessors
this[prop] = val;
}
});
}

 

Code Example:-

//Create an object and assign a initial value

var my_object = { blog_name:  “selvaonrails.wordpress.com” };

//Adding listener (watcher)

my_object.watch(‘blog_name‘, function (id, oldval, newval) {
console.log(‘my_object.’ + id + ‘ changed from ‘ + oldval + ‘ to ‘ + newval);
return newval;
});

Now changing the value of blog_name will print the console statement:-

my_object.blog_name=”SelvaOnRails”

Keyboard Shortcuts using JQuery

Again it is very simple, looks you to feel like a magician if you are done. Just follow the steps :-

Download the shortcut.js file and include it in your layout or view file

http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js

<%= javascript_include_tag ‘shortcut’ %>

Then, add the following lines in the layout or view file where you want the keyboard shortcut to work on

shortcut.add(“e”,function() {
        short_modal2(‘/chats’);
 },{‘disable_in_input’ : true});

disable_in_input: true will make sure the shortcut key ‘e’ won’t work when the user is on input field like textbox and textarea. Default is false.

shortcut.add(“Shift+T”,function() {
short_modal1(‘/tasks/new’);
}
);

For adding a shortcut which is already a shortcut key on a browser like ‘/’, ‘Ctrl + F’, ‘Ctrl + S’ etc…,

shortcut.add(“/”,function() {
    $(‘.keyboard-shortcuts’).css(‘display’,’none’);
 },{‘type’: ‘keydown’, ‘propagate’:false, ‘target’:document
,’keycode’ : 191,’disable_in_input’ : true});

The following are the valid keys (you can also make the combination of any two keys from below) :-

  • All alpha/numeric keys – abc…xyz,01..89
  • Special Characters – Every special character on a standard keyboard can be accessed.
  • Special Keys…
    • Tab
    • Space
    • Return
    • Enter
    • Backspace
    • Scroll_lock
    • Caps_lock
    • Num_lock
    • Pause
    • Insert
    • Home
    • Delete
    • End
    • Page_up
    • Page_down
    • Left
    • Up
    • Right
    • Down
    • F1
    • F2
    • F3
    • F4
    • F5
    • F6
    • F7
    • F8
    • F9
    • F10
    • F11
    • F12

That’s it. Rock the world…

Comparition of Adopting Unobstructive Javascript and XSS in Rails 2 & 3

Cross-Site-Scripting in Rails 2

<%= @post.body %> –> Unsafe
<%= h @post.body %> –> Safe

Cross-Site-Scripting in Rails 3

<%= @post.body %> –> Safe
<%= raw @post.body %> –> Unsafe

Adopting Unobstructive Javascript
Example 1 :

Rails 2:

<%= link_to_remote ‘Show’, :url => post %>

Will generate a HTML like,
“<a href=”#” onclick=”new Ajax.Request(‘/posts/1′, {asynchronous:true,
evalScripts:true, parameters:’authenticity_token=’ +
encodeURIComponent(‘9sk..44d’)}); return false;”>Show</a>”
Rails 3:

<%= link_to ‘Show’, post, :remote => true %>

Will generate a HTML like,
“<a href=”/posts/1″ data-remote=”true”>Show</a>”

Example 2 :

Rails 2:

<% remote_form_for(@post) do |f| %>

Will generate a HTML like,
“<form action=”/posts” id=”new_post” method=”post”
onsubmit=”new Ajax.Request(‘/posts’, {asynchronous:true,
evalScripts:true, parameters:Form.serialize(this)}); return false;”>”
Rails 3:

<% form_for(@post, :remote => true) do |f| %>

Will generate a HTML like,
“<form action=”/posts” data-remote=”true” id=”new_post” method=”post”>”

Example 3 :

Rails 2 & 3:

<%= link_to ‘Destroy’, post, :method => :delete %>

Will generate a HTML like this for Rails 2,
“<a href=”/posts/1″ onclick=”var f = document.createElement(‘form’); f.style.display = ‘none’;
this.parentNode.appendChild(f); f.method = ‘POST’; f.action = this.href;var m =
document.createElement(‘input’); m.setAttribute(‘type’, ‘hidden’); m.setAttribute(‘name’, ‘_method’);
m.setAttribute(‘value’, ‘delete’); f.appendChild(m);var s = document.createElement(‘input’);
s.setAttribute(‘type’, ‘hidden’); s.setAttribute(‘name’, ‘authenticity_token’); s.setAttribute(‘value’,
‘9skdJ0k+l9/q3PWToz6MtfyiB2gcyhnKubeGV6WFL44=’); f.appendChild(s);f.submit();return false;”>Destroy</a>”

And Will generate a HTML like this in Rails 3,
“<a href=”/posts/1″ data-method=”delete” rel=”nofollow”>Destroy</a>”

Example 4 :

Rails 2 & 3:

<%= link_to ‘Destroy’, post, :confirm => ‘Are you sure?’, :method => :delete %>

Will generate a HTML like this for Rails 2,
“<a href=”/posts/1″ onclick=”if (confirm(‘Are you sure?’)) { var f = document.createElement(‘form’);
f.style.display = ‘none’; this.parentNode.appendChild(f); f.method = ‘POST’; f.action = this.href;var m =
document.createElement(‘input’); m.setAttribute(‘type’, ‘hidden’); m.setAttribute(‘name’, ‘_method’);
m.setAttribute(‘value’, ‘delete’); f.appendChild(m);var s = document.createElement(‘input’);
s.setAttribute(‘type’, ‘hidden’); s.setAttribute(‘name’, ‘authenticity_token’); s.setAttribute(‘value’,
‘9skdJ0k+l9/q3PWToz6MtfyiB2gcyhnKubeGV6WFL44=’); f.appendChild(s);f.submit(); };return false;”>Destroy</a>”

And Will generate a HTML like this in Rails 3,
“<a href=”/posts/1″ data-confirm=”Are you sure?” data-method=”delete” rel=”nofollow”>Destroy</a>”

Example 5 :

Rails 2 :

<%= f.submit ‘Create Post’, :disable_with => “Please wait…” %>

Will generate a HTML like ,
“<input id=”post_submit” name=”commit” onclick=”if (window.hiddenCommit)
{ window.hiddenCommit.setAttribute(‘value’, this.value); }else { hiddenCommit =
document.createElement(‘input’);hiddenCommit.type = ‘hidden’;hiddenCommit.value =
this.value;hiddenCommit.name =
this.name;this.form.appendChild(hiddenCommit); }this.setAttribute(‘originalValue’,
this.value);this.disabled = true;this.value=’Please wait…’;result =
(this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) :
this.form.submit());if (result == false) { this.value =
this.getAttribute(‘originalValue’);this.disabled = false; }return result;” type=”submit”
value=”Create Post” />”

Rails 3 :

<%= f.submit :disable_with => “Please wait…” %>

Will generate a HTML like ,

“<input data-disable-with=”Please wait…”
id=”post_submit” name=”commit” type=”submit” value=”Create Post” />”

Drag & Drop Functionality for sorting a list on Ruby On Rails…

There is an easy way of implementing drag and drop sorting functionality in RoR with the help of ‘dragdrop.js’. Here is the steps :-

Consider i’m dealing with the movie application, and having a list of scenes(table named ‘scenes’) for a movie.

First gather the list of scenes in controller :- (scenes_controller.rb)

def list
@scenes=Scene.find :all
end

Note : For doing this sorting you need to have a field named ‘position’ in the appropriate table. for eg, here i have a ‘position'(integer type) field in ‘scenes’ table.

Include your drag and drop script file either in view file (list.html.erb) or in your layout
<%= javascript_include_tag ‘dragdrop.js’ %>

In view file :- (list.html.erb)

<% for scene in @scenes %>
<span>[drag]</span>
<%= scene.scene_title %><br /><br />
<% end %>
<%= sortable_element(“scenes”, :url => sort_scenes_path, :handle => “handle”) %>

Note : Here ‘scenes’ is the name of the params to be passed, and sort_scenes_path will go to the method named ‘sort’ on scenes_controller.rb

Back in controller :- (scenes_controller.rb)

def sort
params[:scenes].each_with_index do |id, index|
Scene.update_all([‘position=?’, index+1], [‘id=?’, id])
end
render :nothing => true
end

That’s it. You have done.

AssetPackager in rails

AssetPackager is nothing but a JavaScript and CSS Asset Compression for Production Rails Apps.

When it comes time to deploy your new web application, instead of sending down a dozen javascript and css files full of formatting and comments, this Rails plugin makes it simple to merge and compress JavaScript and CSS down into one or more files, increasing speed and saving bandwidth.

Step 1 – Install and download the plugin

script/plugin install git://github.com/sbecker/asset_packager.git

Step 2 – Create asset_packages.yml file

rake asset:packager:create_yml

Now the file will be generated under the /config for the first time. You will need to reorder files under ‘base’ so dependencies are loaded in correct order. Feel free to rename or create new packages.

Step 3 – Run the below command to generate the compressed, merged versions for each package

rake asset:packager:build_all

Whenever you rearrange the yaml file, you’ll need to run this task again.

EXAMPLE :-

Javascript Examples:

Example calls

  • either by package name:
  <%= javascript_include_merged :base %>
  • or by the individual assets:
  <%= javascript_include_merged 'prototype', 'effects', 'controls', 'dragdrop', 'application' %>

Output in development:

  <script type="text/javascript" src="/javascripts/prototype.js"></script>
  <script type="text/javascript" src="/javascripts/effects.js"></script>
  <script type="text/javascript" src="/javascripts/controls.js"></script>
  <script type="text/javascript" src="/javascripts/dragdrop.js"></script>
  <script type="text/javascript" src="/javascripts/application.js"></script>

Output in production:

  <script type="text/javascript" src="/javascripts/base_packaged.js?123456789"></script>

Symbols work too, as does :defaults

  <%= javascript_include_merged :defaults %>
  <%= javascript_include_merged :foo, :bar %>

Stylesheet Examples

Example call:

  • either by package name:
  <%= stylesheet_link_merged :base %>
  • or by the individual assets:
  <%= stylesheet_link_merged 'screen', 'header' %>

Output in development:

  <link href="/stylesheets/screen.css" media="screen" rel="Stylesheet" type="text/css" />
  <link href="/stylesheets/header.css" media="screen" rel="Stylesheet" type="text/css" />

Output in production:

  <link href="/stylesheets/base_packaged.css?123456789" media="screen" rel="Stylesheet" type="text/css" />

Handling Keyboard Shortcuts in Rails or HTML

Handling keyboard shortcuts in a Rails app, HTML using javascript is pretty simple.

Just download a shortcut.js from the following URL :

http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js

Rails :-

Paste the file in the /public/javascripts folder

Write the following code in your view / layout file before <body> tag.

<head>
<script src=”/javascripts/shortcut.js” type=”text/javascript”></script>
<script type=”text/javascript”>
shortcut.add(“Ctrl+Shift+X”,function() {alert(“You Pressed Ctrl+Shift+X!”);});
shortcut.add(“Ctrl+a”,function() {alert(“You pressed Ctrl+a!”);});
shortcut.add(“D”,function() {alert(“You Pressed D!”);});
</script>
</head>

Note : Displaying an alert message is not just the action for this concept. Instead of alert message, we can write any javascript function to execute some action or even we make pass it to controller through AXAJ request. (refer :- https://selvaonrails.wordpress.com/2010/08/31/making-a-ajax-request-from-rails/)