Angular’s $http not working. How to fix this problem?

May 14, 2016 0 Comments

Greetings again. Working on angular sometimes you might have faced a simple issue that angular’s $http does not work. Alternately if you try with jquery $.ajax it works smoothly. What could possibly the problem?

Here are some points to note when using angular’s $http.

$http.post

When you use it it works fine, but sometimes not, have you given a thought why?

The key point is you are missing data parameter so .Net is complaining the post api you are trying to hit was not found. See this example.

var data = { quantity: 3, item: true };

var req = {
	method: 'POST',
	url: 'someurl',
	data: data,
	headers: {
		'Content-Type': 'application/json'
	}
};

$http(req).then(function (response) {
	console.log(response.data)
}, function (response) {
	console.log(response)
});

$http.get

$http.get makes even more problem when you hit a resful service with it. You might have missed a simple point. For a long time people have been using $.ajax so they are used to using data as a parameter to be converted to query string for the current request. But angular has made some difference here. For get request angular $http.get needs params instead of data. You should remember this to avoid wasting your time. Here is a simple example.

var req = {
	method: 'GET',
	url: 'someurl',
	data: data,
	headers: {
		'Content-Type': 'application/json'
	}
};

$http(req).then(function (response) {
	console.log(response.data)
}, function (response) {
	console.log(response)
});

This will not work. Because $http.get need params instead of data.

var req = {
	method: 'GET',
	url: 'someurl',
	params: data,
	headers: {
		'Content-Type': 'application/json'
	}
};

$http(req).then(function (response) {
	console.log(response.data)
}, function (response) {
	console.log(response)
});

This will work.

Hope this is useful for someone.


If Binding Magic! Avoiding Duplication Problem in Header Element IDS

November 29, 2014 0 Comments

Welcome again. As you may already have seen my post regarding creating Sinlge Page Application using knockoutjs and jquery mobile.
One thing i wanted to discuss here that you might encounter a simple problem of duplicating the id attribute in header elements.
Why that can happen? Because you are using a template for header and this template is being injected in each page/section. Of
course the ids of header elements will be duplicated and you wont be able to make jquery work using ids and won’t be able to get
the item selected you want on some particular page.
I have seen many questions from people asking how this can be solved. So i thought i should present a simple solution.

Problem:
To understand the problem, consider this example. Here is a template

<nav class="v2_n">
	<a href="#home" id="home" data-transition="fade" >Home</a>
	<a href="#list" id="list" data-transition="fade" >List</a>
	<a href="#form" id="form" data-transition="fade" >Form</a>
</nav>

This template is being called on each section/page.

<section id="home" data-role="page"  data-bind="with:HomePage">
	<header>
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
</section>
<section id="list" data-role="page"  data-bind="with:ListPage">
	<header>
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
</section>
<section id="form" data-role="page"  data-bind="with:FormPage">
	<header>
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
</section>

Solution:

While working on SPA using this approach it is very simple to avoid this problem. You just need a property in parent view model. Let see how we can do this

function VM() {
	var self = this;
 
	self.Title = ko.observable('Knockout! Parent and Child Usage Techniques')
	self.Home  = ko.observable()
	self.Form  = ko.observable()
	self.List  = ko.observable()
 
	/*	Define a property to hold id of current page	*/
	self.CurrentPage = ko.observable()
 
	.
	.
	.
}

And on page change event use this

$(window).on( "pagechange", function( event, data ) {
	var page_id	=	data.toPage[0].id
	/*	
		While navigating among pages each time pass 
		the page id to CurrentPage property	
	*/		
	vm.CurrentPage(page)
 
	switch(page_id)
	{
		case 'form':
		    vm.FormPage().LoadData()
			break;						
		case 'list':
			vm.ListPage().LoadData()	
			break;						
		default:
			vm.HomePage().LoadData()
			break;
	}
});

And now on view you need a simple condition

<section id="home" data-role="page"  data-bind="with:HomePage">
	<!-- ko if:$root.CurrentPage() == 'home' -->	
	<header>
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
	<section class="main_body max_600width">
		// Other content				
	</section>			
	<!-- /ko -->
</section>
<section id="list" data-role="page"  data-bind="with:ListPage">
	<!-- ko if:$root.CurrentPage() == 'list' -->	
	<header>	
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
	<section class="main_body max_600width">
		// Other content				
	</section>	
	<!-- /ko -->			
</section>
<section id="form" data-role="page"  data-bind="with:FormPage">
	<!-- ko if:$root.CurrentPage() == 'form' -->	
	<header>	
		<nav class="v2_n">
			<a href="#home" id="home" data-transition="fade" >Home</a>
			<a href="#list" id="list" data-transition="fade" >List</a>
			<a href="#form" id="form" data-transition="fade" >Form</a>
		</nav>
	</header>
	<section class="main_body max_600width">
		// Other content				
	</section>	
	<!-- /ko -->			
</section>

Now what this does is when you navigate between pages the other contents in each sections gets removed and the page being viewed is generated. So if you inspect section elements you will see only current page is having content and all other sections are empty. This way you can avoid duplication of id attributes in header. Hope this simple technique is useful.

You can view a demo here. Any question, i am here to explain.


Server Side Language Less Views HTML/Javascript (No PHP/ASP/Razor)

November 27, 2014 0 Comments

Greetings! Welcome back. Today i am sharing a simple technique of web development. As many of you already have idea of MVC pattern. There are many famous frameworks out there like Codeingiter, Laravel, CakePHP, YII and of course .Net has a complete bundle. Many of us have been using these frameworks. And on the particular part of V of MVC we have been using different templating libraries to dynamically generate views.

Well! here i am going to recommend (as happening in modern applications) that drop using php,asp, razor etc to generate view because there is some simple approach of generating views. There are many Javascript frameworks and libraries that are doing exactly same thing, lifting burden from client side to generate views after rendering.

Consider this example to understand the problem.

  • You load views with your controller
  • Once views are fully loaded and¬†now you want to load some part of html you are bound to use javacript
  • If these templates you want to load are written inside some already-loaded view, PHP,ASP or Razor code is useless, written in these templates-parts

So what should we do?

The solution

Here is a simple technique for this. You may be already aware of this but pay some attention on this.

  • Load the views with controller but do not do any conditioning and looping and info displaying in them
  • Once views are loaded, you need to display data into the page. And to display information you can use UI Frameworks like Angularjs, knockoutjs, reactjs etc.

How UI Framework or Library gets the data?

