x-editable-rails 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +1 -1
  3. data/README.md +31 -14
  4. data/lib/x-editable-rails.rb +5 -1
  5. data/lib/x-editable-rails/version.rb +1 -1
  6. data/lib/x-editable-rails/view_helpers.rb +20 -0
  7. data/vendor/assets/images/editable/clear.png +0 -0
  8. data/vendor/assets/images/{loading.gif → editable/loading.gif} +0 -0
  9. data/vendor/assets/javascripts/{bootstrap-editable.js → editable/bootstrap-editable.js} +3816 -1425
  10. data/vendor/assets/javascripts/{jquery-editable-poshytip.js → editable/jquery-editable-poshytip.js} +2171 -541
  11. data/vendor/assets/javascripts/{jqueryui-editable.js → editable/jqueryui-editable.js} +2080 -478
  12. data/vendor/assets/javascripts/{rails-editable.js.coffee → editable/rails.js.coffee} +3 -0
  13. data/vendor/assets/stylesheets/editable/bootstrap-editable.css +495 -0
  14. data/vendor/assets/stylesheets/{jquery-editable.css → editable/jquery-editable.css} +63 -18
  15. data/vendor/assets/stylesheets/{jqueryui-editable.css → editable/jqueryui-editable.css} +63 -18
  16. metadata +79 -66
  17. data/.gitignore +0 -19
  18. data/Gemfile +0 -4
  19. data/Rakefile +0 -1
  20. data/vendor/assets/javascripts/bootstrap-editable-inline.js +0 -3769
  21. data/vendor/assets/javascripts/bootstrap-editable-inline.min.js +0 -5
  22. data/vendor/assets/javascripts/bootstrap-editable.min.js +0 -5
  23. data/vendor/assets/javascripts/jquery-editable-inline.js +0 -2892
  24. data/vendor/assets/javascripts/jquery-editable-inline.min.js +0 -5
  25. data/vendor/assets/javascripts/jquery-editable-poshytip.min.js +0 -5
  26. data/vendor/assets/javascripts/jqueryui-editable-inline.js +0 -2916
  27. data/vendor/assets/javascripts/jqueryui-editable-inline.min.js +0 -5
  28. data/vendor/assets/javascripts/jqueryui-editable.min.js +0 -5
  29. data/vendor/assets/stylesheets/bootstrap-editable.css +0 -434
  30. data/x-editable-rails.gemspec +0 -19
