Svelte: using jQuery plugin with Action API


You may have used jQuery in your projects before, however, with the advancements in Frontend frameworks, we are sort of forced to forget about the vast ecosystem of jQuery and its plugins. And the main reason is that your framework of choice is not compatible with jQuery or does not have a jQuery friendly API out of the box. So we either look for an alternative library that is written from scratch or a wrapper library on top of jQuery/Javascript plugin written in your framework of choice. However, Svelte is a different beast and it has something called Action API that lets you use/consume jQuery/Javascript plugin without much framework-related overhead.

I had tweeted my wild prediction last time which what I have show-cased in this tutorial video.

You can watch the video belowūüĎá to see it in action or grab the source code from Github.

Advertisement

Writing your first application using Backbone.js


Getting Started

As we know, writing a Single Page application using just jQuery is not quite a good idea especially when our application grows bigger and we need to modularize our codebase. To resolve this problem, there are many MV* frameworks available for us.

What is Backbone.js

Backbone.js is one of the many Javascript frameworks for creating MVC-like web applications which comes with a default template engine Underscore.js. Backbone.js lets us split our code into Model, Collection and View. The general idea is to organize an interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page.

On the front-end, it’s my architectural framework of choice as it’s both mature, relatively lightweight and can be easily tested using third-party toolkits such as Jasmine or QUnit.
– Developing Backbone.js Applications by Addy Osmani.

What is MVC

In this case, each contact is our Model, all the contacts group together by Collection and View renders the contacts details. We are going to use contacts mysql table for this application so contacts table is our Collection and each row exists in the table is our Model.

Let us begin

Let’s start by writing our first Backbone.js app – Addressbook in Backbone.js. Here is our 2-column layout, one for side links on the left and another to load forms/grid.

addressbookMVC/index.html – Main Layout

<div class='table abWrapper'>
  <div class='row'>
    <div class='cell abLinks'>
      <a href='#add_new_contact'>Add New Contact</a><br />
      <a href='#list_contacts'>List all Contacts</a><br />
      <a href='#search_contacts'>Search any Contact</a><br />
    </div>
    <div class='cell abPanel'>Loading... Please Wait.</div>
  </div>
</div>

Add New Contact – Backbone.View and Backbone.Model

We’ll write our first view addView¬†and load it inside div.abPanel. We can write our custom view by extending¬†Backbone.View.extend()¬†method and¬†can keep our templates either into a same page or can¬†load it from a separate html file. In this case, we’ll simply wrap our template in <script>¬†tag by giving it a special type and an id:

addressbookMVC/index.html – addNewContact Template


  <h2> Add New Contact</h2>
  
    <div>Full Name:</div>  <span class='false full_name_error'></span><br />
    <div>Email Id:</div>  <span class='false email_error'></span><br />
    <div>Phone:</div>  <span class='false phone_error'></span><br />
    <div>Address:</div> 
    
    <span class='success'></span>
    
  

Backbone View allows us to specify custom methods and properties but there are some predefined attributes you should use to simplify the flow and maintain the unity between all backbone apps.
el – specify the DOM element selector where you want to load your template within a page. In our case its div.abPanel.
template РThe _.template method in Underscore compiles JavaScript template into function which can be evaluated for rendering.
initialize – The constructor to keep a piece of code to be executed while creating an instance of a view.

Below is our AB.addView backbone view which compiles the template mentioned above  and load it into el. 

addressbookMVC/js/script.js – addNewContact View

AB.addView = Backbone.View.extend({
  el: 'div.abPanel',
  template: _.template($('#addContactTemplate').html()),
  initialize: function () {
    _.bindAll(this, 'addContactPage');
  },
  addContactPage: function () {
    this.$el.html(this.template());
  }
});

In above code, we have used the _.bindAll method in Underscore which fixes the loss of context for this within methods. So we have to specify all those method names wherein we’ll use this.any_method or this.any_property i.e. this.$el, this.template etc.

In backbone.js, there is no need to grab elements the jquery way and attach some events to them. There is a special attribute events¬†which allows us to attach event listeners to either custom selectors or directly to el¬†if no selector is provided. It takes the form¬†{‘eventName selector’ : ‘callbackMethod’},¬†So¬†we can attach the submit event to our <form> in order to prevent the default form submission and fetch the form data. And once we get the data, we can simply call model.save() method to save the record into the DB which invokes Backbone.sync function every time we attempt to read or save a model to the server by making a RESTful JSON request.

Lets write our contactModel first. Notice that if a passed JSON data to model.save() contains an id key then a method name will be update in model.sync() else it will be create.

addressbookMVC/js/script.js – Contact Model

AB.contactModel = Backbone.Model.extend({
  sync: function (method, model, options) {
    if (method === 'create' || method === 'update') {
      return $.ajax({
        dataType: 'json',
        url: '../php/addNewContact.php',
        data: {
          id: (this.get('id') || ''),
          full_name: (this.get('full_name') || ''),
          email: (this.get('email') || ''),
          phone: (this.get('phone') || ''),
          address: (this.get('address') || '')
        },
        success: function (data) {
          // put your code after the contact is saved/updated.
        }
      });
    }
  }
});