Ok. For this there are actually two ways to get the data for UI model so that it can render html and display data. Lets me tell you what are these.

  1. The first one is quite dirty and you may not like it. All you have to do is prepare the data at server side and on the client side, pass the data to javascript variable using json encoding so that javascript can have a clear object which can be supplied to model for further binding to viewmodel. Here are example in php and razor.
	var serverData = '<!--?php echo json_encode($data)?-->' // $data is sample data from server

And in razor

	var serverData = @Html.Raw(Json.Encode(ViewBag.SampleData)) // ViewBag.SampleData is sample data from server

2. Well, the other way is quite simple in which after page load you need to call ajax request which will give data as json format in the response which can be easily passed to javasciprt model.

Hope this can be useful to someone. Any question can be welcome!!!


Knockout View Loader Plugin

November 27, 2014 0 Comments

Welcome back! as you know knockout version 3.2 is already out, and components are available now. The one thing though which i thought should have been available is loading external views on demand. For this purpose i have developed a plugin that fulfills this requirement. If you are not using AMD module pattern to work with, then you can use this plugin to load view files on demand. Let see what it presents us.

The plugin has only one function(ko.load.view) and it is bound to load .html extension files for the time being.

Here is how we are going to use. You just need to include this file in header.

var home = function(){
	var self = this
	self.name = ko.observable('Raheel')
}
 
var nameEditorComponent = {
	viewModel:home,
	template:ko.load.view('components/views/home') // Load view file
}	
 
ko.components.register('name-editor',nameEditorComponent)
 
$('document').ready(function () {
    ko.applyBindings()
})

And now you can use name editor component

    <name-editor></name-editor>

And that’s it.Also you should not it is not dependent on version 3.2. you can use it to load html files in previous versions too. Hope it is helpful.


Create Chrome Plugin with Knockoutjs

August 26, 2014 0 Comments

Greetings. I am going to present a simple way to create a chrome plugin using knockoutjs. As you know knockout needs two things. A view and a viewmodel. View is simply written in html file while viewmodel is a javascript object/function which is then bound to view with knockout. For loading view you can see this post.

And for loading viewmodel here is the code.

var pluginViewModel = function(){
    // code here
}
 
// for component
ko.components.register('plugin',{
    template : pluginTemplate,
    viewModel : pluginViewModel
});
 
$('body').append('<div data-bind="component:plugin"></div>');
ko.applyBindings()
 
// For simple viewmodel
 
$('body').append(pluginTemplate);
ko.applyBindings(new pluginViewModel())

Hope it is very easy and useful. Do reply if you need to ask anything.


Load HTML File in Chrome Plugin, The Easy Way

August 26, 2014 0 Comments

Greetings. Today i¬†am going to present a simple trick to load html file in chrome plugin. There are so many posts on this topic already still i assume you will like this. Let’s get started.

At first lets see the plugin structure.

/myplugin
    /css
    /images
    /js
    /background.js
    /manifest.json
    /plugin/
        /plugin.html
        /plugin.js

OK. Pretty simple.
Now you can write html code in your plugin.html. We need to add plugin.html in manifest.json so that chrome plugin allow it to load.
In manifest.json add this.

"web_accessible_resources": [
    "plugin/plugin.html"
]

Also we need to load plugin.js file which we can add in content_scripts js array

"content_scripts": [
    {
        matches: [
 
        ],
        css : [],
        js : ["jquery.js","plugin/plugin.js"]
    }
]

We can now proceed to see how plugin.js will load the html file. For this lets make a simple function in plugin.js

function loadPluginTemplate(path){
    var xmlHttp = null;
    xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", chrome.extension.getURL(path), false );
    xmlHttp.send( null );
    return xmlHttp.responseText
}
/* Plugin Template */
var pluginTemplate = loadPluginTemplate("plugin/plugin.html")

this will first load the file using chrome getURL function then with our request it will send the response and we can easily get the responseText and bind it to the body.

$('body').append(pluginTemplate);

And that’s all.

Hope it is very easy and useful.


With Binding Magic! Writing Single Page Application with JQuery Mobile and Knockoutjs

April 10, 2014 4 Comments

Greetings! Its nice to have yet another post regarding knockoutjs. Today i am going to define how we can create Single Page Application using JQuery Mobile and Knockoutjs. You may already have seen some posts on this topic so what’s new in here? The only thing is that i am going to implement the technique which i defined here. Please go through this post of mine and you will thoroughly understand how easy it is to make SPA with JQuery Mobile and knockoutjs.This is pretty simple and gives a good control over the application. After we finish these steps the application will be ready for phone gap to get hands on it. So lets get started.

The Application Structure

Before we dig we need to see how we can organize the application. I have created this structure which suits my needs but you can choose any according to your requirements.

/knockoutjs-jqm-spa/
    /js/
        /jquery.js
        /knockout-3.0.0.js
        /jquery.mobile-1.3.2.js
        /viewmodel.js
        /models/
                /home.js
                /list.js
                /form.js
    /css/
        /style.css
        /jquery.mobile-1.3.2.css
        /images
    /images
    index.html

OK. Now lets go further to see how we can implement this. First we will see how we can use jquery mobile then we will see how we can use knockoutjs.

The Basic Structure of Page

In the first step we need to see how JQuery mobile is implemented on html. The common approach is using sections and assigning data-role = ‘page’ property so that sections can be displayed as pages. In this application i will be using three pages so we need three sections for three pages. Here is the basic page.

<body>
    <!-- /////// home page start /////// -->
    <section id="home" data-role="page"></section>
    <!-- /////// home page end /////// -->
    <!-- /////// list page start /////// -->
    <section id="list" data-role="page"></section>
    <!-- /////// list page end /////// -->
    <!-- /////// form page start /////// -->
    <section id="form" data-role="page"></section>
    <!-- /////// form page end /////// -->
</body>

Each section has an id. These are used to navigate between pages. How we will be navigating ? Lets see the header which has some links to navigate.

<header>
    <nav class="v2_n">
        <a href="#home" class="active" >Home</a>
        <a href="#list" data-transition="fade" >List</a>
        <a href="#form" data-transition="fade" >Form</a>
    </nav>
</header>

Here each link has href attribute which is linked to specific section on the page. Other important thing is transition. You can use any transition like fade , pop and slide.

Parent Model

Now as the basic page is ready we can see the kncokout implementation. Here is the knockout model we will be using. I call it parent model as this will be serving as parent model.

