Commits

Olemis Lang  committed 9d10579

BH Dashboard #146: iPhone checkbox editable type + js lib . Function bindings in BH editable data API

  • Participants
  • Parent commits 85ae3dc
  • Branches t146_inline_edit

Comments (0)

Files changed (5)

 hgsvn/rm_files.diff
 t146/t146_r1386655_jeditable.diff
+t146/t146_r1386655_jeditable_custom.diff
+t146/t146_r1386655_jquery_iphone_checkbox.diff
 t146/t146_r1386655_bheditable.diff

File t146/t146_r1386655_bheditable.diff

 # HG changeset patch
-# Parent c25cea793d1a8641cf1a7a1697e83b0470e588ba
+# Parent fe1dd1d24bcea6ddeeabf64934d79330d4caf23f
 BH Dashboard #146 : Bloodhound in-place edit arquitecture
 
-diff -r c25cea793d1a bhdashboard/htdocs/js/bheditable.js
+diff -r fe1dd1d24bce bhdashboard/htdocs/js/bheditable.js
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/bhdashboard/htdocs/js/bheditable.js	Mon Sep 24 01:26:46 2012 -0500
-@@ -0,0 +1,157 @@
++++ b/bhdashboard/htdocs/js/bheditable.js	Wed Sep 26 22:23:35 2012 -0500
+@@ -0,0 +1,203 @@
 +/*
 +  Licensed to the Apache Software Foundation (ASF) under one
 +  or more contributor license agreements.  See the NOTICE file
 +          $('select', this).find('option').each(function() {
 +              if ($(this).val() == json['selected'] || 
 +                  $(this).text() == $.trim(original.revert)) {
-+                      $(this).attr('selected', 'selected');
++                $(this).attr('selected', 'selected');
 +              }
 +            });
 +
 +        }
 +    });
 +
++  $.editable.addInputType('iphone-checkbox', 
++    {
++      element : function(settings, original) {
++          var checkbox = $('<input />').attr('type', 'checkbox');
++          var container = $('<div />');
++          if (settings.width != 'none')
++            container.css({ width : settings.width });
++          if (settings.height != 'none')
++            container.css({ height : settings.height });
++          container.append(checkbox);
++          $(this).append(container);
++          return checkbox;
++        },
++      content : function(data, settings, original) {
++          if (String == data.constructor)
++            var json = $.parseJSON(data);
++          else
++            var json = data;
++          var value = json['checked'] || $.trim(original.revert);
++
++          json['checkedLabel'] = json['checkedLabel'] || 'yes';
++          json['uncheckedLabel'] = json['uncheckedLabel'] || 'no';
++
++          if (String == value.constructor)
++            value = value.toLowerCase();
++          var TRUE_VALUES = ':yes:true:enabled:on:aye:1:' + 
++              json['checkedLabel'] + ':';
++          value = (value === 1) || (value === true) ||
++              (TRUE_VALUES.indexOf(':'+ value +':') >= 0);
++          var checkbox = $('input[type="checkbox"]', this);
++          if (value)
++              checkbox.attr('checked', 'checked');
++          checkbox.iphoneStyle(json);
++        },
++    });
++
 + /* BLODDHOUND EDITABLE DATA-API
 +  * ============================ */
 +
 +        , data = $editable.data()
 +
 +      var edit_data = {};
++      FUNCTION_OPTIONS = ':callback:submitdata:loaddata:data:onblur:onsubmit:' +
++          'onreset:onerror:';
 +      for (var k in data) {
-+        if (k !== "edit" && k.substr(0, 4) === "edit")
-+          edit_data[k.substr(4)] = data[k];
++        if (k !== "edit" && k.substr(0, 4) === "edit") {
++          var value = data[k];
++          var _k = k.substr(4);
++          if ((FUNCTION_OPTIONS.indexOf(':' + _k + ':') >= 0) &&
++              (value.substr(0, 11) === 'javascript:')) {
++            eval('var newvalue = ' + value.substr(11));
++            value = newvalue;
++          }
++          edit_data[_k] = value;
++        }
 +      }
 +
 +      //alert($.toJSON(edit_data));
 +
 +}(window.jQuery); 
 +
