<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John Kalberer</title>
	<atom:link href="http://johnkalberer.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://johnkalberer.com</link>
	<description></description>
	<lastBuildDate>Wed, 14 Dec 2011 00:13:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Holiday Fun</title>
		<link>http://johnkalberer.com/2011/12/13/holiday-fun/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=holiday-fun</link>
		<comments>http://johnkalberer.com/2011/12/13/holiday-fun/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 00:12:21 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Game]]></category>
		<category><![CDATA[ImpactJS]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=187</guid>
		<description><![CDATA[Just a quick diversion between company projects at work. &#160;This is our company holiday card. &#160;I used ImpactJS to write it &#8212; the library had some compatibility issues here and there with various mobile devices but overall it is a good framework. P.S. &#160;I am back in the land of Appcelerator for the time being [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick diversion between company projects at work. &nbsp;This is our company holiday card. &nbsp;I used <a href="http://impactjs.com/">ImpactJS</a> to write it &#8212; the library had some compatibility issues here and there with various mobile devices but overall it is a good framework.</p>
<div style="width:100%">
<div style="margin:0 auto;width:340px;">
<iframe style="width: 340px; height: 480px; overflow: hidden;border:0;" src="http://johnkalberer.com/proj/snow/"></iframe>
</div>
</div>
<p>P.S. &nbsp;I am back in the land of Appcelerator for the time being so I should have a large update to the Mvc framework at some point.</p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/12/13/holiday-fun/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Appcelerator Mvc Example</title>
		<link>http://johnkalberer.com/2011/09/29/appcelerator-mvc-example/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=appcelerator-mvc-example</link>
		<comments>http://johnkalberer.com/2011/09/29/appcelerator-mvc-example/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 18:34:05 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Appcelerator]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[jsAutomapper]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[titanium]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=135</guid>
		<description><![CDATA[So as promised, I am diving deeper into my Appcelerator Mvc framework. In this post I will give more complex examples on how to use my framework in conjunction with joli so you can truely see how to integrate my framework in a complex, data-driven application. If you haven&#8217;t read over the basics or how [...]]]></description>
			<content:encoded><![CDATA[<p>So as promised, I am diving deeper into my Appcelerator Mvc framework. In this post I will give more complex examples on how to use my framework in conjunction with <a href="https://github.com/xavierlacot/joli.js" target="_blank">joli</a> so you can truely see how to integrate my framework in a complex, data-driven application. If you haven&#8217;t read over the basics or how the routing module works, I recommend you do so. You may also want to read my post on jsAutomapper.<span id="more-135"></span></p>
<p><a title="MVC for Appcelerator" href="http://johnkalberer.com/2011/09/08/mvc-for-appcelerator/">Appcelerator Mvc Introduction</a><br />
<a title="Appcelerator Mvc : Routing" href="http://johnkalberer.com/2011/09/13/appcelerator-mvc-routing/">Appcelerator Mvc Routing</a><br />
<a title="AutoMapper in javascript" href="http://johnkalberer.com/2011/08/24/automapper-in-javascript/">jsAutomapper</a></p>
<hr />
<h2>Setup</h2>
<p>If you follow along with this post you will end up with the same working example I have on the Appcelerator Marketplace. If you just want to walk through the example you can download the project <a title="Appcelerator Mvc" href="http://johnkalberer.com/wp-content/uploads/2011/10/mvc-full.zip" target="_blank"><strong>here</strong></a>. The first thing you are going to want to do is create a new, blank Appcelerator mobile project. Next, save these files and add them to your project:</p>
<ul>
<li><a href="http://johnkalberer.com/wp-content/uploads/2011/09/mvc.js">mvc.js</a></li>
<li><a href="http://johnkalberer.com/wp-content/uploads/2011/09/jsAutomapper.js">jsAutomapper.js</a></li>
<li><a href="https://github.com/xavierlacot/joli.js" target="_blank">joli.js</a></li>
</ul>
<p>You can place the files in the &#8220;~/Resources&#8221; folder or create a subfolder if you prefer. Through this example I will base all my code on the idea that you placed these files in this folder.</p>
<h2>app.js</h2>
<p>Now that you have added the files to the project we are ready to start writing code. Delete everything inside of the app.js file so we can start from scratch. Next add the following code. This will setup any includes we need for the mvc framework. The includes listed here take care of the Mvc framework itself as well as any Controllers you plan on using in your project. I also include a file named &#8220;dal.js&#8221; which is used to access the database and any data models we will need. We will uncomment this line later. We haven&#8217;t created these Controllers yet but list them here anyway &#8212; that&#8217;s coming up in our next step. The last line initializes the Mvc framework and sets up your Controllers as well as Views.</p>
<pre class="brush: js">	Ti.include('mvc.js'); 

	//Ti.include("/dal.js");

	Ti.include('/controllers/HomeController.js');
	//Ti.include('/controllers/AccountsController.js');

	Mvc.init();</pre>
<p>The next portion we have is adding any routes you may want. In this example I include a default route as well as a specific route. I won&#8217;t explain the routing here as I have already gone over it in my <a href="http://johnkalberer.com/2011/09/13/appcelerator-mvc-routing/">routing post</a></p>
<pre class="brush: js">	// make a specific route
	Mvc.mapRoute(
		"DoStuff_Route",
		"DS",
		{
			controller : "Home",
			action : "DoStuff"
		}
	)

	// map a default route
	Mvc.mapRoute(
		"Default_Route",
		"{controller}.{action}.{text}", // could also be {controller}/{action}/{id}
		{
			controller : "Home",
			action : "Default",
			text : "Default Text"
		});</pre>
<p>The last major portion of the code sets up your window management. I use this code as a hook in case you want to render your windows differently or even use this Mvc framework in another context (i.e. the web). In my implementation I basically keep track of a window stack and open/close the windows when appropriate. It should be fairly easy to create your own implementation if you desire alternative behavior&#8230; Anyway, here is the code. I have commented it pretty extensively so you should be able to get the gist of it.</p>
<pre class="brush: js">// manage the windows -- window stack
var openWindows = [];

Mvc.render = function(ui, routeData) {
	var win, index, routeName = routeData.controller + "." + routeData.action;

	// find the index in the stack of windows
	for(var i = openWindows.length - 1; i &gt;= 0; i -= 1) {
		if(openWindows[i]._title === routeName) {
			win = openWindows[i];
			index = i + 1;
			break;
		}
	}
	function cleanup(index) {
		for(var i = index; i &lt; openWindows.length; i += 1) {
			openWindows[i].close();
			openWindows[i] = null;
		}
		openWindows = openWindows.splice(0, index);
	}
	// if the window already exists in the stack
	if(win) {
		// clean up array -- remove all windows
		cleanup(index);

		// remove children from current view
		var children = win.children;
		for(var i = 0; i &lt; children.length; i += 1) {
			win.remove(children[i])
		}
	} else {
		// create a new window
		win = Ti.UI.createWindow({
			_title : routeName,
			fullscreen : true
		});

		win.addEventListener('close', function() {
			// find the index of this window so we can remove it when the back button is pressed
			for(var i = openWindows.length - 1; i &gt;= 0; i -= 1) {
				if(openWindows[i]._title === routeName) {
					index = i;
					break;
				}
			}
			cleanup(index);
		});

		// This handles the creation of the first window so that
		// Appcelerator will exit your app when this window is closed.
		if(openWindows.length === 0) {
			win.exitOnClose = true;
		}

		openWindows.push(win);
		win.open();
	}

	// This adds the controls you created in your view
	win.add(ui);

	// return the window incase you need it for something in your view
	return win;
};</pre>
<p>The last portion of code we need to add to app.js is used to start up the app and navigate to the correct window. If you do not pass any parameters it will resolve to your default route. If you want a specific route then simply pass the appropriate parameters.</p>
<pre class="brush: js">	// This will go off and attempt to render the default route and will
	// fail since we have not created the 'Home' controller yet
	Mvc.start();</pre>
<h2>The Controllers</h2>
<p>Next up we will create the our Controllers. First create a folder named &#8220;controllers&#8221; and place it under the &#8220;~/Resources&#8221; folder. Next create javascript files named &#8220;HomeController.js&#8221; and &#8220;AccountsController.js&#8221; under the &#8220;controllers&#8221; folder. First we will implement the &#8220;HomeController&#8221;. The code in this portion is very straight forward as this Controller does not use the Data Access Layer (dal.js) so we can implement the entire Controller. The &#8220;AccountsController&#8221; on the other hand is fairly complex and uses the Data Access Layer (dal.js) so we will focus on that later.</p>
<h2>HomeController</h2>
<p>Here is the implementation of the &#8220;HomeController&#8221;. The first portion is simply the includes the the Views used by this controller. I structure my code so each Action of the Controller has its own View.</p>
<pre class="brush: js">	// This will be the location for the 'Default' view
	Ti.include('/views/Home/Default.js');
	// another view
	Ti.include('/views/Home/DoStuff.js');</pre>
<p>The next portion is the shell of the Controller. It is a closure which takes in Mvc.Controllers as its parameter so we can populate the framework with all the controllers.</p>
<pre class="brush: js">	(function(c) {
		c.HomeController = {
			// Actions go here...
		};
	}(Mvc.Controllers));</pre>
<p>Inside the HomeController object we now add the Actions &#8220;Default&#8221; and &#8220;DoStuff&#8221;. In the &#8220;Default&#8221; method we create a Model to populate our UI. It populates the Model with things passed to the Action or default values defined in any routes we add in app.js. The &#8220;DoStuff&#8221; Action takes in a string as a parameter, modifies it, and sends it off to its view for rendering. I will show the implementation of &#8220;DefaultModel&#8221; in the next step. We return this model in the &#8220;this.view&#8221; function call of the &#8220;Default&#8221; Action which will send the Model to the view to render out.</p>
<pre class="brush: js">	Default : function(text, other) {
		// Create the model and populate it with some values
		var model = DefaultModel();
		model.text = text;
		model.value = text;

		// This returns a view and tells the framework to render the
		// 'Default' view using the model we created.
		return this.view('Default', model);
	},
	// we could add another action here
	DoStuff : function (value) {
		// manipulate the value parameter and return the appropriate view
		return this.view('DoStuff', value + "!!!");
	}</pre>
<p>Here is the implementation for &#8220;DefaultModel&#8221;. It is simply a factory to create an object.</p>
<pre class="brush: js">	function DefaultModel() {
		return {
			text : null,
			value : 0
		};
	}</pre>
<p>Here is what the &#8220;HomeController.js&#8221; file should look like in the end:</p>
<pre class="brush: js">	// This will be the location for the 'Default' view
	Ti.include('/views/Home/Default.js');
	// another view
	Ti.include('/views/Home/DoStuff.js');

	(function(c) {
		// This is just a basic model used to render
		// the 'Default' view.
		function DefaultModel() {
			return {
				text : null,
				value : 0
			};
		}
		// Initializes the 'HomeController' in Mvc.Controllers
		c.HomeController = {
			Default : function(text, other) {
				// Create the model and populate it with some values
				var model = DefaultModel();
				model.text = text;
				model.value = text;

				// This returns a view and tells the framework to render the
				// 'Default' view using the model we created.
				return this.view('Default', model);
			},
			// we could add another action here
			DoStuff : function (value) {
				// manipulate the value parameter and return the appropriate view
				return this.view('DoStuff', value + "!!!");
			}
		};
	}(Mvc.Controllers));</pre>
<p>That is it for our controllers for the moment. Like I said, the AccountsController has more complexities we need to tackle first so we will ignore the file for now.</p>
<h2>Home Controller Views</h2>
<p>The first thing we need to do here is create a &#8220;views&#8221; folder under &#8220;~/Resources&#8221; and then a &#8220;Home&#8221; folder under the &#8220;views&#8221; folder. Now create &#8220;Default.js&#8221; and &#8220;DoStuff.js&#8221; at &#8220;~/Resources/views/Home&#8221;. We start off by implementing the shell for the &#8220;Default&#8221; view. This works similar to Controllers in the fact that we pass &#8220;Mvc.Views&#8221; into a closure. We make sure that the object in which the View resides (in this case Home) exists and create it if it doesn&#8217;t. We then define our View as a function.</p>
<pre class="brush: js">	(function(v) {
		// Create the 'Home' object if it doesn't already exist
		if(!v.Home) {
			v.Home = {};
		}

		/*
		 * Render the default page
		 */
		v.Home.Default = function(model) {

		};
	}(Mvc.Views));</pre>
<p>The next portion of code will set up the actual UI elements of the window. We create a label and textfield which are populated from the model that was returned from the &#8220;HomeController.Default&#8221; Action and is passed into the function we defined in &#8220;Home.Default&#8221; View. There is also a button that we will use to navigate to the &#8220;HomeController.DoStuff&#8221; Action we previously defined. Since we added the &#8220;DoStuff_Route&#8221; in the app.js we can use the alias of &#8220;DS&#8221; to navigate there. The text value from the textbox is also passed to the Action. Lastly we return the View which contains all the controls used in the window. It is important that we have a single UI object to contain the entire View so it can be added appropriately to the window. This UI object will be used to populate a window created in the &#8220;Mvc.render&#8221; function we also defined in app.js.</p>
<pre class="brush: js">	// get a reference to the view
		// get a reference to the view
		var self = this;

		var view = Ti.UI.createView();
		var label = Ti.UI.createLabel({
		    text : model.text,
		    top: "5%",
		    height : "5%"
		});
		var textField = Ti.UI.createTextField({
		    value : model.value,
		    top : "10%",
		    width: "50%",
		    height: "5%",
			backgroundColor: "#ffffff",
		    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
		});
		var button = Ti.UI.createButton({
		    title : "Submit",
		    width: "50%",
		    height : "15%"
		});

		// This will call DoStuff
		button.addEventListener("click", function(e) {
		    // Uses a specific route ('DS') we defined in app.js
		    self.action("DS", textField.value);
		});
		view.add(label);
		view.add(textField);
		view.add(button);

		return view;</pre>
<p>In the end your code for the &#8220;Home.Default&#8221; view should look like this:</p>
<pre class="brush: js">	(function(v) {
    // Create the 'Home' object if it doesn't already exist
    if(!v.Home) {
        v.Home = {};
    }

    /*
     * Render the default page
     */
    v.Home.Default = function(model) {
		// get a reference to the view
		var self = this;

		var view = Ti.UI.createView();
		var label = Ti.UI.createLabel({
		    text : model.text,
		    top: "5%",
		    height : "5%"
		});
		var textField = Ti.UI.createTextField({
		    value : model.value,
		    top : "10%",
		    width: "50%",
		    height: "5%",
			backgroundColor: "#ffffff",
		    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
		});
		var button = Ti.UI.createButton({
		    title : "Submit",
		    width: "50%",
		    height : "15%"
		});

		// This will call DoStuff
		button.addEventListener("click", function(e) {
		    // Uses a specific route ('DS') we defined in app.js
		    self.action("DS", textField.value);
		});
		view.add(label);
		view.add(textField);
		view.add(button);

		return view;
    };
}(Mvc.Views));</pre>
<p>Now we can start in on the &#8220;Home.DoStuff&#8221; View. This view is very simple and just displays the text in the textbox of the &#8220;Home.Default&#8221; View in addition to a modification (the &#8216;!!!&#8217;) in the &#8220;HomeController.DoStuff&#8221; Action.</p>
<pre class="brush: js">	(function(v) {
		// Create the 'Home' object if it doesn't already exist
		if(!v.Home) {
			v.Home = {};
		}

		/*
		 * Render the DoStuff page
		 */
		v.Home.DoStuff = function(model) {
			var view = Ti.UI.createView({
				backgroundColor : "#fff"
			});
			var label = Ti.UI.createLabel({
				text : model,
				color : "#000"
			});

			view.add(label);

			return view;
		};
	}(Mvc.Views));</pre>
<p>That covers the source up to getting the HomeController running. You should now be able to run the project and see the framework in action although it is a boringly simple app at this point. When you run you should see some text and a textbox. If you modify the text it will show up in the next window along with three exclamation points. Next up we will get into working with joli and the DAL. <strong>If you followed all the steps correctly you should end up with <a href="http://johnkalberer.com/wp-content/uploads/2011/10/mvc-basic.zip">this</a>.</strong></p>
<h2>Data Access and Data Models</h2>
<p>Let me start off first by saying that the Data Access Layer can be a nasty thing if you let it. This is why I prefer to user an <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a> such as joli. This allows you to avoid writing data access code which may end up getting placed in your controller Actions which really defeats separation of concerns. It also allows you to reuse a ton of common functionality with a common API. In addition you can get down and dirty with custom SQL queries when you need it. Anyways, if you haven&#8217;t already, create a &#8220;dal.js&#8221; file and save it under the &#8220;~/Resources&#8221; folder. <strong>You also need to go to app.js and uncomment the &#8220;//Ti.include(&#8220;/dal.js&#8221;);&#8221; line.</strong> The source in this file will be fairly simple as we want to separate out the Data Access code to keep everything neat and tidy. We also will create a global object for accessing the DAL from any other file. So again we create our closure passing in the &#8220;Ti.App&#8221; object.</p>
<pre class="brush: js">	var dal = (function(app) {
		// if the dal has already been defined, return
		if(app.dal) {
			return;
		}

		// initialize the dal object and get a local reference
		var d = app.dal = {};

		return d;
	}(Ti.App));</pre>
<p>Next up we will add all our references to libraries/models we will need and set up our database. After this, add the following code.</p>
<pre class="brush: js">	Ti.include("/joli.js");
	Ti.include("/jsAutomapper.js");

	// set up our database
	joli.connection = new joli.Connection('SampleDatabase');

	// run setup for all models
	Ti.include("/models/Accounts.js");

	// models have been setup. initialize the database
	joli.models.initialize();</pre>
<p>This code creates a database called &#8220;SampleDatabase&#8221; you can name the database whatever you want here. We will do setup for the various tables in the models files &#8212; &#8220;/models/Accounts.js&#8221; for example. When we finally call &#8220;joli.models.initialize&#8221; we have completed our setup of the DAL.</p>
<p>Here is the final source for &#8220;dal.js&#8221;</p>
<pre class="brush: js">	var dal = (function(app) {
	// if the dal has already been defined, return
	if(app.dal) {
		return;
	}

	// initialize the dal object and get a local reference
	var d = app.dal = {};

	return d;
}(Ti.App));

Ti.include("/joli.js");
Ti.include("/jsAutomapper.js");

// set up our database
joli.connection = new joli.Connection('SampleDatabase');

// run setup for all models
Ti.include("/models/Accounts.js");

// models have been setup. initialize the database
joli.models.initialize();
</pre>
<p>Now with that out of the way, we can focus on setting up our Accounts Model. First off, create a folder under &#8220;~/Resources&#8221; called &#8220;models&#8221;. Next create a javascript file called &#8220;Accounts.js&#8221;. This file will be used to house all database initialization code as well as and automapper code used to map between Models and View Models. Models are used to transfer data from your database tables and View Models are objects which map directly to a specific view.</p>
<p>So start off your model implementation by passing &#8220;Ti.App.dal&#8221; into a closure and validating that the &#8220;dal&#8221; object has defined and the &#8220;dal.accounts&#8221; property has not.</p>
<pre class="brush: js">	(function() {
		// dal has not been initialized or accounts have already been initailized
		if(!dal || dal.accounts) {
			return;
		}

	}());</pre>
<p>Next up we will actuall setup our table in the database using joli. This creates a simple table named &#8220;Accounts&#8221; with a few columns (firstName, lastName, email). If you read through the <a href="https://github.com/xavierlacot/joli.js" target="_blank">joli API</a>, it explains you can also add prototype functions to any Account Models as well as helper functions to the dal.accounts object when you do your initialization. I won&#8217;t get into that here but I have found it very useful for extending the existing API.</p>
<pre class="brush: js">	dal.accounts = new joli.model({
		table : 'Accounts',
		columns : {
			id : 'INTEGER PRIMARY KEY AUTOINCREMENT',
			firstName : 'TEXT',
			lastName : 'TEXT',
			email : 'TEXT',
		}
	});</pre>
<p>The next portion is mapping your View Models to your Models and vice-versa. For a Mvc framework I think this is a very important process. I am using jsAutomapper although I am sure there are similar solutions out there. It creates a single place for setting up a transformation between two objects and forms a contract between them. This way if you change a property in your database or in your View Model, you will get immediate feedback when the objects no longer map correctly. You can write unit tests that simply check that the two objects map correctly. This way you don&#8217;t have &#8220;undefined&#8221; showing up in your UI with no knowledge of where it was supposed to be populated or have a random &#8220;object is undefined&#8221; exception from a View Model property show up on some Action or View you haven&#8217;t worked on in weeks.</p>
<p>Here is the next bit of code you need for the Accounts Model. I will let you read through the code/comments and then go over what is actually going on here.</p>
<pre class="brush: js">	// automapper mappings for this model

	// include view models - models can be mapped to multiple view models
	Ti.include("/viewModels/AccountViewModel.js");
	Ti.include("/viewModels/AccountsViewModel.js");
	Ti.include("/viewModels/CreateAccountViewModel.js");

	// This maps an Account to an AccountViewModel -- I pass in the destination key
	// as a function so automapper can use it to create viewmodels
	automapper.createMap("Account", AccountViewModel)
		// we don't actually need the 'firstName' since the column name matches the view model name 1-to-1
		// I just include it as an example
		.forMember("firstName", function() { return this.mapFrom("firstName") })
		// ignore this field since we already have it implemented
		.forMember("fullName", function() { return this.ignore(); });

	// model maps 1-to-1 -- we don't need to set up any members
	automapper.createMap("Account", "CreateAccountViewModel");

	// This maps an AccountViewModel to an Account
	automapper.createMap("CreateAccountViewModel", "Account")
		/*
		 * forAllMembers is run for every mapping
		 * dest - the destination object
		 * prop - the property name to set
		 * value - the value from the source
		*/
		.forAllMembers(function(dest, prop, value) {
			// tell joli to properly set the values
			dest.set(prop, value);
		})
		// ignore joli internal properties
		.forMember("_data", function() { this.ignore(); })
		.forMember("_metadata", function() { this.ignore(); })
		.forMember("_options", function() { this.ignore(); })
		.forMember("_originalData", function() { this.ignore(); })
		.forMember("isNew", function() { this.ignore(); });</pre>
<p>So first off we include references to View Model objects we have yet to define. These are simple files and we will get to them later. Next we create a map between an &#8220;Account&#8221; and a &#8220;AccountViewModel&#8221;. Doing so we can later on take two objects and map all the properties between the two. We add a &#8220;ignore&#8221; to the &#8220;fullName&#8221; property of the &#8220;AccountViewModel&#8221; &#8212; this is a function I have defined in &#8220;AccountViewModel&#8221; and we don&#8217;t want to override it. The next mapping between &#8220;Account&#8221; and &#8220;CreateAccountViewModel&#8221; is pretty self-explanatory. The last mapping between &#8220;CreateAccountViewModel&#8221; and &#8220;Account&#8221; is special in that we use the &#8220;forAllMembers&#8221; call. What this does is when we set any properties in the &#8220;Account&#8221; model, we call this function to do so. This must be done since &#8220;Account&#8221; is a joli object and you must call &#8220;set&#8221; in order to properly set the property on the object to let joli know that we have made changes to the object. If you don&#8217;t when you call &#8220;accountObj.save&#8221;, the database will not pick up our changes. The ignores on this mapping are simply properties which get added to ever joli object (Model). Here is the combined source for the &#8220;Accounts.js&#8221; file.</p>
<pre class="brush: js">	(function() {
		// dal has not been initialized or accounts have already been initailized
		if(!dal || dal.accounts) {
			return;
		}

		// create the accounts table
		dal.accounts = new joli.model({
			table : 'Accounts',
			columns : {
				id : 'INTEGER PRIMARY KEY AUTOINCREMENT',
				firstName : 'TEXT',
				lastName : 'TEXT',
				email : 'TEXT',
			}
		});

		// automapper mappings for this model

		// include view models - models can be mapped to multiple view models
		Ti.include("/viewModels/AccountViewModel.js");
		Ti.include("/viewModels/AccountsViewModel.js");
		Ti.include("/viewModels/CreateAccountViewModel.js");

		// This maps an Account to an AccountViewModel -- I pass in the destination key
		// as a function so automapper can use it to create viewmodels
		automapper.createMap("Account", AccountViewModel)
			// we don't actually need the 'firstName' since the column name matches the view model name 1-to-1
			// I just include it as an example
			.forMember("firstName", function() { return this.mapFrom("firstName") })
			// ignore this field since we already have it implemented
			.forMember("fullName", function() { return this.ignore(); });

		// model maps 1-to-1 -- we don't need to set up any members
		automapper.createMap("Account", "CreateAccountViewModel");

		// This maps an AccountViewModel to an Account
		automapper.createMap("CreateAccountViewModel", "Account")
			/*
			 * forAllMembers is run for every mapping
			 * dest - the destination object
			 * prop - the property name to set
			 * value - the value from the source
			*/
			.forAllMembers(function(dest, prop, value) {
				// tell joli to properly set the values
				dest.set(prop, value);
			})
			// ignore joli internal properties
			.forMember("_data", function() { this.ignore(); })
		        .forMember("_metadata", function() { this.ignore(); })
			.forMember("_options", function() { this.ignore(); })
			.forMember("_originalData", function() { this.ignore(); })
			.forMember("isNew", function() { this.ignore(); });
	}());</pre>
<p>With that completed we are nearly ready to start working on the &#8220;AccountsController&#8221;. The only thing left is to create a &#8220;viewmodels&#8221; folder under the &#8220;~/Resources&#8221; folder and the javascript files &#8220;AccountViewModel.js&#8221;, &#8220;AccountsViewModel.js&#8221;, and &#8220;CreateAccountViewModel.js&#8221;.</p>
<p>AccountViewModel.js</p>
<pre class="brush: js">	/*
	 * Simple Account model used for displaying Accounts in a list
	 */
	function AccountViewModel() {
		return {
			id : null,
			firstName : null,
			lastName : null,
			fullName : function() {
				return this.firstName + " " + this.lastName;
			}
		};
	}</pre>
<p>AccountsViewModel.js</p>
<pre class="brush: js">	/*
	 * A viewmodel which contains a collection of
	 * AccountViewModels
	 *
	 * In this case we could return a collection of
	 * AccountViewModels from the Accounts.Default action
	 * and I usually end up needing to pass additional data
	 */
	function AccountsViewModel() {
		return {
			accounts : []
		};
	}</pre>
<p>CreateAccountViewModel.js</p>
<pre class="brush: js">	function CreateAccountViewModel() {
		return {
			id : null,
			firstName : null,
			lastName : null,
			email : null
		};
	}</pre>
<h2>AccountsController</h2>
<p>We&#8217;ll start off the &#8220;AccountsController&#8221; much like the &#8220;HomeController&#8221;. If you haven&#8217;t already created a file for this, create one under &#8220;~/Resources/controllers&#8221; as &#8220;AccountsController.js&#8221;. After this you must <strong>uncomment &#8220;Ti.include(&#8216;/controllers/AccountsController.js&#8217;);&#8221; the line in app.js</strong>. Next add the stub controller code.</p>
<pre class="brush: js">	(function(c) {
		// include the views
		Ti.include("/views/Accounts/Default.js");
		Ti.include("/views/Accounts/Create.js");

		c.AccountsController = {
		};
	}(Mvc.Controllers));</pre>
<p>Again, we include the View files that we&#8217;ll create later. Next up come the Actions. I will go over each seperately. Stub out the &#8220;AccountsController&#8221; definition like this:</p>
<pre class="brush: js">	c.AccountsController = {
		Default : function() {
		},
		Create : function(id) {
		},
		CreateFinish : function(model) {
		},
		Delete : function(id) {
		}
	};</pre>
<p>So first off is the &#8220;Default&#8221; Action. In this view we want to allow the user to create new Accounts and edit/delete previously created &#8220;Accounts&#8221;. In order to do that we need to list all accounts in the view. So first off we use the DAL to get all Accounts. We then create an AccountsViewModel to house all the AccountViewModels. We then will use automapper to map between the two collections and then return the result to the View. Notice in the code that we pass the &#8220;AccountViewModel&#8221; to the &#8220;automapper.map&#8221; call. This is done in order for automapper to have a factory method to populate the &#8220;model.accounts&#8221; array with the appropriate View Model.</p>
<pre class="brush: js">	/*
	 * Default action which simply shows a list of Accounts
	 */
	Default : function() {
		// use the dal as a repository to grab all accounts
		var accounts = dal.accounts.all();

		var model = AccountsViewModel();

		// automapper knows to map the two collections
		automapper.map("Account", AccountViewModel, accounts, model.accounts);

		// return the model and render the view
		return this.view("Default", model);
	}</pre>
<p>Next up comes the &#8220;Create&#8221; Action. Notice how simple the function becomes now that we are using jsAutomapper to map the Model to View Model and joli for accessing the database. The &#8220;Create&#8221; function is essentialy a create/update method. If you pass in the &#8220;id&#8221; parameter we know that we are updating an existing &#8220;Account&#8221;. This action is used to simply populate the create/update UI.</p>
<pre class="brush: js">	/*
	 * Basic create/update operation for a new Account
	 */
	Create : function(id) {
		var model = CreateAccountViewModel();

		if(id) {
			automapper.map("Account", "CreateAccountViewModel", dal.accounts.findOneById(id), model)
		}

		return this.view("Create", model);
	}</pre>
<p>Next up is the &#8220;CreateFinish&#8221; Action (for lack of a better name). This Action writes any changes you made to the Account model to the database. If it is a new Account we will have joli instantiate an Account for us. If we are updating we query for the appropriate Account.</p>
<pre class="brush: js">	/*
	 * Finishes up the creation/update process by inserting the object into the database
	 */
	CreateFinish : function(model) {
		var account;
		if(!model.id) {
			account = dal.accounts.newRecord();
		} else {
			account = dal.accounts.findOneById(model.id);
		}
		automapper.map("CreateAccountViewModel", "Account", model, account);
		account.save();
	}</pre>
<p>Lastly is the &#8220;Delete&#8221; Action. This is a pretty boring and simple implementation and in this case, boring is good.</p>
<pre class="brush: js">	/*
	 * Delete an Account based on an id
	 */
	Delete : function(id) {
		dal.accounts.deleteRecords(id);
	}</pre>
<p>So that is the &#8220;AccountsController&#8221; in a nutshell. By abstracting much of the logic using a repository pattern (DAL) and using jsAutomapper for object transformation, we ended up with nice, slim controllers. Here is the &#8220;AccountsController.js&#8221; in its entirety.</p>
<pre class="brush: js">	(function(c) {
		// include the views
		Ti.include("/views/Accounts/Default.js");
		Ti.include("/views/Accounts/Create.js");

		c.AccountsController = {
			/*
			 * Default action which simply shows a list of Accounts
			 */
			Default : function() {
				// use the dal as a repository to grab all accounts
				var accounts = dal.accounts.all();

				var model = AccountsViewModel();

				// automapper knows to map the two collections
				automapper.map("Account", AccountViewModel, accounts, model.accounts);

				// return the model and render the view
				return this.view("Default", model);
			},
			/*
			 * Basic create/update operation for a new Account
			 */
			Create : function(id) {
				var model = CreateAccountViewModel();

				if(id) {
					automapper.map("Account", "CreateAccountViewModel", dal.accounts.findOneById(id), model)
				}

				return this.view("Create", model);
			},
			/*
			 * Finishes up the creation/update process by inserting the object into the database
			 */
			CreateFinish : function(model) {
				var account;
				if(!model.id) {
					account = dal.accounts.newRecord();
				} else {
					account = dal.accounts.findOneById(model.id);
				}
				automapper.map("CreateAccountViewModel", "Account", model, account);
				account.save();
			},
			/*
			 * Delete an Account based on an id
			 */
			Delete : function(id) {
				dal.accounts.deleteRecords(id);
			}
		};
	}(Mvc.Controllers));</pre>
<h2>Accounts Views</h2>
<p>The Accounts Views are much more advanced and paint a better picture on how to use the framework. First off is the &#8220;Default&#8221; View. This View allows CRUD on all Accounts. We will have a button to create new Accounts as well as a list of all Accounts that were previously created. This list allows you to select an Account for editing or deleting. This is accomplished by popping up an alert dialog with the options of &#8220;Edit&#8221;, &#8220;Delete&#8221;, and &#8220;Cancel&#8221;. So create an &#8220;Accounts&#8221; folder under &#8220;~/Resources/views&#8221; and create &#8220;Default.js&#8221; and &#8220;Create.js&#8221; javascript file under &#8220;~/Resources/views/Accounts&#8221;. Start off the view by creating its stub.</p>
<pre class="brush: js">	(function(v) {
		// Create the 'Accounts' object if it doesn't already exist
		if(!v.Accounts) {
			v.Accounts = {};
		}
		v.Accounts.Default = function(model) {
		};
	}(Mvc.Views));</pre>
<p>Next we can implement the &#8220;Default&#8221; function. I make a reference to the View as &#8220;self&#8221;. Next I create the view UI control in which we will house the rest of the controls. A button is then added to the view which has a click event which will navigate to the &#8220;Accounts.Create&#8221; action.</p>
<pre class="brush: js">	var self = this;

		var view = Ti.UI.createView({
			backgroundColor : "#000"
		});

		// a button to add a new account
		var createButton = Ti.UI.createButton({
			title : "Create Account",
			top : 0,
			height: "10%"
		});

		createButton.addEventListener("click", function(e) {
			self.action("Create");
		});

		view.add(createButton);</pre>
<p>Now that we have the create portion complete in this CRUD interface, we will implement the read portion. To do so I make a reference to the accounts passed through the View Model and start creating &#8220;TableViewRows&#8221; which are added to the collection. I give each row a property of &#8220;_id&#8221; which we will use when we want to update/delete any Account. Then I create simple &#8220;Alert&#8221; dialog &#8212; I will get to the implementation of the &#8220;click&#8221; event later. In the next portion of this code I create a table and populate it with the collection of rows. I also added a &#8220;click&#8221; event to the table in order to catch any click events on the table rows. I get the Account id I set in the row and assign it to the alert box. This will allow us to pass the id to the &#8220;AccountsController.Create&#8221; or &#8220;AccountsController.Delete&#8221; when we click one of the buttons in the &#8220;Alert&#8221; dialog. The last portion of the code is the &#8220;click&#8221; event for the &#8220;Alert&#8221; dialog. We use the index of our buttons to decide which action we wish to make when this event is fired. When someone clicks the delete button we call two actions. Since the &#8220;Delete&#8221; action does not return anything (Look at &#8220;AccountsController.Delete&#8221;), we know that no content should be displayed and that we shouldn&#8217;t open a new window. Right after that we call the &#8220;Accounts&#8221; action which resolves to &#8220;AccountsController.Default&#8221;. Since we are already displaying this window it simply refreshes the current page. This makes sense since we have now deleted one of the Accounts from the list.</p>
<pre class="brush: js">var accounts = model.accounts,
			data = [];
		for(var i = 0; i < accounts.length; i += 1) {
			data.push(Ti.UI.createTableViewRow({
				title : accounts[i].fullName(),
				// used to store data in the row so we can update later
				_id : accounts[i].id
			}));
		}

		// alert so you can choose to edit or delete
		var alertDialog = Ti.UI.createAlertDialog({
			buttonNames : ["Edit", "Delete", "Cancel"],
			cancel : 2
		});

		var table = Ti.UI.createTableView({
			data : data,
			top : "10%",
			height: "90%"
		});

		// click event for updating a row
		table.addEventListener("click", function(e) {
			// get the id of the Account from the row
			var id = e.row._id;
			alertDialog._id = id;
			alertDialog.show();
		});

		alertDialog.addEventListener("click", function(e) {
			// get the id from the alert box set in the table click event
			var id = e.source._id;
			if(e.index === 0) {
				self.action("Create", id);
			} else if(e.index === 1) {
				self.action("Delete", id);
				self.action("Accounts");  // routing will resolve to Accounts.Default
			}
		});

		view.add(table);

		return view;</pre>
<p>Here is the all the code for the View</p>
<pre class="brush: js">(function(v) {
	// Create the 'Accounts' object if it doesn't already exist
	if(!v.Accounts) {
		v.Accounts = {};
	}
	v.Accounts.Default = function(model) {
		var self = this;

		var view = Ti.UI.createView({
			backgroundColor : "#000"
		});

		// a button to add a new account
		var createButton = Ti.UI.createButton({
			title : "Create Account",
			top : 0,
			height: "10%"
		});

		createButton.addEventListener("click", function(e) {
			self.action("Create");
		});

		view.add(createButton);

		var accounts = model.accounts,
			data = [];
		for(var i = 0; i < accounts.length; i += 1) {
			data.push(Ti.UI.createTableViewRow({
				title : accounts[i].fullName(),
				// used to store data in the row so we can update later
				_id : accounts[i].id
			}));
		}

		// alert so you can choose to edit or delete
		var alertDialog = Ti.UI.createAlertDialog({
			buttonNames : ["Edit", "Delete", "Cancel"],
			cancel : 2
		});

		var table = Ti.UI.createTableView({
			data : data,
			top : "10%",
			height: "90%"
		});

		// click event for updating a row
		table.addEventListener("click", function(e) {
			// get the id of the Account from the row
			var id = e.row._id;
			alertDialog._id = id;
			alertDialog.show();
		});

		alertDialog.addEventListener("click", function(e) {
			// get the id from the alert box set in the table click event
			var id = e.source._id;
			if(e.index === 0) {
				self.action("Create", id);
			} else if(e.index === 1) {
				self.action("Delete", id);
				self.action("Accounts");  // routing will resolve to Accounts.Default
			}
		});

		view.add(table);

		return view;
	};
}(Mvc.Views));</pre>
<p>The last View we need to display is the Accounts "Create" View. This view is very straight forward and has only one major thing I need to talk about. If you haven't created a file for this, create a "Create.js" under "~/Resources/views/Accounts". Here is the source for the "Create" View.</p>
<pre class="brush: js">	 (function(v) {
		// Create the 'Accounts' object if it doesn't already exist
	if(!v.Accounts) {
		v.Accounts = {};
	}
	Ti.include("/utils.js");

	/*
	 * Render the Create page
	 */
	v.Accounts.Create = function(model) {
		var self = this;

		var view = Ti.UI.createView({
			backgroundColor : "#777777",
			height: "100%"
		});

		var fnLabel = Ti.UI.createLabel({
			text : "First Name",
			top: "5%",
			height : "5%"
		});
		var fnTextField = Ti.UI.createTextField({
			width:'50%',
			top : "10%",
			height:"5%",
			backgroundColor: "#ffffff",
		    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
		});
		model.firstName = utils.bind(fnTextField, model.firstName); // bind the textfield to the view model

		var lnLabel = Ti.UI.createLabel({
			text : "Last Name",
			top : "20%",
			height : "5%"
		});
		var lnTextField = Ti.UI.createTextField({
			width:'50%',
			top : "25%",
			height:"5%",
			backgroundColor: "#ffffff",
		    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
		});
		model.lastName = utils.bind(lnTextField, model.lastName); // bind the textfield to the view model

		var emailLabel = Ti.UI.createLabel({
			text : "Email",
			top : "35%",
			height : "5%"
		});
		var emailTextField = Ti.UI.createTextField({
			width:'50%',
			top : "40%",
			height:"5%",
			backgroundColor: "#ffffff",
		    keyboardType:Ti.UI.KEYBOARD_DEFAULT,
		});
		model.email = utils.bind(emailTextField, model.email); // bind the textfield to the view model

		var submit = Ti.UI.createButton({top : "50%", height: "10%"});

		if(model.id) {
			submit.title = "Update";
		} else {
			submit.title = "Create";
		}

		submit.addEventListener("click", function() {
			self.action("CreateFinish", model);
			self.action("Accounts");  // routing will resolve to Accounts.Default
		});

		view.add(fnLabel);
		view.add(fnTextField);
		view.add(lnLabel);
		view.add(lnTextField);
		view.add(emailLabel);
		view.add(emailTextField);

		view.add(submit);

		return view;
	};
}(Mvc.Views));</pre>
<p>The next thing you need to do is create a simple "utils.js" file.  I plan on extending the functionality of this class to include many helper functions but for now, it just enables two-way binding of the View Models to the controls.</p>
<pre class="brush: js">
var utils = (function(app) {
	if(app.utils) {
		return app.utils;
	}
	app.utils = {
		/*
		 * Very basic databinding with an Appcelerator control.
		 */
		bind : function(control, value, fieldName) {
			var self=control;
			if(!fieldName) {
				fieldName = "value";
			}
			function setValue(val) {
				if(typeof val === "undefined") {
					val = "";
				}
				self[fieldName] = val;
			}
			setValue(value);
			return function(input) {
				if(!input) {
					return self[fieldName];
				}
				setValue(value);
			};
		}
	};
	return app.utils;
}(Ti.App));
</pre>
<p>Now that we have completed the AccountsController, let's set up the app so it navigates to the AccountsController by default. Open up app.js and change the last line of the file to <strong>Mvc.start("Accounts");</strong></p>
<h2>Run It!</h2>
<p>That should be everything you need to run the application. This example application should be more than enough to get you going in developing your own application using my framework. As always leave any comments, suggestions, or bugs in my comments section.</p>
<p><strong>Here is the <a href="http://johnkalberer.com/wp-content/uploads/2011/10/mvc-full.zip">Completed Example</a></strong></p>
<h3>UPDATE</h3>
<p>Joel Brage was kind enough to port jsAutomapper to coffeescript. You can download it <a href="http://johnkalberer.com/wp-content/uploads/2011/10/automapper.coffee">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/09/29/appcelerator-mvc-example/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Appcelerator Mvc in Marketplace</title>
		<link>http://johnkalberer.com/2011/09/26/appcelerator-mvc-in-marketplace/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=appcelerator-mvc-in-marketplace</link>
		<comments>http://johnkalberer.com/2011/09/26/appcelerator-mvc-in-marketplace/#comments</comments>
		<pubDate>Mon, 26 Sep 2011 15:49:55 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Appcelerator]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=91</guid>
		<description><![CDATA[Hey, I just wanted to get it out there that my Appcelerator Mvc implementation is up in the Appcelerator marketplace. It has some bug fixes and improvements over the original example I gave here. This week I plan on writing the more in-depth tutorial for using the framework so that should give some better examples [...]]]></description>
			<content:encoded><![CDATA[<p>Hey, I just wanted to get it out there that my Appcelerator Mvc implementation is up in the <a href='https://marketplace.appcelerator.com/apps/837'>Appcelerator marketplace</a>.  It has some bug fixes and improvements over the original example I gave <a href="http://johnkalberer.com/2011/09/08/mvc-for-appcelerator/">here</a>.  </p>
<p>This week I plan on writing the more in-depth tutorial for using the framework so that should give some better examples on how to use the framework on a large application.</p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/09/26/appcelerator-mvc-in-marketplace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Appcelerator Mvc : Routing</title>
		<link>http://johnkalberer.com/2011/09/13/appcelerator-mvc-routing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=appcelerator-mvc-routing</link>
		<comments>http://johnkalberer.com/2011/09/13/appcelerator-mvc-routing/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 17:56:54 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Appcelerator]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[routing]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=117</guid>
		<description><![CDATA[Now that we have went over the basics of my Appcelerator Mvc implementation, we can move onto more advanced features. For this post I will focus on routing. The post should be fairly short since the routing is fairly straight forward. As I mentioned in the first post on this framework, I borrowed heavily from [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we have went over the <a href="http://johnkalberer.com/2011/09/08/structured-mvc-for-appcelerator/">basics of my Appcelerator Mvc implementation</a>, we can move onto more advanced features. For this post I will focus on routing. The post should be fairly short since the routing is fairly straight forward. As I mentioned in the first post on this framework, I borrowed heavily from the routing model used in Asp.Net. Although I don&#8217;t implement all the routing principles used in it&#8217;s model, I think what I have implemented should be more than enough for any Appcelerator application.<strong><span id="more-117"></span></strong> So lets start with a default route:</p>
<pre class="brush: js">	Mvc.mapRoute(
		"Default_Route",
		"{controller}.{action}.{text}", // could also be {controller}/{action}/{id}
		{
			controller : "Home",
			action : "Default",
			text : "Default Text"
		});</pre>
<p>The first parameter here is the name of the route. I use this only for keeping track of various routes incase you wish to override a previously defined route. The next parameter is the important part of the route. This is used to define what variables can be passed to an action. Anything that resides inside curly braces is considered a &#8216;variable&#8217;. The last parameter is an object which defines the default values to be used with the specified. So if we are targeting the default route and we do something like this (<strong>Note:</strong> Mvc.start is normally only called once in app.js but we can use it to see the various actions being hit):</p>
<pre class="brush: js">	Mvc.start(); // resolves to "Home.Default" passing "Default Text" to the 'text' parameter of the action
	Mvc.start("Default"); // resolves to "Home.Default" passing "Default Text" to the 'text' parameter of the action
	Mvc.start("Accounts"); // resolves to "Accounts.Default" passing "Default Text" to the 'text' parameter of the action
	Mvc.start("Home.Foo"); // resolves to "Home.Foo" passing "Default Text" to the text parameter of the action
	Mvc.start("Accounts.Bar.Value"); // resolves to "Accounts.Bar" passing "Value" to the text parameter of the action
	Mvc.start("Accounts", "Foo", 2); // resolves to "Accounts.Default" passing "Foo" to the first parameter and 2 to the second parameter</pre>
<p>After seeing that example you should have a basic idea of how the routing works. In general you should make a &#8220;default&#8221; catch-all route to make things easier to work with. Now lets add two more routes to make things interesting (Note: these routes need to be defined before the &#8220;Default_Route&#8221; as we will check for a match in them first).</p>
<pre class="brush: js">	Mvc.mapRoute(
		"Specific_Route",
		"DeleteAccount.{id}",
		{
			controller : "Account",
			action : "Delete"
		});

	Mvc.mapRoute(
		"Account_Route",
		"Account.{action}.{id}",
		{
			controller : "Account",
			action : "Default",
		});</pre>
<p>You can see that we have two entirely different routes that we have added. The first one is very specific and only has one variable. The &#8220;DeleteAccount&#8221; portion does not map to a controller. In this case we take advantage of the &#8216;default&#8217; parameters listed in the third argument. In the next route, you can see that it is similar to the default route except we do not set the &#8216;controller&#8217; as a variable. Here are some examples of these routes in action:</p>
<pre class="brush: js">	Mvc.start("DeleteAccount.1"); // resolves to "Account.Delete" passing 1 to the 'id' parameter
	Mvc.start("DeleteAccount", 1); // resolves to "Account.Delete" passing 1 to the 'id' parameter
	Mvc.start("Account.Foo.1"); // resolves to "Account.Foo" passing 1 to the 'id' parameter
	Mvc.start("Account.Bar", 1); // resolves to "Account.Bar" passing 1 to the 'id' parameter</pre>
<p>So that is the routing portion of my framework in a nutshell. Like I said, it might be overkill but I am really enjoying how easy it is to get from window to window. In my next post I will show a &#8220;real world&#8221; example of using my framework. It will include <a href="&quot;https://github.com/xavierlacot/joli.js/">joli</a>, <a title="AutoMapper in javascript" href="http://johnkalberer.com/2011/08/24/automapper-in-javascript/">jsAutomapper</a>, and some databinding. It basically shows how I set up my project and use the framework. Anyway, leave your comments/suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/09/13/appcelerator-mvc-routing/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>MVC for Appcelerator</title>
		<link>http://johnkalberer.com/2011/09/08/mvc-for-appcelerator/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mvc-for-appcelerator</link>
		<comments>http://johnkalberer.com/2011/09/08/mvc-for-appcelerator/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 18:08:23 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Appcelerator]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[routingjs]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=49</guid>
		<description><![CDATA[I was recently tasked to create a mobile app at work. Since I had never worked on a mobile app&#160;(not counting web-based apps), I started searching for a cross-platform framework. To make a long&#160;story short, I settled with Appcelerator. I have run into some issues while working on my app but for the most part [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently tasked to create a mobile app at work. Since I had never worked on a mobile app&nbsp;(not counting web-based apps), I started searching for a cross-platform framework. To make a long&nbsp;story short, I settled with <a href="http://www.appcelerator.com">Appcelerator</a>.  I have run into some issues while working on my app but for the most part there are simple workarounds. I love working with javascript and I can definitely see the platform is going&nbsp;somewhere. What I didn&#8217;t like is how easy it is to make bad javascript and end up with very large files. This was a problem that I could solve myself.</p>
<p>I searched around the internet and found a few solutions. Some people were using PureMvc or&nbsp;similar frameworks. I read through the documentation and the frameworks were either too complex&nbsp;for my needs or may have felt out of place when used with Appcelerator. I did find something close&nbsp;to what I wanted by <a href="http://blog.scottmontgomerie.com/01/mvc-in-appcelerator/">Scott Montgomerie</a>. My issues with his implementation was that you constantly have to deal with the current window context and&nbsp;you are coupling your views with your controllers. I also like to stay away from the &#8216;new&#8217; keyword&nbsp;when working with javascript. In addition I wanted routing as I am used to the MVC&nbsp;style of Asp.Net MVC (may be overkill but it was nice to have). It&#8217;s what I know and I love it <img src='http://johnkalberer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<strong><span id="more-49"></span></strong></p>
<p>Before I get started here is the <strong><a href="http://johnkalberer.com/wp-content/uploads/2011/10/mvc-basic.zip">working example</a></strong>.  Keep in mind this has only been tested on Android in my Windows environment and probably needs a bit more testing so this release is just an Alpha.</p>
<p>So with my implementation I wanted to keep things very simple and try to stay away from coupling the&nbsp;framework to Appcelerator. I also wanted routing so I could simply write code that evaluates to,&nbsp;&#8221;Go to the default view for the current controller.&#8221; This led me to a framework with the following setup:</p>
<hr />
<p><strong>For setting up the framework I have:</strong></p>
<ul>
<li><strong>Mvc.init</strong> &#8211; This is called to setup the framework. It initializes and extends all controllers<br />
and views.</li>
<li><strong>Mvc.mapRoute</strong> &#8211; This sets up your default routes and is used internally by the routing engine.</li>
<li><strong>Mvc.render</strong> &#8211; This is a callback function which is invoked after a view has been rendered.<br />
Using this approach we can decouple the Mvc framework from Appcelerator and possibly use in<br />
some other context. In the case of Appcelerator, I used this function for window management.</li>
<li><strong>Mvc.find</strong> &#8211; You shouldn&#8217;t ever need to use this but I exposed it just in case. This will find<br />
your route based on a path.</li>
<li><strong>Mvc.start</strong> &#8211; After everything is set up, this must be called to render the default action. This<br />
will make much more sense after my example.</li>
</ul>
<p><strong>For each controller I simply have:</strong></p>
<ul>
<li><strong>name</strong> &#8211; The name of the view you want to render.</li>
<li><strong>view</strong> &#8211; A function that takes the parameters of &#8220;action&#8221; and &#8220;model&#8221;. The action being the<br />
view you wish to render and the model used to render the view.</li>
</ul>
<p><strong>For each view I have the following functions:</strong></p>
<ul>
<li><strong>action</strong> &#8211; When you pass a path to this function and possibly a value or model, this will invoke<br />
an action on a controller and return a rendered view.</li>
<li><strong>partial</strong> &#8211; This simply takes whatever path you pass in and returns a view. This does not invoke<br />
the action for the route so in some cases you may have a view without an action.</li>
</ul>
<hr />
<p>That right there is the entire framework. It is very simple and easy to use. It also abstracts a ton&nbsp;of the work you have to go through in order to manage your project. Next I&#8217;ll go through how to use the&nbsp;framework with sample code.</p>
<p>The first thing we need to do is grab the mvc code. This is all home-grown except for some regular expressions&nbsp;I borrowed and modified from <a href="http://jsrouter.codeplex.com/">jsRouter</a>. Save this as &#8216;mvc.js&#8217;. Here it is:</p>
<pre class="brush: js">		var Mvc = (function ($) {

			if($.mvc) {
				return $.mvc; // do not reinitialize
			}

			var getRouteCollection;

			function extend() {
				var destination = arguments[0], source;
				for(var i = 1; i &lt; arguments.length; i += 1) { 					source = arguments[i]; 					for (var property in source) { 						if (typeof source[property] === "object" &amp;&amp; 							source[property] !== null ) { 							destination[property] = destination[property] || {}; 							arguments.callee(destination[property], source[property]); 						} else if(destination &amp;&amp; source[property]) { 							destination[property] = source[property]; 						} 					} 				} 				return destination; 			} 			 			function isEmptyObject(obj) { 				for(var prop in obj) { 					if (Object.prototype.hasOwnProperty.call(obj, prop)) { 						return false; 					} 				} 				return true; 			} 			 			// via jsRouter with some modifications -- http://jsrouter.codeplex.com/ 			function buildRegExp(route) { 				// converts the route format into a regular expression that would match matching paths 				var pathSegments = route.path.replace(/[\/\.]+$/, '').split(/\/|\./), 					defaults = route.defaults; 				var regexp = ['^']; 				for (var i = 0, segment, match; (segment = pathSegments[i]) !== undefined; i++) { 					if ((match = /{(\w+)}/.exec(segment)) != null) { 						var argName = match[1]; 						// add a backslash, except for the first segment 						regexp.push((i &gt; 0 ? '(\/' : '') + '([^\/]+)' + (i &gt; 0 ? ')' : ''));

						if (defaults &amp;&amp; defaults[argName] !== undefined) {
							// make the group optional if the parameter has a default value
							regexp.push('?');
						}
					}
					else {
						regexp.push((i &gt; 0 ? '/' : '') + segment);
					}
				}
				regexp.push('$');

				return new RegExp(regexp.join(''), 'i');
			}

			function parsePath(path, route) {
				// parses the values in the hash into an object with the keys the values specified in the given route
				var values = extend({}, route.defaults),
					pathSegments = path.split(/\/|\./);

				for (var i = 0, segment, match; i &lt; pathSegments.length &amp;&amp; (segment = route.segments[i]); i++) {
					if ((match = /{(\w+)}/.exec(segment)) != null) {
						if (pathSegments[i] == '' &amp;&amp; values[match[1]]) {
							continue; // skip empty values when the value is already set to a default value
						}
						values[match[1]] = pathSegments[i];
					}
				}
				return values;
			}

			// The base controller -- all controllers under Mvc.Controllers will get these properties
			function Controller(name) {
				return {
					name : name,
					view : function(action, model) {
						return {
							action : action, // either foo/bar/1, foo.bar.1 or {controller : 'foo', action : 'bar', id : '1'}
							model : model
						};
					}
				};
			}

			$.mvc = {
				Controllers: {}, // object to hold all controllers -- used in initialization
				Views : {}, // object to hold all views
				init : function(options) {
					var ctrlrs = this.Controllers, controller, views = this.Views;

					// set up controllers
					for(var key in ctrlrs) {
						if(!ctrlrs.hasOwnProperty(key)) {
							continue;
						}

						// make sure this is actually a Controller
						if(key.indexOf("Controller") === -1) {
							ctrlrs[key] = null;
							continue;
						}

						// extend the controller to include the properties from baseController
						ctrlrs[key] = extend(ctrlrs[key], Controller(key));
					}

					var self = this;
					self.process = function(route, data) {
						var r = self.find(route), createdObject = false;
						if(!r) {
							throw "Could not find any routes. Register routes via Mvc.mapRoute";
						}

						// set the routeData in sharedData
						rc.context.routeData = extend({}, r.routeData);

						if(!data &amp;&amp; data !== false) {
							data = {};
							createdObject = true;
						}

						// only extend the data object if it is already a complex object
						if(!isEmptyObject(<span class="hiddenGrammarError" pre="">data)) {
							data</span> = extend(data, r.routeData);
						}

						var rd = r.routeData;
						delete data["controller"];
						delete data["action"];				

						if(createdObject &amp;&amp; isEmptyObject(data)) {
							data = null;
						}

						var cname = rd.controller + "Controller", controller = self.Controllers[cname];
						if(!controller) {
							throw "Controller " + cname + " has not been defined";
						}
						if(!controller[rd.action]) {
							throw "Action " + rd.action + " in controller " + cname + " does not exist";
						}
						var view = controller[rd.action].call(controller, data);

						if(!view) {
							// we didn't need to show anything
							return;
						}

						return self._render(view.action, view.model);
					};

					self._render = function(route, data, partial) {
						var r = self.find(route);
						if(!r) {
							throw "Could not find any routes. Register routes via Mvc.mapRoute";
						}
						var cname = r.routeData.controller, vname = r.routeData.action;
						if(!self.Views[cname]) {
							throw "View Controller " + cname + " does not exist in Views collection";
						}
						if(!self.Views[cname][vname]) {
							throw "View " + vname + " does not exist in View Controller " + cname;
						}
						var renderOutput = self.Views[cname][vname](data);
						if(!partial &amp;&amp; self.render) {
							renderOutput = self.render(renderOutput, r.routeData);
						}
						return renderOutput;
					};
					self._partial = function(route, data) {
						// tell the render function that this is a partial render and we should not call
						// the user defined render function
						return self._render(route, data, true);
					}

					// setup the views so they have an 'action' method
					for(var key in views) {
						if(!views.hasOwnProperty(key)) {
							continue;
						}
						views[key].action = self.process;
						views[key].partial = self._partial;
					}

					var rc = this.sharedData = {
						routes : [],
						context : {
							routeData : {
								controller : null,
								action : null
							}
						}
					};
				},
				mapRoute : function (name, path, defaults) {
					var scrubbedPath = path.substr(path.indexOf('{'));

					// get rid of slashes
					if(scrubbedPath[0] === '/') {
						scrubbedPath = scrubbedPath.substring(1, scrubbedPath.length - 1);
					}
					if(scrubbedPath[scrubbedPath.length - 1] === '/') {
						scrubbedPath = scrubbedPath.substr(scrubbedPath.length - 2);
					}

					this.sharedData.routes.push({
						name : name,
						path : path,
						defaults: defaults
					})
				},
				find: function (path) {
					var routes = this.sharedData.routes,
						ctrlrs = this.Controllers,
						context = this.sharedData.context;

					if(!path) {
						path = "";
					}

					// check for match
					for (var i = 0, route; i &lt; routes.length; i++) { 						route = routes[i]; 						if (!route.regexp) { // generate regexps on the fly and cache them for the future 							route.regexp = buildRegExp(route); 							route.segments = route.path.split(/\/|\./); 						} 						var isMatch = route.regexp.test(path); 						if (isMatch) { 							// route found, parse the route values and return an extended object 							 							// populate last controller if it doesn't exist with default 							if(!context.routeData.controller) { 								context.routeData.controller = route.defaults.controller; 							} 							 							// check current controller for match -- takes care of simply passing an action 							var ctrlr = context.routeData.controller + "Controller"; 							var useLastController = ctrlrs[ctrlr] &amp;&amp; 													ctrlrs[ctrlr][path];  							 							var routeData = extend({}, context.routeData); 							if(useLastController) { 								var pathSegments = path.split(/\/|\./), iter = 1; 								routeData.action = pathSegments[0]; 								for(var key in routeData) { 									if(!routeData.hasOwnProperty(key)) { 										continue; 									} 									if(key === "controller" || key === "action") { 										continue; 									} 									 									if(iter &gt;= pathSegments.length) {
										break;
									}

									routeData[key] = pathSegments[iter];
									iter += 1;
								}
							} else {
								routeData = parsePath(path, route);
							}

							return extend({}, route, { routeData : routeData });
						}
					}
					return null;
				},
				start : function (route, data) { // parameters in case we want to start the app with something other than the default page
					this.process(route, data);
				}
			};

			return $.mvc;
		}(Titanium.App));</pre>
<p>The next thing you need to do is erase everything in your app.js file. This file will be the setup/initialization&nbsp;code for the project. We will add the following code.</p>
<pre class="brush: js">		// include a reference to the mvc file
		Ti.include('mvc.js'); 

		// This doesn't exist yet but we'll get to that next
		Ti.include('/controllers/HomeController.js');

		// Initializes the framework
		Mvc.init(); 

		// map a default route
		Mvc.mapRoute(
			"Default_Route",
			"{controller}.{action}.{id}", // could also be {controller}/{action}/{id}
			{
				controller : "Home",
				action : "Default",
				id : null
			});

		// we'll get into this in a bit.
		Mvc.render = function(ui, routeData) { } 

		// This will go off and attempt to render the default route but will
		// fail since we have not created the 'Home' controller yet
		Mvc.start();</pre>
<p>Now I will actually implement the Mvc.render function in app.js. This is super specific to how I want my&nbsp;app to manage windows. It should work for you as well but you may want to customize/improve this&nbsp;code.</p>
<pre class="brush: js">	// manage the windows -- window stack
	var openWindows = [];

	Mvc.render = function(ui, routeData) {
		var win, index, routeName = routeData.controller + "." + routeData.action;

		// find the index in the stack of windows
		for(var i = openWindows.length - 1; i &gt;= 0; i -= 1) {
			if(openWindows[i]._title === routeName) {
				win = openWindows[i];
				index = i + 1;
				break;
			}
		}
		function cleanup(index) {
			for(var i = index; i &lt; openWindows.length; i += 1) {
				openWindows[i].close();
				openWindows[i] = null;
			}
			openWindows = openWindows.splice(0, index);
		}
		// if the window already exists in the stack
		if(win) {
			// clean up array -- remove all windows
			cleanup(index);

			// remove children from current view
			var children = win.children;
			for(var i = 0; i &lt; children.length; i += 1) { 				win.remove(children[i]) 			} 		} else { 			// create a new window 			win = Ti.UI.createWindow({  				_title : routeName, 				fullscreen : true 			}); 			 			win.addEventListener('close', function() { 				// find the index of this window so we can remove it when the back button is pressed 				for(var i = openWindows.length - 1; i &gt;= 0; i -= 1) {
					if(openWindows[i]._title === routeName) {
						index = i;
						break;
					}
				}
				cleanup(index);
			});

			// This handles the creation of the first window so that
			// Appcelerator will exit your app when this window is closed.
			if(openWindows.length === 0) {
				win.exitOnClose = true;
			}

			openWindows.push(win);
			win.open();
		}

		// This adds the controls you created in your view
		win.add(ui);

		// return the window in case you need it for something in your view
		return win;
	};</pre>
<p>That right there is all the code you need to get going. Next we need to actually implement&nbsp;the &#8216;HomeController&#8217;. So create a file called &#8216;HomeController.js&#8217; inside a &#8216;controllers&#8217; folder&nbsp;and add the following code:</p>
<pre class="brush: js">		// This will be the location for the 'Default' view
		Ti.include('/views/Home/Default.js');
		// another view
		Ti.include('/views/Home/DoStuff.js');

		(function(c) {
			// This is just a basic model used to render
			// the 'Default' view.
			function DefaultModel() {
				return {
					text : null,
					value : 0
				};
			}
			// Initializes the 'HomeController' in Mvc.Controllers
			c.HomeController = {
				Default : function() {
					// Create the model and populate it with some values
					var model = DefaultModel();
					model.text = "Sample Text";
					model.value = "Sample value";

					// This returns a view and tells the framework to render the
					// 'Default' view using the model we created.
					return this.view('Default', model);
				},
				// we could add another action here
				DoStuff : function (value) {
					// manipulate the value parameter and return the appropriate view
					return this.view('DoStuff', value + "!!!");
				}
			};
		}(Mvc.Controllers));</pre>
<p>Next we need to implement our view. This is a very simple and similar process&nbsp;to creating Controllers. Create a &#8216;views&#8217; folder and then a &#8216;Home&#8217; folder.</p>
<pre class="brush: js">		(function(v) {
			// Create the 'Home' object if it doesn't already exist
			// This is used by the routing engine to assosciate the
			// view with the correct controller
			if(!v.Home) {
				v.Home = {};
			}

			/*
			 * Render the default page
			 */
			v.Home.Default = function(model) {
				// get a reference to the view
				var self = this;

				var view = Ti.UI.createView({layout : "vertical"});
				var label = Ti.UI.createLabel({
					text : model.text
				});
				var textField = Ti.UI.createTextField({
					value : model.value
				});
				var button = Ti.UI.createButton({
					title : "Submit"
				});

				// This will call DoStuff
				button.addEventListener("click", function(e) {
					self.action("DoStuff", textField.value);
				});
				view.add(label);
				view.add(textField);
				view.add(button);

				return view;
			};
		}(Mvc.Views));</pre>
<p>Lastly we create the &#8216;DoStuff&#8217; view which is nearly the same as the &#8216;Default&#8217;&nbsp;view.</p>
<pre class="brush: js">		(function(v) {
	// Create the 'Home' object if it doesn't already exist
	if(!v.Home) {
		v.Home = {};
	}

	/*
	 * Render the DoStuff page
	 */
	v.Home.DoStuff = function(model) {
		var view = Ti.UI.createView({
			layout : "vertical",
			backgroundColor : "#fff"
		});
		var label = Ti.UI.createLabel({
			text : model,
			color : "#000"
		});

		view.add(label);

		return view;
	};
}(Mvc.Views));</pre>
<hr />
<p>That is my MVC framework in a nutshell although this only shows the basic functionality.&nbsp;In my next post I will expand on this example and integrate model-binding, <a href="http://johnkalberer.com/2011/08/24/automapper-in-javascript/">jsAutomapper</a>, and using joli for data access. I will also focus on the routing portion of my framework&nbsp;and how to do some more advanced things with it. I think this framework is stupidly simple and really allows for SOC as well as forcing you to write better code. If you have any&nbsp;comments/suggestings/bugs feel free to leave them here.</p>
<p>Anyway, you can download the working project <strong><a href="http://johnkalberer.com/wp-content/uploads/2011/10/mvc-basic.zip">HERE</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/09/08/mvc-for-appcelerator/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>AutoMapper in javascript</title>
		<link>http://johnkalberer.com/2011/08/24/automapper-in-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automapper-in-javascript</link>
		<comments>http://johnkalberer.com/2011/08/24/automapper-in-javascript/#comments</comments>
		<pubDate>Wed, 24 Aug 2011 17:51:48 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[AutoMapper]]></category>
		<category><![CDATA[contracts]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[jsAutomapper]]></category>
		<category><![CDATA[mapper]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=47</guid>
		<description><![CDATA[Just like the title says, I created a small javascript implementation of AutoMapper. Because I am cool like that I am calling it jsAutomapper. This is a very, very basic implementation and only has a few of the functions from the original framework but it is more than sufficient for my needs. I am working [...]]]></description>
			<content:encoded><![CDATA[<p>
	Just like the title says, I created a small javascript implementation of AutoMapper. Because I am cool like that I am calling it <strong>jsAutomapper</strong>.  This is a very, very basic implementation and only has a few of the functions from the original framework but it is more than sufficient for my needs.  I am working in Appcelerator and I implemented a MVC framework to clean up my code.  Because of this I needed an easy way to convert between objects stored in the database and my view models.  The benefit of using this implementation is it also forms a contract between your models and view models.  The current implementation only supports basic object mappings.  If anyone shows interest or I need it for my current project, I will implement mappings for complex objects.<strong><span id="more-47"></span></strong>
</p>
<p>
	The automapper javascript implementation:
</p>
<pre name='code' class='brush: js'>
var automapper = (function (app) {
	if(app.automapper) {
		return app.automapper;
	}

	var dictionary = {};

	app.automapper = {
		createMap : function (sourceKey, destinationKey) {
			var combinedKey = sourceKey + destinationKey, functions;
			dictionary[combinedKey] = {};

			functions = {
				forMember : function (key, e) {
					dictionary[combinedKey][key] = e;
					return functions;
				},
				forAllMembers : function(func) {
					dictionary[combinedKey].__forAllMembers = func;
					return functions;
				}
			};
			return functions;
		},
		map : function (sourceKey, destinationKey, sourceValue, destinationValue, lazy) {
			if(!sourceValue &#038;&#038; sourceValue !== false) {
				return;
			}

			function getValue(item) {
				if(typeof item === "function" &#038;&#038; !lazy) {
					return item();
				}
				return item;
			}
			var combinedKey = sourceKey + destinationKey;
			var mappings = dictionary[combinedKey], output, key,
				    extensions = {
						ignore : function () {
							// don't do anything
						},
						mapFrom : function (sourceMemberKey) {
							if (!this.__sourceValue.hasOwnProperty(sourceMemberKey)) {
								throw sourceKey + "." + sourceMemberKey + " has not been defined.";
							}
							var value = getValue(this.__sourceValue[sourceMemberKey]);
							if(mappings.__forAllMembers) {
								mappings.__forAllMembers(this.__destinationValue, this.__key, value);
							} else {
								this.__destinationValue[this.__key] = value;
							}
						}
					};

			if(!mappings) {
				throw "Could not find mapping with a source of " + sourceKey + " and a destination of " + destinationKey;
			}

			function mapItem(destinationValue, sourceValue) {
				for (key in destinationValue) {
					if (!destinationValue.hasOwnProperty(key)) {
						continue;
					}			

					if (mappings.hasOwnProperty(key) &#038;&#038; mappings[key]) {
						if (typeof mappings[key] === "function") {
							extensions.__key = key;
							extensions.__sourceValue = sourceValue;
							extensions.__destinationValue = destinationValue;

							output = mappings[key].call(extensions);
						} else {  // forMember second parameter was not a function
							output = mappings[key];
						}
						// object was returned from the 'forMember' call
						if (output) {
							var value = getValue(output);
							if(mappings.__forAllMembers) {
								mappings.__forAllMembers(destinationValue, key, value);
							} else {
								destinationValue[key] = value;
							}
						}
					}
					else if (!sourceValue.hasOwnProperty(key)) {
						throw sourceKey + "." + key + " has not been defined.";
					} else {
						var value = getValue(sourceValue[key]);
						if(mappings.__forAllMembers) {
							mappings.__forAllMembers(destinationValue, key, value);
						} else {
							destinationValue[key] = value;
						}
					}
				}
			}

			// actually do the mapping here
			if(sourceValue instanceof Array) {
				if(destinationValue instanceof Array) {
					// loop
					for(var i = 0; i < sourceValue.length; i += 1) {
						if(!destinationValue[i]) {
							if(typeof destinationKey !== "function") {
								throw "destinationKey of mapping must be a function in order to initialize the array";
							}
							destinationValue[i] = destinationKey();
						}
						mapItem(destinationValue[i], sourceValue[i]);
					}
				} else {
					throw "Cannot map array to object";
				}
			}
			else if(destinationValue instanceof Array) {
				throw "Cannot map object to array";
			} else {
				mapItem(destinationValue, sourceValue);
			}
		}
	};

	return app.automapper;
}(this));
</pre>
<p>
	Usage:
</p>
<pre name='code' class='brush: js'>
var atest = {
	same : 10,
	bleh : 4
};
var btest = {
	dumb: null,
	func: null,
	foo : null,
	bar : null,
	same : null
};
/*
*  call 'createMap' where "a" and "b" are the name of your
*  models.  These values can be whatever you want but you
*  must match the values when you call 'map'.
*/
automapper.createMap("a","b")
	   // forAllMembers isn't necessary here but it allows you to
	   // customize how you apply values to the destination model
	  .forAllMembers(function(model, prop, value) {
		model[prop] = value;
	  })
	  .forMember("dumb", 12)
	  .forMember("func", function() { return 8 })
	  .forMember("foo", function() { this.ignore(); })
	  .forMember("bar", function() { this.mapFrom("bleh"); });

automapper.map("a", "b", atest, btest);
</pre>
<p>
	Leave any suggestions or bug-fixes in the comments.  Thanks.
</p>
<h3>UPDATE</h3>
<p>Joel Brage was kind enough to port jsAutomapper to coffeescript. You can download it <a href="http://johnkalberer.com/wp-content/uploads/2011/10/automapper.coffee">here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/08/24/automapper-in-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C# SortedBucketList</title>
		<link>http://johnkalberer.com/2011/03/08/c-sortedbucketlist/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=c-sortedbucketlist</link>
		<comments>http://johnkalberer.com/2011/03/08/c-sortedbucketlist/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 18:42:54 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[.Net 3.5]]></category>
		<category><![CDATA[Generic]]></category>
		<category><![CDATA[multiple key]]></category>
		<category><![CDATA[sorted list]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=36</guid>
		<description><![CDATA[So I searched the internets for a while looking for a sorted list that could have multiple entries per key. I didn&#8217;t find one. Here is my go at it. This is not optimized and will be pretty memory heavy. I was just looking for speed. I could have used a different internal collection instead [...]]]></description>
			<content:encoded><![CDATA[<p>   So I searched the internets for a while looking for a sorted list that could have multiple entries per key.  I didn&#8217;t find one.  Here is my go at it.  This is not optimized and will be pretty memory heavy. I was just looking for speed.  I could have used a different internal collection instead of the sorted list but I was using .Net 3.5 and I didn&#8217;t feel like rolling my own.<strong><span id="more-36"></span></strong><br/><br/>
<pre name="code" class="brush: c-sharp">
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Common.Collections
{
    public class SortedBucketList&lt;TKey, TValue> : IDictionary&lt;TKey, TValue>
    {
        /// &lt;summary>
        /// This stores the first key and first value added to the collection.
        /// &lt;/summary>
        private readonly SortedList&lt;TKey, TValue> _sort;
        /// &lt;summary>
        /// The value of this is used to reference the first KeyValuePair stored in the SortedList
        /// &lt;/summary>
        private readonly Dictionary&lt;TValue, TKey> _bucket;

        public SortedBucketList()
        {
            _sort = new SortedList&lt;TKey, TValue>();
            _bucket = new Dictionary&lt;TValue, TKey>();
        }

        public SortedBucketList(IComparer&lt;TKey> comparer)
        {
            _sort = new SortedList&lt;TKey, TValue>(comparer);
            _bucket = new Dictionary&lt;TValue, TKey>();
        }
        public SortedBucketList(IDictionary&lt;TKey, TValue> dictionary)
        {
            _sort = new SortedList&lt;TKey, TValue>(dictionary);
            _bucket = new Dictionary&lt;TValue, TKey>();
            foreach (var value in dictionary)
            {
                _bucket.Add(value.Value, value.Key);
            }
        }
        public SortedBucketList(int capacity)
        {
            _sort = new SortedList&lt;TKey, TValue>(capacity);
            _bucket = new Dictionary&lt;TValue, TKey>(capacity);
        }
        public SortedBucketList(IDictionary&lt;TKey, TValue> dictionary, IComparer&lt;TKey> comparer)
        {
            _sort = new SortedList&lt;TKey, TValue>(dictionary, comparer);
            _bucket = new Dictionary&lt;TValue, TKey>();
            foreach (var value in dictionary)
            {
                _bucket.Add(value.Value, value.Key);
            }
        }
        public SortedBucketList(int capacity, IComparer&lt;TKey> comparer)
        {
            _sort = new SortedList&lt;TKey, TValue>(capacity, comparer);
            _bucket = new Dictionary&lt;TValue, TKey>(capacity);
        }
        public void Add(TKey key, TValue value)
        {
            if (!_sort.ContainsKey(key))
            {
                _sort.Add(key, value);
            }
            _bucket[value] = key;
        }
        public void Clear()
        {
            _sort.Clear();
            _bucket.Clear();
        }
        public bool ContainsKey(TKey key)
        {
            return _sort.ContainsKey(key);
        }
        public bool ContainsValue(TValue value)
        {
            return _bucket.ContainsKey(value);
        }

        public int IndexOfKey(TKey key)
        {
            return _sort.IndexOfKey(key);
        }
        public int IndexOfValue(TValue value)
        {
            TKey key;
            if (_bucket.TryGetValue(value, out key))
            {
                return _sort.IndexOfKey(key);
            }
            return -1;
        }

        public bool Remove(TKey key)
        {
            if (!_sort.Remove(key))
                return false;
            RemoveFromBucket(key);
            return true;
        }
        public void RemoveAt(int index)
        {
            var item = _sort.ElementAt(index);
            _sort.RemoveAt(index);
            RemoveFromBucket(item.Key);
        }

        private void RemoveFromBucket(TKey key)
        {
            var del = new List&lt;TValue>();
            foreach (var kvp in _bucket)
            {
                if (kvp.Value.Equals(key))
                {
                    del.Add(kvp.Key);
                }
            }
            foreach (var item in del)
            {
                _bucket.Remove(item);
            }
        }

        ICollection&lt;TKey> IDictionary&lt;TKey, TValue>.Keys
        {
            get { return _bucket.Values; }
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            throw new NotImplementedException();
        }

        public ICollection&lt;TValue> Values
        {
            get { return _bucket.Keys; }
        }

        TValue IDictionary&lt;TKey, TValue>.this[TKey key]
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public IEnumerable&lt;TValue> this[TKey key]
        {
            get
            {
                var output = new List&lt;TValue>();

                //_bucket.EachParallel(kvp =>
                //                         {
                //                             if (kvp.Value.Equals(key))
                //                             {
                //                                 output.Add(kvp.Key);
                //                             }
                //                         });
                //output.AddRange(from kvp in _bucket where kvp.Value.Equals(key) select kvp.Key);
                foreach (var kvp in _bucket)
                {
                    if (kvp.Value.Equals(key))
                    {
                        output.Add(kvp.Key);
                    }
                }
                return output;
            }
            set
            {
                if (value == null)
                    return;
                if (!_sort.ContainsKey(key))
                {
                    _sort[key] = value.ElementAt(0);
                }
                foreach (var el in value)
                {
                    _bucket[el] = key;
                }
            }
        }

        void ICollection&lt;KeyValuePair&lt;TKey, TValue>>.Add(KeyValuePair&lt;TKey, TValue> item)
        {
            Add(item.Key, item.Value);
        }

        void ICollection&lt;KeyValuePair&lt;TKey, TValue>>.Clear()
        {
            _sort.Clear();
            _bucket.Clear();
        }

        bool ICollection&lt;KeyValuePair&lt;TKey, TValue>>.Contains(KeyValuePair&lt;TKey, TValue> item)
        {
            return ContainsKey(item.Key) &amp;&amp; ContainsValue(item.Value);
        }

        void ICollection&lt;KeyValuePair&lt;TKey, TValue>>.CopyTo(KeyValuePair&lt;TKey, TValue>[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        int ICollection&lt;KeyValuePair&lt;TKey, TValue>>.Count
        {
            get { return _sort.Count; }
        }

        bool ICollection&lt;KeyValuePair&lt;TKey, TValue>>.IsReadOnly
        {
            get { throw new NotImplementedException(); }
        }

        bool ICollection&lt;KeyValuePair&lt;TKey, TValue>>.Remove(KeyValuePair&lt;TKey, TValue> item)
        {
            throw new NotImplementedException();
        }

        IEnumerator&lt;KeyValuePair&lt;TKey, TValue>> IEnumerable&lt;KeyValuePair&lt;TKey, TValue>>.GetEnumerator()
        {
            return _sort.GetEnumerator();
        }

        void IDictionary&lt;TKey, TValue>.Add(TKey key, TValue value)
        {
            Add(key, value);
        }

        bool IDictionary&lt;TKey, TValue>.ContainsKey(TKey key)
        {
            return ContainsKey(key);
        }

        bool IDictionary&lt;TKey, TValue>.Remove(TKey key)
        {
            throw new NotImplementedException();
        }

        bool IDictionary&lt;TKey, TValue>.TryGetValue(TKey key, out TValue value)
        {
            return _sort.TryGetValue(key, out value);
        }

        ICollection&lt;TValue> IDictionary&lt;TKey, TValue>.Values
        {
            get { return _bucket.Keys; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            throw new NotImplementedException();
        }
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/03/08/c-sortedbucketlist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PushButton Engine Basics</title>
		<link>http://johnkalberer.com/2011/02/16/pushbutton-engine-basics/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pushbutton-engine-basics</link>
		<comments>http://johnkalberer.com/2011/02/16/pushbutton-engine-basics/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 01:49:32 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[PBE]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[PushButton Engine]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=31</guid>
		<description><![CDATA[So I am starting to use the PushButton Engine at work and right now I am just learning the architecture in order to teach the rest of the flash developers here how to use it. So far it seems like a great engine it is definitely lacking in &#8216;guided&#8217; documentation on how to get up [...]]]></description>
			<content:encoded><![CDATA[<p>So I am starting to use the <a href="http://www.pushbuttonengine.com">PushButton Engine</a> at work and right now I am just learning the architecture in order to teach the rest of the flash developers here how to use it. So far it seems like a great engine it is definitely lacking in &#8216;guided&#8217; documentation on how to get up to speed. Most of the examples/documentation is there you just need to find it across the PushButton website, Google Code Wiki, PushButton API, PushButton forums, and searching through other blog posts. I will try to include all the resources here so that it is easier for others who are new to the engine to start and help you not avoid the same mistakes I Made.<strong><span id="more-31"></span></strong></p>
<p>The first thing you need to do is check out the <a href="http://pushbuttonengine.com/docs/">documentation</a> and follow each step of the lessons. It is also very helpful if you watch the video talks and at least skim all the reference material on this page. The main thing to take note of here is the xml. I would say it is the core of what makes the PushButton Engine so powerful.</p>
<p>So now that you are up to speed with the basics, you want to actually start modularizing the code and going beyond what was in the lessons. This was a sticking point for me as I had a complete misunderstanding of how the PBE was supposed to be used. As I started trying to break up the code from the lesson, I immediately moved the &#8216;createHero&#8217; function into its own class. As I learned from a long chat on the PushButton IRC channel, this is not the correct way. You need to use <a href="http://pushbuttonengine.com/docs/05-XMLFormat.html#contentAreatoc3">Templates</a> in Level Xml or<br />
<a href="http://code.google.com/p/pushbuttonengine/wiki/Templates">Templates</a>. Since I am just prototyping at this point I chose to use a template as a function. I moved the &#8216;createHero&#8217; code from out of my class (which should have never been used) into a static factory class where I will create/initialize all entities. As this is a prototype I don&#8217;t feel too bad for doing this although for any large project, using xml templates<br />
is definitely the way to go. For this prototype I will be making a simple platform game with mouse navigation.</p>
<p>So now without further ado, we have some code <img src='http://johnkalberer.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  Here is the main function.</p>
<pre class="brush: as3">public function Main():void
{
    PBE.startup(this);

    var sceneView:SceneView = new SceneView();
    sceneView.width = 700;
    sceneView.height = 400;
    PBE.initializeScene(sceneView);

    PBE.defineEntityByFunction("Hero", EntityFactory.CreateHero);

    PBE.makeEntity("Hero");
}</pre>
<p>As you can see, it is very similar to what was in the PushButton example. The only difference here is that instead of calling EntityFactore. CreateHero explicitly, we call PBE.makeEntity which resolves the correct function (I am assuming using a dictionary but I didn&#8217;t look at the source). This is a much cleaner solution because it allows us to swap out the CreateHero function with something else if we really need to throughout the prototype &#8211; although if it gets that involved then perhaps it is time to start using xml templates.</p>
<p>The next bit of code is the EntityFactory.CreateHero</p>
<pre class="brush: as3">public static function CreateHero():IEntity
{
    var entity:IEntity = PBE.allocateEntity();
    entity.initialize("Hero");

    var positionProperty:PropertyReference = new PropertyReference("@Spatial.position");

    var spatial:SimpleSpatialComponent = new SimpleSpatialComponent();
    var render:MovieClipRenderer = new MovieClipRenderer();
    var controller:MouseControllerComponent = new MouseControllerComponent();

    spatial.position = new Point(0, 0);
    spatial.size = new Point(50, 90);
    spatial.spatialManager = PBE.spatialManager;

    render.clip = new Static(); // Something my art guy gave me
    render.frameRate = 60;
    render.loop = true;
    render.positionOffset = new Point(-50, -90);
    render.positionProperty = positionProperty;
    render.rotationProperty = new PropertyReference("@Spatial.rotation");
    render.scene = PBE.scene;

    controller.PositionProperty = positionProperty;

    entity.addComponent(spatial, "Spatial");
    entity.addComponent(render, "Render");
    entity.addComponent(controller, "Controller");

    return entity;
}</pre>
<p>Take note of the line entity.initialize(&#8220;Hero&#8221;). The identifier &#8220;Hero&#8221; can only be used once. PBE uses this identifier in PropertyReferences in order to find component properties of entities. Since I named the entity &#8220;Hero&#8221; I can get to its spatial &#8216;position&#8217; property by using the string &#8221;#Hero.Spatial.position&#8221; in the property reference. You can see an example of this later on in the post. I use a MovieClipRenderer to render an animation for my character. In the future I will be changing this to use an AnimatorComponent but that is for a later post. Also, I have not created a physics component which I will need to do later. For now I am just trying to get things animating</p>
<p>So for my prototype I am making a character which uses the mouse for navigation. I am replacing the mouse cursor with an arrow graphic that always points away from the character and grows/shrinks depending on the distance from the character.</p>
<p>So now I add two lines to the main function to create this arrow.</p>
<pre class="brush: as3">public function Main():void
{
    PBE.startup(this);

    var sceneView:SceneView = new SceneView();
    sceneView.width = 700;
    sceneView.height = 400;
    PBE.initializeScene(sceneView);

    PBE.defineEntityByFunction("Hero", EntityFactory.CreateHero);
    PBE.defineEntityByFunction("Arrow", EntityFactory.CreateArrow);

    PBE.makeEntity("Hero");
    PBE.makeEntity("Arrow");
}</pre>
<p>So I bind the EntityFactore.CreateArrow function and then make the entity. Here is the code for EntityFactory.CreateArrow.</p>
<pre class="brush: as3">public static function CreateArrow():IEntity
{
    var entity:IEntity = PBE.allocateEntity();
    entity.initialize();

    var positionProperty:PropertyReference = new PropertyReference("@Spatial.position");
    var rotationProperty:PropertyReference = new PropertyReference("@Spatial.rotation");

    var spatial:SimpleSpatialComponent = new SimpleSpatialComponent();
    var render:MovieClipRenderer = new MovieClipRenderer();
    var controller:ArrowControllerComponent = new ArrowControllerComponent();

    spatial.position = new Point(0, 0);
    spatial.size = new Point(40, 50);
    spatial.spatialManager = PBE.spatialManager;

    render.clip = new Default(); // Default arrow
    render.frameRate = 60;
    render.loop = true;
    render.positionProperty = positionProperty;
    render.rotationProperty = rotationProperty;
    render.scene = PBE.scene;

    controller.PositionProperty = positionProperty;
    controller.RotationProperty = rotationProperty;
    controller.ScaleProperty = new PropertyReference("@Render.scale");

    entity.addComponent(spatial, "Spatial");
    entity.addComponent(render, "Render");
    entity.addComponent(controller, "Controller");

    return entity;
}</pre>
<p>As you can see, this time when I call entity.initialize I do not pass in an identifier. In this case I do no really need an identifier but if you were doing something such as creating bullet entities where you would have more than one created at a time, you would need to do this since the identifier would clash and PBE would complain. Other than that, this function is very similar to the EntityFactory.CreateHero function.</p>
<p>The next thing I have to worry about is actually moving the arrow with the mouse. For that I created the ArrowControllerComponent.</p>
<pre class="brush: as3">public class ArrowControllerComponent extends TickedComponent
{
    public var PositionProperty:PropertyReference;
    public var RotationProperty:PropertyReference;
    public var ScaleProperty:PropertyReference;

    private var _heroSpatialProperty:PropertyReference = new PropertyReference("#Hero.Spatial.position");

    public static const MINDISTANCE:Number = 200;
    public static const MAXDISTANCE:Number = 300;

    override public function onTick(deltaTime:Number):void
    {
        owner.setProperty(
            PositionProperty,
                new Point(
                    PBE.mainStage.mouseX - .5 * PBE.scene.sceneView.width,
                    PBE.mainStage.mouseY - .5 * PBE.scene.sceneView.height));

        var position:Point = owner.getProperty(PositionProperty) as Point;

        var charPosition:Point = owner.getProperty(_heroSpatialProperty) as Point;
        var difference:Point = position.subtract(charPosition);

        var scale:Number = 1 + Math.max((Math.min(difference.length, MAXDISTANCE) - MINDISTANCE) / (MAXDISTANCE - MINDISTANCE), 0);
        trace(scale);
        owner.setProperty(
            ScaleProperty,
                new Point(1, scale));

        owner.setProperty(
        RotationProperty,
        Math.atan2(difference.y, difference.x) * 57.32 + 90);
    }
}</pre>
<p>So in this class I have four PropertyReferences. The first three are instantiated by the EntityFactory.CreateArrow function when creating that entity. The private _heroSpatialProperty is set and cached so it does not have to find the property each time onTick is called. Doing this is crucial when using PBE because the PropertyReference class is a beast. I looked through the source code a bit and if you do not use the PropertyReference correctly, your project will definitely take a huge performance hit. Anyways, as you can see I use the &#8220;#Hero.Spatial.position&#8221; to resolve the hero&#8217;s position not &#8221;#Hero.@Spatial.position&#8221; which was a mistake I made and took a while to figure out. The next bits of code is just doing math stuff in order to properly position the arrow at the correct cordinates &#8212; mouseX is using the flash coordinates where (0,0) is in the top left while the rest of PBE assumes (0,0) is in the center of the stage/box. I am assuming this is to make integration with Box2D make more sense&#8230;</p>
<p>Well, that is all for now. I will be posting the entire source of this prototype when I am finished with everything. I will keep posting updates as I move along. Next up the<br />
AnimatorComponent and SpriteSheets (or however I figure out how to render movie clips with a state machine).</p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2011/02/16/pushbutton-engine-basics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Simple jQuery + MVC Plugin</title>
		<link>http://johnkalberer.com/2010/12/16/simple-jquery-mvc-plugin/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=simple-jquery-mvc-plugin</link>
		<comments>http://johnkalberer.com/2010/12/16/simple-jquery-mvc-plugin/#comments</comments>
		<pubDate>Fri, 17 Dec 2010 02:17:32 +0000</pubDate>
		<dc:creator>John Kalberer</dc:creator>
				<category><![CDATA[Asp.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[modelbinding]]></category>

		<guid isPermaLink="false">http://johnkalberer.com/?p=20</guid>
		<description><![CDATA[So I needed to create markup via javascript and json which could be easily picked up by MVC&#8217;s default model binder. This plugin takes in json and changes its structure so non-array nodes are changed to have value, id, and name members. I ended up not using json but I could see that I may [...]]]></description>
			<content:encoded><![CDATA[<p>So I needed to create markup via javascript and json which could be easily picked up by MVC&#8217;s default model binder. This plugin takes in json and changes its structure so non-array nodes are changed to have value, id, and name members. I ended up not using json but I could see that I may use it in the future.<strong><span id="more-20"></span></strong></p>
<pre class="brush: js">(function ($) {
    $.mvcname = function (json) {
        function recurseJson(json, parentID, parentName) {
            for (var key in json) {
                var item = json[key];
                var id = key, name = key;
                if(parentID){
                    id = parentID + "__" + id;
                }
                if(parentName) {
                    name = parentName + "." + name;
                }

                if($.isArray(item)) {
                for(var i = 0; i &lt; item.length; i++) {
                    item[i] = recurseJson(item[i], id + "_" + i, name + "[" + i + "]");
                }
            } else {
                json[key] = {
                value: recurseJson(item, id, name),
                id: id,
                name: name
                };
            }
        }
        return json;
    }
    return recurseJson(json);
    };
}(jQuery));</pre>
<p>So if you pass in some json that looks like:</p>
<pre class="brush: js">var json = {
    foo: {
        a: "text",
        b: 1
    },
    bar: [
        {
            c: [2,3,4],
            d: "abc"
        },
        {
            c: [5,7,9]
            d: "text",
        }
    ]
};
$.mvcname(json);</pre>
<p>You will end up with something like:</p>
<pre class="brush: js">json = {
    foo: {
        value: {
            a: "text",
            b: 1
        },
        name: "foo",
        id: "foo"
    },
    bar: [
        {
            c: {
                value: [2,3,4],
                name: "bar[0].c",
                id: "bar_0__c"
            },
            d: {
                value: "abc",
                name: "bar[0].d",
                id: "bar_0__d"
            }
        },
        {
            c: {
                value: [5,7,9,11],
                name: "bar[1].c",
                id: "bar_1__c"
            },
            d: {
                value: "def",
                name: "bar[1].d",
                id: "bar_1__d"
            }
        }
    ]
};</pre>
<p>Quite possibly a useless plugin but have fun&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://johnkalberer.com/2010/12/16/simple-jquery-mvc-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