function VM() {
    var self = this;
 
    self.Title  =   ko.observable('With Binding Magic! SPA with Knockout and JQM!')
    self.HomePage   =   ko.observable()
    self.FormPage   =   ko.observable()
    self.ListPage   =   ko.observable()
 
    self.Data               =   ko.observableArray([])
    self.LastViewedPage     =   ko.observable('Home')
    self.LastPageVisited    =   ko.observable()
 
    self.LastPage = function(){
        self.LastViewedPage(self.LastPageVisited())
        self.HomePage().ModifyMessage(true)
        return true
    }
}

Let me define this model. I have defined an observable property `Title`. This will be used to display application title. Making it in parent model is due to write succinct and DRY code so that we can avoid code repetition. For three sections(pages) i have created three observable properties in the parent model. Each of which will be having a child model i will define later. Other properties `Data`, `LastViewedPage` and `LastVisitedPage` are only to define how we can use parent properties throughout the application. These properties can be served to hold data. In other words, these are alternate of form submit data. When a form is submit you can get its data on the second page. Or you can save data in session so that it is vailable for the other pages. These properties serve the same thing. Here you see a method `LastPage` which i will define later.

You can create as many observable properties to serve for pages as you need and as many other properties as you need to use among pages. Save this file as `viewmodel.js`in the js folder.

Sub Models (Child Models)

Now as we have created an observable property for home page as Home so we need a child model for this. Here is the child model for Home observable of parent model.

home.js

var homePage = function(parent) {
    var self = this
 
    self.Parent         =   ko.observable(parent)
 
    self.GreetingMessage    =   ko.observable('Hi! I am home page')
    self.ModifyMessage      =   ko.observable(false)
 
    self.LoadData   =   function(){
 
        if(self.ModifyMessage()){
            var message =   'You have just landed here from '+self.Parent().LastPageVisited()
            self.GreetingMessage(message)
            self.ModifyMessage(false)
        }
    }
}

In this model you can see this takes a parameter called parent which will be assigned to self.Parent of current model. This is very important and will let us use properties and methods of parent model and other models. I will define them later in this post. Other properties and methods will be used in the page section which we have created as home. Similarly we can define the other pages with the same structure.

list.js

var listPage = function(parent) {
    var self = this
 
    self.Parent     =   ko.observable(parent)
 
    self.PageTitle      =   ko.observable()
    self.Technologies   =   ko.observableArray([])
    self.ReInitialize   =   ko.observable(true)
 
    self.LoadData   =   function(){
 
        self.Parent().LastPageVisited('list')
 
        if(self.ReInitialize()){
            var data    =   [
                {Id:1,Technology:"Jquery",Status:"Active"},
                {Id:2,Technology:"Jquery Mobile",Status:"Active"},
                {Id:3,Technology:"Knockoutjs",Status:"Active"},
                {Id:4,Technology:"Knockoutjs Mapping",Status:"Inactive"},
            ]
            self.Parent().Data(data)
            self.ReInitialize(false)
        }
    }
 
    self.ResetList = function () {
        self.ReInitialize(true)
        self.LoadData()
    }
}

And form.js

var formPage = function(parent) {
    var self = this
 
    self.Parent     =   ko.observable(parent)
 
    self.Id         =   ko.observable()
    self.Technology =   ko.observable()
    self.Status     =   ko.observable()
 
    self.LoadData   =   function(){
        self.Parent().LastPageVisited('form')
        self.Reset()
    }
 
    self.Reset = function () {
        self.Id('')
        self.Technology('')
        self.Status('')
    }
 
    self.AddItem = function () {
        var data = {
            Id  : self.Id(),
            Technology:self.Technology(),
            Status:self.Status()
        }
 
        self.Parent().Data.push(data)
        return true
    }
}

AS we have finished defining sub models we can now see how we can call them in parent model. We need to create a simple function in parent model for this.

self.LoadData = function(){
    self.HomePage(new homePage(self))
    self.FormPage(new formPage(self))
    self.ListPage(new listPage(self))
}
self.LoadData()

Remember when we include files using script tags first we need to load models and then parent model or else it will say undefined property homePage. We are calling this `self.LoadData()` immediately so that each property is initialized when the parent model is applied ko.applyBinding.

And now we can see complete structure of parent model.

viewmodel.js

function VM() {
    var self = this;
 
    self.Title  =   ko.observable('With Binding Magic! Single Page Application with Knockout and JQM!')
    self.HomePage   =   ko.observable()
    self.FormPage   =   ko.observable()
    self.ListPage   =   ko.observable()
 
    self.Data               =   ko.observableArray([])
    self.LastViewedPage     =   ko.observable('Home')
    self.LastPageVisited    =   ko.observable()
 
    self.LoadData = function(){
        self.HomePage(new homePage(self))
        self.FormPage(new formPage(self))
        self.ListPage(new listPage(self))
    }
 
    self.LastPage = function(){
        self.LastViewedPage(self.LastPageVisited())
        self.HomePage().ModifyMessage(true)
        return true
    }
 
    self.LoadData()
}   
 
var vm = new VM()

The important thing to implement is how we are going to bind them in html page sections. This is pretty simple. Just we need `With` binding.

<body>
    <!-- /////// home page start /////// -->
    <section id="home" data-role="page"  data-bind="with:HomePage"></section>
    <!-- /////// home page end /////// -->
    <!-- /////// list page start /////// -->
    <section id="list" data-role="page"  data-bind="with:ListPage"></section>
    <!-- /////// list page end /////// -->
    <!-- /////// form page start /////// -->
    <section id="form" data-role="page"  data-bind="with:FormPage"></section>
    <!-- /////// form page end /////// -->
</body>

And here is the final part of implementation.

$(window).on( "pagechange", function( event, data ) {
    var page_id =   data.toPage[0].id
 
    switch(page_id)
    {
        case 'form':
            vm.FormPage().LoadData()
            break;
        case 'list':
            vm.ListPage().LoadData()
            break;
        default:
            vm.HomePage().LoadData()
            break;
    }
});
$('document').ready(function(){
    ko.applyBindings(vm)
    vm.HomePage().LoadData()
})

We are applying binding on document ready. And you can note in each child model i have created `LoadData` method which initializes the child model with defaults. and also we are calling page change event and telling to call `LoadData` of each page on demand.