Now we’ll create an instance of above model in our view and call the save() method.

addressbookMVC/js/script.js – addNewContact View

AB.addView = Backbone.View.extend({
  events: {
    'submit form#frmAddContact': 'addContact'
  },
  addContact: function (event) {
    var full_name = $('#full_name').val(),
        email = $('#email').val(),
        phone = $('#phone').val(),
        address = $('#address').val(),
        id = $('#id').val();
        
    if (id === '') {
      var contactmodel = new AB.contactModel({
        full_name: full_name,
        email: email,
        phone: phone,
        address: address
      });
    } else {
      var contactmodel = new AB.contactModel({
        id: id,
        full_name: full_name,
        email: email,
        phone: phone,
        address: address
      });
    }
    contactmodel.save();
    return false;
  }
});

List contacts – Backbone.View & Backbone.Collection

Usually we make an AJAX request to fetch all the data in JSON format but there is a special method collection.fetch() available to fetch the default set of models for the collection from the server based on the url¬†defined in the collection. We’ll write our collection by specifying the model and the url:

# addressbookMVC/js/script.js – Contacts Collection

AB.contactsCollection = Backbone.Collection.extend({
  model: AB.contactModel,
  url: '../php/listContacts.php'
});

And we’ll put the templates in index.html:

addressbookMVC/index.html – listContacts Template


  <h2>List Contacts</h2>
  <table id='contactsGrid' width='100%' border='1' cellspacing='1' cellpadding='5'>
    <tr>
      <td width='25%'><b>Full Name</b></td>
      <td width='25%'><b>Email ID</b></td>
      <td width='15%'><b>Phone</b></td>
      <td width='25%'><b>Address</b></td>
      <td width='10%' align='center'><b>Action</b></td>
    </tr>
    
      <tr><td colspan='5'>No Record Found</td></tr>
    
          &lt;tr data-id=&gt;
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td align='center'><a>Edit</a> | <a>Delete</a></td>
          </tr>
    
  </table>

And then call the fetch() within its View:

addressbookMVC/js/script.js – listAllContacts View

AB.listView = Backbone.View.extend({
  el: 'div.abPanel',

  template: _.template($('#listContactsTemplate').html()),

  initialize: function () {
    _.bindAll(this, 'listContactsPage', 'render');
  },

  render: function (response) {
    var self = this;

    this.$el.html(this.template({contacts: response}));
  },

  listContactsPage: function (querystring) {
    var self = this;

    AB.contactscollection.fetch({
      data: querystring,
      success: function (collection, response) {
        self.render(response);
      }
    });
  }
});

Search contacts – Backbone.View and Backbone.Collection

I will not explain this section in detail because it is pretty much similar when it comes to load a searchContacts template into a page and to show all the contacts based on the search criteria, we can reuse the same method listContactsPage({full_name: ‘alice’}) from AB.listView class. We’ll get it once we go through the codebase. Lets move on to Backbone.Router.

Backbone.Router

In Backbone, routers are used to help manage application state and for connecting URLs to application events. This is achieved using hash-tags with URL fragments, or using the browser’s pushState and History API. Some examples of routes may be seen below:
http://addressbook.com/#addNewContact
http://addressbook.com/#editContact/6
When all of our routers have been created, and all of the routes are set up properly, call Backbone.history.start() to begin monitoring hashchange events, and dispatching routes. Inside run method, we are updating the hash to #add_new_contact and triggering it immediately so that renderAddNewContactPage will be called immediately once the page is loaded.

# addressbookMVC/js/script.js – Backbone.Router

var AB = {
  run: function () {
    this.addview = new this.addView();
    this.listview = new this.listView();
    this.searchview = new this.searchView();
    this.contactscollection = new AB.contactsCollection();
    this.router = new this.Router();
    Backbone.history.start();
    this.router.navigate('add_new_contact', {trigger: true});   
  }
};

AB.Router = Backbone.Router.extend({
  routes: {
    'list_contacts': 'renderListContactsPage',
    'add_new_contact': 'renderAddNewContactPage',
    'search_contacts': 'renderSearchContactsPage',
    'edit_contact/:id': 'renderEditContactPage'
  },

  renderAddNewContactPage: function () {
    AB.addview.addContactPage();
  },

  renderListContactsPage: function () {
    AB.listview.setElement('div.abPanel');
    AB.listview.listContactsPage();
  },

  renderSearchContactsPage: function () {
    AB.searchview.searchContactsPage();
  },  

  renderEditContactPage: function (id) {
    AB.addview.addContactPage(id);
  }
});

Summary

I simply love to use Backbone.js in my projects, its amazing.

Download the source code from github

And do share your thoughts in the comment section below.

Updates:

