Thursday, September 22, 2011

JavaScript Hashmap and MVC 3

I was fiddling with an idea that allowed rows to be dynamically added to an html page and deleted off the page. This became a bit tricky because I couldn’t identify the row I wanted to get rid of.

 

Eventually what I ended up doing was maintaining a list of the rows in a JavaScript object that functioned the same as the hash map and as opposed to deleting one row at a time I would remove the entire list from the page and re render it. The reason for this is when submitting arrays to an MVC 3 controller based on a strongly typed model you have to name the hidden input fields sequentially. Something like this:

 

<input type="hidden" id="EventList_0_SomeId" name="EventList[0].SomeId"  value="myid" />
<input type="hidden" id="EventList_0_Capacity" name="EventList[0].Capacity" value="25" />


 



As you probably gathered the next one would increment the 0 in the id and the 0 in the name to 1. The next one 2 and so on and so forth.



 



<input type="hidden" id="EventList_1_SomeId" name="EventList[1].SomeId"  value="myid" />
<input type="hidden" id="EventList_1_Capacity" name="EventList[1].Capacity" value="25" />

<input type="hidden" id="EventList_2_SomeId" name="EventList[2].SomeId" value="myid" />
<input type="hidden" id="EventList_2_Capacity" name="EventList[2].Capacity" value="25" />

<input type="hidden" id="EventList_3_SomeId" name="EventList[3].SomeId" value="myid" />
<input type="hidden" id="EventList_3_Capacity" name="EventList[3].Capacity" value="25" />


Just as a pointer, the name and the id of the input have to be declared or the MVC 3 controller will not resolve the values. The above example is a model that contains a list of objects that contain a property called SomeId and Capacity. If you do it the way I have illustrated above, it will resolve into a nice object representation in the controller that you can manipulate.



 



The Hashmap declaration:



function Map()
{
// members
this.keyArray = new Array(); // Keys
this.valArray = new Array(); // Values

// methods
this.put = put;
this.get = get;
this.size = size;
this.clear = clear;
this.keySet = keySet;
this.valSet = valSet;
this.showMe = showMe; // returns a string with all keys and values in map.
this.findIt = findIt;
this.remove = remove;
}

function put( key, val )
{
var elementIndex = this.findIt( key );

if( elementIndex == (-1) )
{
this.keyArray.push( key );
this.valArray.push( val );
}
else
{
this.valArray[ elementIndex ] = val;
}
}

function get( key )
{
var result = null;
var elementIndex = this.findIt( key );

if( elementIndex != (-1) )
{
result = this.valArray[ elementIndex ];
}

return result;
}

function remove( key )
{
var result = null;
var elementIndex = this.findIt( key );

if( elementIndex != (-1) )
{
this.keyArray = this.keyArray.removeAt(elementIndex);
this.valArray = this.valArray.removeAt(elementIndex);
}

return ;
}

function size()
{
return (this.keyArray.length);
}

function clear()
{
for( var i = 0; i < this.keyArray.length; i++ )
{
this.keyArray.pop(); this.valArray.pop();
}
}

function keySet()
{
return (this.keyArray);
}

function valSet()
{
return (this.valArray);
}

function showMe()
{
var result = "";

for( var i = 0; i < this.keyArray.length; i++ )
{
result += "Key: " + this.keyArray[ i ] + "tValues: " + this.valArray[ i ] + "n";
}
return result;
}

function findIt( key )
{
var result = (-1);

for( var i = 0; i < this.keyArray.length; i++ )
{
if( this.keyArray[ i ] == key )
{
result = i;
break;
}
}
return result;
}

function removeAt( index )
{
var part1 = this.slice( 0, index);
var part2 = this.slice( index+1 );

return( part1.concat( part2 ) );
}
Array.prototype.removeAt = removeAt;


 



The usage is just as simple. Include the JavaScript file and then:



var map = new Map();

map.put("key", value);
map.remove("key");

//etc


 



A really nice feature is that it does not duplicate keys but performs an “update” on the object at that key. So if you want to retrieve all the keys you can do something like this:



 



for (var i = 0; i < hashMap.keyArray.length; i++) {
var value = map.valArray[i];
var key = map.keyArray[i];
console.log(key, value.toSource());
}


 



 



I found the Hashmap declaration over here http://ping.fm/YAKIX



 



Some other interesting tid bits on the MVC embedded arrays, lists and editors for:



0 comments:

Post a Comment