Now here is the complete page

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Single Page Application</title>
        <link rel="stylesheet" href="css/jquery.mobile-1.3.2.css"  />
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-3.0.0.js" ></script>
        <script type="text/javascript" src="js/knockout.mapping.js" ></script>
        <script type="text/javascript" src="js/models/home.js"></script>
        <script type="text/javascript" src="js/models/form.js"></script>
        <script type="text/javascript" src="js/models/list.js"></script>
        <script type="text/javascript" src="js/viewmodel.js" ></script>
        <script type="text/javascript" src="js/jquery.mobile-1.3.2.js"></script>
        <script type="text/javascript">
        $(window).on( "pagechange", function( event, data ) {
            var page_id =   data.toPage[0].id
 
            switch(page_id)
            {
                case 'form':
                    vm.FormPage().LoadData()
                    break;
                case 'list':
                    vm.ListPage().LoadData()
                    break;
                default:
                    vm.HomePage().LoadData()
                    break;
            }
        });
        $('document').ready(function(){
            ko.applyBindings(vm)
            vm.HomePage().LoadData()
        })
        </script>
    </head>
    <body>
        <!-- /////// home page start /////// -->
        <section id="home" data-role="page"  data-bind="with:HomePage">
            <header>
                <nav class="v2_n">
                    <a href="#home" class="active" >Home</a>
                    <a href="#list" data-transition="fade" >List</a>
                    <a href="#form" data-transition="fade" >Form</a>
                </nav>
            </header>
            <section class="main_body max_600width">
                <section class="selection_screen">
                    <div>
                        <h1 id="" data-bind="text:$root.Title"></h1>
                        <p data-bind="text:GreetingMessage"></p>
                    </div>
                <section class="user_dtl">
                <h2>You have recently visited</h2>
            </section>
            <h2 data-bind="text:$root.LastViewedPage"></h2>
        </section>
        <!-- /////// home page end /////// -->
        <!-- /////// list page start /////// -->
        <section id="list" data-role="page"  data-bind="with:ListPage">
            <header>
                <a data-bind="click:$root.LastPage" class="go_back ui-link"  href="#home">Back</a>
                <nav class="v2_n">
                    <a href="#home" data-transition="fade" >Home</a>
                    <a href="#list" class="active" >List</a>
                    <a href="#form" data-transition="fade" >Form</a>
                </nav>
                <a data-bind="click:ResetList" class="go_next ui-link"  href="#">Reset List</a>
            </header>
            <section class="main_body max_600width">
                <section class="selection_screen" data-bind="foreach:$root.Data">
                    <article class="prfl_box">
                        <h3 data-bind="text:Technology"></h3>
                        <p data-bind="text:Id"></p>
                        <p data-bind="text:Status"></p>
                    </article>
                </section>
            </section>
        </section>
        <!-- /////// list page end /////// -->
        <!-- /////// form page start /////// -->
        <section id="form" data-role="page"  data-bind="with:FormPage">
            <header>
                <a data-bind="click:$root.LastPage" class="go_back ui-link" href="#home">Back</a>
                <nav class="v2_n">
                    <a href="#home" data-transition="fade" >Home</a>
                    <a href="#list" data-transition="fade">List</a>
                    <a href="#form" class="active" >Form</a>
                </nav>
            </header>
            <section class="main_body max_600width">
                <form>
                    <article class="new_posts">
                        <h2>Id</h2>
                        <input type="text" data-bind="value:Id"/>
                        <h2>Technology</h2>
                        <input type="text" data-bind="value:Technology"/>
                        <h2>Status</h2>
                        <input type="text" data-bind="value:Status"/>
                        <a href="#list" class="button text_center ui-link" data-bind="click:AddItem" data-transition="slide">Save</a>
                    </article>
                </form>
            </section>
        </section>
        <!-- /////// form page end /////// -->
    </body>
</html>

Demo

You can see it in action here.

Now lets do some explanation which is very important. I break it in two parts.

HTML End

Calling Properties

1. Using parent model properties in any child with html is pretty simple. We need to use $root keyword. For example

data-bind="text:$root.Title"

in any section will let as use Title property of parent model.

2. If we want to call any property of current (self) model we can simply use it with out using any context variable.

For example while we are on home page we can display GreetingMessage like this

data-bind="text:GreetingMessage"

3. If we ever need some sibling (other sub model) property we can still use it. For example we need Technologies of list page on Home section we can call

data-bind="foreach:$root.ListPage().Technologies"

This way you can go any deep level or starting from $root you can access any property.

Calling Methods

Calling parent methods is not different from properties for example calling last page is done like this

data-bind="click:$root.LastPage"

Calling self method is same as calling properties when we are on specific section for example when we are on home page and want to call

data-bind="click:LoadData"

And for calling sibling is

data-bind="click:$root.ListPage().ResetLis()"

Javascript End

Calling Properties

Calling child properties in parent model methods is simple. Like this you can call

self.HomePage().ModifyMessage(true)

This way not only you can access properties but also you can modify them.

If child model like home need to access or modify some parent property it can be called like this

self.Parent().Data()

you can assign or modify Data property. The important thing is that it will be always available in other sub models. So that they can work instead of sesstionStorage or localStorage.

If child model needs to access or modify some property of sibling you can do this

self.Parent().ListPage().ReInitialize()

Calling Methods

For now  i assume you will have a good idea how you can call parent methods in child. Like this

self.Parent().LoadData()

And calling self methods for example if List need to reinitialize itself

self.LoadData()

And for calling sibling methods

self.Parent().FormPage().Reset().

Note : When you bind some method on anchor you always need to return true or false so that navigation can be done. The other important thing is that you can always return true after setting some data for example like this

self.Parent().Data(mydata)

Now the application is ready for Phone Gap to get hands on it.
Hope this helps. If you need some answer you can comment.


Knockoutjs list, Alternate of Checkbox and Radio

March 4, 2014 0 Comments

So today, i am going to present an alternate of check boxes and radio buttons i have created using knockout. Sometimes you might want to use a simpler way to handle check boxes and radio buttons using knockout. I have written a code snippet to meet the needs which is simple and easy to handle.

Alternate of Single CheckBox

So lets’s start. First lets see knockout model we are going to use.