-diff -r c25cea793d1a bhdashboard/htdocs/js/jquery.json.js
+diff -r fe1dd1d24bce bhdashboard/htdocs/js/jquery.json.js
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/bhdashboard/htdocs/js/jquery.json.js	Mon Sep 24 01:26:46 2012 -0500
++++ b/bhdashboard/htdocs/js/jquery.json.js	Wed Sep 26 22:23:35 2012 -0500
 @@ -0,0 +1,23 @@
 +
 +(function($){var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';}
 +c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
 +return'"'+string+'"';};})(jQuery);
 \ No newline at end of file
-diff -r c25cea793d1a bhdashboard/util.py
---- a/bhdashboard/util.py	Sun Sep 23 13:33:21 2012 -0500
-+++ b/bhdashboard/util.py	Mon Sep 24 01:26:46 2012 -0500
+diff -r fe1dd1d24bce bhdashboard/util.py
+--- a/bhdashboard/util.py	Wed Sep 26 22:14:08 2012 -0500
++++ b/bhdashboard/util.py	Wed Sep 26 22:23:35 2012 -0500
 @@ -176,6 +176,17 @@
      )
  

File t146/t146_r1386655_jeditable.diff

 # HG changeset patch
-# Parent cfca98864f9e6af9f8a4f0f08c734e3feba59d20
+# Parent a295bcce21f576df233bed9938516593a5ba2903
 BH Dashboard #146: jEditable files
 
-diff -r cfca98864f9e bhdashboard/htdocs/js/jquery.jeditable.js
+diff -r a295bcce21f5 bhdashboard/htdocs/js/jquery.jeditable.js
 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/bhdashboard/htdocs/js/jquery.jeditable.js	Wed Sep 19 18:56:14 2012 -0500
