<?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>amnuts &#187; Prototype</title>
	<atom:link href="http://blog.amnuts.com/category/prototype/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.amnuts.com</link>
	<description>php projects, javascript, and... stuff.</description>
	<lastBuildDate>Fri, 07 May 2010 09:11:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Easy chained select lists using Zend Framework and Prototype</title>
		<link>http://blog.amnuts.com/2007/08/13/easy-chained-select-lists-using-zend-framework-and-prototype/</link>
		<comments>http://blog.amnuts.com/2007/08/13/easy-chained-select-lists-using-zend-framework-and-prototype/#comments</comments>
		<pubDate>Mon, 13 Aug 2007 15:02:35 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.amnuts.com/2007/08/13/easy-chained-select-lists-using-zend-framework-and-prototype/</guid>
		<description><![CDATA[Building a set of select lists that are dependant of each other can be a daunting task, but for a simple two-level list &#8211; in that what you select from one drop-down will changing what&#8217;s displayed in one or more other drop-downs &#8211; is actually quite easy thanks to Zend Frameworks and Prototype, both of [...]]]></description>
			<content:encoded><![CDATA[<p>Building a set of select lists that are dependant of each other can be a daunting task, but for a simple two-level list &#8211; in that what you select from one drop-down will changing what&#8217;s displayed in one or more other drop-downs &#8211; is actually quite easy thanks to Zend Frameworks and Prototype, both of which support Json.</p>
<p><span id="more-47"></span><br />
What I needed to do was have a list of items.  Each item would have a different type, colours, range and so on.  When I selected an item from a select list I wanted the other optional lists to update.  Now, I&#8217;ve seen this done with Ajax to completely rebuild the html of the select lists, but I didn&#8217;t want to go down that route.  Instead, I decided to use a bit of PHP and a bit of Javascript.</p>
<p>First of all I had to decide how I wanted to store my items.  I could have gone down the headache of a database, but I wanted to keep this simple.  So in steps the always-simply ini file.  Zend Framework makes it really easy to parse this particular format, which is great news!</p>
<p>The ini file looks something like:</p>
<pre class="brush: php;">[_default]

name   = &quot;_default&quot;
type   = &quot;&quot;
range  = &quot;home; garden; garage; kitchen&quot;
colour = &quot;white; silver; black; red; blue; yellow; green&quot;

[fridge : _default]

name   = &quot;Fridges and freezers&quot;
type   = &quot;double; chest; mini&quot;

[fork : _default]

name   = &quot;Forks&quot;
type   = &quot;big; small&quot;
range  = &quot;kitchen; garden&quot;
colour = &quot;silver; black&quot;

[trash : _default]

name   = &quot;Trash cans&quot;</pre>
<p>As you can see, I extend one base item type, changing only what I need to.</p>
<p>Now I have my ini file, I need to convert that to Json.  The easiest way to do this is simply to load the whole ini file into a nicely formatted array and convert that array to the Json format.  The PHP to do that is actually quite simple, and looks something like this:</p>
<pre class="brush: php;">&lt;?php

require 'Zend/Config/Ini.php';
require 'Zend/Json.php';

$config = new Zend_Config_Ini(dirname(__FILE__) . '/items.ini', null);

$items = array();
foreach ($config as $key =&gt; $val) {
    if ($key{0} != '_') {
        foreach ($val as $k =&gt; $v) {
            $items[$key][$k] = (strstr($v, ';')) ? array_map('trim', explode(';', $v)) : $v;
        }
    }
}
$json = Zend_Json::encode($items);
</pre>
<p>Again, the Zend Framework comes to the rescue and does all the hard work for me.  All I have to do is process the ini file, making arrays out of lists (the strings separated with semi-colons) and ignoring anything that starts with an underscore.</p>
<p>That file ends up giving me a Json string and a PHP array, both of which can be used in the form.  In this HTML I have quickly put in the select lists, but I&#8217;m sure you could do something programmatically, or in a template, or something&#8230; this is just for show, after all. <img src='http://blog.amnuts.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<pre class="brush: php;">&lt;?php include('json.php'); ?&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;prototype.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot;&gt;
        var items = '&lt;?php echo $json; ?&gt;'.evalJSON(true);
        var optlist = ['type', 'range', 'colour'];

        Event.observe(window, 'load', function() {
            Event.observe('item', 'change', function() {
                var itype = $F('item');
                optlist.each(function(o) {
                    $(o).options.length = 1;
                    if (itype) {
                        if (items[itype][o].length &gt; 0) {
                            for (i = 0; i &lt; items[itype][o].length; i++) {
                                $(o).options[$(o).options.length] = new Option(items[itype][o][i]);
                            }
                            $(o).enable();
                        } else {
                            $(o).disable();
                        }
                    } else {
                        $(o).disable();
                    }
                });
            });
        });

    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;form action=&quot;&quot; method=&quot;post&quot;&gt;

Item&lt;br /&gt;
&lt;select name=&quot;item&quot; id=&quot;item&quot;&gt;
&lt;option value=&quot;&quot;&gt;Select an item&lt;/option&gt;
&lt;?php

    foreach ($items as $type =&gt; $details) {
        echo '&lt;option value=&quot;', $type, '&quot;&gt;', $details['name'], &quot;&lt;/option&gt;\n&quot;;
    }

?&gt;
&lt;/select&gt;&lt;br /&gt;

Type&lt;br /&gt;
&lt;select name=&quot;type&quot; id=&quot;type&quot; disabled=&quot;disabled&quot;&gt;
    &lt;option value=&quot;&quot;&gt;Please select&lt;/option&gt;
&lt;/select&gt;&lt;br /&gt;

Range&lt;br /&gt;
&lt;select name=&quot;range&quot; id=&quot;range&quot; disabled=&quot;disabled&quot;&gt;
    &lt;option value=&quot;&quot;&gt;Please select&lt;/option&gt;
&lt;/select&gt;&lt;br /&gt;

Colour&lt;br /&gt;
&lt;select name=&quot;colour&quot; id=&quot;colour&quot; disabled=&quot;disabled&quot;&gt;
    &lt;option value=&quot;&quot;&gt;Please select&lt;/option&gt;
&lt;/select&gt;&lt;br /&gt;

&lt;p&gt;&lt;input type=&quot;submit&quot; /&gt;&lt;/p&gt;

&lt;/form&gt;

&lt;/body&gt;
&lt;/html&gt;</pre>
<p>The main part of that is, of course, the javascript.  Using Prototype I&#8217;m easily able to convert the Json string from the PHP file back in to an object, and then set an event observer on the items select list to register a change in value.  All that&#8217;s left to do is loop over the other form elements (which, to make things easy, I hard-coded in to the optlist variable, but again, this could be dynamic) and set the correct values, enabling or disabling the form elements where needed.</p>
<p>The above code can be found running at:</p>
<p><a href="http://dev.amnuts.com/chained/">http://dev.amnuts.com/chained/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.amnuts.com/2007/08/13/easy-chained-select-lists-using-zend-framework-and-prototype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slider &#8211; part 2 &#8211; using a mouse wheel</title>
		<link>http://blog.amnuts.com/2007/06/15/slider-part-2-using-a-mouse-wheel/</link>
		<comments>http://blog.amnuts.com/2007/06/15/slider-part-2-using-a-mouse-wheel/#comments</comments>
		<pubDate>Fri, 15 Jun 2007 13:58:26 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.amnuts.com/2007/06/15/slider-part-2-using-a-mouse-wheel/</guid>
		<description><![CDATA[Following on from the previous post, I thought it&#8217;d be nice to have the handle move on a mouse wheel.  Looking around for mouse wheel integration, it seems that it&#8217;s only a short amount of code to update Prototype to use the mouse wheel.  When it&#8217;s not in the core code, I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from the previous post, I thought it&#8217;d be nice to have the handle move on a mouse wheel.  Looking around for mouse wheel integration, it seems that it&#8217;s only a short amount of code to update Prototype to use the mouse wheel.  When it&#8217;s not in the core code, I don&#8217;t know, as it seems rather handy.  The mouse wheel code is listed at the <a href="http://ajaxian.com/archives/prototype-event-extension-eventwheele">Prototype Event Extension article</a> over at <a href="http://ajaxian.com/">Ajaxian</a>.</p>
<p><span id="more-45"></span></p>
<p>I decided to integrate the code directly in to Prototype, also dropping the following in to &#8216;observe&#8217; and &#8217;stopObserving&#8217;:</p>
<pre class="brush: jscript;">if (name == 'mousewheel' &amp;&amp;
    (element.addEventListener))
    name = 'DOMMouseScroll';</pre>
<p>Then using the same XHTML as before, which was:</p>
<pre class="brush: xml;">&lt;div id=&quot;slider&quot;&gt;
    &lt;div id=&quot;slider-bar&quot;&gt;
        &lt;div id=&quot;slider-handle&quot;&gt;&lt;p id=&quot;percent&quot;&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;</pre>
<p>all you have to do is drop an event on the <strong>div#slider</strong> for the mouse wheel.  That little bit of javscript looks like:</p>
<pre class="brush: jscript;">Event.observe('slider', 'mousewheel', function(e) {
    slide.setValueBy((Event.wheel(e)/10));
});</pre>
<p>Now when you scroll the mouse wheel the slider will change by a value of 10.  This value comes from the &#8216;Event.wheel(e) / 10&#8242; part.  The mouse wheel method returns either 1 or -1, and the slider goes from 0 to 1.  Obviously, if you want the mouse wheel to move the slider by only a value or 1, then divide the delta by 100; &#8216;Event.wheel(e) / 100&#8242;.</p>
<p>As before, you can see it in action at <a href="http://dev.amnuts.com/slider/">http://dev.amnuts.com/slider/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.amnuts.com/2007/06/15/slider-part-2-using-a-mouse-wheel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scriptaculous slider trick</title>
		<link>http://blog.amnuts.com/2007/06/14/scriptaculous-slider-trick/</link>
		<comments>http://blog.amnuts.com/2007/06/14/scriptaculous-slider-trick/#comments</comments>
		<pubDate>Thu, 14 Jun 2007 13:51:47 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Experiments]]></category>
		<category><![CDATA[Prototype]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.amnuts.com/2007/06/14/scriptaculous-slider-trick/</guid>
		<description><![CDATA[Yesterday I was looking at the Scriptaculous library, in particular the slider bar.  I had used it once before with some success, using a graphic for the track and gripper.  But that&#8217;s was boring!  What I wanted was to see the bar fill up with colour when it was slid.  Something [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I was looking at the Scriptaculous library, in particular the slider bar.  I had used it once before with some success, using a graphic for the track and gripper.  But that&#8217;s was boring!  What I wanted was to see the bar fill up with colour when it was slid.  Something like this:</p>
<p><img src="http://blog.amnuts.com/wp-content/uploads/2007/06/slider.jpg" alt="Slider demo" /></p>
<p>I hadn&#8217;t seen anything like this around (not saying it hasn&#8217;t been done, just that I hadn&#8217;t seen it!), so after a bit of playing I found out it was actually very easy to create.  And this is how I did it&#8230;</p>
<p><span id="more-40"></span></p>
<p>All it really does is use a handy little trick with transparent PNG images and background-image positions.  You can find details of what I mean in this handy <a href="http://www.barenakedapp.com/the-design/displaying-percentages">article by Dave Stone, over at Bare Naked App</a>.</p>
<p>So basically I have my slider gripper (or handle), which has a transparent background:</p>
<p><a href="http://blog.amnuts.com/wp-content/uploads/2007/06/gripper.png" title="Slider gripper"><img src="http://blog.amnuts.com/wp-content/uploads/2007/06/gripper.png" alt="Slider gripper" /></a></p>
<p>And the slider track, which has an opaque white background but is transparent where I want the colour to show through (thumbnail shown, but links through to full size image):</p>
<p><a href="http://blog.amnuts.com/wp-content/uploads/2007/06/track.png" title="Slider track"><img src="http://blog.amnuts.com/wp-content/uploads/2007/06/track.thumbnail.png" alt="Slider track" /></a></p>
<p>And then I have the background image, which is essentially double the size of the track and has one half in off-white and one in green  (thumbnail shown, but links through to full size image):</p>
<p><a href="http://blog.amnuts.com/wp-content/uploads/2007/06/bg.gif" title="Slider background"><img src="http://blog.amnuts.com/wp-content/uploads/2007/06/bg.thumbnail.gif" alt="Slider background" /></a></p>
<p>The XHTML used for the slider looks like this:</p>
<pre class="brush: xml;">&lt;div id=&quot;slider&quot;&gt;
    &lt;div id=&quot;slider-bar&quot;&gt;
        &lt;div id=&quot;slider-handle&quot;&gt;&lt;p id=&quot;percent&quot;&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;</pre>
<p>The CSS looks like this:</p>
<pre class="brush: css;">#slider, #slider-bar, #slider-handle {
    border: 0;
    padding: 0;
    margin: 0;
}
#slider {
    width: 300px;
    height:42px;
    background: url(img/bg.gif) no-repeat -300px;
    margin-left: 42px;
}
#slider-bar {
    width:300px;
    height:42px;
    background: url(img/track.png) no-repeat;
}
#slider-handle {
    width:42px;
    height:42px;
    cursor:move;
    background: url(img/gripper.png) no-repeat;
}
#percent {
    font-size: 75%;
    font-family: arial;
    font-weight: bold;
    text-align: center;
    padding-top: 1.1em;
}</pre>
<p>And finally, the Javascript looks like this:</p>
<pre class="brush: jscript;">&lt;script type=&quot;text/javascript&quot;&gt;
// &lt;![CDATA[
var hWidth, bWidth;

function setBgPos(v) {
    var off = v * hWidth;
    var pos = -bWidth + (v * bWidth);
    $('slider').setStyle({backgroundPosition: Math.round(pos - off) + 'px'});
}

function setSlideOutput(v) {
    $('percent').innerHTML = Math.round(v * 100) + '%';
}

Event.observe(window, 'load', function() {
    hWidth = $('slider-handle').getWidth();
    bWidth = $('slider-bar').getWidth();
    var slide = new Control.Slider('slider-handle', 'slider-bar', {
        sliderValue: 0.25,
        onSlide:
            function(v) {
                setBgPos(v);
                setSlideOutput(v);
            },
        onChange:
            function(v) {
                setBgPos(v);
                setSlideOutput(v);
            }
    });
    setBgPos(slide.value);
    setSlideOutput(slide.value);
});
// ]]&gt;
&lt;/script&gt;</pre>
<p>You may notice the offset value, <em>off</em>.  I&#8217;m using this because in my experiment the slider handle doesn&#8217;t fully cover the bar (nor did I want it to), so I cannot have the background image colour go fully across the track.  I had to incrementally offset it depending on the position and size of the handle.</p>
<p>And that&#8217;s it!  Pretty darned easy, but looks really neat.  You can see it in action at <a href="http://dev.amnuts.com/slider/">http://dev.amnuts.com/slider/</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.amnuts.com/2007/06/14/scriptaculous-slider-trick/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Same height for elements</title>
		<link>http://blog.amnuts.com/2007/02/09/same-height-for-elements/</link>
		<comments>http://blog.amnuts.com/2007/02/09/same-height-for-elements/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 23:52:22 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Prototype]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.amnuts.com/2007/02/09/same-height-for-elements/</guid>
		<description><![CDATA[Surely this is easy, right?  Just set the height property in your css.  Well, yes and no.  That&#8217;s all well and good if you know what height the elements are going to be, but quite often you might be pulling information out of a database in to the elements and you don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Surely this is easy, right?  Just set the <em>height</em> property in your css.  Well, yes and no.  That&#8217;s all well and good if you know what height the elements are going to be, but quite often you might be pulling information out of a database in to the elements and you don&#8217;t know how big that information is going to be.  You can&#8217;t use the <em>overflow</em> because that&#8217;s not the designer&#8217;s concept.  No; they want three boxes on screen that all have the same height so they&#8217;re all nice and ordered and symmetrical.</p>
<p><span id="more-29"></span><br />
What about using tables?</p>
<p>Wash your mouth out!  No, of course we don&#8217;t want to use tables.  Instead that old friend of ours, javascript, comes to the rescue.  Using that fabulous library <a href="http://www.prototypejs.org/">Prototype</a>, because I&#8217;m lazy, you could do something like this:</p>
<pre lang="javascript">
<script src="prototype.js" type="text/javascript"></script>
<script type="text/javascript"> 
function resizeElements() 
{ 
    var maxH = 0; 
    var nodes = document.getElementsByClassName('max-height'); 
    for (var i = 0; i < nodes.length; i++) { 
        var h = Element.getHeight(nodes[i]);
        maxH = (h > maxH) ? h : maxH; 
    } 
    for (var i = 0; i < nodes.length; i++) { 
        Element.setStyle(nodes[i], $H({height:maxH+'px',overflow:'hidden'})); 
    } 

    maxH = 0; 
    nodes = document.getElementsByClassName("min-height"); 
    for (var i = 0; i < nodes.length; i++) { 
        var h = Element.getHeight(nodes[i]); 
        maxH = ((h < maxH) || !maxH) ? h : maxH; 
    } 
    for (var i = 0; i < nodes.length; i++) { 
        Element.setStyle(nodes[i], $H({height:maxH+'px',overflow:'hidden'})); 
    } 
} 
Event.observe(window, 'load', resizeElements, false); 
</script>
</script></pre>
<h4>What does it do?</h4>
<p>The title of the post should be enough to give it away.  It makes the elements you decide all have the same height.  If you use the class <em>max-height</em> then the elements will all be the same height as the tallest one, and if you use <em>min-height</em> they will have the same height as the shortest one.</p>
<h4>How do you use it?</h4>
<p>Simply drop in one of the classes on all the divs you want to make the same height, for example:</p>
<pre lang="html">
<div id="d1" class="max-height">
  some text
</div>
<div id="d2" class="max-height">
  more 
  more 
  more 
  more 
  more 
  more 
  more 
  more 
  more 
</div>
<div id="d3" class="max-height">
  final bit of text 
  final bit of text 
  final bit of text 
</div>
<div id="d4">
  not resized...
</div>
</pre>
<h4>And everyone is happy&#8230;</h4>
<p>The designer is happy because you&#8217;ve retained the nice symmetrical boxes.  You&#8217;re happy because you&#8217;re using nice clean code that&#8217;ll degrade nicely.  I&#8217;m happy because you&#8217;ve read this. <img src='http://blog.amnuts.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.amnuts.com/2007/02/09/same-height-for-elements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