function Filter(settings){
    var self    =   this
    self.Active     =   ko.observable(false)
    self.Id         =   ko.computed(function(){
        if(settings.activeId){
            return settings.activeId
        }else{
            return ( self.Active() == true ) ? 1 : 0
        }
    })
    self.Class      =   ko.computed(function(){
        settings.activeClass    =   (settings.activeClass) ? settings.activeClass : 'selected'
        settings.inActiveClass  =   (settings.inActiveClass) ? settings.inActiveClass : ''
        return ( self.Active() == true ) ? settings.activeClass : settings.inActiveClass
    })
    self.Label      =   ko.computed(function(){
        settings.activeText     =   (settings.activeText) ? settings.activeText : 'True'
        settings.inactiveText   =   (settings.inactiveText) ? settings.inactiveText : 'False'
        if(settings.toggleText==true){
            return (self.Active() == false) ? settings.inactiveText : settings.activeText
        }else{
            return settings.activeText
        }
    })
    self.LabelColor =   ko.computed(function(){
        if(settings.toggleTextColor == true){
            if(settings.activeTextClass){
                return ( self.Active() == true ) ? settings.activeTextClass : settings.inActiveTextClass
            }else{
                return ( self.Active() == true ) ? '' : ''
            }
        }
    })
    self.Toggle = function(){
        self.Active(!self.Active())
    }
    self.LoadData = function(){
        self.Active(settings.active)
    }
    self.LoadData()
}

Now let’s see how we can use it. For this i am going to create a simple model which will use it.

var page    =   function(){
    var self    =   this
 
    self.IsRead     =   ko.observable('')
 
    self.InitializeData =   function(){
        var options =   {
            toggleText          :   true,
            active              :   false,
            toggleTextColor     :   true,
            activeId            :   23,
            activeClass         :   '',
            inActiveClass       :   'un_check',
            activeText          :   'I have accepted',
            inactiveText        :   'I have not accepted',
            activeTextClass     :   'selected_filter',
            inActiveTextClass   :   ''
        }
        self.IsRead(new Filter(options))
    }
    self.InitializeData()
}
 
$('document').ready(function(){
    ko.applyBindings(new page())
})

Now let me define its properties what it does.

Configuration

toggleText , activeText and inActiveText

We can set the value of toggleText to true or false. If we set it active the text will be toggled. If we give parameters in activeText and inActiveText these text will be toggled. And if we do not assign these parameters it will display True  and False keywords. If we set it to false always activeText will be displayed and if we do not assign active text it will always display True.

active

With this we can handle the default behaviour. Setting it true will check it by default and setting it false will display it as unchecked.

activeTextClass , inActiveTextClass , toggleTextColor

activeTextClass and inActiveTextClass are applied to activeText and inActiveText. this is handled with css binding. Toggling will work only when toggleTextColor is set to true.

activeClass, inActiveClass

activeClass and inActiveClass are applied to the anchor we will be using.

activeId

activeId  is the default value you want to give to the item. If you leave it you always have 1 when active and 0 when inactive.

OK. The settings has been defined. Now let’s see the binding.

<ul class="srh_fltr" data-bind="with:IsRead">
    <li>
        <label class="selected_filter" data-bind="text:Label,css:LabelColor">True</label>
        <div class="check_box">
            <a class="active selected" data-bind="css:Class,click:Toggle">
                <img src="http://imgh.us/spacer_4.gif" alt="" />
            </a>
        </div>
    </li>
</ul>

As you can see i am using `with` in ul tag so that i am able to use it as usual binding. label has text and css binding.  And anchor has css and click binding. Now to see it in action view the demo.

Demo

When you need to get the value you can do it easily with self.myproperty().Id() or for text self.myproperty().Label(). One thing to note here is that all the configuration is optional. It will have default values for everything. Here are some useful properties of Filter model which we have assigned in out observable.

  • Label
  • LabelColor (css class for handling label)

  • Class (css class for handling anchor or clickable tag)
  • Toggle (function for toggle between active and inactive)
  • Id (the id of current item we have set)

To get the id and text you can use Id and Label and you will have selected Id and selected text.

The single checkbox is finished here. Now we can move to see how we can use another code snippet as a list.

Radio Alternative List with Knockout

For a list which will work instead of radio boxes we need to understand some points.

  • We need an observableArray property which should have key value pairs.
  • The list is dependent on Filter model i have defined above. Using it means gain all the functionality of Filter model.
  • List have same configuration as Filter model but with some more parameters.

Ok. these were the points to understand. Now lets see the usage.

At first lets see the Filters model not Filter.

function Filters(settings){
    var self            =   this
    self.List           =   ko.observableArray([])
    self.Id             =   ko.observable()
    self.Ids            =   ko.observableArray([])
    self.Description    =   ko.observable()
    self.Descriptions   =   ko.observableArray([])
 
    self.SetActive = function(){
        var result          =   []
        var defaultKey      =   (settings.matchKey) ? settings.matchKey : 'Id'
        var activeText      =   (settings.activeText) ? settings.activeText : 'Value'
        var inactiveText    =   (settings.inactiveText) ? settings.inactiveText : 'Description'
        var activeIds       =   settings.activeIds
        var ids             =   []
        var items = ko.utils.arrayForEach(settings.List,function(item){
            if(in_array(item[defaultKey],activeIds)){
 
                if(!settings.isMultiselect){
                    self.Id(item[defaultKey])
                    self.Description(item[activeText])
                }else{
                    self.Ids.push(item[defaultKey])
                    self.Descriptions().push(item[activeText])
                }
            }
            var active  = in_array(item[defaultKey],activeIds) ? true : false
            var options =   {
                toggleTextColor     :   (settings.toggleTextColor) ? settings.toggleTextColor : false,
                toggleText          :   (settings.toggleText) ? settings.toggleText : false,
                active              :   active,
                activeId            :   item[defaultKey],
                activeClass         :   (settings.activeClass) ? settings.activeClass : 'selected',
                inActiveClass       :   (settings.inActiveClass) ? settings.inActiveClass : '',
                activeText          :   (item[activeText]) ? item[activeText] : 'True',
                inactiveText        :   (item[inactiveText]) ? item[inactiveText] : 'False',
                activeTextClass     :   (settings.activeTextClass) ? settings.activeTextClass : '',
                inActiveTextClass   :   (settings.inActiveTextClass) ? settings.inActiveTextClass : ''
            }
            result.push(new Filter(options))
        })
 
        self.List(result)
    }
 
    self.ConvertToInteger = function(accepted){
        var AcceptedChoices =   []
        ko.utils.arrayForEach(accepted, function(item) {
            AcceptedChoices.push(parseInt(item))
        })
        return  AcceptedChoices
    }
 
    self.ToggleClick    =   function(data){
        if(settings.isMultiselect){
            var selectedItems   =   []
            var selectedDescriptions    =   []
            var items   =   ko.utils.arrayForEach(self.List(), function(item) {
                var index   =   self.List().indexOf(item)
                if(item.Id() == data.Id()){
                    self.List()[index].Toggle()
                }
            })
            var items   =   ko.utils.arrayForEach(self.List(), function(item) {
                var index   =   self.List().indexOf(item)
 
                if(item.Active() == true){
                    selectedItems.push(item.Id())
                    selectedDescriptions.push(item.Label())
                }
            })
            self.Ids(selectedItems)
            self.Descriptions(selectedDescriptions)
        }else{
            var items   =   ko.utils.arrayForEach(self.List(), function(item){
                var index   =   self.List().indexOf(item)
 
                if(item.Active() == true){
                    self.List()[index].Toggle()
                }
 
                if(item.Id() == data.Id()){
                    self.List()[index].Toggle()
                }
 
            })
            self.Id(data.Id())
            self.Description(data.Label())
        }
    }
    /*  Initialization  */
    self.LoadData = function(){
        self.SetActive()
    }
    /*  Initialization End Here */
    self.LoadData()
}