++++ b/bhdashboard/htdocs/js/jquery.jeditable.js	Wed Sep 26 18:05:46 2012 -0500
 @@ -0,0 +1,546 @@
 +/*
 + * Jeditable - jQuery in place edit plugin
 +    };
 +
 +})(jQuery);
-diff -r cfca98864f9e bhdashboard/htdocs/js/jquery.jeditable.mini.js
---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
-+++ b/bhdashboard/htdocs/js/jquery.jeditable.mini.js	Wed Sep 19 18:56:14 2012 -0500
-@@ -0,0 +1,1 @@
-+(function($){$.fn.editable=function(target,options){if("disable"==target){$(this).data("disabled.editable",true);return}if("enable"==target){$(this).data("disabled.editable",false);return}if("destroy"==target){$(this).unbind($(this).data("event.editable")).removeData("disabled.editable").removeData("event.editable");return}var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types.defaults.buttons;var content=$.editable.types[settings.type].content||$.editable.types.defaults.content;var element=$.editable.types[settings.type].element||$.editable.types.defaults.element;var reset=$.editable.types[settings.type].reset||$.editable.types.defaults.reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr("title",settings.tooltip)}settings.autowidth="auto"==settings.width;settings.autoheight="auto"==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data("event.editable",settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder)}$(this).bind(settings.event,function(e){if(true===$(this).data("disabled.editable")){return}if(self.editing){return}if(false===onedit.apply(this,[settings,self])){return}e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr("title")}if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight}else{if(settings.width!="none"){settings.width=settings.autowidth?$(self).width():settings.width}if(settings.height!="none"){settings.height=settings.autoheight?$(self).height():settings.height}}if($(this).html().toLowerCase().replace(/(;|"|\/)/g,"")==settings.placeholder.toLowerCase().replace(/(;|"|\/)/g,"")){$(this).html("")}self.editing=true;self.revert=$(self).html();$(self).html("");var form=$("<form />");if(settings.cssclass){if("inherit"==settings.cssclass){form.attr("class",$(self).attr("class"))}else{form.attr("class",settings.cssclass)}}if(settings.style){if("inherit"==settings.style){form.attr("style",$(self).attr("style"));form.css("display",$(self).css("display"))}else{form.attr("style",settings.style)}}var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self])},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]))}else{$.extend(loaddata,settings.loaddata)}$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false}})}else{if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings])}}else{input_content=self.revert}}content.apply(form,[input_content,settings,self]);input.attr("name",settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(":input:visible:enabled:first",form).focus();if(settings.select){input.select()}input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self])}});var t;if("cancel"==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self])},500)})}else{if("submit"==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit()},200)})}else{if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings])})}else{input.blur(function(e){})}}}form.submit(function(e){if(t){clearTimeout(t)}e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder)}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]))}else{$.extend(submitdata,settings.submitdata)}if("PUT"==settings.method){submitdata._method="put"}$(self).html(settings.indicator);var ajaxoptions={type:"POST",data:submitdata,dataType:"html",url:settings.target,success:function(result,status){if(ajaxoptions.dataType=="html"){$(self).html(result)}self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder)}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr])}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions)}}}$(self).attr("title",settings.tooltip);return false})});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder)}if(settings.tooltip){$(self).attr("title",settings.tooltip)}}}}})};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden"></input>');$(this).append(input);return(input)},content:function(string,settings,original){$(":input:first",this).val(string)},reset:function(settings,original){original.reset(this)},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit()}})}else{var submit=$('<button type="submit" />');submit.html(settings.submit)}$(this).append(submit)}if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel)}else{var cancel=$('<button type="cancel" />');cancel.html(settings.cancel)}$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset}else{var reset=$.editable.types.defaults.reset}reset.apply(form,[settings,original]);return false})}}},text:{element:function(settings,original){var input=$("<input />");if(settings.width!="none"){input.attr("width",settings.width)}if(settings.height!="none"){input.attr("height",settings.height)}input.attr("autocomplete","off");$(this).append(input);return(input)}},textarea:{element:function(settings,original){var textarea=$("<textarea />");if(settings.rows){textarea.attr("rows",settings.rows)}else{if(settings.height!="none"){textarea.height(settings.height)}}if(settings.cols){textarea.attr("cols",settings.cols)}else{if(settings.width!="none"){textarea.width(settings.width)}}$(this).append(textarea);return(textarea)}},select:{element:function(settings,original){var select=$("<select />");$(this).append(select);return(select)},content:function(data,settings,original){if(String==data.constructor){eval("var json = "+data)}else{var json=data}for(var key in json){if(!json.hasOwnProperty(key)){continue}if("selected"==key){continue}var option=$("<option />").val(key).append(json[key]);$("select",this).append(option)}$("select",this).children().each(function(){if($(this).val()==json.selected||$(this).text()==$.trim(original.revert)){$(this).attr("selected","selected")}});if(!settings.submit){var form=this;$("select",this).change(function(){form.submit()})}}}},addInputType:function(name,input){$.editable.types[name]=input}};$.fn.editable.defaults={name:"value",id:"id",type:"text",width:"auto",height:"auto",event:"click.editable",onblur:"cancel",loadtype:"GET",loadtext:"Loading...",placeholder:"Click to edit",loaddata:{},submitdata:{},ajaxoptions:{}}})(jQuery);
-\ No newline at end of file

File t146/t146_r1386655_jeditable_custom.diff

+# HG changeset patch
+# Parent 8ec76296a6b27d65da4c65f73e50561ef72777bf
+BH Dashboard #146: Enhanced jEditable
+
+diff -r 8ec76296a6b2 bhdashboard/htdocs/js/jquery.jeditable.js
+--- a/bhdashboard/htdocs/js/jquery.jeditable.js	Wed Sep 26 18:05:46 2012 -0500
++++ b/bhdashboard/htdocs/js/jquery.jeditable.js	Wed Sep 26 22:26:11 2012 -0500
+@@ -177,6 +177,9 @@
+                 /* Create the form object. */
+                 var form = $('<form />');
+                 
++                /* Add created form to self. */
++                $(self).append(form);
++         
+                 /* Apply css or style or both. */
+                 if (settings.cssclass) {
+                     if ('inherit' == settings.cssclass) {
+@@ -242,7 +245,7 @@
+                 buttons.apply(form, [settings, self]);
+          
+                 /* Add created form to self. */
+-                $(self).append(form);
++                //$(self).append(form);
+          
+                 /* Attach 3rd party plugin if requested. */
+                 plugin.apply(form, [settings, self]);

File t146/t146_r1386655_jquery_iphone_checkbox.diff

+# HG changeset patch
+# Parent efeff498c9cb65f1efe719ca76638b607717eb5e
+BH Dashboard #146 : Including jQuery iphone-style-checkboxes ( http://github.com/tdreyno/iphone-style-checkboxes )
+
+diff --git a/bhdashboard/htdocs/css/iphone-style-checkboxes.css b/bhdashboard/htdocs/css/iphone-style-checkboxes.css
+new file mode 100644
+--- /dev/null
++++ b/bhdashboard/htdocs/css/iphone-style-checkboxes.css
+@@ -0,0 +1,78 @@
++/* Disable text selection outside of IE */
++.iPhoneCheckContainer, 
++.iPhoneCheckContainer label {
++  user-select: none;
++  -moz-user-select: none;
++  -khtml-user-select: none; }
++
++.iPhoneCheckDisabled {  
++  filter: alpha(opacity=50);
++  -moz-opacity: 0.5;
++  -khtml-opacity: 0.5;
++  opacity: 0.5; }
++
++
++.iPhoneCheckContainer {
++  position: relative;
++  height: 27px;
++  cursor: pointer;
++  overflow: hidden; }
++  .iPhoneCheckContainer input {
++    position: absolute;
++    top: 5px;
++    left: 30px; 
++    filter: alpha(opacity=0);
++    -moz-opacity: 0;
++    -khtml-opacity: 0;
++    opacity: 0; }
++  .iPhoneCheckContainer label {
++    white-space: nowrap;
++    font-size: 17px;
++    line-height: 17px;
++    font-weight: bold;
++    font-family: Helvetica Neue, Arial, Helvetica, sans-serif;
++    text-transform: uppercase;
++    cursor: pointer;
++    display: block;
++    height: 27px;
++    position: absolute;
++    width: auto;
++    top: 0;
++    padding-top: 5px;
++    overflow: hidden; }
++  label.iPhoneCheckLabelOn {
++    color: #fff;
++    background: url(../img/on.png) no-repeat;
++    text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.6);
++    left: 0;
++    padding-top: 5px; }
++    label.iPhoneCheckLabelOn span {
++      padding-left: 8px; }
++  label.iPhoneCheckLabelOff {
++    color: #8B8B8B;
++    background: url(../img/off.png) no-repeat right 0;
++    text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.6);
++    text-align: right;
++    right: 0; }
++    label.iPhoneCheckLabelOff span {
++      padding-right: 8px; }
++    
++.iPhoneCheckHandle {
++  display: block;
++  height: 27px;
++  cursor: pointer;
++  position: absolute;
++  top: 0;
++  left: 0;
++  width: 0;
++  background: url(../img/slider_left.png) no-repeat;
++  padding-left: 3px; }
++  .iPhoneCheckHandleRight {
++    height: 100%;
++    width: 100%;
++    padding-right: 3px;
++    background: url(../img/slider_right.png) no-repeat right 0; }
++  .iPhoneCheckHandleCenter {
++    height: 100%;
++    width: 100%;
++    background: url(../img/slider_center.png); }
+diff --git a/bhdashboard/htdocs/img/off.png b/bhdashboard/htdocs/img/off.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..f414051ecc72db50e3267adb99ad288d22a293ad
+GIT binary patch
+literal 2577
+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
+
+diff --git a/bhdashboard/htdocs/img/on.png b/bhdashboard/htdocs/img/on.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..94425e5841c89fb0b226d987b1a6d9199c372b3f
+GIT binary patch
+literal 2496
+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
+KMNUMnLSTYI@WUwp
+
+diff --git a/bhdashboard/htdocs/img/slider.png b/bhdashboard/htdocs/img/slider.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..80e05ff2dde736f92872019c10e6e69e4caf7179
+GIT binary patch
+literal 1228
+zc$@*u1T*`IP)<h;3K|Lk000e1NJLTq001Wd000{Z1^@s6{~MO$00004XF*Lt007q5
+z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$UP(kjRCwCN
+zSG!7`K@gsA&QY6ypoK~*tAK@1kdP|xVB<Rk(xyxs$TMi;I|NdNl!6Ghq9CRUgj~cJ
+zGug}R?9BehT95zv_v~$EXTJGn79v82hlfvz=zV&grzf``>+dQ(pVRYZe}Df92L}hw
+z(vL4YJ3DJzTU)feyi6o{Uit#+o8Z<<`XKbQep=Y;XN#NZ_fBsC{ki)?*Vor{c6RnH
+zb-tLVuXnq<yKC#~>-6*2FZ%c6hiwcmG+9`Xw@hzw%7KDl>oB?6pVrE7-lDj`mNA$%
+zHa2K!X=&}`<m4Tv?pIrzoAmqUrfkGz5{UEJvNCBw*^x_6`7rBPd)quNQ~g+3r)@@D
+zmz6;kNP29#`F%s1NuR9OJWX1i&FA&J<yaUjLW7m2<8dAy?!#gLU|2Sr&9d@O=2a&>
+zQCo-(yXJ>%{)!*6?*U42UHdJeVXIAF(dqE(>fpTXl3gV_xwxjuEp09X5H17gps850
+z;7J~8A%L!BRVIz(%?n`2VVL^dat1`@>I9ycw}MoIiQw!n-5<GI;vyin5h9e#te9fP
+zt!>IFID?(lo%JM5i8hoYPxPIQBFYBvs;dhdEUE$lHbtC}_``U&!bOl_1075lx|^f8
+zQ2|%C=XSPzQQ8cQE>iatrI#il%N5ZBxI^csTaKB$T`O|fdx552$D|E7n>`fK?Ue9)
+zgM4s0w^jmF+Xqe$JgyN3h*^bVAUdmw1`CnJx#Q_6cguuwG$6RUl`6oS0xkXY-!S23
+zfS?>|R63XDwVh&yfYLeA`UGYgM<ugi5%k|2rnJ(zNIZcWmsPR|0o-<BPiir@f_xea
+z0YR1Lq({o4ygt?e7}LJP5{9I2dpE0sh5}-snHUgRIaURFk~gyDin$EUvZ-U7Dp-ZG
+zMxsPu2}PQ59IfQ6d<hx@B5OKJ=Irb)&ID*2<|x3F2N{Kw;1(VLu2GMAI5zL=L8M}|
+zD8>!TgK}I_0jsq-)@+}m5XY3{u!9NL@Fc~zIaXgt$F&3VG<_M*89xjmPh*A{IBh68
+zC9t3NIjc<Q!^%dPW(d|KD8ikvVtG<=rGlAT&UID<87Wj(S1ejGmxjM)Z|4c9A&Yz$
+z5M;$-Wb2M=L?xPvpalhcw*+%dYK&O8AwYvINVuI5L*fTxDnq)mH5eS%35J@@5{z+T
+ztKFt`BKOTjb27vtc)*;N&eF*fN+(sQQVVEuH7Rvo1E<|pq*ZNJDs|(DbD!3Oem)Q^
+z_x<nv-&JmI9qX;3Z6%Pe!$Q<(je?enMu(s$33Dd`|J~pJ%gvuD4)E#n@>1(|w#y1z
+zd%VchBEiP<m|kL7FF1tZLZkI!F#vNID-@=CWyZ*QTwGk_-ygH(-X0$xzr4G<Tif2=
+zrj?bI#pO+7a+kb8y)Y1pWx2TMge9|~)CqN;(CzIlou8l6>FH^{x4uQ@m7}Ahe9Ql!
+qH~!5>yzzh48~^LQy}hgd0t^6MQ^T06mz3!M0000<MNUMnLSTYbNKFL*
+
+diff --git a/bhdashboard/htdocs/img/slider_center.png b/bhdashboard/htdocs/img/slider_center.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..310fc8cccfed20f5941de6a1b6a5c7c5c1722bb9
+GIT binary patch
+literal 260
+zc$@(Q0sH=mP)<h;3K|Lk000e1NJLTq000C4000{Z0ssI2)DyX90000PbVXQnQ*UN;
+zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyrb$FWRCwA%P|*&AAPidx|NjxZ`ey>i
+zsd#E)vfFS1BxGB=t^*+idJkfZ#1b$8KILp>BJa=w*2e?R>ZFMr>$0Q)(&OAKtjW_Y
+z7&ietEH)YwgPhX%g*-G9LB+&@qsN5Yd7g*sloBy>vw@sHXlja-Qu+#5mTzAH>$*|n
+z$S~AehuXgH)*(iI$Dy&P3-3J7LA$QYwvnOteUGo2rm55Z0t^6tOGp^$Su~UY0000<
+KMNUMnLSTa9gK3li
+
+diff --git a/bhdashboard/htdocs/img/slider_left.png b/bhdashboard/htdocs/img/slider_left.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..51576ce351944e96229b04bfa03f8f03e907e9ff
+GIT binary patch
+literal 324
+zc$@)50lWT*P)<h;3K|Lk000e1NJLTq000C4000{Z1^@s6TX8Nh0000PbVXQnQ*UN;
+zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy=1D|BRCwA{Q85m}FbwoLnL(lph_M4w
+zhi+`F{ECqki9dAdD|i9w-n9=vLZUEGWE_Xmc8KC!?#|}~B0@z`tcmEPYv<B5-Dq*m
+zvTU2@`ONF#sKp{l5_+^Pu>$+ma!JqEi%8`jz}$IH&>I5C#~pELZ9uqT21yUVFdi6z
+z&R`?^zg{I1Q|2Gz=NToC-jt`3*w$$wy(z^UGHz=CkE1&^mMKGpL-c=+J}C!hjHZPJ
+z8+EZ@!}t+^z~1!UeL9;Zfa--y(=_CqGoQdXR8@7W>zcamtuh^;EX(k7=kRl10R{jI
+W5i+_owTc4(0000<MNUMnLSTZtTZT^n
+
+diff --git a/bhdashboard/htdocs/img/slider_right.png b/bhdashboard/htdocs/img/slider_right.png
+new file mode 100644
+index 0000000000000000000000000000000000000000..447d94a6cb4ebf2f9016bc118dd441dc43f4dbd4
+GIT binary patch
+literal 321
+zc$@)20lxl;P)<h;3K|Lk000e1NJLTq000C4000{Z1^@s6TX8Nh0000PbVXQnQ*UN;
+zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy<4Ht8RCwBCQ9EwKFbsX9G<ND@-@+%z
+z*gJUf9SU^qn3H(%A+qKM2D};uDtOD3&tN1hrOL9B4ul>b$oD9c+P3`xaMbu}n#PfH
+zPUd;WFbpRpcYHZtP!t8Ks(M#q&jP{idP7;3n&ZO~kq0owK=E55*4Hu<L}(+37!gN;
+zmB?Dyc!DT}&66m~f6bIM6nPh{73$(K|8I$+YsDsNln}`$rBogU<7}{GOTuB07g22A
+z*QGs+O3*;I4+Z!8!{_JV;`cdClW#lNWmzzeBl^DgcloBS>*jd5&$_PNuK)u8EfzVU
+TqbKrS00000NkvXXu0mjf#?yy8
+
+diff --git a/bhdashboard/htdocs/js/iphone-style-checkboxes.js b/bhdashboard/htdocs/js/iphone-style-checkboxes.js
+new file mode 100644
+--- /dev/null
++++ b/bhdashboard/htdocs/js/iphone-style-checkboxes.js
+@@ -0,0 +1,213 @@
++/*!
++// iPhone-style Checkboxes jQuery plugin
++// Copyright Thomas Reynolds, licensed GPL & MIT
++*/
++;(function($, iphoneStyle) {
++
++// Constructor
++$[iphoneStyle] = function(elem, options) {
++  this.$elem = $(elem);
++  
++  // Import options into instance variables
++  var obj = this;
++  $.each(options, function(key, value) {
++    obj[key] = value;
++  });
++  
++  // Initialize the control
++  this.wrapCheckboxWithDivs();
++  this.attachEvents();
++  this.disableTextSelection();
++  
++  if (this.resizeHandle)    { this.optionallyResize('handle'); }
++  if (this.resizeContainer) { this.optionallyResize('container'); }
++  
++  this.initialPosition();
++};
++
++$.extend($[iphoneStyle].prototype, {
++  // Wrap the existing input[type=checkbox] with divs for styling and grab DOM references to the created nodes
++  wrapCheckboxWithDivs: function() {
++    this.$elem.wrap('<div class="' + this.containerClass + '" />');
++    this.container = this.$elem.parent();
++    
++    this.offLabel  = $('<label class="'+ this.labelOffClass +'">' +
++                         '<span>'+ this.uncheckedLabel +'</span>' +
++                       '</label>').appendTo(this.container);
++    this.offSpan   = this.offLabel.children('span');
++    
++    this.onLabel   = $('<label class="'+ this.labelOnClass +'">' +
++                         '<span>'+ this.checkedLabel +'</span>' +
++                       '</label>').appendTo(this.container);
++    this.onSpan    = this.onLabel.children('span');
++    
++    this.handle    = $('<div class="' + this.handleClass + '">' +
++                         '<div class="' + this.handleRightClass + '">' +
++                           '<div class="' + this.handleCenterClass + '" />' +
++                         '</div>' +
++                       '</div>').appendTo(this.container);
++  },
++  
++  // Disable IE text selection, other browsers are handled in CSS
++  disableTextSelection: function() {
++    if (!$.browser.msie) { return; }
++
++    // Elements containing text should be unselectable
++    $.each([this.handle, this.offLabel, this.onLabel, this.container], function(el) {
++      $(el).attr("unselectable", "on");
++    });
++  },
++  
++  // Automatically resize the handle or container
++  optionallyResize: function(mode) {
++    var onLabelWidth  = this.onLabel.width(),
++        offLabelWidth = this.offLabel.width(),
++        newWidth      = (onLabelWidth < offLabelWidth) ? onLabelWidth : offLabelWidth;
++
++    if (mode == 'container') { newWidth += this.handle.width() + 15; }
++    this[mode].css({ width: newWidth });
++  },
++  
++  attachEvents: function() {
++    var obj = this;
++    
++    // A mousedown anywhere in the control will start tracking for dragging
++    this.container
++      .bind('mousedown touchstart', function(event) {          
++        event.preventDefault();
++        
++        if (obj.$elem.is(':disabled')) { return; }
++          
++        var x = event.pageX || event.changedTouches[0].pageX;
++        $[iphoneStyle].currentlyClicking = obj.handle;
++        $[iphoneStyle].dragStartPosition = x - (parseInt(obj.handle.css('left'), 10) || 0);
++      })
++    
++      // Utilize event bubbling to handle drag on any element beneath the container
++      .bind('iPhoneDrag', function(event, x) {
++        event.preventDefault();
++        
++        if (obj.$elem.is(':disabled')) { return; }
++        
++        var p = (x - $[iphoneStyle].dragStartPosition) / obj.rightSide;
++        if (p < 0) { p = 0; }
++        if (p > 1) { p = 1; }
++      
++        obj.handle.css({ left: p * obj.rightSide });
++        obj.onLabel.css({ width: p * obj.rightSide + 4 });
++        obj.offSpan.css({ marginRight: -p * obj.rightSide });
++        obj.onSpan.css({ marginLeft: -(1 - p) * obj.rightSide });
++      })
++    
++        // Utilize event bubbling to handle drag end on any element beneath the container
++      .bind('iPhoneDragEnd', function(event, x) {
++        if (obj.$elem.is(':disabled')) { return; }
++        
++        if ($[iphoneStyle].dragging) {
++          var p = (x - $[iphoneStyle].dragStartPosition) / obj.rightSide;
++          obj.$elem.attr('checked', (p >= 0.5));
++        } else {
++          obj.$elem.attr('checked', !obj.$elem.attr('checked'));
++        }
++
++        $[iphoneStyle].currentlyClicking = null;
++        $[iphoneStyle].dragging = null;
++        obj.$elem.change();
++      });
++  
++    // Animate when we get a change event
++    this.$elem.change(function() {
++      if (obj.$elem.is(':disabled')) {
++        obj.container.addClass(obj.disabledClass);
++      } else {
++        obj.container.removeClass(obj.disabledClass);
++      }
++      
++      var new_left = obj.$elem.attr('checked') ? obj.rightSide : 0;
++
++      obj.handle.animate({         left: new_left },                 obj.duration);
++      obj.onLabel.animate({       width: new_left + 4 },             obj.duration);
++      obj.offSpan.animate({ marginRight: -new_left },                obj.duration);
++      obj.onSpan.animate({   marginLeft: new_left - obj.rightSide }, obj.duration);
++    });
++  },
++  
++  // Setup the control's inital position
++  initialPosition: function() {
++    this.offLabel.css({ width: this.container.width() - 5 });
++
++    var offset = ($.browser.msie && $.browser.version < 7) ? 3 : 6;
++    this.rightSide = this.container.width() - this.handle.width() - offset;
++
++    if (this.$elem.is(':checked')) {
++      this.handle.css({ left: this.rightSide });
++      this.onLabel.css({ width: this.rightSide + 4 });
++      this.offSpan.css({ marginRight: -this.rightSide });
++    } else {
++      this.onLabel.css({ width: 0 });
++      this.onSpan.css({ marginLeft: -this.rightSide });
++    }
++    
++    if (this.$elem.is(':disabled')) {
++      this.container.addClass(this.disabledClass);
++    }
++  }
++});
++
++// jQuery-specific code
++$.fn[iphoneStyle] = function(options) {
++  var checkboxes = this.filter(':checkbox');
++  
++  // Fail early if we don't have any checkboxes passed in
++  if (!checkboxes.length) { return this; }
++  
++  // Merge options passed in with global defaults
++  var opt = $.extend({}, $[iphoneStyle].defaults, options);
++  
++  checkboxes.each(function() {
++    $(this).data(iphoneStyle, new $[iphoneStyle](this, opt));
++  });
++
++  if (!$[iphoneStyle].initComplete) {
++    // As the mouse moves on the page, animate if we are in a drag state
++    $(document)
++      .bind('mousemove touchmove', function(event) {
++        if (!$[iphoneStyle].currentlyClicking) { return; }
++        if (event.pageX != $[iphoneStyle].dragStartPosition) { $[iphoneStyle].dragging = true; }
++        event.preventDefault();
++    
++        var x = event.pageX || event.changedTouches[0].pageX;
++        $(event.target).trigger('iPhoneDrag', [x]);
++      })
++
++      // When the mouse comes up, leave drag state
++      .bind('mouseup touchend', function(event) {        
++        if (!$[iphoneStyle].currentlyClicking) { return; }
++        event.preventDefault();
++    
++        var x = event.pageX || event.changedTouches[0].pageX;
++        $($[iphoneStyle].currentlyClicking).trigger('iPhoneDragEnd', [x]);
++      });
++      
++    $[iphoneStyle].initComplete = true;
++  }
++  
++  return this;
++}; // End of $.fn[iphoneStyle]
++
++$[iphoneStyle].defaults = {
++  duration:          200,                       // Time spent during slide animation
++  checkedLabel:      'ON',                      // Text content of "on" state
++  uncheckedLabel:    'OFF',                     // Text content of "off" state
++  resizeHandle:      true,                      // Automatically resize the handle to cover either label
++  resizeContainer:   true,                      // Automatically resize the widget to contain the labels
++  disabledClass:     'iPhoneCheckDisabled',
++  containerClass:    'iPhoneCheckContainer',
++  labelOnClass:      'iPhoneCheckLabelOn',
++  labelOffClass:     'iPhoneCheckLabelOff',
++  handleClass:       'iPhoneCheckHandle',
++  handleCenterClass: 'iPhoneCheckHandleCenter',
++  handleRightClass:  'iPhoneCheckHandleRight'
++};
++
++})(jQuery, 'iphoneStyle');