@@ -1,5 +0,0 @@
1
- /*! X-editable - v1.3.0
2
- * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3
- * http://github.com/vitalets/x-editable
4
- * Copyright (c) 2012 Vitaliy Potapov; Licensed MIT */
5
- (function(e){var t=function(t,n){this.options=e.extend({},e.fn.editableform.defaults,n),this.$div=e(t),this.options.scope||(this.options.scope=this),this.initInput()};t.prototype={constructor:t,initInput:function(){var t,n;if(typeof e.fn.editabletypes[this.options.type]!="function"){e.error("Unknown type: "+this.options.type);return}t=e.fn.editabletypes[this.options.type],n=e.fn.editableutils.sliceObj(this.options,e.fn.editableutils.objectKeys(t.defaults)),this.input=new t(n),this.value=this.input.str2value(this.options.value)},initTemplate:function(){this.$form=e(e.fn.editableform.template)},initButtons:function(){this.$form.find(".editable-buttons").append(e.fn.editableform.buttons)},render:function(){this.$loading=e(e.fn.editableform.loading),this.$div.empty().append(this.$loading),this.showLoading(),this.initTemplate(),this.options.showbuttons?this.initButtons():this.$form.find(".editable-buttons").remove(),this.$div.triggerHandler("rendering"),e.when(this.input.render()).then(e.proxy(function(){this.$form.find("div.editable-input").append(this.input.$input),this.options.showbuttons||this.input.autosubmit(),this.input.$clear&&this.$form.find("div.editable-input").append(e('<div class="editable-clear">').append(this.input.$clear)),this.$div.append(this.$form),this.$form.find(".editable-cancel").click(e.proxy(this.cancel,this)),this.input.error?(this.error(this.input.error),this.$form.find(".editable-submit").attr("disabled",!0),this.input.$input.attr("disabled",!0),this.$form.submit(function(e){e.preventDefault()})):(this.error(!1),this.input.$input.removeAttr("disabled"),this.$form.find(".editable-submit").removeAttr("disabled"),this.input.value2input(this.value),this.$form.submit(e.proxy(this.submit,this))),this.$div.triggerHandler("rendered"),this.showForm()},this))},cancel:function(){this.$div.triggerHandler("cancel")},showLoading:function(){var e;this.$form?(this.$loading.width(this.$form.outerWidth()),this.$loading.height(this.$form.outerHeight()),this.$form.hide()):(e=this.$loading.parent().width(),e&&this.$loading.width(e)),this.$loading.show()},showForm:function(e){this.$loading.hide(),this.$form.show(),e!==!1&&this.input.activate(),this.$div.triggerHandler("show")},error:function(t){var n=this.$form.find(".control-group"),r=this.$form.find(".editable-error-block");t===!1?(n.removeClass(e.fn.editableform.errorGroupClass),r.removeClass(e.fn.editableform.errorBlockClass).empty().hide()):(n.addClass(e.fn.editableform.errorGroupClass),r.addClass(e.fn.editableform.errorBlockClass).text(t).show())},submit:function(t){t.stopPropagation(),t.preventDefault();var n,r=this.input.input2value();if(n=this.validate(r)){this.error(n),this.showForm();return}if(!this.options.savenochange&&this.input.value2str(r)==this.input.value2str(this.value)){this.$div.triggerHandler("nochange");return}e.when(this.save(r)).done(e.proxy(function(e){var t=typeof this.options.success=="function"?this.options.success.call(this.options.scope,e,r):null;if(t===!1){this.error(!1),this.showForm(!1);return}if(typeof t=="string"){this.error(t),this.showForm();return}t&&typeof t=="object"&&t.hasOwnProperty("newValue")&&(r=t.newValue),this.error(!1),this.value=r,this.$div.triggerHandler("save",{newValue:r,response:e})},this)).fail(e.proxy(function(e){this.error(typeof e=="string"?e:e.responseText||e.statusText||"Unknown error!"),this.showForm()},this))},save:function(t){var n=this.input.value2submit(t);this.options.pk=e.fn.editableutils.tryParseJson(this.options.pk,!0);var r=typeof this.options.pk=="function"?this.options.pk.call(this.options.scope):this.options.pk,i=!!(typeof this.options.url=="function"||this.options.url&&(this.options.send==="always"||this.options.send==="auto"&&r)),s;if(i)return this.showLoading(),s={name:this.options.name||"",value:n,pk:r},typeof this.options.params=="function"?s=this.options.params.call(this.options.scope,s):(this.options.params=e.fn.editableutils.tryParseJson(this.options.params,!0),e.extend(s,this.options.params)),typeof this.options.url=="function"?this.options.url.call(this.options.scope,s):e.ajax(e.extend({url:this.options.url,data:s,type:"POST"},this.options.ajaxOptions))},validate:function(e){e===undefined&&(e=this.value);if(typeof this.options.validate=="function")return this.options.validate.call(this.options.scope,e)},option:function(e,t){this.options[e]=t,e==="value"&&this.setValue(t)},setValue:function(e,t){t?this.value=this.input.str2value(e):this.value=e}},e.fn.editableform=function(n){var r=arguments;return this.each(function(){var i=e(this),s=i.data("editableform"),o=typeof n=="object"&&n;s||i.data("editableform",s=new t(this,o)),typeof n=="string"&&s[n].apply(s,Array.prototype.slice.call(r,1))})},e.fn.editableform.Constructor=t,e.fn.editableform.defaults={type:"text",url:null,params:null,name:null,pk:null,value:null,send:"auto",validate:null,success:null,ajaxOptions:null,showbuttons:!0,scope:null,savenochange:!1},e.fn.editableform.template='<form class="form-inline editableform"><div class="control-group"><div><div class="editable-input"></div><div class="editable-buttons"></div></div><div class="editable-error-block"></div></div></form>',e.fn.editableform.loading='<div class="editableform-loading"></div>',e.fn.editableform.buttons='<button type="submit" class="editable-submit">ok</button><button type="button" class="editable-cancel">cancel</button>',e.fn.editableform.errorGroupClass=null,e.fn.editableform.errorBlockClass="editable-error"})(window.jQuery),function(e){e.fn.editableutils={inherit:function(e,t){var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e,e.superclass=t.prototype},setCursorPosition:function(e,t){if(e.setSelectionRange)e.setSelectionRange(t,t);else if(e.createTextRange){var n=e.createTextRange();n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",t),n.select()}},tryParseJson:function(e,t){if(typeof e=="string"&&e.length&&e.match(/^[\{\[].*[\}\]]$/))if(t)try{e=(new Function("return "+e))()}catch(n){}finally{return e}else e=(new Function("return "+e))();return e},sliceObj:function(t,n,r){var i,s,o={};if(!e.isArray(n)||!n.length)return o;for(var u=0;u<n.length;u++){i=n[u],t.hasOwnProperty(i)&&(o[i]=t[i]);if(r===!0)continue;s=i.toLowerCase(),t.hasOwnProperty(s)&&(o[i]=t[s])}return o},getConfigData:function(t){var n={};return e.each(t.data(),function(e,t){if(typeof t!="object"||t&&typeof t=="object"&&t.constructor===Object)n[e]=t}),n},objectKeys:function(e){if(Object.keys)return Object.keys(e);if(e!==Object(e))throw new TypeError("Object.keys called on a non-object");var t=[],n;for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t},escape:function(t){return e("<div>").text(t).html()}}}(window.jQuery),function(e){var t=function(e,t){this.init(e,t)};t.prototype={containerName:null,innerCss:null,init:function(n,r){this.$element=e(n),this.options=e.extend({},e.fn.editableContainer.defaults,e.fn.editableutils.getConfigData(this.$element),r),this.splitOptions(),this.initContainer(),this.$element.on("destroyed",e.proxy(function(){this.destroy()},this)),e(document).data("editable-handlers-attached")||(e(document).on("keyup.editable",function(t){t.which===27&&e(".editable-open").editableContainer("hide")}),e(document).on("click.editable",function(n){var r=e(n.target);if(r.is(".editable-container")||r.parents(".editable-container").length||r.parents(".ui-datepicker-header").length)return;t.prototype.closeOthers(n.target)}),e(document).data("editable-handlers-attached",!0))},splitOptions:function(){this.containerOptions={},this.formOptions={};var t=e.fn[this.containerName].defaults;for(var n in this.options)n in t?this.containerOptions[n]=this.options[n]:this.formOptions[n]=this.options[n]},initContainer:function(){this.call(this.containerOptions)},initForm:function(){return this.formOptions.scope=this.$element[0],this.$form=e("<div>").editableform(this.formOptions).on({save:e.proxy(this.save,this),cancel:e.proxy(function(){this.hide("cancel")},this),nochange:e.proxy(function(){this.hide("nochange")},this),show:e.proxy(this.setPosition,this),rendering:e.proxy(this.setPosition,this),rendered:e.proxy(function(){this.$element.triggerHandler("shown")},this)}),this.$form},tip:function(){return this.container().$tip},container:function(){return this.$element.data(this.containerName)},call:function(){this.$element[this.containerName].apply(this.$element,arguments)},show:function(e){this.$element.addClass("editable-open"),e!==!1&&this.closeOthers(this.$element[0]),this.innerShow()},innerShow:function(){this.call("show"),this.tip().addClass("editable-container"),this.initForm(),this.tip().find(this.innerCss).empty().append(this.$form),this.$form.editableform("render")},hide:function(e){if(!this.tip()||!this.tip().is(":visible")||!this.$element.hasClass("editable-open"))return;this.$element.removeClass("editable-open"),this.innerHide(),this.$element.triggerHandler("hidden",e)},innerHide:function(){this.call("hide")},toggle:function(e){this.tip&&this.tip().is(":visible")?this.hide():this.show(e)},setPosition:function(){},save:function(e,t){this.hide("save"),this.$element.triggerHandler("save",t)},option:function(e,t){this.options[e]=t,e in this.containerOptions?(this.containerOptions[e]=t,this.setContainerOption(e,t)):(this.formOptions[e]=t,this.$form&&this.$form.editableform("option",e,t))},setContainerOption:function(e,t){this.call("option",e,t)},destroy:function(){this.call("destroy")},closeOthers:function(t){e(".editable-open").each(function(n,r){if(r===t||e(r).find(t).length)return;var i=e(r),s=i.data("editableContainer");if(!s)return;s.options.onblur==="cancel"?i.data("editableContainer").hide("onblur"):s.options.onblur==="submit"&&i.data("editableContainer").tip().find("form").submit()})},activate:function(){this.tip&&this.tip().is(":visible")&&this.$form&&this.$form.data("editableform").input.activate()}},e.fn.editableContainer=function(n){var r=arguments;return this.each(function(){var i=e(this),s="editableContainer",o=i.data(s),u=typeof n=="object"&&n;o||i.data(s,o=new t(this,u)),typeof n=="string"&&o[n].apply(o,Array.prototype.slice.call(r,1))})},e.fn.editableContainer.Constructor=t,e.fn.editableContainer.defaults={value:null,placement:"top",autohide:!0,onblur:"cancel"},jQuery.event.special.destroyed={remove:function(e){e.handler&&e.handler()}}}(window.jQuery),function(e){var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.editable.defaults,e.fn.editableutils.getConfigData(this.$element),n),this.init()};t.prototype={constructor:t,init:function(){var t,n=!1,r,i;if(!e.fn.editableContainer){e.error("You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)");return}this.options.name=this.options.name||this.$element.attr("id");if(typeof e.fn.editabletypes[this.options.type]!="function"){e.error("Unknown type: "+this.options.type);return}t=e.fn.editabletypes[this.options.type],this.typeOptions=e.fn.editableutils.sliceObj(this.options,e.fn.editableutils.objectKeys(t.defaults)),this.input=new t(this.typeOptions),this.options.value===undefined||this.options.value===null?(this.value=this.input.html2value(e.trim(this.$element.html())),n=!0):(this.options.value=e.fn.editableutils.tryParseJson(this.options.value,!0),typeof this.options.value=="string"?this.value=this.input.str2value(this.options.value):this.value=this.options.value),this.$element.addClass("editable"),this.options.toggle!=="manual"?(this.$element.addClass("editable-click"),this.$element.on(this.options.toggle+".editable",e.proxy(function(e){e.preventDefault();if(this.options.toggle==="mouseenter")this.show();else{var t=this.options.toggle!=="click";this.toggle(t)}},this))):this.$element.attr("tabindex",-1),r=!n&&this.value!==null&&this.value!==undefined,r&=this.options.autotext==="always"||this.options.autotext==="auto"&&!this.$element.text().length,e.when(r?this.render():!0).then(e.proxy(function(){this.options.disabled?this.disable():this.enable(),this.$element.triggerHandler("init",this)},this))},render:function(){if(this.options.display===!1)return;return this.input.options.hasOwnProperty("source")?this.input.value2html(this.value,this.$element[0],this.options.display):typeof this.options.display=="function"?this.options.display.call(this.$element[0],this.value):this.input.value2html(this.value,this.$element[0])},enable:function(){this.options.disabled=!1,this.$element.removeClass("editable-disabled"),this.handleEmpty(),this.options.toggle!=="manual"&&this.$element.attr("tabindex")==="-1"&&this.$element.removeAttr("tabindex")},disable:function(){this.options.disabled=!0,this.hide(),this.$element.addClass("editable-disabled"),this.handleEmpty(),this.$element.attr("tabindex",-1)},toggleDisabled:function(){this.options.disabled?this.enable():this.disable()},option:function(t,n){if(t&&typeof t=="object"){e.each(t,e.proxy(function(t,n){this.option(e.trim(t),n)},this));return}this.options[t]=n;if(t==="disabled"){n?this.disable():this.enable();return}t==="value"&&this.setValue(n),this.container&&this.container.option(t,n)},handleEmpty:function(){if(this.options.display===!1)return;var t="editable-empty";this.options.disabled?this.$element.hasClass(t)&&(this.$element.empty(),this.$element.removeClass(t)):e.trim(this.$element.text())===""?this.$element.addClass(t).text(this.options.emptytext):this.$element.removeClass(t)},show:function(t){if(this.options.disabled)return;if(!this.container){var n=e.extend({},this.options,{value:this.value});this.$element.editableContainer(n),this.$element.on("save.internal",e.proxy(this.save,this)),this.container=this.$element.data("editableContainer")}else if(this.container.tip().is(":visible"))return;this.container.show(t)},hide:function(){this.container&&this.container.hide()},toggle:function(e){this.container&&this.container.tip().is(":visible")?this.hide():this.show(e)},save:function(e,t){typeof this.options.url!="function"&&this.options.display!==!1&&t.response===undefined&&this.input.value2str(this.value)!==this.input.value2str(t.newValue)?this.$element.addClass("editable-unsaved"):this.$element.removeClass("editable-unsaved"),this.setValue(t.newValue)},validate:function(){if(typeof this.options.validate=="function")return this.options.validate.call(this,this.value)},setValue:function(t,n){n?this.value=this.input.str2value(t):this.value=t,this.container&&this.container.option("value",this.value),e.when(this.render()).then(e.proxy(function(){this.handleEmpty()},this))},activate:function(){this.container&&this.container.activate()}},e.fn.editable=function(n){var r={},i=arguments,s="editable";switch(n){case"validate":return this.each(function(){var t=e(this),n=t.data(s),i;n&&(i=n.validate())&&(r[n.options.name]=i)}),r;case"getValue":return this.each(function(){var t=e(this),n=t.data(s);n&&n.value!==undefined&&n.value!==null&&(r[n.options.name]=n.input.value2submit(n.value))}),r;case"submit":var o=arguments[1]||{},u=this,a=this.editable("validate"),f;return e.isEmptyObject(a)?(f=this.editable("getValue"),o.data&&e.extend(f,o.data),e.ajax(e.extend({url:o.url,data:f,type:"POST"},o.ajaxOptions)).success(function(e){typeof o.success=="function"&&o.success.call(u,e,o)}).error(function(){typeof o.error=="function"&&o.error.apply(u,arguments)})):typeof o.error=="function"&&o.error.call(u,a),this}return this.each(function(){var r=e(this),o=r.data(s),u=typeof n=="object"&&n;o||r.data(s,o=new t(this,u)),typeof n=="string"&&o[n].apply(o,Array.prototype.slice.call(i,1))})},e.fn.editable.defaults={type:"text",disabled:!1,toggle:"click",emptytext:"Empty",autotext:"auto",value:null,display:null}}(window.jQuery),function(e){e.fn.editabletypes={};var t=function(){};t.prototype={init:function(t,n,r){this.type=t,this.options=e.extend({},r,n),this.$input=null,this.$clear=null,this.error=null},render:function(){this.$input=e(this.options.tpl),this.options.inputclass&&this.$input.addClass(this.options.inputclass),this.options.placeholder&&this.$input.attr("placeholder",this.options.placeholder)},value2html:function(t,n){e(n).text(t)},html2value:function(t){return e("<div>").html(t).text()},value2str:function(e){return e},str2value:function(e){return e},value2submit:function(e){return e},value2input:function(e){this.$input.val(e)},input2value:function(){return this.$input.val()},activate:function(){this.$input.is(":visible")&&this.$input.focus()},clear:function(){this.$input.val(null)},escape:function(t){return e("<div>").text(t).html()},autosubmit:function(){}},t.defaults={tpl:"",inputclass:"input-medium",name:null},e.extend(e.fn.editabletypes,{abstractinput:t})}(window.jQuery),function(e){var t=function(e){};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this);var n=e.Deferred();return this.error=null,this.sourceData=null,this.prependData=null,this.onSourceReady(function(){this.renderList(),n.resolve()},function(){this.error=this.options.sourceError,n.resolve()}),n.promise()},html2value:function(e){return null},value2html:function(t,n,r){var i=e.Deferred();return this.onSourceReady(function(){typeof r=="function"?r.call(n,t,this.sourceData):this.value2htmlFinal(t,n),i.resolve()},function(){i.resolve()}),i.promise()},onSourceReady:function(t,n){if(e.isArray(this.sourceData)){t.call(this);return}try{this.options.source=e.fn.editableutils.tryParseJson(this.options.source,!1)}catch(r){n.call(this);return}if(typeof this.options.source=="string"){if(this.options.sourceCache){var i=this.options.source+(this.options.name?"-"+this.options.name:""),s;e(document).data(i)||e(document).data(i,{}),s=e(document).data(i);if(s.loading===!1&&s.sourceData){this.sourceData=s.sourceData,t.call(this);return}if(s.loading===!0){s.callbacks.push(e.proxy(function(){this.sourceData=s.sourceData,t.call(this)},this)),s.err_callbacks.push(e.proxy(n,this));return}s.loading=!0,s.callbacks=[],s.err_callbacks=[]}e.ajax({url:this.options.source,type:"get",cache:!1,data:this.options.name?{name:this.options.name}:{},dataType:"json",success:e.proxy(function(r){s&&(s.loading=!1),this.sourceData=this.makeArray(r),e.isArray(this.sourceData)?(this.doPrepend(),t.call(this),s&&(s.sourceData=this.sourceData,e.each(s.callbacks,function(){this.call()}))):(n.call(this),s&&e.each(s.err_callbacks,function(){this.call()}))},this),error:e.proxy(function(){n.call(this),s&&(s.loading=!1,e.each(s.err_callbacks,function(){this.call()}))},this)})}else this.sourceData=this.makeArray(this.options.source),e.isArray(this.sourceData)?(this.doPrepend(),t.call(this)):n.call(this)},doPrepend:function(){if(this.options.prepend===null||this.options.prepend===undefined)return;e.isArray(this.prependData)||(this.options.prepend=e.fn.editableutils.tryParseJson(this.options.prepend,!0),typeof this.options.prepend=="string"&&(this.options.prepend={"":this.options.prepend}),this.prependData=this.makeArray(this.options.prepend)),e.isArray(this.prependData)&&e.isArray(this.sourceData)&&(this.sourceData=this.prependData.concat(this.sourceData))},renderList:function(){},value2htmlFinal:function(e,t){},makeArray:function(t){var n,r,i=[],s;if(!t||typeof t=="string")return null;if(e.isArray(t)){s=function(e,t){r={value:e,text:t};if(n++>=2)return!1};for(var o=0;o<t.length;o++)typeof t[o]=="object"?(n=0,e.each(t[o],s),n===1?i.push(r):n>1&&t[o].hasOwnProperty("value")&&t[o].hasOwnProperty("text")&&i.push(t[o])):i.push({value:t[o],text:t[o]})}else e.each(t,function(e,t){i.push({value:e,text:t})});return i},itemByVal:function(t){if(e.isArray(this.sourceData))for(var n=0;n<this.sourceData.length;n++)if(this.sourceData[n].value==t)return this.sourceData[n]}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{source:null,prepend:!1,sourceError:"Error when loading list",sourceCache:!0}),e.fn.editabletypes.list=t}(window.jQuery),function(e){var t=function(e){this.init("text",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{activate:function(){this.$input.is(":visible")&&(this.$input.focus(),e.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length))}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:'<input type="text">',placeholder:null}),e.fn.editabletypes.text=t}(window.jQuery),function(e){var t=function(e){this.init("textarea",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.$input.keydown(function(t){t.ctrlKey&&t.which===13&&e(this).closest("form").submit()})},value2html:function(t,n){var r="",i;if(t){i=t.split("\n");for(var s=0;s<i.length;s++)i[s]=e("<div>").text(i[s]).html();r=i.join("<br>")}e(n).html(r)},html2value:function(t){if(!t)return"";var n=t.split(/<br\s*\/?>/i);for(var r=0;r<n.length;r++)n[r]=e("<div>").html(n[r]).text();return n.join("\n")},activate:function(){this.$input.is(":visible")&&(e.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length),this.$input.focus())}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:"<textarea></textarea>",inputclass:"input-large",placeholder:null}),e.fn.editabletypes.textarea=t}(window.jQuery),function(e){var t=function(e){this.init("select",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.list),e.extend(t.prototype,{renderList:function(){if(!e.isArray(this.sourceData))return;for(var t=0;t<this.sourceData.length;t++)this.$input.append(e("<option>",{value:this.sourceData[t].value}).text(this.sourceData[t].text));this.$input.on("keydown.editable",function(t){t.which===13&&e(this).closest("form").submit()})},value2htmlFinal:function(e,n){var r="",i=this.itemByVal(e);i&&(r=i.text),t.superclass.constructor.superclass.value2html(r,n)},autosubmit:function(){this.$input.off("keydown.editable").on("change.editable",function(){e(this).closest("form").submit()})}}),t.defaults=e.extend({},e.fn.editabletypes.list.defaults,{tpl:"<select></select>"}),e.fn.editabletypes.select=t}(window.jQuery),function(e){var t=function(e){this.init("checklist",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.list),e.extend(t.prototype,{renderList:function(){var t,n;if(!e.isArray(this.sourceData))return;for(var r=0;r<this.sourceData.length;r++)t=e("<label>").append(e("<input>",{type:"checkbox",value:this.sourceData[r].value,name:this.options.name})).append(e("<span>").text(" "+this.sourceData[r].text)),e("<div>").append(t).appendTo(this.$input)},value2str:function(t){return e.isArray(t)?t.sort().join(e.trim(this.options.separator)):""},str2value:function(t){var n,r=null;return typeof t=="string"&&t.length?(n=new RegExp("\\s*"+e.trim(this.options.separator)+"\\s*"),r=t.split(n)):e.isArray(t)&&(r=t),r},value2input:function(t){var n=this.$input.find('input[type="checkbox"]');n.removeAttr("checked"),e.isArray(t)&&t.length&&n.each(function(n,r){var i=e(r);e.each(t,function(e,t){i.val()==t&&i.attr("checked","checked")})})},input2value:function(){var t=[];return this.$input.find("input:checked").each(function(n,r){t.push(e(r).val())}),t},value2htmlFinal:function(t,n){var r=[],i=e.grep(this.sourceData,function(n){return e.grep(t,function(e){return e==n.value}).length});i.length?(e.each(i,function(t,n){r.push(e.fn.editableutils.escape(n.text))}),e(n).html(r.join("<br>"))):e(n).empty()},activate:function(){this.$input.find('input[type="checkbox"]').first().focus()},autosubmit:function(){this.$input.find('input[type="checkbox"]').on("keydown",function(t){t.which===13&&e(this).closest("form").submit()})}}),t.defaults=e.extend({},e.fn.editabletypes.list.defaults,{tpl:"<div></div>",inputclass:"editable-checklist",separator:","}),e.fn.editabletypes.checklist=t}(window.jQuery),function(e){var t=function(e){this.init("password",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),e.extend(t.prototype,{value2html:function(t,n){t?e(n).text("[hidden]"):e(n).empty()},html2value:function(e){return null}}),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="password">'}),e.fn.editabletypes.password=t}(window.jQuery),function(e){var t=function(e){this.init("email",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="email">'}),e.fn.editabletypes.email=t}(window.jQuery),function(e){var t=function(e){this.init("url",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="url">'}),e.fn.editabletypes.url=t}(window.jQuery),function(e){var t=function(e){this.init("tel",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="tel">'}),e.fn.editabletypes.tel=t}(window.jQuery),function(e){var t=function(e){this.init("number",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.options.min!==null&&this.$input.attr("min",this.options.min),this.options.max!==null&&this.$input.attr("max",this.options.max),this.options.step!==null&&this.$input.attr("step",this.options.step)}}),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="number">',inputclass:"input-mini",min:null,max:null,step:null}),e.fn.editabletypes.number=t}(window.jQuery),function(e){var t=function(e){this.init("range",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.number),e.extend(t.prototype,{render:function(){this.$input=e(this.options.tpl);var t=this.$input.filter("input");this.options.inputclass&&t.addClass(this.options.inputclass),this.options.min!==null&&t.attr("min",this.options.min),this.options.max!==null&&t.attr("max",this.options.max),this.options.step!==null&&t.attr("step",this.options.step),t.on("input",function(){e(this).siblings("output").text(e(this).val())})},activate:function(){this.$input.filter("input").focus()}}),t.defaults=e.extend({},e.fn.editabletypes.number.defaults,{tpl:'<input type="range"><output style="width: 30px; display: inline-block"></output>',inputclass:"input-medium"}),e.fn.editabletypes.range=t}(window.jQuery),function(e){e.extend(e.fn.editableform.Constructor.prototype,{initTemplate:function(){this.$form=e(e.fn.editableform.template),this.$form.find(".editable-error-block").addClass("help-block")}}),e.fn.editableform.buttons='<button type="submit" class="btn btn-primary editable-submit"><i class="icon-ok icon-white"></i></button><button type="button" class="btn editable-cancel"><i class="icon-remove"></i></button>',e.fn.editableform.errorGroupClass="error",e.fn.editableform.errorBlockClass=null}(window.jQuery),function(e){e.extend(e.fn.editableContainer.Constructor.prototype,{containerName:"editableform",innerCss:null,initContainer:function(){this.options.anim||(this.options.anim=0)},splitOptions:function(){this.containerOptions={},this.formOptions=this.options},tip:function(){return this.$form},innerShow:function(){this.$element.hide(),this.$form&&this.$form.remove(),this.initForm(),this.tip().addClass("editable-container").addClass("editable-inline"),this.$form.insertAfter(this.$element),this.$form.show(this.options.anim),this.$form.editableform("render")},innerHide:function(){this.$form.hide(this.options.anim,e.proxy(function(){this.$element.show()},this))},destroy:function(){this.tip().remove()}}),e.fn.editableContainer.defaults=e.extend({},e.fn.editableContainer.defaults,{anim:"fast"})}(window.jQuery),function(e){var t=function(n){this.init("date",n,t.defaults);var r=e.fn.editableutils.sliceObj(this.options,["format"]);this.options.datepicker=e.extend({},t.defaults.datepicker,r,n.datepicker),this.options.viewformat||(this.options.viewformat=this.options.datepicker.format),this.options.datepicker.language=this.options.datepicker.language||"en",this.dpg=e.fn.datepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.datepicker.format),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.$input.datepicker(this.options.datepicker),this.options.clear&&(this.$clear=e('<a href="#"></a>').html(this.options.clear).click(e.proxy(function(e){e.preventDefault(),e.stopPropagation(),this.clear()},this)))},value2html:function(e,n){var r=e?this.dpg.formatDate(e,this.parsedViewFormat,this.options.datepicker.language):"";t.superclass.value2html(r,n)},html2value:function(e){return e?this.dpg.parseDate(e,this.parsedViewFormat,this.options.datepicker.language):null},value2str:function(e){return e?this.dpg.formatDate(e,this.parsedFormat,this.options.datepicker.language):""},str2value:function(e){return e?this.dpg.parseDate(e,this.parsedFormat,this.options.datepicker.language):null},value2submit:function(e){return this.value2str(e)},value2input:function(e){this.$input.datepicker("update",e)},input2value:function(){return this.$input.data("datepicker").date},activate:function(){},clear:function(){this.$input.data("datepicker").date=null,this.$input.find(".active").removeClass("active")},autosubmit:function(){this.$input.on("changeDate",function(t){var n=e(this).closest("form");setTimeout(function(){n.submit()},200)})}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:"<div></div>",inputclass:"editable-date well",format:"yyyy-mm-dd",viewformat:null,datepicker:{weekStart:0,startView:0,autoclose:!1},clear:"&times; clear"}),e.fn.editabletypes.date=t}(window.jQuery),!function(e){function t(){return new Date(Date.UTC.apply(Date,arguments))}function n(){var e=new Date;return t(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate())}var r=function(t,n){var r=this;this.element=e(t),this.language=n.language||this.element.data("date-language")||"en",this.language=this.language in i?this.language:"en",this.format=s.parseFormat(n.format||this.element.data("date-format")||"mm/dd/yyyy"),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.is(".date")?this.element.find(".add-on"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&this.component.length===0&&(this.component=!1),this.isInput?this.element.on({focus:e.proxy(this.show,this),keyup:e.proxy(this.update,this),keydown:e.proxy(this.keydown,this)}):this.component&&this.hasInput?(this.element.find("input").on({focus:e.proxy(this.show,this),keyup:e.proxy(this.update,this),keydown:e.proxy(this.keydown,this)}),this.component.on("click",e.proxy(this.show,this))):this.element.is("div")?this.isInline=!0:this.element.on("click",e.proxy(this.show,this)),this.picker=e(s.template).appendTo(this.isInline?this.element:"body").on({click:e.proxy(this.click,this),mousedown:e.proxy(this.mousedown,this)}),this.isInline?this.picker.addClass("datepicker-inline"):this.picker.addClass("dropdown-menu"),e(document).on("mousedown",function(t){e(t.target).closest(".datepicker").length==0&&r.hide()}),this.autoclose=!1,"autoclose"in n?this.autoclose=n.autoclose:"dateAutoclose"in this.element.data()&&(this.autoclose=this.element.data("date-autoclose")),this.keyboardNavigation=!0,"keyboardNavigation"in n?this.keyboardNavigation=n.keyboardNavigation:"dateKeyboardNavigation"in this.element.data()&&(this.keyboardNavigation=this.element.data("date-keyboard-navigation"));switch(n.startView||this.element.data("date-start-view")){case 2:case"decade":this.viewMode=this.startViewMode=2;break;case 1:case"year":this.viewMode=this.startViewMode=1;break;case 0:case"month":default:this.viewMode=this.startViewMode=0}this.todayBtn=n.todayBtn||this.element.data("date-today-btn")||!1,this.todayHighlight=n.todayHighlight||this.element.data("date-today-highlight")||!1,this.weekStart=(n.weekStart||this.element.data("date-weekstart")||i[this.language].weekStart||0)%7,this.weekEnd=(this.weekStart+6)%7,this.startDate=-Infinity,this.endDate=Infinity,this.setStartDate(n.startDate||this.element.data("date-startdate")),this.setEndDate(n.endDate||this.element.data("date-enddate")),this.fillDow(),this.fillMonths(),this.update(),this.showMode(),this.isInline&&this.show()};r.prototype={constructor:r,show:function(t){this.picker.show(),this.height=this.component?this.component.outerHeight():this.element.outerHeight(),this.update(),this.place(),e(window).on("resize",e.proxy(this.place,this)),t&&(t.stopPropagation(),t.preventDefault()),this.element.trigger({type:"show",date:this.date})},hide:function(t){if(this.isInline)return;this.picker.hide(),e(window).off("resize",this.place),this.viewMode=this.startViewMode,this.showMode(),this.isInput||e(document).off("mousedown",this.hide),t&&t.currentTarget.value&&this.setValue(),this.element.trigger({type:"hide",date:this.date})},getDate:function(){var e=this.getUTCDate();return new Date(e.getTime()+e.getTimezoneOffset()*6e4)},getUTCDate:function(){return this.date},setDate:function(e){this.setUTCDate(new Date(e.getTime()-e.getTimezoneOffset()*6e4))},setUTCDate:function(e){this.date=e,this.setValue()},setValue:function(){var e=this.getFormattedDate();this.isInput?this.element.prop("value",e):(this.component&&this.element.find("input").prop("value",e),this.element.data("date",e))},getFormattedDate:function(e){return e==undefined&&(e=this.format),s.formatDate(this.date,e,this.language)},setStartDate:function(e){this.startDate=e||-Infinity,this.startDate!==-Infinity&&(this.startDate=s.parseDate(this.startDate,this.format,this.language)),this.update(),this.updateNavArrows()},setEndDate:function(e){this.endDate=e||Infinity,this.endDate!==Infinity&&(this.endDate=s.parseDate(this.endDate,this.format,this.language)),this.update(),this.updateNavArrows()},place:function(){if(this.isInline)return;var t=parseInt(this.element.parents().filter(function(){return e(this).css("z-index")!="auto"}).first().css("z-index"))+10,n=this.component?this.component.offset():this.element.offset();this.picker.css({top:n.top+this.height,left:n.left,zIndex:t})},update:function(){var e,t=!1;arguments&&arguments.length&&(typeof arguments[0]=="string"||arguments[0]instanceof Date)?(e=arguments[0],t=!0):e=this.isInput?this.element.prop("value"):this.element.data("date")||this.element.find("input").prop("value"),this.date=s.parseDate(e,this.format,this.language),t&&this.setValue(),this.date<this.startDate?this.viewDate=new Date(this.startDate):this.date>this.endDate?this.viewDate=new Date(this.endDate):this.viewDate=new Date(this.date),this.fill()},fillDow:function(){var e=this.weekStart,t="<tr>";while(e<this.weekStart+7)t+='<th class="dow">'+i[this.language].daysMin[e++%7]+"</th>";t+="</tr>",this.picker.find(".datepicker-days thead").append(t)},fillMonths:function(){var e="",t=0;while(t<12)e+='<span class="month">'+i[this.language].monthsShort[t++]+"</span>";this.picker.find(".datepicker-months td").html(e)},fill:function(){var e=new Date(this.viewDate),n=e.getUTCFullYear(),r=e.getUTCMonth(),o=this.startDate!==-Infinity?this.startDate.getUTCFullYear():-Infinity,u=this.startDate!==-Infinity?this.startDate.getUTCMonth():-Infinity,a=this.endDate!==Infinity?this.endDate.getUTCFullYear():Infinity,f=this.endDate!==Infinity?this.endDate.getUTCMonth():Infinity,l=this.date&&this.date.valueOf(),c=new Date;this.picker.find(".datepicker-days thead th:eq(1)").text(i[this.language].months[r]+" "+n),this.picker.find("tfoot th.today").text(i[this.language].today).toggle(this.todayBtn!==!1),this.updateNavArrows(),this.fillMonths();var h=t(n,r-1,28,0,0,0,0),p=s.getDaysInMonth(h.getUTCFullYear(),h.getUTCMonth());h.setUTCDate(p),h.setUTCDate(p-(h.getUTCDay()-this.weekStart+7)%7);var d=new Date(h);d.setUTCDate(d.getUTCDate()+42),d=d.valueOf();var v=[],m;while(h.valueOf()<d){h.getUTCDay()==this.weekStart&&v.push("<tr>"),m="";if(h.getUTCFullYear()<n||h.getUTCFullYear()==n&&h.getUTCMonth()<r)m+=" old";else if(h.getUTCFullYear()>n||h.getUTCFullYear()==n&&h.getUTCMonth()>r)m+=" new";this.todayHighlight&&h.getUTCFullYear()==c.getFullYear()&&h.getUTCMonth()==c.getMonth()&&h.getUTCDate()==c.getDate()&&(m+=" today"),l&&h.valueOf()==l&&(m+=" active");if(h.valueOf()<this.startDate||h.valueOf()>this.endDate)m+=" disabled";v.push('<td class="day'+m+'">'+h.getUTCDate()+"</td>"),h.getUTCDay()==this.weekEnd&&v.push("</tr>"),h.setUTCDate(h.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(v.join(""));var g=this.date&&this.date.getUTCFullYear(),y=this.picker.find(".datepicker-months").find("th:eq(1)").text(n).end().find("span").removeClass("active");g&&g==n&&y.eq(this.date.getUTCMonth()).addClass("active"),(n<o||n>a)&&y.addClass("disabled"),n==o&&y.slice(0,u).addClass("disabled"),n==a&&y.slice(f+1).addClass("disabled"),v="",n=parseInt(n/10,10)*10;var b=this.picker.find(".datepicker-years").find("th:eq(1)").text(n+"-"+(n+9)).end().find("td");n-=1;for(var w=-1;w<11;w++)v+='<span class="year'+(w==-1||w==10?" old":"")+(g==n?" active":"")+(n<o||n>a?" disabled":"")+'">'+n+"</span>",n+=1;b.html(v)},updateNavArrows:function(){var e=new Date(this.viewDate),t=e.getUTCFullYear(),n=e.getUTCMonth();switch(this.viewMode){case 0:this.startDate!==-Infinity&&t<=this.startDate.getUTCFullYear()&&n<=this.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==Infinity&&t>=this.endDate.getUTCFullYear()&&n>=this.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.startDate!==-Infinity&&t<=this.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==Infinity&&t>=this.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}},click:function(n){n.stopPropagation(),n.preventDefault();var r=e(n.target).closest("span, td, th");if(r.length==1)switch(r[0].nodeName.toLowerCase()){case"th":switch(r[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var i=s.modes[this.viewMode].navStep*(r[0].className=="prev"?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,i);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,i)}this.fill();break;case"today":var o=new Date;o=t(o.getFullYear(),o.getMonth(),o.getDate(),0,0,0),this.showMode(-2);var u=this.todayBtn=="linked"?null:"view";this._setDate(o,u)}break;case"span":if(!r.is(".disabled")){this.viewDate.setUTCDate(1);if(r.is(".month")){var a=r.parent().find("span").index(r);this.viewDate.setUTCMonth(a),this.element.trigger({type:"changeMonth",date:this.viewDate})}else{var f=parseInt(r.text(),10)||0;this.viewDate.setUTCFullYear(f),this.element.trigger({type:"changeYear",date:this.viewDate})}this.showMode(-1),this.fill()}break;case"td":if(r.is(".day")&&!r.is(".disabled")){var l=parseInt(r.text(),10)||1,f=this.viewDate.getUTCFullYear(),a=this.viewDate.getUTCMonth();r.is(".old")?a==0?(a=11,f-=1):a-=1:r.is(".new")&&(a==11?(a=0,f+=1):a+=1),this._setDate(t(f,a,l,0,0,0,0))}}},_setDate:function(e,t){if(!t||t=="date")this.date=e;if(!t||t=="view")this.viewDate=e;this.fill(),this.setValue(),this.element.trigger({type:"changeDate",date:this.date});var n;this.isInput?n=this.element:this.component&&(n=this.element.find("input")),n&&(n.change(),this.autoclose&&this.hide())},moveMonth:function(e,t){if(!t)return e;var n=new Date(e.valueOf()),r=n.getUTCDate(),i=n.getUTCMonth(),s=Math.abs(t),o,u;t=t>0?1:-1;if(s==1){u=t==-1?function(){return n.getUTCMonth()==i}:function(){return n.getUTCMonth()!=o},o=i+t,n.setUTCMonth(o);if(o<0||o>11)o=(o+12)%12}else{for(var a=0;a<s;a++)n=this.moveMonth(n,t);o=n.getUTCMonth(),n.setUTCDate(r),u=function(){return o!=n.getUTCMonth()}}while(u())n.setUTCDate(--r),n.setUTCMonth(o);return n},moveYear:function(e,t){return this.moveMonth(e,t*12)},dateWithinRange:function(e){return e>=this.startDate&&e<=this.endDate},keydown:function(e){if(this.picker.is(":not(:visible)")){e.keyCode==27&&this.show();return}var t=!1,n,r,i,s,o;switch(e.keyCode){case 27:this.hide(),e.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;n=e.keyCode==37?-1:1,e.ctrlKey?(s=this.moveYear(this.date,n),o=this.moveYear(this.viewDate,n)):e.shiftKey?(s=this.moveMonth(this.date,n),o=this.moveMonth(this.viewDate,n)):(s=new Date(this.date),s.setUTCDate(this.date.getUTCDate()+n),o=new Date(this.viewDate),o.setUTCDate(this.viewDate.getUTCDate()+n)),this.dateWithinRange(s)&&(this.date=s,this.viewDate=o,this.setValue(),this.update(),e.preventDefault(),t=!0);break;case 38:case 40:if(!this.keyboardNavigation)break;n=e.keyCode==38?-1:1,e.ctrlKey?(s=this.moveYear(this.date,n),o=this.moveYear(this.viewDate,n)):e.shiftKey?(s=this.moveMonth(this.date,n),o=this.moveMonth(this.viewDate,n)):(s=new Date(this.date),s.setUTCDate(this.date.getUTCDate()+n*7),o=new Date(this.viewDate),o.setUTCDate(this.viewDate.getUTCDate()+n*7)),this.dateWithinRange(s)&&(this.date=s,this.viewDate=o,this.setValue(),this.update(),e.preventDefault(),t=!0);break;case 13:this.hide(),e.preventDefault();break;case 9:this.hide()}if(t){this.element.trigger({type:"changeDate",date:this.date});var u;this.isInput?u=this.element:this.component&&(u=this.element.find("input")),u&&u.change()}},showMode:function(e){e&&(this.viewMode=Math.max(0,Math.min(2,this.viewMode+e))),this.picker.find(">div").hide().filter(".datepicker-"+s.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}},e.fn.datepicker=function(t){var n=Array.apply(null,arguments);return n.shift(),this.each(function(){var i=e(this),s=i.data("datepicker"),o=typeof t=="object"&&t;s||i.data("datepicker",s=new r(this,e.extend({},e.fn.datepicker.defaults,o))),typeof t=="string"&&typeof s[t]=="function"&&s[t].apply(s,n)})},e.fn.datepicker.defaults={},e.fn.datepicker.Constructor=r;var i=e.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today"}},s={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(e){return e%4===0&&e%100!==0||e%400===0},getDaysInMonth:function(e,t){return[31,s.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31][t]},validParts:/dd?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\r]+/g,parseFormat:function(e){var t=e.replace(this.validParts,"\0").split("\0"),n=e.match(this.validParts);if(!t||!t.length||!n||n.length==0)throw new Error("Invalid date format.");return{separators:t,parts:n}},parseDate:function(n,s,o){if(n instanceof Date)return n;if(/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(n)){var u=/([-+]\d+)([dmwy])/,a=n.match(/([-+]\d+)([dmwy])/g),f,l;n=new Date;for(var c=0;c<a.length;c++){f=u.exec(a[c]),l=parseInt(f[1]);switch(f[2]){case"d":n.setUTCDate(n.getUTCDate()+l);break;case"m":n=r.prototype.moveMonth.call(r.prototype,n,l);break;case"w":n.setUTCDate(n.getUTCDate()+l*7);break;case"y":n=r.prototype.moveYear.call(r.prototype,n,l)}}return t(n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate(),0,0,0)}var a=n&&n.match(this.nonpunctuation)||[],n=new Date,h={},p=["yyyy","yy","M","MM","m","mm","d","dd"],d={yyyy:function(e,t){return e.setUTCFullYear(t)},yy:function(e,t){return e.setUTCFullYear(2e3+t)},m:function(e,t){t-=1;while(t<0)t+=12;t%=12,e.setUTCMonth(t);while(e.getUTCMonth()!=t)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}},v,m,f;d.M=d.MM=d.mm=d.m,d.dd=d.d,n=t(n.getFullYear(),n.getMonth(),n.getDate(),0,0,0);if(a.length==s.parts.length){for(var c=0,g=s.parts.length;c<g;c++){v=parseInt(a[c],10),f=s.parts[c];if(isNaN(v))switch(f){case"MM":m=e(i[o].months).filter(function(){var e=this.slice(0,a[c].length),t=a[c].slice(0,e.length);return e==t}),v=e.inArray(m[0],i[o].months)+1;break;case"M":m=e(i[o].monthsShort).filter(function(){var e=this.slice(0,a[c].length),t=a[c].slice(0,e.length);return e==t}),v=e.inArray(m[0],i[o].monthsShort)+1}h[f]=v}for(var c=0,y;c<p.length;c++)y=p[c],y in h&&d[y](n,h[y])}return n},formatDate:function(t,n,r){var s={d:t.getUTCDate(),m:t.getUTCMonth()+1,M:i[r].monthsShort[t.getUTCMonth()],MM:i[r].months[t.getUTCMonth()],yy:t.getUTCFullYear().toString().substring(2),yyyy:t.getUTCFullYear()};s.dd=(s.d<10?"0":"")+s.d,s.mm=(s.m<10?"0":"")+s.m;var t=[],o=e.extend([],n.separators);for(var u=0,a=n.parts.length;u<a;u++)o.length&&t.push(o.shift()),t.push(s[n.parts[u]]);return t.join("")},headTemplate:'<thead><tr><th class="prev"><i class="icon-arrow-left"/></th><th colspan="5" class="switch"></th><th class="next"><i class="icon-arrow-right"/></th></tr></thead>',contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>',footTemplate:'<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'};s.template='<div class="datepicker"><div class="datepicker-days"><table class=" table-condensed">'+s.headTemplate+"<tbody></tbody>"+s.footTemplate+"</table>"+"</div>"+'<div class="datepicker-months">'+'<table class="table-condensed">'+s.headTemplate+s.contTemplate+s.footTemplate+"</table>"+"</div>"+'<div class="datepicker-years">'+'<table class="table-condensed">'+s.headTemplate+s.contTemplate+s.footTemplate+"</table>"+"</div>"+"</div>",e.fn.datepicker.DPGlobal=s}(window.jQuery);
@@ -1,5 +0,0 @@
1
- /*! X-editable - v1.3.0
2
- * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3
- * http://github.com/vitalets/x-editable
4
- * Copyright (c) 2012 Vitaliy Potapov; Licensed MIT */
5
- (function(e){var t=function(t,n){this.options=e.extend({},e.fn.editableform.defaults,n),this.$div=e(t),this.options.scope||(this.options.scope=this),this.initInput()};t.prototype={constructor:t,initInput:function(){var t,n;if(typeof e.fn.editabletypes[this.options.type]!="function"){e.error("Unknown type: "+this.options.type);return}t=e.fn.editabletypes[this.options.type],n=e.fn.editableutils.sliceObj(this.options,e.fn.editableutils.objectKeys(t.defaults)),this.input=new t(n),this.value=this.input.str2value(this.options.value)},initTemplate:function(){this.$form=e(e.fn.editableform.template)},initButtons:function(){this.$form.find(".editable-buttons").append(e.fn.editableform.buttons)},render:function(){this.$loading=e(e.fn.editableform.loading),this.$div.empty().append(this.$loading),this.showLoading(),this.initTemplate(),this.options.showbuttons?this.initButtons():this.$form.find(".editable-buttons").remove(),this.$div.triggerHandler("rendering"),e.when(this.input.render()).then(e.proxy(function(){this.$form.find("div.editable-input").append(this.input.$input),this.options.showbuttons||this.input.autosubmit(),this.input.$clear&&this.$form.find("div.editable-input").append(e('<div class="editable-clear">').append(this.input.$clear)),this.$div.append(this.$form),this.$form.find(".editable-cancel").click(e.proxy(this.cancel,this)),this.input.error?(this.error(this.input.error),this.$form.find(".editable-submit").attr("disabled",!0),this.input.$input.attr("disabled",!0),this.$form.submit(function(e){e.preventDefault()})):(this.error(!1),this.input.$input.removeAttr("disabled"),this.$form.find(".editable-submit").removeAttr("disabled"),this.input.value2input(this.value),this.$form.submit(e.proxy(this.submit,this))),this.$div.triggerHandler("rendered"),this.showForm()},this))},cancel:function(){this.$div.triggerHandler("cancel")},showLoading:function(){var e;this.$form?(this.$loading.width(this.$form.outerWidth()),this.$loading.height(this.$form.outerHeight()),this.$form.hide()):(e=this.$loading.parent().width(),e&&this.$loading.width(e)),this.$loading.show()},showForm:function(e){this.$loading.hide(),this.$form.show(),e!==!1&&this.input.activate(),this.$div.triggerHandler("show")},error:function(t){var n=this.$form.find(".control-group"),r=this.$form.find(".editable-error-block");t===!1?(n.removeClass(e.fn.editableform.errorGroupClass),r.removeClass(e.fn.editableform.errorBlockClass).empty().hide()):(n.addClass(e.fn.editableform.errorGroupClass),r.addClass(e.fn.editableform.errorBlockClass).text(t).show())},submit:function(t){t.stopPropagation(),t.preventDefault();var n,r=this.input.input2value();if(n=this.validate(r)){this.error(n),this.showForm();return}if(!this.options.savenochange&&this.input.value2str(r)==this.input.value2str(this.value)){this.$div.triggerHandler("nochange");return}e.when(this.save(r)).done(e.proxy(function(e){var t=typeof this.options.success=="function"?this.options.success.call(this.options.scope,e,r):null;if(t===!1){this.error(!1),this.showForm(!1);return}if(typeof t=="string"){this.error(t),this.showForm();return}t&&typeof t=="object"&&t.hasOwnProperty("newValue")&&(r=t.newValue),this.error(!1),this.value=r,this.$div.triggerHandler("save",{newValue:r,response:e})},this)).fail(e.proxy(function(e){this.error(typeof e=="string"?e:e.responseText||e.statusText||"Unknown error!"),this.showForm()},this))},save:function(t){var n=this.input.value2submit(t);this.options.pk=e.fn.editableutils.tryParseJson(this.options.pk,!0);var r=typeof this.options.pk=="function"?this.options.pk.call(this.options.scope):this.options.pk,i=!!(typeof this.options.url=="function"||this.options.url&&(this.options.send==="always"||this.options.send==="auto"&&r)),s;if(i)return this.showLoading(),s={name:this.options.name||"",value:n,pk:r},typeof this.options.params=="function"?s=this.options.params.call(this.options.scope,s):(this.options.params=e.fn.editableutils.tryParseJson(this.options.params,!0),e.extend(s,this.options.params)),typeof this.options.url=="function"?this.options.url.call(this.options.scope,s):e.ajax(e.extend({url:this.options.url,data:s,type:"POST"},this.options.ajaxOptions))},validate:function(e){e===undefined&&(e=this.value);if(typeof this.options.validate=="function")return this.options.validate.call(this.options.scope,e)},option:function(e,t){this.options[e]=t,e==="value"&&this.setValue(t)},setValue:function(e,t){t?this.value=this.input.str2value(e):this.value=e}},e.fn.editableform=function(n){var r=arguments;return this.each(function(){var i=e(this),s=i.data("editableform"),o=typeof n=="object"&&n;s||i.data("editableform",s=new t(this,o)),typeof n=="string"&&s[n].apply(s,Array.prototype.slice.call(r,1))})},e.fn.editableform.Constructor=t,e.fn.editableform.defaults={type:"text",url:null,params:null,name:null,pk:null,value:null,send:"auto",validate:null,success:null,ajaxOptions:null,showbuttons:!0,scope:null,savenochange:!1},e.fn.editableform.template='<form class="form-inline editableform"><div class="control-group"><div><div class="editable-input"></div><div class="editable-buttons"></div></div><div class="editable-error-block"></div></div></form>',e.fn.editableform.loading='<div class="editableform-loading"></div>',e.fn.editableform.buttons='<button type="submit" class="editable-submit">ok</button><button type="button" class="editable-cancel">cancel</button>',e.fn.editableform.errorGroupClass=null,e.fn.editableform.errorBlockClass="editable-error"})(window.jQuery),function(e){e.fn.editableutils={inherit:function(e,t){var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e,e.superclass=t.prototype},setCursorPosition:function(e,t){if(e.setSelectionRange)e.setSelectionRange(t,t);else if(e.createTextRange){var n=e.createTextRange();n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",t),n.select()}},tryParseJson:function(e,t){if(typeof e=="string"&&e.length&&e.match(/^[\{\[].*[\}\]]$/))if(t)try{e=(new Function("return "+e))()}catch(n){}finally{return e}else e=(new Function("return "+e))();return e},sliceObj:function(t,n,r){var i,s,o={};if(!e.isArray(n)||!n.length)return o;for(var u=0;u<n.length;u++){i=n[u],t.hasOwnProperty(i)&&(o[i]=t[i]);if(r===!0)continue;s=i.toLowerCase(),t.hasOwnProperty(s)&&(o[i]=t[s])}return o},getConfigData:function(t){var n={};return e.each(t.data(),function(e,t){if(typeof t!="object"||t&&typeof t=="object"&&t.constructor===Object)n[e]=t}),n},objectKeys:function(e){if(Object.keys)return Object.keys(e);if(e!==Object(e))throw new TypeError("Object.keys called on a non-object");var t=[],n;for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.push(n);return t},escape:function(t){return e("<div>").text(t).html()}}}(window.jQuery),function(e){var t=function(e,t){this.init(e,t)};t.prototype={containerName:null,innerCss:null,init:function(n,r){this.$element=e(n),this.options=e.extend({},e.fn.editableContainer.defaults,e.fn.editableutils.getConfigData(this.$element),r),this.splitOptions(),this.initContainer(),this.$element.on("destroyed",e.proxy(function(){this.destroy()},this)),e(document).data("editable-handlers-attached")||(e(document).on("keyup.editable",function(t){t.which===27&&e(".editable-open").editableContainer("hide")}),e(document).on("click.editable",function(n){var r=e(n.target);if(r.is(".editable-container")||r.parents(".editable-container").length||r.parents(".ui-datepicker-header").length)return;t.prototype.closeOthers(n.target)}),e(document).data("editable-handlers-attached",!0))},splitOptions:function(){this.containerOptions={},this.formOptions={};var t=e.fn[this.containerName].defaults;for(var n in this.options)n in t?this.containerOptions[n]=this.options[n]:this.formOptions[n]=this.options[n]},initContainer:function(){this.call(this.containerOptions)},initForm:function(){return this.formOptions.scope=this.$element[0],this.$form=e("<div>").editableform(this.formOptions).on({save:e.proxy(this.save,this),cancel:e.proxy(function(){this.hide("cancel")},this),nochange:e.proxy(function(){this.hide("nochange")},this),show:e.proxy(this.setPosition,this),rendering:e.proxy(this.setPosition,this),rendered:e.proxy(function(){this.$element.triggerHandler("shown")},this)}),this.$form},tip:function(){return this.container().$tip},container:function(){return this.$element.data(this.containerName)},call:function(){this.$element[this.containerName].apply(this.$element,arguments)},show:function(e){this.$element.addClass("editable-open"),e!==!1&&this.closeOthers(this.$element[0]),this.innerShow()},innerShow:function(){this.call("show"),this.tip().addClass("editable-container"),this.initForm(),this.tip().find(this.innerCss).empty().append(this.$form),this.$form.editableform("render")},hide:function(e){if(!this.tip()||!this.tip().is(":visible")||!this.$element.hasClass("editable-open"))return;this.$element.removeClass("editable-open"),this.innerHide(),this.$element.triggerHandler("hidden",e)},innerHide:function(){this.call("hide")},toggle:function(e){this.tip&&this.tip().is(":visible")?this.hide():this.show(e)},setPosition:function(){},save:function(e,t){this.hide("save"),this.$element.triggerHandler("save",t)},option:function(e,t){this.options[e]=t,e in this.containerOptions?(this.containerOptions[e]=t,this.setContainerOption(e,t)):(this.formOptions[e]=t,this.$form&&this.$form.editableform("option",e,t))},setContainerOption:function(e,t){this.call("option",e,t)},destroy:function(){this.call("destroy")},closeOthers:function(t){e(".editable-open").each(function(n,r){if(r===t||e(r).find(t).length)return;var i=e(r),s=i.data("editableContainer");if(!s)return;s.options.onblur==="cancel"?i.data("editableContainer").hide("onblur"):s.options.onblur==="submit"&&i.data("editableContainer").tip().find("form").submit()})},activate:function(){this.tip&&this.tip().is(":visible")&&this.$form&&this.$form.data("editableform").input.activate()}},e.fn.editableContainer=function(n){var r=arguments;return this.each(function(){var i=e(this),s="editableContainer",o=i.data(s),u=typeof n=="object"&&n;o||i.data(s,o=new t(this,u)),typeof n=="string"&&o[n].apply(o,Array.prototype.slice.call(r,1))})},e.fn.editableContainer.Constructor=t,e.fn.editableContainer.defaults={value:null,placement:"top",autohide:!0,onblur:"cancel"},jQuery.event.special.destroyed={remove:function(e){e.handler&&e.handler()}}}(window.jQuery),function(e){var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.editable.defaults,e.fn.editableutils.getConfigData(this.$element),n),this.init()};t.prototype={constructor:t,init:function(){var t,n=!1,r,i;if(!e.fn.editableContainer){e.error("You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)");return}this.options.name=this.options.name||this.$element.attr("id");if(typeof e.fn.editabletypes[this.options.type]!="function"){e.error("Unknown type: "+this.options.type);return}t=e.fn.editabletypes[this.options.type],this.typeOptions=e.fn.editableutils.sliceObj(this.options,e.fn.editableutils.objectKeys(t.defaults)),this.input=new t(this.typeOptions),this.options.value===undefined||this.options.value===null?(this.value=this.input.html2value(e.trim(this.$element.html())),n=!0):(this.options.value=e.fn.editableutils.tryParseJson(this.options.value,!0),typeof this.options.value=="string"?this.value=this.input.str2value(this.options.value):this.value=this.options.value),this.$element.addClass("editable"),this.options.toggle!=="manual"?(this.$element.addClass("editable-click"),this.$element.on(this.options.toggle+".editable",e.proxy(function(e){e.preventDefault();if(this.options.toggle==="mouseenter")this.show();else{var t=this.options.toggle!=="click";this.toggle(t)}},this))):this.$element.attr("tabindex",-1),r=!n&&this.value!==null&&this.value!==undefined,r&=this.options.autotext==="always"||this.options.autotext==="auto"&&!this.$element.text().length,e.when(r?this.render():!0).then(e.proxy(function(){this.options.disabled?this.disable():this.enable(),this.$element.triggerHandler("init",this)},this))},render:function(){if(this.options.display===!1)return;return this.input.options.hasOwnProperty("source")?this.input.value2html(this.value,this.$element[0],this.options.display):typeof this.options.display=="function"?this.options.display.call(this.$element[0],this.value):this.input.value2html(this.value,this.$element[0])},enable:function(){this.options.disabled=!1,this.$element.removeClass("editable-disabled"),this.handleEmpty(),this.options.toggle!=="manual"&&this.$element.attr("tabindex")==="-1"&&this.$element.removeAttr("tabindex")},disable:function(){this.options.disabled=!0,this.hide(),this.$element.addClass("editable-disabled"),this.handleEmpty(),this.$element.attr("tabindex",-1)},toggleDisabled:function(){this.options.disabled?this.enable():this.disable()},option:function(t,n){if(t&&typeof t=="object"){e.each(t,e.proxy(function(t,n){this.option(e.trim(t),n)},this));return}this.options[t]=n;if(t==="disabled"){n?this.disable():this.enable();return}t==="value"&&this.setValue(n),this.container&&this.container.option(t,n)},handleEmpty:function(){if(this.options.display===!1)return;var t="editable-empty";this.options.disabled?this.$element.hasClass(t)&&(this.$element.empty(),this.$element.removeClass(t)):e.trim(this.$element.text())===""?this.$element.addClass(t).text(this.options.emptytext):this.$element.removeClass(t)},show:function(t){if(this.options.disabled)return;if(!this.container){var n=e.extend({},this.options,{value:this.value});this.$element.editableContainer(n),this.$element.on("save.internal",e.proxy(this.save,this)),this.container=this.$element.data("editableContainer")}else if(this.container.tip().is(":visible"))return;this.container.show(t)},hide:function(){this.container&&this.container.hide()},toggle:function(e){this.container&&this.container.tip().is(":visible")?this.hide():this.show(e)},save:function(e,t){typeof this.options.url!="function"&&this.options.display!==!1&&t.response===undefined&&this.input.value2str(this.value)!==this.input.value2str(t.newValue)?this.$element.addClass("editable-unsaved"):this.$element.removeClass("editable-unsaved"),this.setValue(t.newValue)},validate:function(){if(typeof this.options.validate=="function")return this.options.validate.call(this,this.value)},setValue:function(t,n){n?this.value=this.input.str2value(t):this.value=t,this.container&&this.container.option("value",this.value),e.when(this.render()).then(e.proxy(function(){this.handleEmpty()},this))},activate:function(){this.container&&this.container.activate()}},e.fn.editable=function(n){var r={},i=arguments,s="editable";switch(n){case"validate":return this.each(function(){var t=e(this),n=t.data(s),i;n&&(i=n.validate())&&(r[n.options.name]=i)}),r;case"getValue":return this.each(function(){var t=e(this),n=t.data(s);n&&n.value!==undefined&&n.value!==null&&(r[n.options.name]=n.input.value2submit(n.value))}),r;case"submit":var o=arguments[1]||{},u=this,a=this.editable("validate"),f;return e.isEmptyObject(a)?(f=this.editable("getValue"),o.data&&e.extend(f,o.data),e.ajax(e.extend({url:o.url,data:f,type:"POST"},o.ajaxOptions)).success(function(e){typeof o.success=="function"&&o.success.call(u,e,o)}).error(function(){typeof o.error=="function"&&o.error.apply(u,arguments)})):typeof o.error=="function"&&o.error.call(u,a),this}return this.each(function(){var r=e(this),o=r.data(s),u=typeof n=="object"&&n;o||r.data(s,o=new t(this,u)),typeof n=="string"&&o[n].apply(o,Array.prototype.slice.call(i,1))})},e.fn.editable.defaults={type:"text",disabled:!1,toggle:"click",emptytext:"Empty",autotext:"auto",value:null,display:null}}(window.jQuery),function(e){e.fn.editabletypes={};var t=function(){};t.prototype={init:function(t,n,r){this.type=t,this.options=e.extend({},r,n),this.$input=null,this.$clear=null,this.error=null},render:function(){this.$input=e(this.options.tpl),this.options.inputclass&&this.$input.addClass(this.options.inputclass),this.options.placeholder&&this.$input.attr("placeholder",this.options.placeholder)},value2html:function(t,n){e(n).text(t)},html2value:function(t){return e("<div>").html(t).text()},value2str:function(e){return e},str2value:function(e){return e},value2submit:function(e){return e},value2input:function(e){this.$input.val(e)},input2value:function(){return this.$input.val()},activate:function(){this.$input.is(":visible")&&this.$input.focus()},clear:function(){this.$input.val(null)},escape:function(t){return e("<div>").text(t).html()},autosubmit:function(){}},t.defaults={tpl:"",inputclass:"input-medium",name:null},e.extend(e.fn.editabletypes,{abstractinput:t})}(window.jQuery),function(e){var t=function(e){};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this);var n=e.Deferred();return this.error=null,this.sourceData=null,this.prependData=null,this.onSourceReady(function(){this.renderList(),n.resolve()},function(){this.error=this.options.sourceError,n.resolve()}),n.promise()},html2value:function(e){return null},value2html:function(t,n,r){var i=e.Deferred();return this.onSourceReady(function(){typeof r=="function"?r.call(n,t,this.sourceData):this.value2htmlFinal(t,n),i.resolve()},function(){i.resolve()}),i.promise()},onSourceReady:function(t,n){if(e.isArray(this.sourceData)){t.call(this);return}try{this.options.source=e.fn.editableutils.tryParseJson(this.options.source,!1)}catch(r){n.call(this);return}if(typeof this.options.source=="string"){if(this.options.sourceCache){var i=this.options.source+(this.options.name?"-"+this.options.name:""),s;e(document).data(i)||e(document).data(i,{}),s=e(document).data(i);if(s.loading===!1&&s.sourceData){this.sourceData=s.sourceData,t.call(this);return}if(s.loading===!0){s.callbacks.push(e.proxy(function(){this.sourceData=s.sourceData,t.call(this)},this)),s.err_callbacks.push(e.proxy(n,this));return}s.loading=!0,s.callbacks=[],s.err_callbacks=[]}e.ajax({url:this.options.source,type:"get",cache:!1,data:this.options.name?{name:this.options.name}:{},dataType:"json",success:e.proxy(function(r){s&&(s.loading=!1),this.sourceData=this.makeArray(r),e.isArray(this.sourceData)?(this.doPrepend(),t.call(this),s&&(s.sourceData=this.sourceData,e.each(s.callbacks,function(){this.call()}))):(n.call(this),s&&e.each(s.err_callbacks,function(){this.call()}))},this),error:e.proxy(function(){n.call(this),s&&(s.loading=!1,e.each(s.err_callbacks,function(){this.call()}))},this)})}else this.sourceData=this.makeArray(this.options.source),e.isArray(this.sourceData)?(this.doPrepend(),t.call(this)):n.call(this)},doPrepend:function(){if(this.options.prepend===null||this.options.prepend===undefined)return;e.isArray(this.prependData)||(this.options.prepend=e.fn.editableutils.tryParseJson(this.options.prepend,!0),typeof this.options.prepend=="string"&&(this.options.prepend={"":this.options.prepend}),this.prependData=this.makeArray(this.options.prepend)),e.isArray(this.prependData)&&e.isArray(this.sourceData)&&(this.sourceData=this.prependData.concat(this.sourceData))},renderList:function(){},value2htmlFinal:function(e,t){},makeArray:function(t){var n,r,i=[],s;if(!t||typeof t=="string")return null;if(e.isArray(t)){s=function(e,t){r={value:e,text:t};if(n++>=2)return!1};for(var o=0;o<t.length;o++)typeof t[o]=="object"?(n=0,e.each(t[o],s),n===1?i.push(r):n>1&&t[o].hasOwnProperty("value")&&t[o].hasOwnProperty("text")&&i.push(t[o])):i.push({value:t[o],text:t[o]})}else e.each(t,function(e,t){i.push({value:e,text:t})});return i},itemByVal:function(t){if(e.isArray(this.sourceData))for(var n=0;n<this.sourceData.length;n++)if(this.sourceData[n].value==t)return this.sourceData[n]}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{source:null,prepend:!1,sourceError:"Error when loading list",sourceCache:!0}),e.fn.editabletypes.list=t}(window.jQuery),function(e){var t=function(e){this.init("text",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{activate:function(){this.$input.is(":visible")&&(this.$input.focus(),e.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length))}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:'<input type="text">',placeholder:null}),e.fn.editabletypes.text=t}(window.jQuery),function(e){var t=function(e){this.init("textarea",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.$input.keydown(function(t){t.ctrlKey&&t.which===13&&e(this).closest("form").submit()})},value2html:function(t,n){var r="",i;if(t){i=t.split("\n");for(var s=0;s<i.length;s++)i[s]=e("<div>").text(i[s]).html();r=i.join("<br>")}e(n).html(r)},html2value:function(t){if(!t)return"";var n=t.split(/<br\s*\/?>/i);for(var r=0;r<n.length;r++)n[r]=e("<div>").html(n[r]).text();return n.join("\n")},activate:function(){this.$input.is(":visible")&&(e.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length),this.$input.focus())}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:"<textarea></textarea>",inputclass:"input-large",placeholder:null}),e.fn.editabletypes.textarea=t}(window.jQuery),function(e){var t=function(e){this.init("select",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.list),e.extend(t.prototype,{renderList:function(){if(!e.isArray(this.sourceData))return;for(var t=0;t<this.sourceData.length;t++)this.$input.append(e("<option>",{value:this.sourceData[t].value}).text(this.sourceData[t].text));this.$input.on("keydown.editable",function(t){t.which===13&&e(this).closest("form").submit()})},value2htmlFinal:function(e,n){var r="",i=this.itemByVal(e);i&&(r=i.text),t.superclass.constructor.superclass.value2html(r,n)},autosubmit:function(){this.$input.off("keydown.editable").on("change.editable",function(){e(this).closest("form").submit()})}}),t.defaults=e.extend({},e.fn.editabletypes.list.defaults,{tpl:"<select></select>"}),e.fn.editabletypes.select=t}(window.jQuery),function(e){var t=function(e){this.init("checklist",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.list),e.extend(t.prototype,{renderList:function(){var t,n;if(!e.isArray(this.sourceData))return;for(var r=0;r<this.sourceData.length;r++)t=e("<label>").append(e("<input>",{type:"checkbox",value:this.sourceData[r].value,name:this.options.name})).append(e("<span>").text(" "+this.sourceData[r].text)),e("<div>").append(t).appendTo(this.$input)},value2str:function(t){return e.isArray(t)?t.sort().join(e.trim(this.options.separator)):""},str2value:function(t){var n,r=null;return typeof t=="string"&&t.length?(n=new RegExp("\\s*"+e.trim(this.options.separator)+"\\s*"),r=t.split(n)):e.isArray(t)&&(r=t),r},value2input:function(t){var n=this.$input.find('input[type="checkbox"]');n.removeAttr("checked"),e.isArray(t)&&t.length&&n.each(function(n,r){var i=e(r);e.each(t,function(e,t){i.val()==t&&i.attr("checked","checked")})})},input2value:function(){var t=[];return this.$input.find("input:checked").each(function(n,r){t.push(e(r).val())}),t},value2htmlFinal:function(t,n){var r=[],i=e.grep(this.sourceData,function(n){return e.grep(t,function(e){return e==n.value}).length});i.length?(e.each(i,function(t,n){r.push(e.fn.editableutils.escape(n.text))}),e(n).html(r.join("<br>"))):e(n).empty()},activate:function(){this.$input.find('input[type="checkbox"]').first().focus()},autosubmit:function(){this.$input.find('input[type="checkbox"]').on("keydown",function(t){t.which===13&&e(this).closest("form").submit()})}}),t.defaults=e.extend({},e.fn.editabletypes.list.defaults,{tpl:"<div></div>",inputclass:"editable-checklist",separator:","}),e.fn.editabletypes.checklist=t}(window.jQuery),function(e){var t=function(e){this.init("password",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),e.extend(t.prototype,{value2html:function(t,n){t?e(n).text("[hidden]"):e(n).empty()},html2value:function(e){return null}}),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="password">'}),e.fn.editabletypes.password=t}(window.jQuery),function(e){var t=function(e){this.init("email",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="email">'}),e.fn.editabletypes.email=t}(window.jQuery),function(e){var t=function(e){this.init("url",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="url">'}),e.fn.editabletypes.url=t}(window.jQuery),function(e){var t=function(e){this.init("tel",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="tel">'}),e.fn.editabletypes.tel=t}(window.jQuery),function(e){var t=function(e){this.init("number",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.text),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.options.min!==null&&this.$input.attr("min",this.options.min),this.options.max!==null&&this.$input.attr("max",this.options.max),this.options.step!==null&&this.$input.attr("step",this.options.step)}}),t.defaults=e.extend({},e.fn.editabletypes.text.defaults,{tpl:'<input type="number">',inputclass:"input-mini",min:null,max:null,step:null}),e.fn.editabletypes.number=t}(window.jQuery),function(e){var t=function(e){this.init("range",e,t.defaults)};e.fn.editableutils.inherit(t,e.fn.editabletypes.number),e.extend(t.prototype,{render:function(){this.$input=e(this.options.tpl);var t=this.$input.filter("input");this.options.inputclass&&t.addClass(this.options.inputclass),this.options.min!==null&&t.attr("min",this.options.min),this.options.max!==null&&t.attr("max",this.options.max),this.options.step!==null&&t.attr("step",this.options.step),t.on("input",function(){e(this).siblings("output").text(e(this).val())})},activate:function(){this.$input.filter("input").focus()}}),t.defaults=e.extend({},e.fn.editabletypes.number.defaults,{tpl:'<input type="range"><output style="width: 30px; display: inline-block"></output>',inputclass:"input-medium"}),e.fn.editabletypes.range=t}(window.jQuery),function(e){e.extend(e.fn.editableform.Constructor.prototype,{initTemplate:function(){this.$form=e(e.fn.editableform.template),this.$form.find(".editable-error-block").addClass("help-block")}}),e.fn.editableform.buttons='<button type="submit" class="btn btn-primary editable-submit"><i class="icon-ok icon-white"></i></button><button type="button" class="btn editable-cancel"><i class="icon-remove"></i></button>',e.fn.editableform.errorGroupClass="error",e.fn.editableform.errorBlockClass=null}(window.jQuery),function(e){e.extend(e.fn.editableContainer.Constructor.prototype,{containerName:"popover",innerCss:e(e.fn.popover.defaults.template).find("p").length?".popover-content p":".popover-content",initContainer:function(){e.extend(this.containerOptions,{trigger:"manual",selector:!1,content:" "}),this.call(this.containerOptions)},setContainerOption:function(e,t){this.container().options[e]=t},setPosition:function(){(function(){var e=this.tip(),t,n,r,i,s,o;s=typeof this.options.placement=="function"?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,t=/in/.test(s),e.removeClass("top right bottom left").css({top:0,left:0,display:"block"}),n=this.getPosition(t),r=e[0].offsetWidth,i=e[0].offsetHeight;switch(t?s.split(" ")[1]:s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}e.offset(o).addClass(s).addClass("in")}).call(this.container())}})}(window.jQuery),function(e){var t=function(n){this.init("date",n,t.defaults);var r=e.fn.editableutils.sliceObj(this.options,["format"]);this.options.datepicker=e.extend({},t.defaults.datepicker,r,n.datepicker),this.options.viewformat||(this.options.viewformat=this.options.datepicker.format),this.options.datepicker.language=this.options.datepicker.language||"en",this.dpg=e.fn.datepicker.DPGlobal,this.parsedFormat=this.dpg.parseFormat(this.options.datepicker.format),this.parsedViewFormat=this.dpg.parseFormat(this.options.viewformat)};e.fn.editableutils.inherit(t,e.fn.editabletypes.abstractinput),e.extend(t.prototype,{render:function(){t.superclass.render.call(this),this.$input.datepicker(this.options.datepicker),this.options.clear&&(this.$clear=e('<a href="#"></a>').html(this.options.clear).click(e.proxy(function(e){e.preventDefault(),e.stopPropagation(),this.clear()},this)))},value2html:function(e,n){var r=e?this.dpg.formatDate(e,this.parsedViewFormat,this.options.datepicker.language):"";t.superclass.value2html(r,n)},html2value:function(e){return e?this.dpg.parseDate(e,this.parsedViewFormat,this.options.datepicker.language):null},value2str:function(e){return e?this.dpg.formatDate(e,this.parsedFormat,this.options.datepicker.language):""},str2value:function(e){return e?this.dpg.parseDate(e,this.parsedFormat,this.options.datepicker.language):null},value2submit:function(e){return this.value2str(e)},value2input:function(e){this.$input.datepicker("update",e)},input2value:function(){return this.$input.data("datepicker").date},activate:function(){},clear:function(){this.$input.data("datepicker").date=null,this.$input.find(".active").removeClass("active")},autosubmit:function(){this.$input.on("changeDate",function(t){var n=e(this).closest("form");setTimeout(function(){n.submit()},200)})}}),t.defaults=e.extend({},e.fn.editabletypes.abstractinput.defaults,{tpl:"<div></div>",inputclass:"editable-date well",format:"yyyy-mm-dd",viewformat:null,datepicker:{weekStart:0,startView:0,autoclose:!1},clear:"&times; clear"}),e.fn.editabletypes.date=t}(window.jQuery),!function(e){function t(){return new Date(Date.UTC.apply(Date,arguments))}function n(){var e=new Date;return t(e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate())}var r=function(t,n){var r=this;this.element=e(t),this.language=n.language||this.element.data("date-language")||"en",this.language=this.language in i?this.language:"en",this.format=s.parseFormat(n.format||this.element.data("date-format")||"mm/dd/yyyy"),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.is(".date")?this.element.find(".add-on"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&this.component.length===0&&(this.component=!1),this.isInput?this.element.on({focus:e.proxy(this.show,this),keyup:e.proxy(this.update,this),keydown:e.proxy(this.keydown,this)}):this.component&&this.hasInput?(this.element.find("input").on({focus:e.proxy(this.show,this),keyup:e.proxy(this.update,this),keydown:e.proxy(this.keydown,this)}),this.component.on("click",e.proxy(this.show,this))):this.element.is("div")?this.isInline=!0:this.element.on("click",e.proxy(this.show,this)),this.picker=e(s.template).appendTo(this.isInline?this.element:"body").on({click:e.proxy(this.click,this),mousedown:e.proxy(this.mousedown,this)}),this.isInline?this.picker.addClass("datepicker-inline"):this.picker.addClass("dropdown-menu"),e(document).on("mousedown",function(t){e(t.target).closest(".datepicker").length==0&&r.hide()}),this.autoclose=!1,"autoclose"in n?this.autoclose=n.autoclose:"dateAutoclose"in this.element.data()&&(this.autoclose=this.element.data("date-autoclose")),this.keyboardNavigation=!0,"keyboardNavigation"in n?this.keyboardNavigation=n.keyboardNavigation:"dateKeyboardNavigation"in this.element.data()&&(this.keyboardNavigation=this.element.data("date-keyboard-navigation"));switch(n.startView||this.element.data("date-start-view")){case 2:case"decade":this.viewMode=this.startViewMode=2;break;case 1:case"year":this.viewMode=this.startViewMode=1;break;case 0:case"month":default:this.viewMode=this.startViewMode=0}this.todayBtn=n.todayBtn||this.element.data("date-today-btn")||!1,this.todayHighlight=n.todayHighlight||this.element.data("date-today-highlight")||!1,this.weekStart=(n.weekStart||this.element.data("date-weekstart")||i[this.language].weekStart||0)%7,this.weekEnd=(this.weekStart+6)%7,this.startDate=-Infinity,this.endDate=Infinity,this.setStartDate(n.startDate||this.element.data("date-startdate")),this.setEndDate(n.endDate||this.element.data("date-enddate")),this.fillDow(),this.fillMonths(),this.update(),this.showMode(),this.isInline&&this.show()};r.prototype={constructor:r,show:function(t){this.picker.show(),this.height=this.component?this.component.outerHeight():this.element.outerHeight(),this.update(),this.place(),e(window).on("resize",e.proxy(this.place,this)),t&&(t.stopPropagation(),t.preventDefault()),this.element.trigger({type:"show",date:this.date})},hide:function(t){if(this.isInline)return;this.picker.hide(),e(window).off("resize",this.place),this.viewMode=this.startViewMode,this.showMode(),this.isInput||e(document).off("mousedown",this.hide),t&&t.currentTarget.value&&this.setValue(),this.element.trigger({type:"hide",date:this.date})},getDate:function(){var e=this.getUTCDate();return new Date(e.getTime()+e.getTimezoneOffset()*6e4)},getUTCDate:function(){return this.date},setDate:function(e){this.setUTCDate(new Date(e.getTime()-e.getTimezoneOffset()*6e4))},setUTCDate:function(e){this.date=e,this.setValue()},setValue:function(){var e=this.getFormattedDate();this.isInput?this.element.prop("value",e):(this.component&&this.element.find("input").prop("value",e),this.element.data("date",e))},getFormattedDate:function(e){return e==undefined&&(e=this.format),s.formatDate(this.date,e,this.language)},setStartDate:function(e){this.startDate=e||-Infinity,this.startDate!==-Infinity&&(this.startDate=s.parseDate(this.startDate,this.format,this.language)),this.update(),this.updateNavArrows()},setEndDate:function(e){this.endDate=e||Infinity,this.endDate!==Infinity&&(this.endDate=s.parseDate(this.endDate,this.format,this.language)),this.update(),this.updateNavArrows()},place:function(){if(this.isInline)return;var t=parseInt(this.element.parents().filter(function(){return e(this).css("z-index")!="auto"}).first().css("z-index"))+10,n=this.component?this.component.offset():this.element.offset();this.picker.css({top:n.top+this.height,left:n.left,zIndex:t})},update:function(){var e,t=!1;arguments&&arguments.length&&(typeof arguments[0]=="string"||arguments[0]instanceof Date)?(e=arguments[0],t=!0):e=this.isInput?this.element.prop("value"):this.element.data("date")||this.element.find("input").prop("value"),this.date=s.parseDate(e,this.format,this.language),t&&this.setValue(),this.date<this.startDate?this.viewDate=new Date(this.startDate):this.date>this.endDate?this.viewDate=new Date(this.endDate):this.viewDate=new Date(this.date),this.fill()},fillDow:function(){var e=this.weekStart,t="<tr>";while(e<this.weekStart+7)t+='<th class="dow">'+i[this.language].daysMin[e++%7]+"</th>";t+="</tr>",this.picker.find(".datepicker-days thead").append(t)},fillMonths:function(){var e="",t=0;while(t<12)e+='<span class="month">'+i[this.language].monthsShort[t++]+"</span>";this.picker.find(".datepicker-months td").html(e)},fill:function(){var e=new Date(this.viewDate),n=e.getUTCFullYear(),r=e.getUTCMonth(),o=this.startDate!==-Infinity?this.startDate.getUTCFullYear():-Infinity,u=this.startDate!==-Infinity?this.startDate.getUTCMonth():-Infinity,a=this.endDate!==Infinity?this.endDate.getUTCFullYear():Infinity,f=this.endDate!==Infinity?this.endDate.getUTCMonth():Infinity,l=this.date&&this.date.valueOf(),c=new Date;this.picker.find(".datepicker-days thead th:eq(1)").text(i[this.language].months[r]+" "+n),this.picker.find("tfoot th.today").text(i[this.language].today).toggle(this.todayBtn!==!1),this.updateNavArrows(),this.fillMonths();var h=t(n,r-1,28,0,0,0,0),p=s.getDaysInMonth(h.getUTCFullYear(),h.getUTCMonth());h.setUTCDate(p),h.setUTCDate(p-(h.getUTCDay()-this.weekStart+7)%7);var d=new Date(h);d.setUTCDate(d.getUTCDate()+42),d=d.valueOf();var v=[],m;while(h.valueOf()<d){h.getUTCDay()==this.weekStart&&v.push("<tr>"),m="";if(h.getUTCFullYear()<n||h.getUTCFullYear()==n&&h.getUTCMonth()<r)m+=" old";else if(h.getUTCFullYear()>n||h.getUTCFullYear()==n&&h.getUTCMonth()>r)m+=" new";this.todayHighlight&&h.getUTCFullYear()==c.getFullYear()&&h.getUTCMonth()==c.getMonth()&&h.getUTCDate()==c.getDate()&&(m+=" today"),l&&h.valueOf()==l&&(m+=" active");if(h.valueOf()<this.startDate||h.valueOf()>this.endDate)m+=" disabled";v.push('<td class="day'+m+'">'+h.getUTCDate()+"</td>"),h.getUTCDay()==this.weekEnd&&v.push("</tr>"),h.setUTCDate(h.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(v.join(""));var g=this.date&&this.date.getUTCFullYear(),y=this.picker.find(".datepicker-months").find("th:eq(1)").text(n).end().find("span").removeClass("active");g&&g==n&&y.eq(this.date.getUTCMonth()).addClass("active"),(n<o||n>a)&&y.addClass("disabled"),n==o&&y.slice(0,u).addClass("disabled"),n==a&&y.slice(f+1).addClass("disabled"),v="",n=parseInt(n/10,10)*10;var b=this.picker.find(".datepicker-years").find("th:eq(1)").text(n+"-"+(n+9)).end().find("td");n-=1;for(var w=-1;w<11;w++)v+='<span class="year'+(w==-1||w==10?" old":"")+(g==n?" active":"")+(n<o||n>a?" disabled":"")+'">'+n+"</span>",n+=1;b.html(v)},updateNavArrows:function(){var e=new Date(this.viewDate),t=e.getUTCFullYear(),n=e.getUTCMonth();switch(this.viewMode){case 0:this.startDate!==-Infinity&&t<=this.startDate.getUTCFullYear()&&n<=this.startDate.getUTCMonth()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==Infinity&&t>=this.endDate.getUTCFullYear()&&n>=this.endDate.getUTCMonth()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"});break;case 1:case 2:this.startDate!==-Infinity&&t<=this.startDate.getUTCFullYear()?this.picker.find(".prev").css({visibility:"hidden"}):this.picker.find(".prev").css({visibility:"visible"}),this.endDate!==Infinity&&t>=this.endDate.getUTCFullYear()?this.picker.find(".next").css({visibility:"hidden"}):this.picker.find(".next").css({visibility:"visible"})}},click:function(n){n.stopPropagation(),n.preventDefault();var r=e(n.target).closest("span, td, th");if(r.length==1)switch(r[0].nodeName.toLowerCase()){case"th":switch(r[0].className){case"switch":this.showMode(1);break;case"prev":case"next":var i=s.modes[this.viewMode].navStep*(r[0].className=="prev"?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,i);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,i)}this.fill();break;case"today":var o=new Date;o=t(o.getFullYear(),o.getMonth(),o.getDate(),0,0,0),this.showMode(-2);var u=this.todayBtn=="linked"?null:"view";this._setDate(o,u)}break;case"span":if(!r.is(".disabled")){this.viewDate.setUTCDate(1);if(r.is(".month")){var a=r.parent().find("span").index(r);this.viewDate.setUTCMonth(a),this.element.trigger({type:"changeMonth",date:this.viewDate})}else{var f=parseInt(r.text(),10)||0;this.viewDate.setUTCFullYear(f),this.element.trigger({type:"changeYear",date:this.viewDate})}this.showMode(-1),this.fill()}break;case"td":if(r.is(".day")&&!r.is(".disabled")){var l=parseInt(r.text(),10)||1,f=this.viewDate.getUTCFullYear(),a=this.viewDate.getUTCMonth();r.is(".old")?a==0?(a=11,f-=1):a-=1:r.is(".new")&&(a==11?(a=0,f+=1):a+=1),this._setDate(t(f,a,l,0,0,0,0))}}},_setDate:function(e,t){if(!t||t=="date")this.date=e;if(!t||t=="view")this.viewDate=e;this.fill(),this.setValue(),this.element.trigger({type:"changeDate",date:this.date});var n;this.isInput?n=this.element:this.component&&(n=this.element.find("input")),n&&(n.change(),this.autoclose&&this.hide())},moveMonth:function(e,t){if(!t)return e;var n=new Date(e.valueOf()),r=n.getUTCDate(),i=n.getUTCMonth(),s=Math.abs(t),o,u;t=t>0?1:-1;if(s==1){u=t==-1?function(){return n.getUTCMonth()==i}:function(){return n.getUTCMonth()!=o},o=i+t,n.setUTCMonth(o);if(o<0||o>11)o=(o+12)%12}else{for(var a=0;a<s;a++)n=this.moveMonth(n,t);o=n.getUTCMonth(),n.setUTCDate(r),u=function(){return o!=n.getUTCMonth()}}while(u())n.setUTCDate(--r),n.setUTCMonth(o);return n},moveYear:function(e,t){return this.moveMonth(e,t*12)},dateWithinRange:function(e){return e>=this.startDate&&e<=this.endDate},keydown:function(e){if(this.picker.is(":not(:visible)")){e.keyCode==27&&this.show();return}var t=!1,n,r,i,s,o;switch(e.keyCode){case 27:this.hide(),e.preventDefault();break;case 37:case 39:if(!this.keyboardNavigation)break;n=e.keyCode==37?-1:1,e.ctrlKey?(s=this.moveYear(this.date,n),o=this.moveYear(this.viewDate,n)):e.shiftKey?(s=this.moveMonth(this.date,n),o=this.moveMonth(this.viewDate,n)):(s=new Date(this.date),s.setUTCDate(this.date.getUTCDate()+n),o=new Date(this.viewDate),o.setUTCDate(this.viewDate.getUTCDate()+n)),this.dateWithinRange(s)&&(this.date=s,this.viewDate=o,this.setValue(),this.update(),e.preventDefault(),t=!0);break;case 38:case 40:if(!this.keyboardNavigation)break;n=e.keyCode==38?-1:1,e.ctrlKey?(s=this.moveYear(this.date,n),o=this.moveYear(this.viewDate,n)):e.shiftKey?(s=this.moveMonth(this.date,n),o=this.moveMonth(this.viewDate,n)):(s=new Date(this.date),s.setUTCDate(this.date.getUTCDate()+n*7),o=new Date(this.viewDate),o.setUTCDate(this.viewDate.getUTCDate()+n*7)),this.dateWithinRange(s)&&(this.date=s,this.viewDate=o,this.setValue(),this.update(),e.preventDefault(),t=!0);break;case 13:this.hide(),e.preventDefault();break;case 9:this.hide()}if(t){this.element.trigger({type:"changeDate",date:this.date});var u;this.isInput?u=this.element:this.component&&(u=this.element.find("input")),u&&u.change()}},showMode:function(e){e&&(this.viewMode=Math.max(0,Math.min(2,this.viewMode+e))),this.picker.find(">div").hide().filter(".datepicker-"+s.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}},e.fn.datepicker=function(t){var n=Array.apply(null,arguments);return n.shift(),this.each(function(){var i=e(this),s=i.data("datepicker"),o=typeof t=="object"&&t;s||i.data("datepicker",s=new r(this,e.extend({},e.fn.datepicker.defaults,o))),typeof t=="string"&&typeof s[t]=="function"&&s[t].apply(s,n)})},e.fn.datepicker.defaults={},e.fn.datepicker.Constructor=r;var i=e.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today"}},s={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(e){return e%4===0&&e%100!==0||e%400===0},getDaysInMonth:function(e,t){return[31,s.isLeapYear(e)?29:28,31,30,31,30,31,31,30,31,30,31][t]},validParts:/dd?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[-`{-~\t\n\r]+/g,parseFormat:function(e){var t=e.replace(this.validParts,"\0").split("\0"),n=e.match(this.validParts);if(!t||!t.length||!n||n.length==0)throw new Error("Invalid date format.");return{separators:t,parts:n}},parseDate:function(n,s,o){if(n instanceof Date)return n;if(/^[-+]\d+[dmwy]([\s,]+[-+]\d+[dmwy])*$/.test(n)){var u=/([-+]\d+)([dmwy])/,a=n.match(/([-+]\d+)([dmwy])/g),f,l;n=new Date;for(var c=0;c<a.length;c++){f=u.exec(a[c]),l=parseInt(f[1]);switch(f[2]){case"d":n.setUTCDate(n.getUTCDate()+l);break;case"m":n=r.prototype.moveMonth.call(r.prototype,n,l);break;case"w":n.setUTCDate(n.getUTCDate()+l*7);break;case"y":n=r.prototype.moveYear.call(r.prototype,n,l)}}return t(n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate(),0,0,0)}var a=n&&n.match(this.nonpunctuation)||[],n=new Date,h={},p=["yyyy","yy","M","MM","m","mm","d","dd"],d={yyyy:function(e,t){return e.setUTCFullYear(t)},yy:function(e,t){return e.setUTCFullYear(2e3+t)},m:function(e,t){t-=1;while(t<0)t+=12;t%=12,e.setUTCMonth(t);while(e.getUTCMonth()!=t)e.setUTCDate(e.getUTCDate()-1);return e},d:function(e,t){return e.setUTCDate(t)}},v,m,f;d.M=d.MM=d.mm=d.m,d.dd=d.d,n=t(n.getFullYear(),n.getMonth(),n.getDate(),0,0,0);if(a.length==s.parts.length){for(var c=0,g=s.parts.length;c<g;c++){v=parseInt(a[c],10),f=s.parts[c];if(isNaN(v))switch(f){case"MM":m=e(i[o].months).filter(function(){var e=this.slice(0,a[c].length),t=a[c].slice(0,e.length);return e==t}),v=e.inArray(m[0],i[o].months)+1;break;case"M":m=e(i[o].monthsShort).filter(function(){var e=this.slice(0,a[c].length),t=a[c].slice(0,e.length);return e==t}),v=e.inArray(m[0],i[o].monthsShort)+1}h[f]=v}for(var c=0,y;c<p.length;c++)y=p[c],y in h&&d[y](n,h[y])}return n},formatDate:function(t,n,r){var s={d:t.getUTCDate(),m:t.getUTCMonth()+1,M:i[r].monthsShort[t.getUTCMonth()],MM:i[r].months[t.getUTCMonth()],yy:t.getUTCFullYear().toString().substring(2),yyyy:t.getUTCFullYear()};s.dd=(s.d<10?"0":"")+s.d,s.mm=(s.m<10?"0":"")+s.m;var t=[],o=e.extend([],n.separators);for(var u=0,a=n.parts.length;u<a;u++)o.length&&t.push(o.shift()),t.push(s[n.parts[u]]);return t.join("")},headTemplate:'<thead><tr><th class="prev"><i class="icon-arrow-left"/></th><th colspan="5" class="switch"></th><th class="next"><i class="icon-arrow-right"/></th></tr></thead>',contTemplate:'<tbody><tr><td colspan="7"></td></tr></tbody>',footTemplate:'<tfoot><tr><th colspan="7" class="today"></th></tr></tfoot>'};s.template='<div class="datepicker"><div class="datepicker-days"><table class=" table-condensed">'+s.headTemplate+"<tbody></tbody>"+s.footTemplate+"</table>"+"</div>"+'<div class="datepicker-months">'+'<table class="table-condensed">'+s.headTemplate+s.contTemplate+s.footTemplate+"</table>"+"</div>"+'<div class="datepicker-years">'+'<table class="table-condensed">'+s.headTemplate+s.contTemplate+s.footTemplate+"</table>"+"</div>"+"</div>",e.fn.datepicker.DPGlobal=s}(window.jQuery);
@@ -1,2892 +0,0 @@
1
- /*! X-editable - v1.3.0
2
- * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
3
- * http://github.com/vitalets/x-editable
4
- * Copyright (c) 2012 Vitaliy Potapov; Licensed MIT */
5
-
6
- /**
7
- Form with single input element, two buttons and two states: normal/loading.
8
- Applied as jQuery method to DIV tag (not to form tag!). This is because form can be in loading state when spinner shown.
9
- Editableform is linked with one of input types, e.g. 'text', 'select' etc.
10
-
11
- @class editableform
12
- @uses text
13
- @uses textarea
14
- **/
15
- (function ($) {
16
-
17
- var EditableForm = function (div, options) {
18
- this.options = $.extend({}, $.fn.editableform.defaults, options);
19
- this.$div = $(div); //div, containing form. Not form tag! Not editable-element.
20
- if(!this.options.scope) {
21
- this.options.scope = this;
22
- }
23
- this.initInput();
24
- };
25
-
26
- EditableForm.prototype = {
27
- constructor: EditableForm,
28
- initInput: function() { //called once
29
- var TypeConstructor, typeOptions;
30
-
31
- //create input of specified type
32
- if(typeof $.fn.editabletypes[this.options.type] === 'function') {
33
- TypeConstructor = $.fn.editabletypes[this.options.type];
34
- typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
35
- this.input = new TypeConstructor(typeOptions);
36
- } else {
37
- $.error('Unknown type: '+ this.options.type);
38
- return;
39
- }
40
-
41
- this.value = this.input.str2value(this.options.value);
42
- },
43
- initTemplate: function() {
44
- this.$form = $($.fn.editableform.template);
45
- },
46
- initButtons: function() {
47
- this.$form.find('.editable-buttons').append($.fn.editableform.buttons);
48
- },
49
- /**
50
- Renders editableform
51
-
52
- @method render
53
- **/
54
- render: function() {
55
- this.$loading = $($.fn.editableform.loading);
56
- this.$div.empty().append(this.$loading);
57
- this.showLoading();
58
-
59
- //init form template and buttons
60
- this.initTemplate();
61
- if(this.options.showbuttons) {
62
- this.initButtons();
63
- } else {
64
- this.$form.find('.editable-buttons').remove();
65
- }
66
-
67
- /**
68
- Fired when rendering starts
69
- @event rendering
70
- @param {Object} event event object
71
- **/
72
- this.$div.triggerHandler('rendering');
73
-
74
- //render input
75
- $.when(this.input.render())
76
- .then($.proxy(function () {
77
- //input
78
- this.$form.find('div.editable-input').append(this.input.$input);
79
-
80
- //automatically submit inputs when no buttons shown
81
- if(!this.options.showbuttons) {
82
- this.input.autosubmit();
83
- }
84
-
85
- //"clear" link
86
- if(this.input.$clear) {
87
- this.$form.find('div.editable-input').append($('<div class="editable-clear">').append(this.input.$clear));
88
- }
89
-
90
- //append form to container
91
- this.$div.append(this.$form);
92
-
93
- //attach 'cancel' handler
94
- this.$form.find('.editable-cancel').click($.proxy(this.cancel, this));
95
-
96
- if(this.input.error) {
97
- this.error(this.input.error);
98
- this.$form.find('.editable-submit').attr('disabled', true);
99
- this.input.$input.attr('disabled', true);
100
- //prevent form from submitting
101
- this.$form.submit(function(e){ e.preventDefault(); });
102
- } else {
103
- this.error(false);
104
- this.input.$input.removeAttr('disabled');
105
- this.$form.find('.editable-submit').removeAttr('disabled');
106
- this.input.value2input(this.value);
107
- //attach submit handler
108
- this.$form.submit($.proxy(this.submit, this));
109
- }
110
-
111
- /**
112
- Fired when form is rendered
113
- @event rendered
114
- @param {Object} event event object
115
- **/
116
- this.$div.triggerHandler('rendered');
117
-
118
- this.showForm();
119
- }, this));
120
- },
121
- cancel: function() {
122
- /**
123
- Fired when form was cancelled by user
124
- @event cancel
125
- @param {Object} event event object
126
- **/
127
- this.$div.triggerHandler('cancel');
128
- },
129
- showLoading: function() {
130
- var w;
131
- if(this.$form) {
132
- //set loading size equal to form
133
- this.$loading.width(this.$form.outerWidth());
134
- this.$loading.height(this.$form.outerHeight());
135
- this.$form.hide();
136
- } else {
137
- //stretch loading to fill container width
138
- w = this.$loading.parent().width();
139
- if(w) {
140
- this.$loading.width(w);
141
- }
142
- }
143
- this.$loading.show();
144
- },
145
-
146
- showForm: function(activate) {
147
- this.$loading.hide();
148
- this.$form.show();
149
- if(activate !== false) {
150
- this.input.activate();
151
- }
152
- /**
153
- Fired when form is shown
154
- @event show
155
- @param {Object} event event object
156
- **/
157
- this.$div.triggerHandler('show');
158
- },
159
-
160
- error: function(msg) {
161
- var $group = this.$form.find('.control-group'),
162
- $block = this.$form.find('.editable-error-block');
163
-
164
- if(msg === false) {
165
- $group.removeClass($.fn.editableform.errorGroupClass);
166
- $block.removeClass($.fn.editableform.errorBlockClass).empty().hide();
167
- } else {
168
- $group.addClass($.fn.editableform.errorGroupClass);
169
- $block.addClass($.fn.editableform.errorBlockClass).text(msg).show();
170
- }
171
- },
172
-
173
- submit: function(e) {
174
- e.stopPropagation();
175
- e.preventDefault();
176
-
177
- var error,
178
- newValue = this.input.input2value(); //get new value from input
179
-
180
- //validation
181
- if (error = this.validate(newValue)) {
182
- this.error(error);
183
- this.showForm();
184
- return;
185
- }
186
-
187
- //if value not changed --> trigger 'nochange' event and return
188
- /*jslint eqeq: true*/
189
- if (!this.options.savenochange && this.input.value2str(newValue) == this.input.value2str(this.value)) {
190
- /*jslint eqeq: false*/
191
- /**
192
- Fired when value not changed but form is submitted. Requires savenochange = false.
193
- @event nochange
194
- @param {Object} event event object
195
- **/
196
- this.$div.triggerHandler('nochange');
197
- return;
198
- }
199
-
200
- //sending data to server
201
- $.when(this.save(newValue))
202
- .done($.proxy(function(response) {
203
- //run success callback
204
- var res = typeof this.options.success === 'function' ? this.options.success.call(this.options.scope, response, newValue) : null;
205
-
206
- //if success callback returns false --> keep form open and do not activate input
207
- if(res === false) {
208
- this.error(false);
209
- this.showForm(false);
210
- return;
211
- }
212
-
213
- //if success callback returns string --> keep form open, show error and activate input
214
- if(typeof res === 'string') {
215
- this.error(res);
216
- this.showForm();
217
- return;
218
- }
219
-
220
- //if success callback returns object like {newValue: <something>} --> use that value instead of submitted
221
- if(res && typeof res === 'object' && res.hasOwnProperty('newValue')) {
222
- newValue = res.newValue;
223
- }
224
-
225
- //clear error message
226
- this.error(false);
227
- this.value = newValue;
228
- /**
229
- Fired when form is submitted
230
- @event save
231
- @param {Object} event event object
232
- @param {Object} params additional params
233
- @param {mixed} params.newValue submitted value
234
- @param {Object} params.response ajax response
235
-
236
- @example
237
- $('#form-div').on('save'), function(e, params){
238
- if(params.newValue === 'username') {...}
239
- });
240
- **/
241
- this.$div.triggerHandler('save', {newValue: newValue, response: response});
242
- }, this))
243
- .fail($.proxy(function(xhr) {
244
- this.error(typeof xhr === 'string' ? xhr : xhr.responseText || xhr.statusText || 'Unknown error!');
245
- this.showForm();
246
- }, this));
247
- },
248
-
249
- save: function(newValue) {
250
- //convert value for submitting to server
251
- var submitValue = this.input.value2submit(newValue);
252
-
253
- //try parse composite pk defined as json string in data-pk
254
- this.options.pk = $.fn.editableutils.tryParseJson(this.options.pk, true);
255
-
256
- var pk = (typeof this.options.pk === 'function') ? this.options.pk.call(this.options.scope) : this.options.pk,
257
- send = !!(typeof this.options.url === 'function' || (this.options.url && ((this.options.send === 'always') || (this.options.send === 'auto' && pk)))),
258
- params;
259
-
260
- if (send) { //send to server
261
- this.showLoading();
262
-
263
- //standard params
264
- params = {
265
- name: this.options.name || '',
266
- value: submitValue,
267
- pk: pk
268
- };
269
-
270
- //additional params
271
- if(typeof this.options.params === 'function') {
272
- params = this.options.params.call(this.options.scope, params);
273
- } else {
274
- //try parse json in single quotes (from data-params attribute)
275
- this.options.params = $.fn.editableutils.tryParseJson(this.options.params, true);
276
- $.extend(params, this.options.params);
277
- }
278
-
279
- if(typeof this.options.url === 'function') { //user's function
280
- return this.options.url.call(this.options.scope, params);
281
- } else {
282
- //send ajax to server and return deferred object
283
- return $.ajax($.extend({
284
- url : this.options.url,
285
- data : params,
286
- type : 'POST'
287
- }, this.options.ajaxOptions));
288
- }
289
- }
290
- },
291
-
292
- validate: function (value) {
293
- if (value === undefined) {
294
- value = this.value;
295
- }
296
- if (typeof this.options.validate === 'function') {
297
- return this.options.validate.call(this.options.scope, value);
298
- }
299
- },
300
-
301
- option: function(key, value) {
302
- this.options[key] = value;
303
- if(key === 'value') {
304
- this.setValue(value);
305
- }
306
- },
307
-
308
- setValue: function(value, convertStr) {
309
- if(convertStr) {
310
- this.value = this.input.str2value(value);
311
- } else {
312
- this.value = value;
313
- }
314
- }
315
- };
316
-
317
- /*
318
- Initialize editableform. Applied to jQuery object.
319
-
320
- @method $().editableform(options)
321
- @params {Object} options
322
- @example
323
- var $form = $('&lt;div&gt;').editableform({
324
- type: 'text',
325
- name: 'username',
326
- url: '/post',
327
- value: 'vitaliy'
328
- });
329
-
330
- //to display form you should call 'render' method
331
- $form.editableform('render');
332
- */
333
- $.fn.editableform = function (option) {
334
- var args = arguments;
335
- return this.each(function () {
336
- var $this = $(this),
337
- data = $this.data('editableform'),
338
- options = typeof option === 'object' && option;
339
- if (!data) {
340
- $this.data('editableform', (data = new EditableForm(this, options)));
341
- }
342
-
343
- if (typeof option === 'string') { //call method
344
- data[option].apply(data, Array.prototype.slice.call(args, 1));
345
- }
346
- });
347
- };
348
-
349
- //keep link to constructor to allow inheritance
350
- $.fn.editableform.Constructor = EditableForm;
351
-
352
- //defaults
353
- $.fn.editableform.defaults = {
354
- /* see also defaults for input */
355
-
356
- /**
357
- Type of input. Can be <code>text|textarea|select|date|checklist</code>
358
-
359
- @property type
360
- @type string
361
- @default 'text'
362
- **/
363
- type: 'text',
364
- /**
365
- Url for submit, e.g. <code>'/post'</code>
366
- If function - it will be called instead of ajax. Function can return deferred object to run fail/done callbacks.
367
-
368
- @property url
369
- @type string|function
370
- @default null
371
- @example
372
- url: function(params) {
373
- if(params.value === 'abc') {
374
- var d = new $.Deferred;
375
- return d.reject('field cannot be "abc"'); //returning error via deferred object
376
- } else {
377
- someModel.set(params.name, params.value); //save data in some js model
378
- }
379
- }
380
- **/
381
- url:null,
382
- /**
383
- Additional params for submit. If defined as <code>object</code> - it is **appended** to original ajax data (pk, name and value).
384
- If defined as <code>function</code> - returned object **overwrites** original ajax data.
385
- @example
386
- params: function(params) {
387
- //originally params contain pk, name and value
388
- params.a = 1;
389
- return params;
390
- }
391
-
392
- @property params
393
- @type object|function
394
- @default null
395
- **/
396
- params:null,
397
- /**
398
- Name of field. Will be submitted on server. Can be taken from <code>id</code> attribute
399
-
400
- @property name
401
- @type string
402
- @default null
403
- **/
404
- name: null,
405
- /**
406
- Primary key of editable object (e.g. record id in database). For composite keys use object, e.g. <code>{id: 1, lang: 'en'}</code>.
407
- Can be calculated dynamically via function.
408
-
409
- @property pk
410
- @type string|object|function
411
- @default null
412
- **/
413
- pk: null,
414
- /**
415
- Initial value. If not defined - will be taken from element's content.
416
- For __select__ type should be defined (as it is ID of shown text).
417
-
418
- @property value
419
- @type string|object
420
- @default null
421
- **/
422
- value: null,
423
- /**
424
- Strategy for sending data on server. Can be <code>auto|always|never</code>.
425
- When 'auto' data will be sent on server only if pk defined, otherwise new value will be stored in element.
426
-
427
- @property send
428
- @type string
429
- @default 'auto'
430
- **/
431
- send: 'auto',
432
- /**
433
- Function for client-side validation. If returns string - means validation not passed and string showed as error.
434
-
435
- @property validate
436
- @type function
437
- @default null
438
- @example
439
- validate: function(value) {
440
- if($.trim(value) == '') {
441
- return 'This field is required';
442
- }
443
- }
444
- **/
445
- validate: null,
446
- /**
447
- Success callback. Called when value successfully sent on server and **response status = 200**.
448
- Useful to work with json response. For example, if your backend response can be <code>{success: true}</code>
449
- or <code>{success: false, msg: "server error"}</code> you can check it inside this callback.
450
- If it returns **string** - means error occured and string is shown as error message.
451
- If it returns **object like** <code>{newValue: &lt;something&gt;}</code> - it overwrites value, submitted by user.
452
- Otherwise newValue simply rendered into element.
453
-
454
- @property success
455
- @type function
456
- @default null
457
- @example
458
- success: function(response, newValue) {
459
- if(!response.success) return response.msg;
460
- }
461
- **/
462
- success: null,
463
- /**
464
- Additional options for ajax request.
465
- List of values: http://api.jquery.com/jQuery.ajax
466
-
467
- @property ajaxOptions
468
- @type object
469
- @default null
470
- @since 1.1.1
471
- **/
472
- ajaxOptions: null,
473
- /**
474
- Whether to show buttons or not.
475
- Form without buttons can be auto-submitted by input or by onblur = 'submit'.
476
- @example
477
- ajaxOptions: {
478
- method: 'PUT',
479
- dataType: 'xml'
480
- }
481
-
482
- @property showbuttons
483
- @type boolean
484
- @default true
485
- @since 1.1.1
486
- **/
487
- showbuttons: true,
488
- /**
489
- Scope for callback methods (success, validate).
490
- If <code>null</code> means editableform instance itself.
491
-
492
- @property scope
493
- @type DOMElement|object
494
- @default null
495
- @since 1.2.0
496
- @private
497
- **/
498
- scope: null,
499
- /**
500
- Whether to save or cancel value when it was not changed but form was submitted
501
-
502
- @property savenochange
503
- @type boolean
504
- @default false
505
- @since 1.2.0
506
- **/
507
- savenochange: false
508
- };
509
-
510
- /*
511
- Note: following params could redefined in engine: bootstrap or jqueryui:
512
- Classes 'control-group' and 'editable-error-block' must always present!
513
- */
514
- $.fn.editableform.template = '<form class="form-inline editableform">'+
515
- '<div class="control-group">' +
516
- '<div><div class="editable-input"></div><div class="editable-buttons"></div></div>'+
517
- '<div class="editable-error-block"></div>' +
518
- '</div>' +
519
- '</form>';
520
-
521
- //loading div
522
- $.fn.editableform.loading = '<div class="editableform-loading"></div>';
523
-
524
- //buttons
525
- $.fn.editableform.buttons = '<button type="submit" class="editable-submit">ok</button>'+
526
- '<button type="button" class="editable-cancel">cancel</button>';
527
-
528
- //error class attached to control-group
529
- $.fn.editableform.errorGroupClass = null;
530
-
531
- //error class attached to editable-error-block
532
- $.fn.editableform.errorBlockClass = 'editable-error';
533
- }(window.jQuery));
534
- /**
535
- * EditableForm utilites
536
- */
537
- (function ($) {
538
- //utils
539
- $.fn.editableutils = {
540
- /**
541
- * classic JS inheritance function
542
- */
543
- inherit: function (Child, Parent) {
544
- var F = function() { };
545
- F.prototype = Parent.prototype;
546
- Child.prototype = new F();
547
- Child.prototype.constructor = Child;
548
- Child.superclass = Parent.prototype;
549
- },
550
-
551
- /**
552
- * set caret position in input
553
- * see http://stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area
554
- */
555
- setCursorPosition: function(elem, pos) {
556
- if (elem.setSelectionRange) {
557
- elem.setSelectionRange(pos, pos);
558
- } else if (elem.createTextRange) {
559
- var range = elem.createTextRange();
560
- range.collapse(true);
561
- range.moveEnd('character', pos);
562
- range.moveStart('character', pos);
563
- range.select();
564
- }
565
- },
566
-
567
- /**
568
- * function to parse JSON in *single* quotes. (jquery automatically parse only double quotes)
569
- * That allows such code as: <a data-source="{'a': 'b', 'c': 'd'}">
570
- * safe = true --> means no exception will be thrown
571
- * for details see http://stackoverflow.com/questions/7410348/how-to-set-json-format-to-html5-data-attributes-in-the-jquery
572
- */
573
- tryParseJson: function(s, safe) {
574
- if (typeof s === 'string' && s.length && s.match(/^[\{\[].*[\}\]]$/)) {
575
- if (safe) {
576
- try {
577
- /*jslint evil: true*/
578
- s = (new Function('return ' + s))();
579
- /*jslint evil: false*/
580
- } catch (e) {} finally {
581
- return s;
582
- }
583
- } else {
584
- /*jslint evil: true*/
585
- s = (new Function('return ' + s))();
586
- /*jslint evil: false*/
587
- }
588
- }
589
- return s;
590
- },
591
-
592
- /**
593
- * slice object by specified keys
594
- */
595
- sliceObj: function(obj, keys, caseSensitive /* default: false */) {
596
- var key, keyLower, newObj = {};
597
-
598
- if (!$.isArray(keys) || !keys.length) {
599
- return newObj;
600
- }
601
-
602
- for (var i = 0; i < keys.length; i++) {
603
- key = keys[i];
604
- if (obj.hasOwnProperty(key)) {
605
- newObj[key] = obj[key];
606
- }
607
-
608
- if(caseSensitive === true) {
609
- continue;
610
- }
611
-
612
- //when getting data-* attributes via $.data() it's converted to lowercase.
613
- //details: http://stackoverflow.com/questions/7602565/using-data-attributes-with-jquery
614
- //workaround is code below.
615
- keyLower = key.toLowerCase();
616
- if (obj.hasOwnProperty(keyLower)) {
617
- newObj[key] = obj[keyLower];
618
- }
619
- }
620
-
621
- return newObj;
622
- },
623
-
624
- /**
625
- * exclude complex objects from $.data() before pass to config
626
- */
627
- getConfigData: function($element) {
628
- var data = {};
629
- $.each($element.data(), function(k, v) {
630
- if(typeof v !== 'object' || (v && typeof v === 'object' && v.constructor === Object)) {
631
- data[k] = v;
632
- }
633
- });
634
- return data;
635
- },
636
-
637
- objectKeys: function(o) {
638
- if (Object.keys) {
639
- return Object.keys(o);
640
- } else {
641
- if (o !== Object(o)) {
642
- throw new TypeError('Object.keys called on a non-object');
643
- }
644
- var k=[], p;
645
- for (p in o) {
646
- if (Object.prototype.hasOwnProperty.call(o,p)) {
647
- k.push(p);
648
- }
649
- }
650
- return k;
651
- }
652
-
653
- },
654
-
655
- /**
656
- method to escape html.
657
- **/
658
- escape: function(str) {
659
- return $('<div>').text(str).html();
660
- }
661
- };
662
- }(window.jQuery));
663
- /**
664
- Attaches stand-alone container with editable-form to HTML element. Element is used only for positioning, value is not stored anywhere.<br>
665
- This method applied internally in <code>$().editable()</code>. You should subscribe on it's events (save / cancel) to get profit of it.<br>
666
- Final realization can be different: bootstrap-popover, jqueryui-tooltip, poshytip, inline-div. It depends on which js file you include.<br>
667
- Applied as jQuery method.
668
-
669
- @class editableContainer
670
- @uses editableform
671
- **/
672
- (function ($) {
673
-
674
- var EditableContainer = function (element, options) {
675
- this.init(element, options);
676
- };
677
-
678
- //methods
679
- EditableContainer.prototype = {
680
- containerName: null, //tbd in child class
681
- innerCss: null, //tbd in child class
682
- init: function(element, options) {
683
- this.$element = $(element);
684
- //todo: what is in priority: data or js?
685
- this.options = $.extend({}, $.fn.editableContainer.defaults, $.fn.editableutils.getConfigData(this.$element), options);
686
- this.splitOptions();
687
- this.initContainer();
688
-
689
- //bind 'destroyed' listener to destroy container when element is removed from dom
690
- this.$element.on('destroyed', $.proxy(function(){
691
- this.destroy();
692
- }, this));
693
-
694
- //attach document handlers (once)
695
- if(!$(document).data('editable-handlers-attached')) {
696
- //close all on escape
697
- $(document).on('keyup.editable', function (e) {
698
- if (e.which === 27) {
699
- $('.editable-open').editableContainer('hide');
700
- //todo: return focus on element
701
- }
702
- });
703
-
704
- //close containers when click outside
705
- $(document).on('click.editable', function(e) {
706
- var $target = $(e.target);
707
-
708
- //if click inside some editableContainer --> no nothing
709
- if($target.is('.editable-container') || $target.parents('.editable-container').length || $target.parents('.ui-datepicker-header').length) {
710
- return;
711
- } else {
712
- //close all open containers (except one)
713
- EditableContainer.prototype.closeOthers(e.target);
714
- }
715
- });
716
-
717
- $(document).data('editable-handlers-attached', true);
718
- }
719
- },
720
-
721
- //split options on containerOptions and formOptions
722
- splitOptions: function() {
723
- this.containerOptions = {};
724
- this.formOptions = {};
725
- var cDef = $.fn[this.containerName].defaults;
726
- for(var k in this.options) {
727
- if(k in cDef) {
728
- this.containerOptions[k] = this.options[k];
729
- } else {
730
- this.formOptions[k] = this.options[k];
731
- }
732
- }
733
- },
734
-
735
- initContainer: function(){
736
- this.call(this.containerOptions);
737
- },
738
-
739
- initForm: function() {
740
- this.formOptions.scope = this.$element[0]; //set scope of form callbacks to element
741
- this.$form = $('<div>')
742
- .editableform(this.formOptions)
743
- .on({
744
- save: $.proxy(this.save, this),
745
- cancel: $.proxy(function(){ this.hide('cancel'); }, this),
746
- nochange: $.proxy(function(){ this.hide('nochange'); }, this),
747
- show: $.proxy(this.setPosition, this), //re-position container every time form is shown (occurs each time after loading state)
748
- rendering: $.proxy(this.setPosition, this), //this allows to place container correctly when loading shown
749
- rendered: $.proxy(function(){
750
- /**
751
- Fired when container is shown and form is rendered (for select will wait for loading dropdown options)
752
-
753
- @event shown
754
- @param {Object} event event object
755
- @example
756
- $('#username').on('shown', function() {
757
- var $tip = $(this).data('editableContainer').tip();
758
- $tip.find('input').val('overwriting value of input..');
759
- });
760
- **/
761
- this.$element.triggerHandler('shown');
762
- }, this)
763
- });
764
- return this.$form;
765
- },
766
-
767
- /*
768
- Returns jquery object of container
769
- @method tip()
770
- */
771
- tip: function() {
772
- return this.container().$tip;
773
- },
774
-
775
- container: function() {
776
- return this.$element.data(this.containerName);
777
- },
778
-
779
- call: function() {
780
- this.$element[this.containerName].apply(this.$element, arguments);
781
- },
782
-
783
- /**
784
- Shows container with form
785
- @method show()
786
- @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
787
- **/
788
- show: function (closeAll) {
789
- this.$element.addClass('editable-open');
790
- if(closeAll !== false) {
791
- //close all open containers (except this)
792
- this.closeOthers(this.$element[0]);
793
- }
794
-
795
- this.innerShow();
796
- },
797
-
798
- /* internal show method. To be overwritten in child classes */
799
- innerShow: function () {
800
- this.call('show');
801
- this.tip().addClass('editable-container');
802
- this.initForm();
803
- this.tip().find(this.innerCss).empty().append(this.$form);
804
- this.$form.editableform('render');
805
- },
806
-
807
- /**
808
- Hides container with form
809
- @method hide()
810
- @param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|nochange|undefined (=manual)</code>
811
- **/
812
- hide: function(reason) {
813
- if(!this.tip() || !this.tip().is(':visible') || !this.$element.hasClass('editable-open')) {
814
- return;
815
- }
816
- this.$element.removeClass('editable-open');
817
- this.innerHide();
818
- /**
819
- Fired when container was hidden. It occurs on both save or cancel.
820
-
821
- @event hidden
822
- @param {object} event event object
823
- @param {string} reason Reason caused hiding. Can be <code>save|cancel|onblur|nochange|undefined (=manual)</code>
824
- @example
825
- $('#username').on('hidden', function(e, reason) {
826
- if(reason === 'save' || reason === 'cancel') {
827
- //auto-open next editable
828
- $(this).closest('tr').next().find('.editable').editable('show');
829
- }
830
- });
831
- **/
832
- this.$element.triggerHandler('hidden', reason);
833
- },
834
-
835
- /* internal hide method. To be overwritten in child classes */
836
- innerHide: function () {
837
- this.call('hide');
838
- },
839
-
840
- /**
841
- Toggles container visibility (show / hide)
842
- @method toggle()
843
- @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
844
- **/
845
- toggle: function(closeAll) {
846
- if(this.tip && this.tip().is(':visible')) {
847
- this.hide();
848
- } else {
849
- this.show(closeAll);
850
- }
851
- },
852
-
853
- /*
854
- Updates the position of container when content changed.
855
- @method setPosition()
856
- */
857
- setPosition: function() {
858
- //tbd in child class
859
- },
860
-
861
- save: function(e, params) {
862
- this.hide('save');
863
- /**
864
- Fired when new value was submitted. You can use <code>$(this).data('editableContainer')</code> inside handler to access to editableContainer instance
865
-
866
- @event save
867
- @param {Object} event event object
868
- @param {Object} params additional params
869
- @param {mixed} params.newValue submitted value
870
- @param {Object} params.response ajax response
871
- @example
872
- $('#username').on('save', function(e, params) {
873
- //assuming server response: '{success: true}'
874
- var pk = $(this).data('editableContainer').options.pk;
875
- if(params.response && params.response.success) {
876
- alert('value: ' + params.newValue + ' with pk: ' + pk + ' saved!');
877
- } else {
878
- alert('error!');
879
- }
880
- });
881
- **/
882
- this.$element.triggerHandler('save', params);
883
- },
884
-
885
- /**
886
- Sets new option
887
-
888
- @method option(key, value)
889
- @param {string} key
890
- @param {mixed} value
891
- **/
892
- option: function(key, value) {
893
- this.options[key] = value;
894
- if(key in this.containerOptions) {
895
- this.containerOptions[key] = value;
896
- this.setContainerOption(key, value);
897
- } else {
898
- this.formOptions[key] = value;
899
- if(this.$form) {
900
- this.$form.editableform('option', key, value);
901
- }
902
- }
903
- },
904
-
905
- setContainerOption: function(key, value) {
906
- this.call('option', key, value);
907
- },
908
-
909
- /**
910
- Destroys the container instance
911
- @method destroy()
912
- **/
913
- destroy: function() {
914
- this.call('destroy');
915
- },
916
-
917
- /*
918
- Closes other containers except one related to passed element.
919
- Other containers can be cancelled or submitted (depends on onblur option)
920
- */
921
- closeOthers: function(element) {
922
- $('.editable-open').each(function(i, el){
923
- //do nothing with passed element and it's children
924
- if(el === element || $(el).find(element).length) {
925
- return;
926
- }
927
-
928
- //otherwise cancel or submit all open containers
929
- var $el = $(el),
930
- ec = $el.data('editableContainer');
931
-
932
- if(!ec) {
933
- return;
934
- }
935
-
936
- if(ec.options.onblur === 'cancel') {
937
- $el.data('editableContainer').hide('onblur');
938
- } else if(ec.options.onblur === 'submit') {
939
- $el.data('editableContainer').tip().find('form').submit();
940
- }
941
- });
942
-
943
- },
944
-
945
- /**
946
- Activates input of visible container (e.g. set focus)
947
- @method activate()
948
- **/
949
- activate: function() {
950
- if(this.tip && this.tip().is(':visible') && this.$form) {
951
- this.$form.data('editableform').input.activate();
952
- }
953
- }
954
-
955
- };
956
-
957
- /**
958
- jQuery method to initialize editableContainer.
959
-
960
- @method $().editableContainer(options)
961
- @params {Object} options
962
- @example
963
- $('#edit').editableContainer({
964
- type: 'text',
965
- url: '/post',
966
- pk: 1,
967
- value: 'hello'
968
- });
969
- **/
970
- $.fn.editableContainer = function (option) {
971
- var args = arguments;
972
- return this.each(function () {
973
- var $this = $(this),
974
- dataKey = 'editableContainer',
975
- data = $this.data(dataKey),
976
- options = typeof option === 'object' && option;
977
-
978
- if (!data) {
979
- $this.data(dataKey, (data = new EditableContainer(this, options)));
980
- }
981
-
982
- if (typeof option === 'string') { //call method
983
- data[option].apply(data, Array.prototype.slice.call(args, 1));
984
- }
985
- });
986
- };
987
-
988
- //store constructor
989
- $.fn.editableContainer.Constructor = EditableContainer;
990
-
991
- //defaults
992
- $.fn.editableContainer.defaults = {
993
- /**
994
- Initial value of form input
995
-
996
- @property value
997
- @type mixed
998
- @default null
999
- @private
1000
- **/
1001
- value: null,
1002
- /**
1003
- Placement of container relative to element. Can be <code>top|right|bottom|left</code>. Not used for inline container.
1004
-
1005
- @property placement
1006
- @type string
1007
- @default 'top'
1008
- **/
1009
- placement: 'top',
1010
- /**
1011
- Whether to hide container on save/cancel.
1012
-
1013
- @property autohide
1014
- @type boolean
1015
- @default true
1016
- @private
1017
- **/
1018
- autohide: true,
1019
- /**
1020
- Action when user clicks outside the container. Can be <code>cancel|submit|ignore</code>.
1021
- Setting <code>ignore</code> allows to have several containers open.
1022
-
1023
- @property onblur
1024
- @type string
1025
- @default 'cancel'
1026
- @since 1.1.1
1027
- **/
1028
- onblur: 'cancel'
1029
- };
1030
-
1031
- /*
1032
- * workaround to have 'destroyed' event to destroy popover when element is destroyed
1033
- * see http://stackoverflow.com/questions/2200494/jquery-trigger-event-when-an-element-is-removed-from-the-dom
1034
- */
1035
- jQuery.event.special.destroyed = {
1036
- remove: function(o) {
1037
- if (o.handler) {
1038
- o.handler();
1039
- }
1040
- }
1041
- };
1042
-
1043
- }(window.jQuery));
1044
-
1045
- /**
1046
- Makes editable any HTML element on the page. Applied as jQuery method.
1047
-
1048
- @class editable
1049
- @uses editableContainer
1050
- **/
1051
- (function ($) {
1052
-
1053
- var Editable = function (element, options) {
1054
- this.$element = $(element);
1055
- this.options = $.extend({}, $.fn.editable.defaults, $.fn.editableutils.getConfigData(this.$element), options);
1056
- this.init();
1057
- };
1058
-
1059
- Editable.prototype = {
1060
- constructor: Editable,
1061
- init: function () {
1062
- var TypeConstructor,
1063
- isValueByText = false,
1064
- doAutotext,
1065
- finalize;
1066
-
1067
- //editableContainer must be defined
1068
- if(!$.fn.editableContainer) {
1069
- $.error('You must define $.fn.editableContainer via including corresponding file (e.g. editable-popover.js)');
1070
- return;
1071
- }
1072
-
1073
- //name
1074
- this.options.name = this.options.name || this.$element.attr('id');
1075
-
1076
- //create input of specified type. Input will be used for converting value, not in form
1077
- if(typeof $.fn.editabletypes[this.options.type] === 'function') {
1078
- TypeConstructor = $.fn.editabletypes[this.options.type];
1079
- this.typeOptions = $.fn.editableutils.sliceObj(this.options, $.fn.editableutils.objectKeys(TypeConstructor.defaults));
1080
- this.input = new TypeConstructor(this.typeOptions);
1081
- } else {
1082
- $.error('Unknown type: '+ this.options.type);
1083
- return;
1084
- }
1085
-
1086
- //set value from settings or by element's text
1087
- if (this.options.value === undefined || this.options.value === null) {
1088
- this.value = this.input.html2value($.trim(this.$element.html()));
1089
- isValueByText = true;
1090
- } else {
1091
- /*
1092
- value can be string when received from 'data-value' attribute
1093
- for complext objects value can be set as json string in data-value attribute,
1094
- e.g. data-value="{city: 'Moscow', street: 'Lenina'}"
1095
- */
1096
- this.options.value = $.fn.editableutils.tryParseJson(this.options.value, true);
1097
- if(typeof this.options.value === 'string') {
1098
- this.value = this.input.str2value(this.options.value);
1099
- } else {
1100
- this.value = this.options.value;
1101
- }
1102
- }
1103
-
1104
- //add 'editable' class to every editable element
1105
- this.$element.addClass('editable');
1106
-
1107
- //attach handler activating editable. In disabled mode it just prevent default action (useful for links)
1108
- if(this.options.toggle !== 'manual') {
1109
- this.$element.addClass('editable-click');
1110
- this.$element.on(this.options.toggle + '.editable', $.proxy(function(e){
1111
- e.preventDefault();
1112
- //stop propagation not required anymore because in document click handler it checks event target
1113
- //e.stopPropagation();
1114
-
1115
- if(this.options.toggle === 'mouseenter') {
1116
- //for hover only show container
1117
- this.show();
1118
- } else {
1119
- //when toggle='click' we should not close all other containers as they will be closed automatically in document click listener
1120
- var closeAll = (this.options.toggle !== 'click');
1121
- this.toggle(closeAll);
1122
- }
1123
- }, this));
1124
- } else {
1125
- this.$element.attr('tabindex', -1); //do not stop focus on element when toggled manually
1126
- }
1127
-
1128
- //check conditions for autotext:
1129
- //if value was generated by text or value is empty, no sense to run autotext
1130
- doAutotext = !isValueByText && this.value !== null && this.value !== undefined;
1131
- doAutotext &= (this.options.autotext === 'always') || (this.options.autotext === 'auto' && !this.$element.text().length);
1132
- $.when(doAutotext ? this.render() : true).then($.proxy(function() {
1133
- if(this.options.disabled) {
1134
- this.disable();
1135
- } else {
1136
- this.enable();
1137
- }
1138
- /**
1139
- Fired when element was initialized by editable method.
1140
-
1141
- @event init
1142
- @param {Object} event event object
1143
- @param {Object} editable editable instance
1144
- @since 1.2.0
1145
- **/
1146
- this.$element.triggerHandler('init', this);
1147
- }, this));
1148
- },
1149
-
1150
- /*
1151
- Renders value into element's text.
1152
- Can call custom display method from options.
1153
- Can return deferred object.
1154
- @method render()
1155
- */
1156
- render: function() {
1157
- //do not display anything
1158
- if(this.options.display === false) {
1159
- return;
1160
- }
1161
- //if it is input with source, we pass callback in third param to be called when source is loaded
1162
- if(this.input.options.hasOwnProperty('source')) {
1163
- return this.input.value2html(this.value, this.$element[0], this.options.display);
1164
- //if display method defined --> use it
1165
- } else if(typeof this.options.display === 'function') {
1166
- return this.options.display.call(this.$element[0], this.value);
1167
- //else use input's original value2html() method
1168
- } else {
1169
- return this.input.value2html(this.value, this.$element[0]);
1170
- }
1171
- },
1172
-
1173
- /**
1174
- Enables editable
1175
- @method enable()
1176
- **/
1177
- enable: function() {
1178
- this.options.disabled = false;
1179
- this.$element.removeClass('editable-disabled');
1180
- this.handleEmpty();
1181
- if(this.options.toggle !== 'manual') {
1182
- if(this.$element.attr('tabindex') === '-1') {
1183
- this.$element.removeAttr('tabindex');
1184
- }
1185
- }
1186
- },
1187
-
1188
- /**
1189
- Disables editable
1190
- @method disable()
1191
- **/
1192
- disable: function() {
1193
- this.options.disabled = true;
1194
- this.hide();
1195
- this.$element.addClass('editable-disabled');
1196
- this.handleEmpty();
1197
- //do not stop focus on this element
1198
- this.$element.attr('tabindex', -1);
1199
- },
1200
-
1201
- /**
1202
- Toggles enabled / disabled state of editable element
1203
- @method toggleDisabled()
1204
- **/
1205
- toggleDisabled: function() {
1206
- if(this.options.disabled) {
1207
- this.enable();
1208
- } else {
1209
- this.disable();
1210
- }
1211
- },
1212
-
1213
- /**
1214
- Sets new option
1215
-
1216
- @method option(key, value)
1217
- @param {string|object} key option name or object with several options
1218
- @param {mixed} value option new value
1219
- @example
1220
- $('.editable').editable('option', 'pk', 2);
1221
- **/
1222
- option: function(key, value) {
1223
- //set option(s) by object
1224
- if(key && typeof key === 'object') {
1225
- $.each(key, $.proxy(function(k, v){
1226
- this.option($.trim(k), v);
1227
- }, this));
1228
- return;
1229
- }
1230
-
1231
- //set option by string
1232
- this.options[key] = value;
1233
-
1234
- //disabled
1235
- if(key === 'disabled') {
1236
- if(value) {
1237
- this.disable();
1238
- } else {
1239
- this.enable();
1240
- }
1241
- return;
1242
- }
1243
-
1244
- //value
1245
- if(key === 'value') {
1246
- this.setValue(value);
1247
- }
1248
-
1249
- //transfer new option to container!
1250
- if(this.container) {
1251
- this.container.option(key, value);
1252
- }
1253
- },
1254
-
1255
- /*
1256
- * set emptytext if element is empty (reverse: remove emptytext if needed)
1257
- */
1258
- handleEmpty: function () {
1259
- //do not handle empty if we do not display anything
1260
- if(this.options.display === false) {
1261
- return;
1262
- }
1263
-
1264
- var emptyClass = 'editable-empty';
1265
- //emptytext shown only for enabled
1266
- if(!this.options.disabled) {
1267
- if ($.trim(this.$element.text()) === '') {
1268
- this.$element.addClass(emptyClass).text(this.options.emptytext);
1269
- } else {
1270
- this.$element.removeClass(emptyClass);
1271
- }
1272
- } else {
1273
- //below required if element disable property was changed
1274
- if(this.$element.hasClass(emptyClass)) {
1275
- this.$element.empty();
1276
- this.$element.removeClass(emptyClass);
1277
- }
1278
- }
1279
- },
1280
-
1281
- /**
1282
- Shows container with form
1283
- @method show()
1284
- @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
1285
- **/
1286
- show: function (closeAll) {
1287
- if(this.options.disabled) {
1288
- return;
1289
- }
1290
-
1291
- //init editableContainer: popover, tooltip, inline, etc..
1292
- if(!this.container) {
1293
- var containerOptions = $.extend({}, this.options, {
1294
- value: this.value
1295
- });
1296
- this.$element.editableContainer(containerOptions);
1297
- this.$element.on("save.internal", $.proxy(this.save, this));
1298
- this.container = this.$element.data('editableContainer');
1299
- } else if(this.container.tip().is(':visible')) {
1300
- return;
1301
- }
1302
-
1303
- //show container
1304
- this.container.show(closeAll);
1305
- },
1306
-
1307
- /**
1308
- Hides container with form
1309
- @method hide()
1310
- **/
1311
- hide: function () {
1312
- if(this.container) {
1313
- this.container.hide();
1314
- }
1315
- },
1316
-
1317
- /**
1318
- Toggles container visibility (show / hide)
1319
- @method toggle()
1320
- @param {boolean} closeAll Whether to close all other editable containers when showing this one. Default true.
1321
- **/
1322
- toggle: function(closeAll) {
1323
- if(this.container && this.container.tip().is(':visible')) {
1324
- this.hide();
1325
- } else {
1326
- this.show(closeAll);
1327
- }
1328
- },
1329
-
1330
- /*
1331
- * called when form was submitted
1332
- */
1333
- save: function(e, params) {
1334
- //if url is not user's function and value was not sent to server and value changed --> mark element with unsaved css.
1335
- if(typeof this.options.url !== 'function' && this.options.display !== false && params.response === undefined && this.input.value2str(this.value) !== this.input.value2str(params.newValue)) {
1336
- this.$element.addClass('editable-unsaved');
1337
- } else {
1338
- this.$element.removeClass('editable-unsaved');
1339
- }
1340
-
1341
- // this.hide();
1342
- this.setValue(params.newValue);
1343
-
1344
- /**
1345
- Fired when new value was submitted. You can use <code>$(this).data('editable')</code> to access to editable instance
1346
-
1347
- @event save
1348
- @param {Object} event event object
1349
- @param {Object} params additional params
1350
- @param {mixed} params.newValue submitted value
1351
- @param {Object} params.response ajax response
1352
- @example
1353
- $('#username').on('save', function(e, params) {
1354
- //assuming server response: '{success: true}'
1355
- var pk = $(this).data('editable').options.pk;
1356
- if(params.response && params.response.success) {
1357
- alert('value: ' + params.newValue + ' with pk: ' + pk + ' saved!');
1358
- } else {
1359
- alert('error!');
1360
- }
1361
- });
1362
- **/
1363
- //event itself is triggered by editableContainer. Description here is only for documentation
1364
- },
1365
-
1366
- validate: function () {
1367
- if (typeof this.options.validate === 'function') {
1368
- return this.options.validate.call(this, this.value);
1369
- }
1370
- },
1371
-
1372
- /**
1373
- Sets new value of editable
1374
- @method setValue(value, convertStr)
1375
- @param {mixed} value new value
1376
- @param {boolean} convertStr whether to convert value from string to internal format
1377
- **/
1378
- setValue: function(value, convertStr) {
1379
- if(convertStr) {
1380
- this.value = this.input.str2value(value);
1381
- } else {
1382
- this.value = value;
1383
- }
1384
- if(this.container) {
1385
- this.container.option('value', this.value);
1386
- }
1387
- $.when(this.render())
1388
- .then($.proxy(function() {
1389
- this.handleEmpty();
1390
- }, this));
1391
- },
1392
-
1393
- /**
1394
- Activates input of visible container (e.g. set focus)
1395
- @method activate()
1396
- **/
1397
- activate: function() {
1398
- if(this.container) {
1399
- this.container.activate();
1400
- }
1401
- }
1402
- };
1403
-
1404
- /* EDITABLE PLUGIN DEFINITION
1405
- * ======================= */
1406
-
1407
- /**
1408
- jQuery method to initialize editable element.
1409
-
1410
- @method $().editable(options)
1411
- @params {Object} options
1412
- @example
1413
- $('#username').editable({
1414
- type: 'text',
1415
- url: '/post',
1416
- pk: 1
1417
- });
1418
- **/
1419
- $.fn.editable = function (option) {
1420
- //special API methods returning non-jquery object
1421
- var result = {}, args = arguments, datakey = 'editable';
1422
- switch (option) {
1423
- /**
1424
- Runs client-side validation for all matched editables
1425
-
1426
- @method validate()
1427
- @returns {Object} validation errors map
1428
- @example
1429
- $('#username, #fullname').editable('validate');
1430
- // possible result:
1431
- {
1432
- username: "username is required",
1433
- fullname: "fullname should be minimum 3 letters length"
1434
- }
1435
- **/
1436
- case 'validate':
1437
- this.each(function () {
1438
- var $this = $(this), data = $this.data(datakey), error;
1439
- if (data && (error = data.validate())) {
1440
- result[data.options.name] = error;
1441
- }
1442
- });
1443
- return result;
1444
-
1445
- /**
1446
- Returns current values of editable elements. If value is <code>null</code> or <code>undefined</code> it will not be returned
1447
- @method getValue()
1448
- @returns {Object} object of element names and values
1449
- @example
1450
- $('#username, #fullname').editable('validate');
1451
- // possible result:
1452
- {
1453
- username: "superuser",
1454
- fullname: "John"
1455
- }
1456
- **/
1457
- case 'getValue':
1458
- this.each(function () {
1459
- var $this = $(this), data = $this.data(datakey);
1460
- if (data && data.value !== undefined && data.value !== null) {
1461
- result[data.options.name] = data.input.value2submit(data.value);
1462
- }
1463
- });
1464
- return result;
1465
-
1466
- /**
1467
- This method collects values from several editable elements and submit them all to server.
1468
- Internally it runs client-side validation for all fields and submits only in case of success.
1469
- See <a href="#newrecord">creating new records</a> for details.
1470
-
1471
- @method submit(options)
1472
- @param {object} options
1473
- @param {object} options.url url to submit data
1474
- @param {object} options.data additional data to submit
1475
- @param {object} options.ajaxOptions additional ajax options
1476
- @param {function} options.error(obj) error handler
1477
- @param {function} options.success(obj,config) success handler
1478
- @returns {Object} jQuery object
1479
- **/
1480
- case 'submit': //collects value, validate and submit to server for creating new record
1481
- var config = arguments[1] || {},
1482
- $elems = this,
1483
- errors = this.editable('validate'),
1484
- values;
1485
-
1486
- if($.isEmptyObject(errors)) {
1487
- values = this.editable('getValue');
1488
- if(config.data) {
1489
- $.extend(values, config.data);
1490
- }
1491
-
1492
- $.ajax($.extend({
1493
- url: config.url,
1494
- data: values,
1495
- type: 'POST'
1496
- }, config.ajaxOptions))
1497
- .success(function(response) {
1498
- //successful response 200 OK
1499
- if(typeof config.success === 'function') {
1500
- config.success.call($elems, response, config);
1501
- }
1502
- })
1503
- .error(function(){ //ajax error
1504
- if(typeof config.error === 'function') {
1505
- config.error.apply($elems, arguments);
1506
- }
1507
- });
1508
- } else { //client-side validation error
1509
- if(typeof config.error === 'function') {
1510
- config.error.call($elems, errors);
1511
- }
1512
- }
1513
- return this;
1514
- }
1515
-
1516
- //return jquery object
1517
- return this.each(function () {
1518
- var $this = $(this),
1519
- data = $this.data(datakey),
1520
- options = typeof option === 'object' && option;
1521
-
1522
- if (!data) {
1523
- $this.data(datakey, (data = new Editable(this, options)));
1524
- }
1525
-
1526
- if (typeof option === 'string') { //call method
1527
- data[option].apply(data, Array.prototype.slice.call(args, 1));
1528
- }
1529
- });
1530
- };
1531
-
1532
-
1533
- $.fn.editable.defaults = {
1534
- /**
1535
- Type of input. Can be <code>text|textarea|select|date|checklist</code> and more
1536
-
1537
- @property type
1538
- @type string
1539
- @default 'text'
1540
- **/
1541
- type: 'text',
1542
- /**
1543
- Sets disabled state of editable
1544
-
1545
- @property disabled
1546
- @type boolean
1547
- @default false
1548
- **/
1549
- disabled: false,
1550
- /**
1551
- How to toggle editable. Can be <code>click|dblclick|mouseenter|manual</code>.
1552
- When set to <code>manual</code> you should manually call <code>show/hide</code> methods of editable.
1553
- **Note**: if you call <code>show</code> or <code>toggle</code> inside **click** handler of some DOM element,
1554
- you need to apply <code>e.stopPropagation()</code> because containers are being closed on any click on document.
1555
-
1556
- @example
1557
- $('#edit-button').click(function(e) {
1558
- e.stopPropagation();
1559
- $('#username').editable('toggle');
1560
- });
1561
-
1562
- @property toggle
1563
- @type string
1564
- @default 'click'
1565
- **/
1566
- toggle: 'click',
1567
- /**
1568
- Text shown when element is empty.
1569
-
1570
- @property emptytext
1571
- @type string
1572
- @default 'Empty'
1573
- **/
1574
- emptytext: 'Empty',
1575
- /**
1576
- Allows to automatically set element's text based on it's value. Can be <code>auto|always|never</code>. Useful for select and date.
1577
- For example, if dropdown list is <code>{1: 'a', 2: 'b'}</code> and element's value set to <code>1</code>, it's html will be automatically set to <code>'a'</code>.
1578
- <code>auto</code> - text will be automatically set only if element is empty.
1579
- <code>always|never</code> - always(never) try to set element's text.
1580
-
1581
- @property autotext
1582
- @type string
1583
- @default 'auto'
1584
- **/
1585
- autotext: 'auto',
1586
- /**
1587
- Initial value of input. Taken from <code>data-value</code> or element's text.
1588
-
1589
- @property value
1590
- @type mixed
1591
- @default element's text
1592
- **/
1593
- value: null,
1594
- /**
1595
- Callback to perform custom displaying of value in element's text.
1596
- If <code>null</code>, default input's value2html() will be called.
1597
- If <code>false</code>, no displaying methods will be called, element's text will no change.
1598
- Runs under element's scope.
1599
- Second parameter __sourceData__ is passed for inputs with source (select, checklist).
1600
-
1601
- @property display
1602
- @type function|boolean
1603
- @default null
1604
- @since 1.2.0
1605
- @example
1606
- display: function(value, sourceData) {
1607
- var escapedValue = $('<div>').text(value).html();
1608
- $(this).html('<b>'+escapedValue+'</b>');
1609
- }
1610
- **/
1611
- display: null
1612
- };
1613
-
1614
- }(window.jQuery));
1615
-
1616
- /**
1617
- AbstractInput - base class for all editable inputs.
1618
- It defines interface to be implemented by any input type.
1619
- To create your own input you can inherit from this class.
1620
-
1621
- @class abstractinput
1622
- **/
1623
- (function ($) {
1624
-
1625
- //types
1626
- $.fn.editabletypes = {};
1627
-
1628
- var AbstractInput = function () { };
1629
-
1630
- AbstractInput.prototype = {
1631
- /**
1632
- Initializes input
1633
-
1634
- @method init()
1635
- **/
1636
- init: function(type, options, defaults) {
1637
- this.type = type;
1638
- this.options = $.extend({}, defaults, options);
1639
- this.$input = null;
1640
- this.$clear = null;
1641
- this.error = null;
1642
- },
1643
-
1644
- /**
1645
- Renders input from tpl. Can return jQuery deferred object.
1646
-
1647
- @method render()
1648
- **/
1649
- render: function() {
1650
- this.$input = $(this.options.tpl);
1651
- if(this.options.inputclass) {
1652
- this.$input.addClass(this.options.inputclass);
1653
- }
1654
-
1655
- if (this.options.placeholder) {
1656
- this.$input.attr('placeholder', this.options.placeholder);
1657
- }
1658
- },
1659
-
1660
- /**
1661
- Sets element's html by value.
1662
-
1663
- @method value2html(value, element)
1664
- @param {mixed} value
1665
- @param {DOMElement} element
1666
- **/
1667
- value2html: function(value, element) {
1668
- $(element).text(value);
1669
- },
1670
-
1671
- /**
1672
- Converts element's html to value
1673
-
1674
- @method html2value(html)
1675
- @param {string} html
1676
- @returns {mixed}
1677
- **/
1678
- html2value: function(html) {
1679
- return $('<div>').html(html).text();
1680
- },
1681
-
1682
- /**
1683
- Converts value to string (for internal compare). For submitting to server used value2submit().
1684
-
1685
- @method value2str(value)
1686
- @param {mixed} value
1687
- @returns {string}
1688
- **/
1689
- value2str: function(value) {
1690
- return value;
1691
- },
1692
-
1693
- /**
1694
- Converts string received from server into value.
1695
-
1696
- @method str2value(str)
1697
- @param {string} str
1698
- @returns {mixed}
1699
- **/
1700
- str2value: function(str) {
1701
- return str;
1702
- },
1703
-
1704
- /**
1705
- Converts value for submitting to server
1706
-
1707
- @method value2submit(value)
1708
- @param {mixed} value
1709
- @returns {mixed}
1710
- **/
1711
- value2submit: function(value) {
1712
- return value;
1713
- },
1714
-
1715
- /**
1716
- Sets value of input.
1717
-
1718
- @method value2input(value)
1719
- @param {mixed} value
1720
- **/
1721
- value2input: function(value) {
1722
- this.$input.val(value);
1723
- },
1724
-
1725
- /**
1726
- Returns value of input. Value can be object (e.g. datepicker)
1727
-
1728
- @method input2value()
1729
- **/
1730
- input2value: function() {
1731
- return this.$input.val();
1732
- },
1733
-
1734
- /**
1735
- Activates input. For text it sets focus.
1736
-
1737
- @method activate()
1738
- **/
1739
- activate: function() {
1740
- if(this.$input.is(':visible')) {
1741
- this.$input.focus();
1742
- }
1743
- },
1744
-
1745
- /**
1746
- Creates input.
1747
-
1748
- @method clear()
1749
- **/
1750
- clear: function() {
1751
- this.$input.val(null);
1752
- },
1753
-
1754
- /**
1755
- method to escape html.
1756
- **/
1757
- escape: function(str) {
1758
- return $('<div>').text(str).html();
1759
- },
1760
-
1761
- /**
1762
- attach handler to automatically submit form when value changed (useful when buttons not shown)
1763
- **/
1764
- autosubmit: function() {
1765
-
1766
- }
1767
- };
1768
-
1769
- AbstractInput.defaults = {
1770
- /**
1771
- HTML template of input. Normally you should not change it.
1772
-
1773
- @property tpl
1774
- @type string
1775
- @default ''
1776
- **/
1777
- tpl: '',
1778
- /**
1779
- CSS class automatically applied to input
1780
-
1781
- @property inputclass
1782
- @type string
1783
- @default input-medium
1784
- **/
1785
- inputclass: 'input-medium',
1786
- /**
1787
- Name attribute of input
1788
-
1789
- @property name
1790
- @type string
1791
- @default null
1792
- **/
1793
- name: null
1794
- };
1795
-
1796
- $.extend($.fn.editabletypes, {abstractinput: AbstractInput});
1797
-
1798
- }(window.jQuery));
1799
-
1800
- /**
1801
- List - abstract class for inputs that have source option loaded from js array or via ajax
1802
-
1803
- @class list
1804
- @extends abstractinput
1805
- **/
1806
- (function ($) {
1807
-
1808
- var List = function (options) {
1809
-
1810
- };
1811
-
1812
- $.fn.editableutils.inherit(List, $.fn.editabletypes.abstractinput);
1813
-
1814
- $.extend(List.prototype, {
1815
- render: function () {
1816
- List.superclass.render.call(this);
1817
- var deferred = $.Deferred();
1818
- this.error = null;
1819
- this.sourceData = null;
1820
- this.prependData = null;
1821
- this.onSourceReady(function () {
1822
- this.renderList();
1823
- deferred.resolve();
1824
- }, function () {
1825
- this.error = this.options.sourceError;
1826
- deferred.resolve();
1827
- });
1828
-
1829
- return deferred.promise();
1830
- },
1831
-
1832
- html2value: function (html) {
1833
- return null; //can't set value by text
1834
- },
1835
-
1836
- value2html: function (value, element, display) {
1837
- var deferred = $.Deferred();
1838
- this.onSourceReady(function () {
1839
- if(typeof display === 'function') {
1840
- //custom display method
1841
- display.call(element, value, this.sourceData);
1842
- } else {
1843
- this.value2htmlFinal(value, element);
1844
- }
1845
- deferred.resolve();
1846
- }, function () {
1847
- //do nothing with element
1848
- deferred.resolve();
1849
- });
1850
-
1851
- return deferred.promise();
1852
- },
1853
-
1854
- // ------------- additional functions ------------
1855
-
1856
- onSourceReady: function (success, error) {
1857
- //if allready loaded just call success
1858
- if($.isArray(this.sourceData)) {
1859
- success.call(this);
1860
- return;
1861
- }
1862
-
1863
- // try parse json in single quotes (for double quotes jquery does automatically)
1864
- try {
1865
- this.options.source = $.fn.editableutils.tryParseJson(this.options.source, false);
1866
- } catch (e) {
1867
- error.call(this);
1868
- return;
1869
- }
1870
-
1871
- //loading from url
1872
- if (typeof this.options.source === 'string') {
1873
- //try to get from cache
1874
- if(this.options.sourceCache) {
1875
- var cacheID = this.options.source + (this.options.name ? '-' + this.options.name : ''),
1876
- cache;
1877
-
1878
- if (!$(document).data(cacheID)) {
1879
- $(document).data(cacheID, {});
1880
- }
1881
- cache = $(document).data(cacheID);
1882
-
1883
- //check for cached data
1884
- if (cache.loading === false && cache.sourceData) { //take source from cache
1885
- this.sourceData = cache.sourceData;
1886
- success.call(this);
1887
- return;
1888
- } else if (cache.loading === true) { //cache is loading, put callback in stack to be called later
1889
- cache.callbacks.push($.proxy(function () {
1890
- this.sourceData = cache.sourceData;
1891
- success.call(this);
1892
- }, this));
1893
-
1894
- //also collecting error callbacks
1895
- cache.err_callbacks.push($.proxy(error, this));
1896
- return;
1897
- } else { //no cache yet, activate it
1898
- cache.loading = true;
1899
- cache.callbacks = [];
1900
- cache.err_callbacks = [];
1901
- }
1902
- }
1903
-
1904
- //loading sourceData from server
1905
- $.ajax({
1906
- url: this.options.source,
1907
- type: 'get',
1908
- cache: false,
1909
- data: this.options.name ? {name: this.options.name} : {},
1910
- dataType: 'json',
1911
- success: $.proxy(function (data) {
1912
- if(cache) {
1913
- cache.loading = false;
1914
- }
1915
- this.sourceData = this.makeArray(data);
1916
- if($.isArray(this.sourceData)) {
1917
- this.doPrepend();
1918
- success.call(this);
1919
- if(cache) {
1920
- //store result in cache
1921
- cache.sourceData = this.sourceData;
1922
- $.each(cache.callbacks, function () { this.call(); }); //run success callbacks for other fields
1923
- }
1924
- } else {
1925
- error.call(this);
1926
- if(cache) {
1927
- $.each(cache.err_callbacks, function () { this.call(); }); //run error callbacks for other fields
1928
- }
1929
- }
1930
- }, this),
1931
- error: $.proxy(function () {
1932
- error.call(this);
1933
- if(cache) {
1934
- cache.loading = false;
1935
- //run error callbacks for other fields
1936
- $.each(cache.err_callbacks, function () { this.call(); });
1937
- }
1938
- }, this)
1939
- });
1940
- } else { //options as json/array
1941
- this.sourceData = this.makeArray(this.options.source);
1942
- if($.isArray(this.sourceData)) {
1943
- this.doPrepend();
1944
- success.call(this);
1945
- } else {
1946
- error.call(this);
1947
- }
1948
- }
1949
- },
1950
-
1951
- doPrepend: function () {
1952
- if(this.options.prepend === null || this.options.prepend === undefined) {
1953
- return;
1954
- }
1955
-
1956
- if(!$.isArray(this.prependData)) {
1957
- //try parse json in single quotes
1958
- this.options.prepend = $.fn.editableutils.tryParseJson(this.options.prepend, true);
1959
- if (typeof this.options.prepend === 'string') {
1960
- this.options.prepend = {'': this.options.prepend};
1961
- }
1962
- this.prependData = this.makeArray(this.options.prepend);
1963
- }
1964
-
1965
- if($.isArray(this.prependData) && $.isArray(this.sourceData)) {
1966
- this.sourceData = this.prependData.concat(this.sourceData);
1967
- }
1968
- },
1969
-
1970
- /*
1971
- renders input list
1972
- */
1973
- renderList: function() {
1974
- // this method should be overwritten in child class
1975
- },
1976
-
1977
- /*
1978
- set element's html by value
1979
- */
1980
- value2htmlFinal: function(value, element) {
1981
- // this method should be overwritten in child class
1982
- },
1983
-
1984
- /**
1985
- * convert data to array suitable for sourceData, e.g. [{value: 1, text: 'abc'}, {...}]
1986
- */
1987
- makeArray: function(data) {
1988
- var count, obj, result = [], iterateEl;
1989
- if(!data || typeof data === 'string') {
1990
- return null;
1991
- }
1992
-
1993
- if($.isArray(data)) { //array
1994
- iterateEl = function (k, v) {
1995
- obj = {value: k, text: v};
1996
- if(count++ >= 2) {
1997
- return false;// exit each if object has more than one value
1998
- }
1999
- };
2000
-
2001
- for(var i = 0; i < data.length; i++) {
2002
- if(typeof data[i] === 'object') {
2003
- count = 0;
2004
- $.each(data[i], iterateEl);
2005
- if(count === 1) {
2006
- result.push(obj);
2007
- } else if(count > 1 && data[i].hasOwnProperty('value') && data[i].hasOwnProperty('text')) {
2008
- result.push(data[i]);
2009
- } else {
2010
- //data contains incorrect objects
2011
- }
2012
- } else {
2013
- result.push({value: data[i], text: data[i]});
2014
- }
2015
- }
2016
- } else { //object
2017
- $.each(data, function (k, v) {
2018
- result.push({value: k, text: v});
2019
- });
2020
- }
2021
- return result;
2022
- },
2023
-
2024
- //search for item by particular value
2025
- itemByVal: function(val) {
2026
- if($.isArray(this.sourceData)) {
2027
- for(var i=0; i<this.sourceData.length; i++){
2028
- /*jshint eqeqeq: false*/
2029
- if(this.sourceData[i].value == val) {
2030
- /*jshint eqeqeq: true*/
2031
- return this.sourceData[i];
2032
- }
2033
- }
2034
- }
2035
- }
2036
-
2037
- });
2038
-
2039
- List.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
2040
- /**
2041
- Source data for list. If string - considered ajax url to load items. Otherwise should be an array.
2042
- Array format is: <code>[{value: 1, text: "text"}, {...}]</code><br>
2043
- For compability it also supports format <code>{value1: "text1", value2: "text2" ...}</code> but it does not guarantee elements order.
2044
- If source is **string**, results will be cached for fields with the same source and name. See also <code>sourceCache</code> option.
2045
-
2046
- @property source
2047
- @type string|array|object
2048
- @default null
2049
- **/
2050
- source:null,
2051
- /**
2052
- Data automatically prepended to the beginning of dropdown list.
2053
-
2054
- @property prepend
2055
- @type string|array|object
2056
- @default false
2057
- **/
2058
- prepend:false,
2059
- /**
2060
- Error message when list cannot be loaded (e.g. ajax error)
2061
-
2062
- @property sourceError
2063
- @type string
2064
- @default Error when loading list
2065
- **/
2066
- sourceError: 'Error when loading list',
2067
- /**
2068
- if <code>true</code> and source is **string url** - results will be cached for fields with the same source and name.
2069
- Usefull for editable grids.
2070
-
2071
- @property sourceCache
2072
- @type boolean
2073
- @default true
2074
- @since 1.2.0
2075
- **/
2076
- sourceCache: true
2077
- });
2078
-
2079
- $.fn.editabletypes.list = List;
2080
-
2081
- }(window.jQuery));
2082
- /**
2083
- Text input
2084
-
2085
- @class text
2086
- @extends abstractinput
2087
- @final
2088
- @example
2089
- <a href="#" id="username" data-type="text" data-pk="1">awesome</a>
2090
- <script>
2091
- $(function(){
2092
- $('#username').editable({
2093
- url: '/post',
2094
- title: 'Enter username'
2095
- });
2096
- });
2097
- </script>
2098
- **/
2099
- (function ($) {
2100
- var Text = function (options) {
2101
- this.init('text', options, Text.defaults);
2102
- };
2103
-
2104
- $.fn.editableutils.inherit(Text, $.fn.editabletypes.abstractinput);
2105
-
2106
- $.extend(Text.prototype, {
2107
- activate: function() {
2108
- if(this.$input.is(':visible')) {
2109
- this.$input.focus();
2110
- $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
2111
- }
2112
- }
2113
- });
2114
-
2115
- Text.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
2116
- /**
2117
- @property tpl
2118
- @default <input type="text">
2119
- **/
2120
- tpl: '<input type="text">',
2121
- /**
2122
- Placeholder attribute of input. Shown when input is empty.
2123
-
2124
- @property placeholder
2125
- @type string
2126
- @default null
2127
- **/
2128
- placeholder: null
2129
- });
2130
-
2131
- $.fn.editabletypes.text = Text;
2132
-
2133
- }(window.jQuery));
2134
-
2135
- /**
2136
- Textarea input
2137
-
2138
- @class textarea
2139
- @extends abstractinput
2140
- @final
2141
- @example
2142
- <a href="#" id="comments" data-type="textarea" data-pk="1">awesome comment!</a>
2143
- <script>
2144
- $(function(){
2145
- $('#comments').editable({
2146
- url: '/post',
2147
- title: 'Enter comments'
2148
- });
2149
- });
2150
- </script>
2151
- **/
2152
- (function ($) {
2153
-
2154
- var Textarea = function (options) {
2155
- this.init('textarea', options, Textarea.defaults);
2156
- };
2157
-
2158
- $.fn.editableutils.inherit(Textarea, $.fn.editabletypes.abstractinput);
2159
-
2160
- $.extend(Textarea.prototype, {
2161
- render: function () {
2162
- Textarea.superclass.render.call(this);
2163
-
2164
- //ctrl + enter
2165
- this.$input.keydown(function (e) {
2166
- if (e.ctrlKey && e.which === 13) {
2167
- $(this).closest('form').submit();
2168
- }
2169
- });
2170
- },
2171
-
2172
- value2html: function(value, element) {
2173
- var html = '', lines;
2174
- if(value) {
2175
- lines = value.split("\n");
2176
- for (var i = 0; i < lines.length; i++) {
2177
- lines[i] = $('<div>').text(lines[i]).html();
2178
- }
2179
- html = lines.join('<br>');
2180
- }
2181
- $(element).html(html);
2182
- },
2183
-
2184
- html2value: function(html) {
2185
- if(!html) {
2186
- return '';
2187
- }
2188
- var lines = html.split(/<br\s*\/?>/i);
2189
- for (var i = 0; i < lines.length; i++) {
2190
- lines[i] = $('<div>').html(lines[i]).text();
2191
- }
2192
- return lines.join("\n");
2193
- },
2194
-
2195
- activate: function() {
2196
- if(this.$input.is(':visible')) {
2197
- $.fn.editableutils.setCursorPosition(this.$input.get(0), this.$input.val().length);
2198
- this.$input.focus();
2199
- }
2200
- }
2201
- });
2202
-
2203
- Textarea.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
2204
- /**
2205
- @property tpl
2206
- @default <textarea></textarea>
2207
- **/
2208
- tpl:'<textarea></textarea>',
2209
- /**
2210
- @property inputclass
2211
- @default input-large
2212
- **/
2213
- inputclass: 'input-large',
2214
- /**
2215
- Placeholder attribute of input. Shown when input is empty.
2216
-
2217
- @property placeholder
2218
- @type string
2219
- @default null
2220
- **/
2221
- placeholder: null
2222
- });
2223
-
2224
- $.fn.editabletypes.textarea = Textarea;
2225
-
2226
- }(window.jQuery));
2227
-
2228
- /**
2229
- Select (dropdown)
2230
-
2231
- @class select
2232
- @extends list
2233
- @final
2234
- @example
2235
- <a href="#" id="status" data-type="select" data-pk="1" data-url="/post" data-original-title="Select status"></a>
2236
- <script>
2237
- $(function(){
2238
- $('#status').editable({
2239
- value: 2,
2240
- source: [
2241
- {value: 1, text: 'Active'},
2242
- {value: 2, text: 'Blocked'},
2243
- {value: 3, text: 'Deleted'}
2244
- ]
2245
- }
2246
- });
2247
- });
2248
- </script>
2249
- **/
2250
- (function ($) {
2251
-
2252
- var Select = function (options) {
2253
- this.init('select', options, Select.defaults);
2254
- };
2255
-
2256
- $.fn.editableutils.inherit(Select, $.fn.editabletypes.list);
2257
-
2258
- $.extend(Select.prototype, {
2259
- renderList: function() {
2260
- if(!$.isArray(this.sourceData)) {
2261
- return;
2262
- }
2263
-
2264
- for(var i=0; i<this.sourceData.length; i++) {
2265
- this.$input.append($('<option>', {value: this.sourceData[i].value}).text(this.sourceData[i].text));
2266
- }
2267
-
2268
- //enter submit
2269
- this.$input.on('keydown.editable', function (e) {
2270
- if (e.which === 13) {
2271
- $(this).closest('form').submit();
2272
- }
2273
- });
2274
- },
2275
-
2276
- value2htmlFinal: function(value, element) {
2277
- var text = '', item = this.itemByVal(value);
2278
- if(item) {
2279
- text = item.text;
2280
- }
2281
- Select.superclass.constructor.superclass.value2html(text, element);
2282
- },
2283
-
2284
- autosubmit: function() {
2285
- this.$input.off('keydown.editable').on('change.editable', function(){
2286
- $(this).closest('form').submit();
2287
- });
2288
- }
2289
- });
2290
-
2291
- Select.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
2292
- /**
2293
- @property tpl
2294
- @default <select></select>
2295
- **/
2296
- tpl:'<select></select>'
2297
- });
2298
-
2299
- $.fn.editabletypes.select = Select;
2300
-
2301
- }(window.jQuery));
2302
- /**
2303
- List of checkboxes.
2304
- Internally value stored as javascript array of values.
2305
-
2306
- @class checklist
2307
- @extends list
2308
- @final
2309
- @example
2310
- <a href="#" id="options" data-type="checklist" data-pk="1" data-url="/post" data-original-title="Select options"></a>
2311
- <script>
2312
- $(function(){
2313
- $('#options').editable({
2314
- value: [2, 3],
2315
- source: [
2316
- {value: 1, text: 'option1'},
2317
- {value: 2, text: 'option2'},
2318
- {value: 3, text: 'option3'}
2319
- ]
2320
- }
2321
- });
2322
- });
2323
- </script>
2324
- **/
2325
- (function ($) {
2326
-
2327
- var Checklist = function (options) {
2328
- this.init('checklist', options, Checklist.defaults);
2329
- };
2330
-
2331
- $.fn.editableutils.inherit(Checklist, $.fn.editabletypes.list);
2332
-
2333
- $.extend(Checklist.prototype, {
2334
- renderList: function() {
2335
- var $label, $div;
2336
- if(!$.isArray(this.sourceData)) {
2337
- return;
2338
- }
2339
-
2340
- for(var i=0; i<this.sourceData.length; i++) {
2341
- $label = $('<label>').append($('<input>', {
2342
- type: 'checkbox',
2343
- value: this.sourceData[i].value,
2344
- name: this.options.name
2345
- }))
2346
- .append($('<span>').text(' '+this.sourceData[i].text));
2347
-
2348
- $('<div>').append($label).appendTo(this.$input);
2349
- }
2350
- },
2351
-
2352
- value2str: function(value) {
2353
- return $.isArray(value) ? value.sort().join($.trim(this.options.separator)) : '';
2354
- },
2355
-
2356
- //parse separated string
2357
- str2value: function(str) {
2358
- var reg, value = null;
2359
- if(typeof str === 'string' && str.length) {
2360
- reg = new RegExp('\\s*'+$.trim(this.options.separator)+'\\s*');
2361
- value = str.split(reg);
2362
- } else if($.isArray(str)) {
2363
- value = str;
2364
- }
2365
- return value;
2366
- },
2367
-
2368
- //set checked on required checkboxes
2369
- value2input: function(value) {
2370
- var $checks = this.$input.find('input[type="checkbox"]');
2371
- $checks.removeAttr('checked');
2372
- if($.isArray(value) && value.length) {
2373
- $checks.each(function(i, el) {
2374
- var $el = $(el);
2375
- // cannot use $.inArray as it performs strict comparison
2376
- $.each(value, function(j, val){
2377
- /*jslint eqeq: true*/
2378
- if($el.val() == val) {
2379
- /*jslint eqeq: false*/
2380
- $el.attr('checked', 'checked');
2381
- }
2382
- });
2383
- });
2384
- }
2385
- },
2386
-
2387
- input2value: function() {
2388
- var checked = [];
2389
- this.$input.find('input:checked').each(function(i, el) {
2390
- checked.push($(el).val());
2391
- });
2392
- return checked;
2393
- },
2394
-
2395
- //collect text of checked boxes
2396
- value2htmlFinal: function(value, element) {
2397
- var html = [],
2398
- /*jslint eqeq: true*/
2399
- checked = $.grep(this.sourceData, function(o){
2400
- return $.grep(value, function(v){ return v == o.value; }).length;
2401
- });
2402
- /*jslint eqeq: false*/
2403
- if(checked.length) {
2404
- $.each(checked, function(i, v) { html.push($.fn.editableutils.escape(v.text)); });
2405
- $(element).html(html.join('<br>'));
2406
- } else {
2407
- $(element).empty();
2408
- }
2409
- },
2410
-
2411
- activate: function() {
2412
- this.$input.find('input[type="checkbox"]').first().focus();
2413
- },
2414
-
2415
- autosubmit: function() {
2416
- this.$input.find('input[type="checkbox"]').on('keydown', function(e){
2417
- if (e.which === 13) {
2418
- $(this).closest('form').submit();
2419
- }
2420
- });
2421
- }
2422
- });
2423
-
2424
- Checklist.defaults = $.extend({}, $.fn.editabletypes.list.defaults, {
2425
- /**
2426
- @property tpl
2427
- @default <div></div>
2428
- **/
2429
- tpl:'<div></div>',
2430
-
2431
- /**
2432
- @property inputclass
2433
- @type string
2434
- @default editable-checklist
2435
- **/
2436
- inputclass: 'editable-checklist',
2437
-
2438
- /**
2439
- Separator of values when reading from 'data-value' string
2440
-
2441
- @property separator
2442
- @type string
2443
- @default ', '
2444
- **/
2445
- separator: ','
2446
- });
2447
-
2448
- $.fn.editabletypes.checklist = Checklist;
2449
-
2450
- }(window.jQuery));
2451
-
2452
- /**
2453
- HTML5 input types.
2454
- Following types are supported:
2455
-
2456
- * password
2457
- * email
2458
- * url
2459
- * tel
2460
- * number
2461
- * range
2462
-
2463
- Learn more about html5 inputs:
2464
- http://www.w3.org/wiki/HTML5_form_additions
2465
- To check browser compatibility please see:
2466
- https://developer.mozilla.org/en-US/docs/HTML/Element/Input
2467
-
2468
- @class html5types
2469
- @extends text
2470
- @final
2471
- @since 1.3.0
2472
- @example
2473
- <a href="#" id="email" data-type="email" data-pk="1">admin@example.com</a>
2474
- <script>
2475
- $(function(){
2476
- $('#email').editable({
2477
- url: '/post',
2478
- title: 'Enter email'
2479
- });
2480
- });
2481
- </script>
2482
- **/
2483
-
2484
- /**
2485
- @property tpl
2486
- @default depends on type
2487
- **/
2488
-
2489
- /*
2490
- Password
2491
- */
2492
- (function ($) {
2493
- var Password = function (options) {
2494
- this.init('password', options, Password.defaults);
2495
- };
2496
- $.fn.editableutils.inherit(Password, $.fn.editabletypes.text);
2497
- $.extend(Password.prototype, {
2498
- //do not display password, show '[hidden]' instead
2499
- value2html: function(value, element) {
2500
- if(value) {
2501
- $(element).text('[hidden]');
2502
- } else {
2503
- $(element).empty();
2504
- }
2505
- },
2506
- //as password not displayed, should not set value by html
2507
- html2value: function(html) {
2508
- return null;
2509
- }
2510
- });
2511
- Password.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
2512
- tpl: '<input type="password">'
2513
- });
2514
- $.fn.editabletypes.password = Password;
2515
- }(window.jQuery));
2516
-
2517
-
2518
- /*
2519
- Email
2520
- */
2521
- (function ($) {
2522
- var Email = function (options) {
2523
- this.init('email', options, Email.defaults);
2524
- };
2525
- $.fn.editableutils.inherit(Email, $.fn.editabletypes.text);
2526
- Email.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
2527
- tpl: '<input type="email">'
2528
- });
2529
- $.fn.editabletypes.email = Email;
2530
- }(window.jQuery));
2531
-
2532
-
2533
- /*
2534
- Url
2535
- */
2536
- (function ($) {
2537
- var Url = function (options) {
2538
- this.init('url', options, Url.defaults);
2539
- };
2540
- $.fn.editableutils.inherit(Url, $.fn.editabletypes.text);
2541
- Url.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
2542
- tpl: '<input type="url">'
2543
- });
2544
- $.fn.editabletypes.url = Url;
2545
- }(window.jQuery));
2546
-
2547
-
2548
- /*
2549
- Tel
2550
- */
2551
- (function ($) {
2552
- var Tel = function (options) {
2553
- this.init('tel', options, Tel.defaults);
2554
- };
2555
- $.fn.editableutils.inherit(Tel, $.fn.editabletypes.text);
2556
- Tel.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
2557
- tpl: '<input type="tel">'
2558
- });
2559
- $.fn.editabletypes.tel = Tel;
2560
- }(window.jQuery));
2561
-
2562
-
2563
- /*
2564
- Number
2565
- */
2566
- (function ($) {
2567
- var NumberInput = function (options) {
2568
- this.init('number', options, NumberInput.defaults);
2569
- };
2570
- $.fn.editableutils.inherit(NumberInput, $.fn.editabletypes.text);
2571
- $.extend(NumberInput.prototype, {
2572
- render: function () {
2573
- NumberInput.superclass.render.call(this);
2574
-
2575
- if (this.options.min !== null) {
2576
- this.$input.attr('min', this.options.min);
2577
- }
2578
-
2579
- if (this.options.max !== null) {
2580
- this.$input.attr('max', this.options.max);
2581
- }
2582
-
2583
- if (this.options.step !== null) {
2584
- this.$input.attr('step', this.options.step);
2585
- }
2586
- }
2587
- });
2588
- NumberInput.defaults = $.extend({}, $.fn.editabletypes.text.defaults, {
2589
- tpl: '<input type="number">',
2590
- inputclass: 'input-mini',
2591
- min: null,
2592
- max: null,
2593
- step: null
2594
- });
2595
- $.fn.editabletypes.number = NumberInput;
2596
- }(window.jQuery));
2597
-
2598
-
2599
- /*
2600
- Range (inherit from number)
2601
- */
2602
- (function ($) {
2603
- var Range = function (options) {
2604
- this.init('range', options, Range.defaults);
2605
- };
2606
- $.fn.editableutils.inherit(Range, $.fn.editabletypes.number);
2607
- $.extend(Range.prototype, {
2608
- render: function () {
2609
- this.$input = $(this.options.tpl);
2610
- var $slider = this.$input.filter('input');
2611
- if(this.options.inputclass) {
2612
- $slider.addClass(this.options.inputclass);
2613
- }
2614
- if (this.options.min !== null) {
2615
- $slider.attr('min', this.options.min);
2616
- }
2617
-
2618
- if (this.options.max !== null) {
2619
- $slider.attr('max', this.options.max);
2620
- }
2621
-
2622
- if (this.options.step !== null) {
2623
- $slider.attr('step', this.options.step);
2624
- }
2625
-
2626
- $slider.on('input', function(){
2627
- $(this).siblings('output').text($(this).val());
2628
- });
2629
- },
2630
- activate: function() {
2631
- this.$input.filter('input').focus();
2632
- }
2633
- });
2634
- Range.defaults = $.extend({}, $.fn.editabletypes.number.defaults, {
2635
- tpl: '<input type="range"><output style="width: 30px; display: inline-block"></output>',
2636
- inputclass: 'input-medium'
2637
- });
2638
- $.fn.editabletypes.range = Range;
2639
- }(window.jQuery));
2640
- /**
2641
- * Editable Inline
2642
- * ---------------------
2643
- */
2644
- (function ($) {
2645
-
2646
- //extend methods
2647
- $.extend($.fn.editableContainer.Constructor.prototype, {
2648
- containerName: 'editableform',
2649
- innerCss: null,
2650
-
2651
- initContainer: function(){
2652
- //no init for container
2653
- //only convert anim to miliseconds (int)
2654
- if(!this.options.anim) {
2655
- this.options.anim = 0;
2656
- }
2657
- },
2658
-
2659
- splitOptions: function() {
2660
- this.containerOptions = {};
2661
- this.formOptions = this.options;
2662
- },
2663
-
2664
- tip: function() {
2665
- return this.$form;
2666
- },
2667
-
2668
- innerShow: function () {
2669
- this.$element.hide();
2670
-
2671
- if(this.$form) {
2672
- this.$form.remove();
2673
- }
2674
-
2675
- this.initForm();
2676
- this.tip().addClass('editable-container').addClass('editable-inline');
2677
- this.$form.insertAfter(this.$element);
2678
- this.$form.show(this.options.anim);
2679
- this.$form.editableform('render');
2680
- },
2681
-
2682
- innerHide: function () {
2683
- this.$form.hide(this.options.anim, $.proxy(function() {
2684
- this.$element.show();
2685
- }, this));
2686
- },
2687
-
2688
- destroy: function() {
2689
- this.tip().remove();
2690
- }
2691
- });
2692
-
2693
- //defaults
2694
- $.fn.editableContainer.defaults = $.extend({}, $.fn.editableContainer.defaults, {
2695
- anim: 'fast'
2696
- });
2697
-
2698
-
2699
- }(window.jQuery));
2700
- /**
2701
- jQuery UI Datepicker.
2702
- Description and examples: http://jqueryui.com/datepicker.
2703
- This input is also accessible as **date** type. Do not use it together with __bootstrap-datepicker__ as both apply <code>$().datepicker()</code> method.
2704
-
2705
- @class dateui
2706
- @extends abstractinput
2707
- @final
2708
- @example
2709
- <a href="#" id="dob" data-type="date" data-pk="1" data-url="/post" data-original-title="Select date">15/05/1984</a>
2710
- <script>
2711
- $(function(){
2712
- $('#dob').editable({
2713
- format: 'yyyy-mm-dd',
2714
- viewformat: 'dd/mm/yyyy',
2715
- datepicker: {
2716
- firstDay: 1
2717
- }
2718
- }
2719
- });
2720
- });
2721
- </script>
2722
- **/
2723
- (function ($) {
2724
-
2725
- var DateUI = function (options) {
2726
- this.init('dateui', options, DateUI.defaults);
2727
-
2728
- //set popular options directly from settings or data-* attributes
2729
- var directOptions = $.fn.editableutils.sliceObj(this.options, ['format']);
2730
-
2731
- //overriding datepicker config (as by default jQuery extend() is not recursive)
2732
- this.options.datepicker = $.extend({}, DateUI.defaults.datepicker, directOptions, options.datepicker);
2733
-
2734
- //by default viewformat equals to format
2735
- if(!this.options.viewformat) {
2736
- this.options.viewformat = this.options.datepicker.format;
2737
- }
2738
-
2739
- //correct formats: replace yyyy with yy
2740
- this.options.viewformat = this.options.viewformat.replace('yyyy', 'yy');
2741
- this.options.datepicker.format = this.options.datepicker.format.replace('yyyy', 'yy');
2742
-
2743
- //copy format to dateFormat (dateFormat option required for ui datepicker).
2744
- //This allows common option 'format' for all datepickers
2745
- this.options.datepicker.dateFormat = this.options.datepicker.format;
2746
- };
2747
-
2748
- $.fn.editableutils.inherit(DateUI, $.fn.editabletypes.abstractinput);
2749
-
2750
- $.extend(DateUI.prototype, {
2751
- render: function () {
2752
- DateUI.superclass.render.call(this);
2753
- this.$input.datepicker(this.options.datepicker);
2754
-
2755
- if(this.options.clear) {
2756
- this.$clear = $('<a href="#"></a>').html(this.options.clear).click($.proxy(function(e){
2757
- e.preventDefault();
2758
- e.stopPropagation();
2759
- this.clear();
2760
- }, this));
2761
- }
2762
- },
2763
-
2764
- value2html: function(value, element) {
2765
- var text = $.datepicker.formatDate(this.options.viewformat, value);
2766
- DateUI.superclass.value2html(text, element);
2767
- },
2768
-
2769
- html2value: function(html) {
2770
- if(typeof html !== 'string') {
2771
- return html;
2772
- }
2773
-
2774
- //if string does not match format, UI datepicker throws exception
2775
- var d;
2776
- try {
2777
- d = $.datepicker.parseDate(this.options.viewformat, html);
2778
- } catch(e) {}
2779
-
2780
- return d;
2781
- },
2782
-
2783
- value2str: function(value) {
2784
- return $.datepicker.formatDate(this.options.datepicker.dateFormat, value);
2785
- },
2786
-
2787
- str2value: function(str) {
2788
- if(typeof str !== 'string') {
2789
- return str;
2790
- }
2791
-
2792
- //if string does not match format, UI datepicker throws exception
2793
- var d;
2794
- try {
2795
- d = $.datepicker.parseDate(this.options.datepicker.dateFormat, str);
2796
- } catch(e) {}
2797
-
2798
- return d;
2799
- },
2800
-
2801
- value2submit: function(value) {
2802
- return this.value2str(value);
2803
- },
2804
-
2805
- value2input: function(value) {
2806
- this.$input.datepicker('setDate', value);
2807
- },
2808
-
2809
- input2value: function() {
2810
- return this.$input.datepicker('getDate');
2811
- },
2812
-
2813
- activate: function() {
2814
- },
2815
-
2816
- clear: function() {
2817
- this.$input.datepicker('setDate', null);
2818
- },
2819
-
2820
- autosubmit: function() {
2821
- this.$input.on('mouseup', 'table.ui-datepicker-calendar a.ui-state-default', function(e){
2822
- var $form = $(this).closest('form');
2823
- setTimeout(function() {
2824
- $form.submit();
2825
- }, 200);
2826
- });
2827
- }
2828
-
2829
- });
2830
-
2831
- DateUI.defaults = $.extend({}, $.fn.editabletypes.abstractinput.defaults, {
2832
- /**
2833
- @property tpl
2834
- @default <div></div>
2835
- **/
2836
- tpl:'<div></div>',
2837
- /**
2838
- @property inputclass
2839
- @default 'editable-date'
2840
- **/
2841
- inputclass: 'editable-date',
2842
- /**
2843
- Format used for sending value to server. Also applied when converting date from <code>data-value</code> attribute.<br>
2844
- Full list of tokens: http://docs.jquery.com/UI/Datepicker/formatDate
2845
-
2846
- @property format
2847
- @type string
2848
- @default yyyy-mm-dd
2849
- **/
2850
- format:'yyyy-mm-dd',
2851
- /**
2852
- Format used for displaying date. Also applied when converting date from element's text on init.
2853
- If not specified equals to <code>format</code>
2854
-
2855
- @property viewformat
2856
- @type string
2857
- @default null
2858
- **/
2859
- viewformat: null,
2860
-
2861
- /**
2862
- Configuration of datepicker.
2863
- Full list of options: http://api.jqueryui.com/datepicker
2864
-
2865
- @property datepicker
2866
- @type object
2867
- @default {
2868
- firstDay: 0,
2869
- changeYear: true,
2870
- changeMonth: true
2871
- }
2872
- **/
2873
- datepicker: {
2874
- firstDay: 0,
2875
- changeYear: true,
2876
- changeMonth: true
2877
- },
2878
- /**
2879
- Text shown as clear date button.
2880
- If <code>false</code> clear button will not be rendered.
2881
-
2882
- @property clear
2883
- @type boolean|string
2884
- @default 'x clear'
2885
- **/
2886
- clear: '&times; clear'
2887
- });
2888
-
2889
- $.fn.editabletypes.dateui = DateUI;
2890
- $.fn.editabletypes.date = DateUI;
2891
-
2892
- }(window.jQuery));