Here is the model we are going to use.

self.MyChoice   =   ko.observable('')
 
self.Choices    =   ko.observable([
    {Id:1,Value:'First Option',Description:'This is first option'},
    {Id:2,Value:'Second Option',Description:'This is second option'},
    {Id:3,Value:'Third Option',Description:'This is third option'},
    {Id:4,Value:'Forth Option',Description:'This is forth option'},
    {Id:5,Value:'Fifth Option',Description:'This is fifth option'},
    {Id:6,Value:'Sixth Option',Description:'This is sixth option'}
])
var options =   {
    isMultiselect       :   false,
    matchKey            :   'Id',
    activeText          :   'Value',
    inactiveText        :   'Description',
    List                :   self.Choices(),
    toggleText          :   true,
    toggleTextColor     :   true,
    activeIds           :   [4],
    activeClass         :   '',
    inActiveClass       :   'un_check',
    activeTextClass     :   'selected_filter',
    inActiveTextClass   :   ''
}
self.MyChoice(new Filters(options))

OK. You can see i have created an observable array called Choices. And MyChoice is an observable property which will have Filters model. You can see i have added some more parameters in configuration. Let me define them.

isMultiSelect

if set to false it will act like a group of radio buttons. Only one is selected at a time. If set it to true the list will now act like multiple checkboxes and many or all of them can be selected.

matchKey , activeText , inactiveText

These will have names of indexes of observable array. Here i have assigned Id in Key from Choices observable array. Value as active text and description as inActiveText. If you select the toggleText to false it will always display Value as activeText.

activeIds

If you want to select an item by default you can assign its value in the form of array in activeId. When the list is generated the id you assigned will be selected.

List

This is the property you need to assign an observable array which will have key and value pairs.

To see it in action lets’ have its demo on fiddle.

Demo

The binding is the previous one except two things. I have used List to generate the list. And i have used ToggleClick instead of Toggle. And to get the value you can use self.myproperty().Id() and to get text you can use self.myproperty().Description().

Checkbox Alternative List with Knockout

For this all we need to do is set isMultiSelect to true and you will be able to select multiple items from the list. For multiple default selections you can give multiple ids in activeIds.  Here is the fiddle demo for this.

Demo

Now to get the selected values you can use self.myproperty().Ids() and to get selected texts you can use self.myproperty().Descriptions().

This way you will now be able to make lists which will work instead of checkboxes and radio buttons. Moreover you can handle them with css classes.


With binding magic, Make Parent and Child Structure in your app with knockoutJs

January 1, 2014 1 Comments

Knockoutjs is a Javascript Library that lets you write and handle dynamic web user interface.When using knockout you can say ‘By by JQuery and Welcome knockout’. Well here i am going to¬†define how you can use it in the application in a structural way. If you haven’t have any idea¬†you can visit knockoutjs.com. And to get skilled in knockout usage¬†you can see Rniemeyer’s Blog where he has written many posts¬†regarding its better usage.

What am i going to present in this post?

The problem

To understand the problem let’s have a scanrio. I have an application with three pages home.html , form.html and list.html.¬†Each page has a viewmodel associated with it. And each page has a function in viewmodel that redirects to the home page.¬†Each viewmodel has a property title that should be displayed in the app.

First lets see the application structure

/myapp/
    /js/
        /jquery.js
        /knockout-2.3.0.js
    /css/
        /style.css
    /home.html
    /form.html
    /list.html

Let’s see the pages.

Home.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript">
        var page = function() {
            var self = this
 
            self.Title      =   ko.observable('Knockout Techniques')
            self.FirstName  =   ko.observable()
            self.LastName   =   ko.observable()
 
            self.LoadData   =   function(){
                self.FirstName('Muhammad')
                self.LastName('Raheel')
            }
 
            self.Navigate = function(page){
                if(page == 'list'){
                    window.location =   'list.html'
                }else if(page == 'form'){
                    window.location =   'form.html'
                }else{
                    window.location =   'home.html'
                }
            }
 
            /*  Call LoadData for Initialization    */
            self.LoadData()
        }
 
        $( document ).ready(function() {
            ko.applyBindings(new page())
        })
        </script>
    </head>
    <body>
        <h2 data-bind='text:Title'></h2>
        <h3 data-bind='text:FirstName'></h3>
        <h3 data-bind='text:LastName'></h3>
        <table>
            <tr>
                <td>Go to Form Page </td>
                <td><a data-bind="click:Navigate.bind($data,'form'),text:'Form'" /></td>
            </tr>
            <tr>
                <td>Go to List Page </td>
                <td><a data-bind="click:Navigate.bind($data,'list'),text:'List'"></a></td>
            </tr>
        </table>
    </body>
</html>

Here is form.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript">
        var page = function() {
            var self = this
 
            self.Title      =   ko.observable('Knockout Techniques')
            self.FirstName  =   ko.observable()
            self.LastName   =   ko.observable()
            self.FullName   =   ko.computed(function(){
                return self.FirstName() +' '+self.LastName()
            })
 
            self.LoadData   =   function(){
                self.FirstName('Muhammad')
                self.LastName('Raheel')
            }
 
            self.Navigate = function(page){
                if(page == 'list'){
                    window.location =   'list.html'
                }else if(page == 'form'){
                    window.location =   'form.html'
                }else{
                    window.location =   'home.html'
                }
            }
 
            /*  Call LoadData for Initialization    */
            self.LoadData()
        }
 
        $( document ).ready(function() {
            ko.applyBindings(new page())
        })
        </script>
    </head>
    <body>
        <h2 data-bind='text:Title'></h2>
        <input type="text" data-bind='value:FirstName' />
        <br />
        <input type="text" data-bind='value:LastName' />
        <br />
        <h2 data-bind='text:FullName'></h2>
 
        <table>
            <tr>
                <td>Go to Home Page </td>
                <td><a data-bind="click:Navigate.bind($data,'home'),text:'Home'"></a></td>
            </tr>
            <tr>
                <td>Go to List Page </td>
                <td><a data-bind="click:Navigate.bind($data,'list'),text:'List'"></a></td>
            </tr>
        </table>
    </body>
