<?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>Michael De Wildt &#187; JQuery</title>
	<atom:link href="http://www.mikeyd.com.au/category/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mikeyd.com.au</link>
	<description>An uber nerd rambling about open source, PHP, Python and whatever I find interesting</description>
	<lastBuildDate>Wed, 04 Jan 2012 22:36:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cross browser PHP drop down menu generator powered by JQuery and CSS.</title>
		<link>http://www.mikeyd.com.au/2010/05/15/cross-browser-php-drop-down-menu-generator-powered-by-jquery-and-css/</link>
		<comments>http://www.mikeyd.com.au/2010/05/15/cross-browser-php-drop-down-menu-generator-powered-by-jquery-and-css/#comments</comments>
		<pubDate>Sat, 15 May 2010 06:49:26 +0000</pubDate>
		<dc:creator>Mikey</dc:creator>
				<category><![CDATA[JQuery]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.mikeyd.com.au/?p=150</guid>
		<description><![CDATA[I needed to create a drop down menu that supported all the major browsers that was generated with dynamic content. So I decided to use the tried and true unordered HTML list approach. This approach can be easily controlled with pure CSS in browsers like Chrome and Firefox, however, other browsers such as Internet Explorer [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to create a drop down menu that supported all the major browsers that was generated with dynamic content. So I decided to use the tried and true unordered HTML list approach. This approach can be easily controlled with pure CSS in browsers like Chrome and Firefox, however, other browsers such as Internet Explorer cause issues so JQuery is required to force compliance across multiple platforms and browsers.</p>
<p>First I created this neat little class that can be used to create an object model of MenuItems that can be later serialized into a HTML unordered list. This model is basically a linked list of MenuItems where the serialize function just iterates through each object and its children converting its properties into a string.</p>
<pre class="brush:php">class MenuItem {

    private $name;
    private $url;
    private $level;
    private $items;

    public function __construct($item_name, $item_lvl, $item_url = "#") {
        $this-&gt;name = $item_name;
        $this-&gt;url = $item_url;
        $this-&gt;level = $item_lvl;
        $this-&gt;items = array();
    }

    public function add_item(MenuItem $menu_item) {
        $this-&gt;items[] = $menu_item;
    }

    public function serialize() {
	$html = "";

        if ($this-&gt;level == 0) {
            $html = "&lt;ul class=\"menu\"&gt;\n";
        }

        if (!empty($this-&gt;items)) {
            $html .= "&lt;li class=\"{$this-&gt;get_class()} menu_arrow\"&gt;";
        } else {
            $html .= "&lt;li class=\"{$this-&gt;get_class()}\"&gt;";
        }

        $html .= "&lt;a href=\"$this-&gt;url\"&gt;$this-&gt;name";

        if (!empty($this-&gt;items)) {
            $html .= "&lt;/a&gt;\n&lt;ul class=\"{$this-&gt;get_class()}_block\"&gt;\n";
            foreach ($this-&gt;items as $menu_item) {
                $html .= $menu_item-&gt;serialize();
            }
            $html .= "&lt;/ul&gt;\n";
        } else {
            $html .= "&lt;/a&gt;";
        }

        $html .= "&lt;/li&gt;\n";

        if ($this-&gt;level == 0) {
            $html .= "&lt;/ul&gt;\n";
        }

        return $html;
    }

    private function get_class() {
        switch ($this-&gt;level) {
            case 0:
                $class = "level_zero";
                break;
            case 1:
                $class = "level_one";
                break;
            case 2:
                $class = "level_two";
                break;
        }
        return $class;
    }
}</pre>
<p>This class makes it very easy to dynamically generate a multi tiered menu. All you have to do is create your base items and add them to the MenuItem that they belong too.</p>
<pre class="brush:php">$search_links = new MenuItem("Search", 1);
$search_links-&gt;add_item(
        new MenuItem("Google", 2, "http://www.google.com")
);
$search_links-&gt;add_item(
        new MenuItem("Yahoo", 2, "http://www.yahoo.com")
);

$social_links = new MenuItem("Social", 1);
$social_links-&gt;add_item(
        new MenuItem("Facebook", 2, "http://www.facebook.com")
);
$social_links-&gt;add_item(
        new MenuItem("Twitter", 2, "http://www.twitter.com")
);

$menu = new MenuItem("Links", 0);
$menu-&gt;add_item($search_links);
$menu-&gt;add_item($social_links);

echo $menu-&gt;serialize();</pre>
<p>The code above generates the unordered list below which, as mentioned before, can be controlled with pure CSS in the newer standards compliant browsers.</p>
<pre class="brush: xml;">
&lt;ul class=&quot;menu&quot;&gt;
&lt;li class=&quot;level_zero menu_arrow&quot;&gt;&lt;a href=&quot;#&quot;&gt;Links&lt;/a&gt;
&lt;ul class=&quot;level_zero_block&quot;&gt;
&lt;li class=&quot;level_one menu_arrow&quot;&gt;&lt;a href=&quot;#&quot;&gt;Search&lt;/a&gt;
&lt;ul class=&quot;level_one_block&quot;&gt;
&lt;li class=&quot;level_two&quot;&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;Google&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;level_two&quot;&gt;&lt;a href=&quot;http://www.yahoo.com&quot;&gt;Yahoo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level_one menu_arrow&quot;&gt;&lt;a href=&quot;#&quot;&gt;Social&lt;/a&gt;
&lt;ul class=&quot;level_one_block&quot;&gt;
&lt;li class=&quot;level_two&quot;&gt;&lt;a href=&quot;http://www.facebook.com&quot;&gt;Facebook&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;level_two&quot;&gt;&lt;a href=&quot;http://www.twitter.com&quot;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</pre>
<p>The list above is controlled with the tiniest amount of CSS below. Of course the nicer you wan&#8217;t your menu to look the more CSS you will need to throw in! </p>
<pre class="brush:css">
ul.menu li ul {
	display: none;
}
</pre>
<p>The JQuery code I used to control the above menu is larger then it needs to be in order to make the menu support most browsers and operating systems. Many of the hacks in the script is to force Internet Explorer 6/7 to conform to the likes of Chrome and Firefox. Only the min width value needs to be set here to get your menu pop outs positioned correctly.</p>
<pre class="brush: jscript;">/* IE does not support min-width so we can get it with js since we are
 * already iterating through the items to display them.
 */
function setMinWidth(element) {
	if (element.width() &lt; 150) {
		element.css('width', '150px')
	}
}

/* IE positoning is kinda random compared to FF, Chrome and Safari so
 * this is to force it to conform.
 */
function positionPopout(element, top) {
	element.css('display', 'block');
	element.css('top', top + "px");
	setMinWidth(element);
}

$(document).ready(function() {
	$('li.level_zero').hover(
		function() {
			var element = $('ul.level_zero_block', this);
			var top = $(this).offset().top + $(this).height();

			//Fix IE left
			element.css('left', ($(this).position().left + 2) + "px");
			positionPopout(element, top);
		},
		function() {
			$('ul.level_zero_block', this).css('display', 'none');
		}
	);

	$('li.level_one').hover(
		function() {
			var element = $('ul.level_one_block', this);
			var top = $(this).offset().top -  + $(this).height();

			positionPopout(element, top);
			setMinWidth(element);
		},
		function() {
			$('ul.level_one_block', this).css('display', 'none');
		}
	);

	$('li.level_two').hover(
		function() {
			var element = $('ul.level_two_block', this);
			var top = $(this).offset().top - ($(this).height() * 2);

			positionPopout(element, top);
			setMinWidth(element);
		},
		function() {
			$('ul.level_two_block', this).css('display', 'none');
		}
	);
});</pre>
<p>This way of providing a drop down menu for your website is not a new idea, however I think using the MenuItem class is an elegant and easy way of dynamically generating this style of menu.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeyd.com.au/2010/05/15/cross-browser-php-drop-down-menu-generator-powered-by-jquery-and-css/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dynamically Populate a Select/Drop Down List using ASP.NET MVC, JQuery and Json</title>
		<link>http://www.mikeyd.com.au/2009/08/22/dynamically-populate-a-selectdrop-down-list-using-aspnet-mvc-jquery-and-json/</link>
		<comments>http://www.mikeyd.com.au/2009/08/22/dynamically-populate-a-selectdrop-down-list-using-aspnet-mvc-jquery-and-json/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 07:10:13 +0000</pubDate>
		<dc:creator>Mikey</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Json]]></category>

		<guid isPermaLink="false">http://www.mikeyd.com.au/?p=39</guid>
		<description><![CDATA[It has been a while since my last blog due to me being flat out at work during the week and snowboarding on the weekends! Today the weather is terrible up in the alps and I managed to catch the flu so it was a good time to catch up on some personal projects. I [...]]]></description>
			<content:encoded><![CDATA[<p>It has been a while since my last blog due to me being flat out at work during the week and snowboarding on the weekends!</p>
<p>Today the weather is terrible up in the alps and I managed to catch the flu so it was a good time to catch up on some personal projects. I was working on an ASP.NET MVC website for my sister and decided to use AJAX to populate a select list based on a selection in another select list. The ASP.NET MVC framework and JQuery makes it very easy to use AJAX to do this.</p>
<p>This is nothing new but very powerful if you want to create a nice fluent forms user interface. For the most part the process was very easy. However I ran into an issue where JQuery was treating the Json returned from the server as a string instead of an object. Thus making if difficult to retrieve the data I wanted. I will explain how I got around this later in the post.</p>
<p>The first thing you need to do create the server side method. This is very easy using ASP.NET MVC! Of course you would probably get your data from a database of some sort, however this is just a nice way of showing how its done. The method below gets a list of Foo objects based on the FooId parameter using LINQ&#8217;s Where method.</p>
<pre class="brush:csharp">public class Foo
{
    public int FooId { get; set; }
    public string Name { get; set; }
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetFooList(int FooId)
{
    var fooList = new List();
    fooList.Add(new Foo { FooId = 1, Name = "One" } );
    fooList.Add(new Foo { FooId = 1, Name = "Two" } );
    fooList.Add(new Foo { FooId = 2, Name = "Three" });
    fooList.Add(new Foo { FooId = 2, Name = "Four" });
    return Json(fooList.Where(foo =&gt; foo.FooId == FooId).ToList());
}</pre>
<p>Now for the client side code. On my page I have two select lists. One is a list of Id’s and the other is a list of names. When a user selects an id from the first select list the second is populated with the names relating to that id. The lists can be created easily using using the ASP.NET MVC Helpers or writing the HTML yourself.</p>
<pre class="brush:xml">
<select id="IdList">
<option>1</option>
<option>2</option>
</select>
</pre>
<p>Finally the JQuery code in order to add the functionality to the page. JQuery makes it easy to execute server side methods and receive Json. The code below binds the AJAX post method to the change event of the IdList select list. The post function has three variables; The sever method to execute, the parameters to pass as Json and the function to execute with the data returned from the server. You can either execute a named or a anonymous function. I chose the latter because I am not doing too much inside the function.</p>
<pre class="brush:javascript"> $(function() {
        $("#IdList").change(function() {
            $.getJSON("/Controller/GetFooList", { FooId: $("#IdList").val() },
            function(fooList) {
                $("#NameList").empty();
                $.each(fooList, function(i, foo) {
                    $("#NameList").append(""+ foo.Name+ "");
                });
            });
        });
    });</pre>
<p>The biggest issue I came across was, originally, the FooList Json was being represented as a string therefore the JQuery each method was iterating through each character of the string rather then each object. After a bit reading I came across the JSON.parse method in the JQuery library. This method parses the string to Json which means that the JQuery each method functions as I expected.</p>
<p>There we have it. Like I said nothing new here but interesting never the less.</p>
<p>The only thing I don’t like about this code is the append method in my JQuery. Surly there is a better way of adding options to a select element?</p>
<p><strong>UPDATE 120/01/2011:  I have recently realised that using eval is bad! This is because it will evaluate ANY javascript returned from the server. Therefore there is a chance that someone with malicious intent could insert their own javascript into your request. So instead you should use jQuery&#8217;s getJSON method instead. The above code has been modified to use this function.</strong></p>
<p></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mikeyd.com.au/2009/08/22/dynamically-populate-a-selectdrop-down-list-using-aspnet-mvc-jquery-and-json/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