Since a very long time, I wanted to try out Require.js in my projects and what could be the best way than to rewrite the addressBook in backbone.js and require.js again.
So here it is: addressBook in Backbone.js and Require.js

Happy Hacking ūüôā

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

jQuery video series: The making of Address book


Hello friends,

I really enjoyed making these¬†screen-casts¬†for the first time and it was an awesome experience. I personally believed that to learn any new technology or library, one has to get acquainted with the basics and write a small generic application to get the hang of it. Below are the¬†things¬†that I’ve covered in this video series:

The Addressbook in jQuery
The Addressbook in jQuery

  • Basic Instinct¬†
    • Why to use jQuery and¬†Where to get it from?
    • $ and beyond (overriding $)
    • Difference between document.ready and window.load
    • Selectors, dom traversing and events
    • Ajax and writing custom jquery function
  • Welcome to the jungle of jQuery
    • Selectors to fetch the values of form elements
    • Ajax calls to save the data (using php and mysql)
  • A list apart
    • List all the contacts in a tabular format
    • Delete contact functionality
  • Searching through
    • Search contacts by name or email

You can download the code from github.com.

References: 

P.S. There are many ways to improve the code. You can add edit-contact functionality or you can avoid unnecessary ajax calls to load forms/grids by simply keeping them in index.html and show/hide on demand instead of calling `$.load()` every time. Plus, its not always a valid choice to use only jQuery to write a Single Page app as there are lots of good MVC or MVVM frameworks available that can save your substantial amount of time and effort.

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

socialFlair – Stackoverflow like User Flairs to showcase your Social Profiles


Hurrey,

I’ve released one more Opensource project, socialFlair¬†on github today. It is a simple jQuery plugin which lets you embed social flairs in your about-me page of ¬†your personal website or blog. Currently, it is available for Twitter, Github and Facebook. This is how it looks:

socialFlair
socialFlair

Update1: 

Live Demo: http://jsfiddle.net/codef0rmer/wzpNB/embedded/result/

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

Select grouped checkboxes in jQuery


Have you ever noticed in gmail where we  select/deselect all the visible mails with the help of a checkbox given on top? Now it is possible to do it in a single line of javascript. For that purpose, you need to use jQuery.

Suppose you have a bunch of checkboxes having same id as show below:

Parent Checkbox:

<input type="checkbox" id='parent_id' />

Grouped Checkboxes:

<input type="checkbox" id='result_data_id' name="result_data_1" value="1" />
<input type="checkbox" id='result_data_id' name="result_data_2" value="2" />
<input type="checkbox" id='result_data_id' name="result_data_3" value="3" />
<input type="checkbox" id='result_data_id' name="result_data_4" value="4" />
<input type="checkbox" id='result_data_id' name="result_data_5" value="5" />

Now we have to attach onchange event to our parent checkbox this way:

$('#parent_id').change(function () {
$('input[id=result_data_id]').attr('checked', this.checked);
});

That’s it. Isn’t that simple and fun? BTW, do not forget to drop a comment.

Sort & Save ordering of JqueryUI Tab: An hack


Back Again…

Few days back i was searching for JqueryUI tab sorting and get the sort order. And as we all know, this can only be possible by using sortable plugin that JqueryUI provides.
i.e. $(this).sortable(‘serialize’);

But, this code will fail in case of tab and you will not get the sort order, instead you will get `undefined`. Yeah, its a bug in ui.sortable.js.

So i came up with the hack to get the sort order of tab, the easy way.
Here we go, below is the tab html we are going to create.

<div id="tabs">
<ul>
<li id="li-1"><a id="a-1" href="#tabs-1">Nunc tincidunt (a-1)</a></li>
<li id="li-2"><a id="a-2" href="#tabs-2">Proin dolor (a-2)</a></li>
<li id="li-3"><a id="a-3" href="#tabs-3">Aenean lacinia (a-3)</a></li>
</ul>
<div id="tabs-1">
<p>Lorem Ipsum</p>
</div>
<div id="tabs-2">
<p>Dolor Sit</p>
</div>
<div id="tabs-3">
<p>Amet</p>
</div>
</div>

In order to convert above div structure into tabbed interface. we need to add
jquery.js, ui.code.js, ui.tabs.js, ui.sortable.js and finally theme css, ui.all.css, ui.tabs.css etc.

Now create tabbed interface using following code and make tabs sortable,

$("#tabs").tabs().find("ul").sortable({
        axis : "x",
        update: function (e, ui) {
              var csv = "";
             $("#tabs > ul > li > a").each(function(i){
                  csv+= ( csv == "" ? "" : "," )+this.id;
             });
             alert(csv);
        }
});

Above i have added update callback function which is been called whenever we will drag and drop tab from one position to another. And we get the id of tabs in proper order in CSV  format.

That’s it. Now go and explode that CSV value using comma in any scripting language like php, and save the array index in database to intact the sort order.

see the DEMO

Happy Coding…¬† ūüôā