</html>

And here is list.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript">
        var page = function() {
            var self = this
 
            self.Title  =   ko.observable('Knockout Techniques')
            self.Users  =   ko.observableArray([
                { Name : 'Raheel',Age:27},
                { Name : 'Saleem',Age:24},
                { Name : 'Aamir',Age:25}
            ])
 
            self.Navigate = function(page){
                if(page == 'list'){
                    window.location =   'list.html'
                }else if(page == 'form'){
                    window.location =   'form.html'
                }else{
                    window.location =   'home.html'
                }
            }
        }
 
        $( document ).ready(function() {
            ko.applyBindings(new page())
        })
        </script>
    </head>
    <body>
        <h2 data-bind='text:Title'></h2>
 
        <table>
            <thead>
                <tr>
                    <td>Name</td>
                    <td>Age</td>
                </tr>
            </thead>
            <tbody data-bind='foreach:Users'>
                <tr>
                    <td data-bind='text:$data.Name'></td>
                    <td data-bind='text:$data.Age'></td>
                </tr>
            </tbody>
        </table>
 
        <table>
            <tr>
                <td>Go to Home Page </td>
                <td><a data-bind="click:Navigate.bind($data,'home'),text:'Home'"></a></td>
            </tr>
            <tr>
                <td>Go to Form Page </td>
                <td><a data-bind="click:Navigate.bind($data,'form'),text:'Form'" /></td>
            </tr>
        </table>
    </body>
</html>

OK. The structure of all pages is pretty simple. But some things here are to be noted.
1.Title property is duplicating in every viewmodel.
2.Navigate function is duplicating in ever viewmodel.

The Solution

So we are now going to work around to write succinct and DRY code.
In the first step we are going to create a parent viewmodel.

<script type="text/javascript">
    function VM() {
        var self = this;
 
        self.Title  =   ko.observable('Knockout! Parent and Child Usage Techniques')
        self.Home   =   ko.observable()
        self.Form   =   ko.observable()
        self.List   =   ko.observable()
 
        self.ParentMethod = function(data){
            console.log('Hi! i am called from a child');
        }
 
        self.Navigate = function(page){
            if(page == 'list'){
                window.location =   'list.html'
            }else if(page == 'form'){
                window.location =   'form.html'
            }else{
                window.location =   'home.html'
            }
        }
    }
 
    var vm = new VM()
</script>

OK. In this viewmodel we have moved navigation function and Title property as we will be using it on every page. Here i have created observable property for every page. Home property for home.html Form property for form.html and so on. Next i have written Title property we will be calling on every page. And Navigation function we will be calling on every page. This lets us write common code between page to write only on one place.

Now lets see pages then i will describe how the magic works.

Home.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript" src="js/parentModel.js" ></script>
        <script type="text/javascript">
        var page = function(parent) {
            var self = this
 
            self.FirstName  =   ko.observable()
            self.LastName   =   ko.observable()
 
            self.LoadData   =   function(){
                self.FirstName('Muhammad')
                self.LastName('Raheel')
            }
 
            self.HomePageMethod =   function(){
                console.log('I am called from Home page.')
            }
 
            /*  Call LoadData for Initialization    */
            self.LoadData()
        }
 
        $( document ).ready(function() {
            vm.Home(new page(vm))
            ko.applyBindings(vm)
        })
        </script>
    </head>
    <body data-bind='with:Home'>
        <h2 data-bind='text:$root.Title'></h2>
        <h3 data-bind='text:FirstName'></h3>
        <h3 data-bind='text:LastName'></h3>
        <p data-bind='text:"ClickMe",click:HomePageMethod'></p>
        <table>
            <tr>
                <td>Go to Form Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'form'),text:'Form'" /></td>
            </tr>
            <tr>
                <td>Go to List Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'list'),text:'List'"></a></td>
            </tr>
        </table>
    </body>
</html>

Here is form.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript" src="js/parentModel.js" ></script>
        <script type="text/javascript">
        var page = function(parent) {
            var self = this
 
            self.FirstName  =   ko.observable()
            self.LastName   =   ko.observable()
            self.FullName   =   ko.computed(function(){
                return self.FirstName() +' '+self.LastName()
            })
 
            self.LoadData   =   function(){
                self.FirstName('Muhammad')
                self.LastName('Raheel')
            }
 
            self.FormPageMethod =   function(){
                console.log('I am called from Form page.')
            }
 
            /*  Call LoadData for Initialization    */
            self.LoadData()
        }
 
        $( document ).ready(function() {
            vm.Form(new page(vm))
            ko.applyBindings(vm)
        })
        </script>
    </head>
    <body data-bind='with:Form'>
        <h2 data-bind='text:$root.Title'></h2>
        <input type="text" data-bind='value:FirstName' />
        <br />
        <input type="text" data-bind='value:LastName' />
        <br />
        <h2 data-bind='text:FullName'></h2>
        <p data-bind='text:"ClickMe",click:FormPageMethod'></p>
        <table>
            <tr>
                <td>Go to Home Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'home'),text:'Home'"></a></td>
            </tr>
            <tr>
                <td>Go to List Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'list'),text:'List'"></a></td>
            </tr>
        </table>
    </body>
</html>

And here is list.html

<!DOCTYPE html>
<html>
    <head>
        <title>Knockout! Parent Child Usage </title>
        <link rel="stylesheet" type="text/css" href="css/style.css" />
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/knockout-2.3.0.js" ></script>
        <script type="text/javascript" src="js/parentModel.js" ></script>
        <script type="text/javascript">
        var page = function(parent) {
            var self = this
 
            self.Users  =   ko.observableArray([
                { Name : 'Raheel',Age:27},
                { Name : 'Saleem',Age:24},
                { Name : 'Aamir',Age:25}
            ])
 
            self.ListPageMethod =   function(){
                console.log('I am called from List page.')
            }
        }
 
        $( document ).ready(function() {
            vm.List(new page(vm))
            ko.applyBindings(vm)
        })
        </script>
    </head>
    <body data-bind='with:List'>
        <h2 data-bind='text:$root.Title'></h2>
 
        <table>
            <thead>
                <tr>
                    <td>Name</td>
                    <td>Age</td>
                </tr>
            </thead>
            <tbody data-bind='foreach:Users'>
                <tr>
                    <td data-bind='text:$data.Name'></td>
                    <td data-bind='text:$data.Age'></td>
                </tr>
            </tbody>
        </table>
        <p data-bind='text:"ClickMe",click:ListPageMethod'></p>
        <table>
            <tr>
                <td>Go to Home Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'home'),text:'Home'"></a></td>
            </tr>
            <tr>
                <td>Go to Form Page </td>
                <td><a data-bind="click:$root.Navigate.bind($data,'form'),text:'Form'" /></td>
            </tr>
        </table>
    </body>
</html>

In all the above peges the technique is same. so i am only describing home.html.
Before this we can put a glance on the structure again

/myapp/
    /js/
        /jquery.js
        /knockout-2.3.0.js
        /parentModel.js
    /css/
        /style.css
    /home.html
    /form.html
    /list.html

OK. Here you can see i have added parentModel on every page like this

<script type="text/javascript" src="js/parentModel.js" ></script>

This is because we are going to attach parentModel to every page.¬†As you can see we created a model for home.html and assigned it in parentModel’s Home property which is observable.¬†The other important thing and the magic IS this line

<body data-bind='with:Home'>

With this we are telling home page to use the model we just assigned to Home property.¬†If we skip this step we will be facing ‘Unable to parse binding’. Or we will need to do some workaround.¬†Using with binding will let us use child model’s properties and methods as usual as though we are using a¬†simple model for a page.

Now lets have a look how we can use child methods and properties then we will be seeing how we can use parent properties and methods.

How to Use Child Properties and Methods?

Now as we are using with binding on our body tag it means inside body we can use any property or method of child viewmodel.

Accessing Methods

For accessing child we have 3 choices. Lets say i want to call HomePageMethod which is method of  childmodel.

Use $data keyword

<p data-bind='text:"ClickMe",click:$data.HomePageMethod'></p>

This method of calling childmodel’s methods is not recommended. Because it can create some problem when you are inside¬†a loop.

Start from root

<p data-bind='text:"ClickMe",click:$root.Home().HomePageMethod'></p>

This method is fine but not recommended too. Although it will never produce any problem but to write readable and clean¬†code use $root only for calling parent Model’s method and properties so that you can easily distinguish between parent¬†and child usage.

Or use simple call.

<a data-bind='text:"Console Me too", click:HomePageMethod'></a>

This will give you a neat and clean code to understand and you can easily find that this is a call to child method.

Passing Parameters to Child Method

You can use any method of passing parameters to methods. For this you can see the documentation

Accessing Properties

For accessing properties we have all three choices. I recommend the last one.

<a data-bind='text:FirstName'></a>

How to Use Parent Methods and Properties?

Accessing Parent Methods

Use $root keyword

<a data-bind="click:$root.Navigate.bind($data,'form'),text:'Form'" />

This will let us use parentModel’s Navigate method.

Passing Parameters

Passing parameters method is same just like we did for child methods.

Accessing Properties

To access any property of parent class you can use $root keyword.

<h2 data-bind='text:$root.Title'></h2>

This will display parentModel’s Title property.

Final Thoughts

In the current post we have seen how we can use knockout to define a parent class and all the other classes will be assigned¬†as observable property of parent viewmodel. This structure only shows how you can write code which is common for multiple¬†viewmodels and you don’t want to write it in each viewmodel. Similiarly, Some properties that are common can be defined in¬†parent viewModel and will be available in each viewmodel. So here parent means a class that only contains common code nothing¬†else. Hope this helps. For any question you can give response.


Things Codeigniter Lacks

January 1, 2014 1 Comments

Things Codeigniter Lacks

This is my first ever post. I have been using Codeigniter for two years now. Although i liked this framework too much and this gives a kick start to a new programmer. I have used this framework following techniques of Jamie Rumbelow by customizing MY_Controller and MY_Model. I should mention here Phil Sturgeon’s template library the best one. The CMS based on this framework called Halogy is the product i like most which is under development again now. Customizing after too much research and googling it is still gives some lapses which i would like to share here.

1. Extending Core Classes

        Extending core classes is a great functionality for programmers and gives control over the framework. How ever, this is also a pain if i need to work on multiple projects where there are different requirements for each project and each time i am bound to customize core classes to meet my requirements.

2. Creating Instance

    In Codeigniter you may have seen that  for many libraries and helpers you are creating instance something like this

$CI = &get_instance();

Although this way you can access parent class any where in the application just by calling above instruction but programmers like me are lazy enough to use this. I wanted to gain access over the instance anywhere in the application without initializing the instance every time. I have seen another great PHP framework called Laravel (where i am moving now after using CI for two years) is giving exactly the same thing i want. The reason is that it caused me a lot of problem while coding because with Codeigniter i am habitual to use $this keyword and if i forget somewhere to initialize the instance than it produces problem and it is a time wasteage. I should mention here Laravel uses static methods which does not need to load or include before using.

3. File Upload

¬† ¬† The problem with file upload is pretty simple but i am surprised to see no one has ever mentioned this problem in the blogs and articles and even forum (or i may be missing). When working with file uploads with other form data and great form_validation class. To understand this problem let’s go step by step.

I have a form with file field and text boxes and other input boxes. Now using form validation class i can validate fields. While validating a file field i am bound to use do_upload method of Upload class. The problem rises when text boxes validation fails and file has been uploaded to server. This is not what i want. What if validation fails for 5 times. Five files will be uploaded to server and take space. Instead i only wanted to validate file and if validation is successful than upload the file. I had to do a work around for this problem by extending Upload class.

Here is a reference to my work.

4. Pagination

     Another lack i see is pagination problem. Although pagination class is simple and good but it would be batter if we can use a per page functionality. I mean if there exist a method that would allow user to view how many records per page he wants to see but i found about this no luck and of course, i had to do work around for this too.

These are simple thoughts. I don’t say Codeigniter is bad but i need this in a framework and i expect a framework is what provides more control and easy to a programmer. People might have found other things too and i am expecting Ellis Labs to improve the Codeigntier version with all the things that attracts programmers.