(function(e){if(typeof exports!="undefined"&&typeof require!="undefined")var t=e.jQuery||e.Zepto||e.ender||require("jquery"),n=e._||require("underscore"),r=e.Backbone||require("backbone");else var t=e.jQuery,n=e._,r=e.Backbone;var i=function(){return r.View.extend({hasFocus:!1,initialize:function(e){if(!i.templates.form)throw new Error("Templates not loaded");this.schema=function(){if(e.schema)return e.schema;var t=e.model;if(!t)throw new Error("Could not find schema");return n.isFunction(t.schema)?t.schema():t.schema}(),e=n.extend({template:"form",fieldsetTemplate:"fieldset",fieldTemplate:"field"},e);if(!e.fieldsets){var t=e.fields||n.keys(this.schema);e.fieldsets=[{fields:t}]}this.options=e,this.model=e.model,this.data=e.data,this.fields={}},render:function(){var e=this,r=this.options,s=i.templates[r.template],o=t(s({fieldsets:''})),u=t(".bbf-tmp",o);return n.each(r.fieldsets,function(t){u.append(e.renderFieldset(t))}),u.children().unwrap(),this.setElement(o),this.hasFocus&&this.trigger("blur",this),this},renderFieldset:function(e){var r=this,s=i.templates[this.options.fieldsetTemplate],o=this.schema,u=i.helpers.getNested;n.isArray(e)&&(e={fields:e});var a=t(s(n.extend({},e,{legend:'',fields:''})));e.legend?a.find(".bbf-tmp-legend").replaceWith(e.legend):a.find(".bbf-tmp-legend").parent().remove();var f=t(".bbf-tmp-fields",a);return n.each(e.fields,function(e){var t=function(){if(o[e])return o[e];var t=e.replace(/\./g,".subSchema.");return u(o,t)}();if(!t)throw"Field '"+e+"' not found in schema";var i=r.fields[e]=r.createField(e,t),s=i.render().el;i.editor.on("all",function(t){var r=n.toArray(arguments);r[0]=e+":"+t,r.splice(1,0,this),this.trigger.apply(this,r)},r),i.editor.on("change",function(){this.trigger("change",r)},r),i.editor.on("focus",function(){if(this.hasFocus)return;this.trigger("focus",this)},r),i.editor.on("blur",function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(n.find(e.fields,function(e){return e.editor.hasFocus}))return;e.trigger("blur",e)},0)},r),t.type!=="Hidden"&&f.append(s)}),f=f.children().unwrap(),a},createField:function(e,t){t.template=t.template||this.options.fieldTemplate;var n={form:this,key:e,schema:t,idPrefix:this.options.idPrefix,template:this.options.fieldTemplate};return this.model?n.model=this.model:this.data?n.value=this.data[e]:n.value=null,new i.Field(n)},validate:function(){var e=this,t=this.fields,r=this.model,i={};n.each(t,function(e){var t=e.validate();t&&(i[e.key]=t)});if(r&&r.validate){var s=r.validate(this.getValue());if(s){var o=n.isObject(s)&&!n.isArray(s);o||(i._others=i._others||[],i._others.push(s)),o&&n.each(s,function(t,n){if(e.fields[n]&&!i[n])e.fields[n].setError(t),i[n]=t;else{i._others=i._others||[];var r={};r[n]=t,i._others.push(r)}})}}return n.isEmpty(i)?null:i},commit:function(){var e=this.validate();if(e)return e;var t;this.model.set(this.getValue(),{error:function(e,n){t=n}});if(t)return t},getValue:function(e){if(e)return this.fields[e].getValue();var t={};return n.each(this.fields,function(e){t[e.key]=e.getValue()}),t},setValue:function(e,t){var n={};typeof e=="string"?n[e]=t:n=e;var r;for(r in this.schema)n[r]!==undefined&&this.fields[r].setValue(n[r])},focus:function(){if(this.hasFocus)return;var e=this.options.fieldsets[0];if(e){var t;n.isArray(e)?t=e[0]:t=e.fields[0],t&&this.fields[t].editor.focus()}},blur:function(){if(!this.hasFocus)return;var e=n.find(this.fields,function(e){return e.editor.hasFocus});e&&e.editor.blur()},remove:function(){var e=this.fields;for(var t in e)e[t].remove();r.View.prototype.remove.call(this)},trigger:function(e){return e==="focus"?this.hasFocus=!0:e==="blur"&&(this.hasFocus=!1),r.View.prototype.trigger.apply(this,arguments)}})}();i.helpers=function(){var e={};return e.getNested=function(e,t){var n=t.split("."),r=e;for(var i=0,s=n.length;i',help:'',error:''}},render:function(){var n=this.schema,r=i.templates,s={form:this.form,key:this.key,schema:n,idPrefix:this.options.idPrefix,id:this.getId()};this.model?s.model=this.model:s.value=this.value;var o=this.editor=e.createEditor(n.type,s),u=t(r[n.template](this.renderingContext(n,o)));return n.title===!1&&u.find('label[for="'+o.id+'"]').first().remove(),u.find(".bbf-tmp-editor").replaceWith(o.render().el),this.$help=t(".bbf-tmp-help",u).parent(),this.$help.empty(),this.schema.help&&this.$help.html(this.schema.help),this.$error=t(t(".bbf-tmp-error",u).parent()[0]),this.$error&&this.$error.empty(),this.schema.fieldClass&&u.addClass(this.schema.fieldClass),this.schema.fieldAttrs&&u.attr(this.schema.fieldAttrs),this.setElement(u),this},getId:function(){var e=this.options.idPrefix,t=this.key;return t=t.replace(/\./g,"_"),n.isString(e)||n.isNumber(e)?e+t:n.isNull(e)?t:this.model?this.model.cid+"_"+t:t},validate:function(){var e=this.editor.validate();return e?this.setError(e.message):this.clearError(),e},setError:function(e){if(this.editor.hasNestedForm)return;var t=i.classNames.error;this.$el.addClass(t),this.$error?this.$error.html(e):this.$help&&this.$help.html(e)},clearError:function(){var e=i.classNames.error;this.$el.removeClass(e);if(this.$error)this.$error.empty();else if(this.$help){this.$help.empty();var t=this.schema.help;t&&this.$help.html(t)}},commit:function(){return this.editor.commit()},getValue:function(){return this.editor.getValue()},setValue:function(e){this.editor.setValue(e)},focus:function(){this.editor.focus()},blur:function(){this.editor.blur()},remove:function(){this.editor.remove(),r.View.prototype.remove.call(this)}})}(),i.editors=function(){var e=i.helpers,s={};return s.Base=r.View.extend({defaultValue:null,hasFocus:!1,initialize:function(e){var e=e||{};if(e.model){if(!e.key)throw"Missing option: 'key'";this.model=e.model,this.value=this.model.get(e.key)}else e.value&&(this.value=e.value);this.value===undefined&&(this.value=this.defaultValue),this.key=e.key,this.form=e.form,this.schema=e.schema||{},this.validators=e.validators||this.schema.validators,this.$el.attr("name",this.getName()),this.schema.editorClass&&this.$el.addClass(this.schema.editorClass),this.schema.editorAttrs&&this.$el.attr(this.schema.editorAttrs)},getValue:function(){throw"Not implemented. Extend and override this method."},setValue:function(){throw"Not implemented. Extend and override this method."},focus:function(){throw"Not implemented. Extend and override this method."},blur:function(){throw"Not implemented. Extend and override this method."},getName:function(){var e=this.key||"";return e.replace(/\./g,"_")},commit:function(e){var t=this.validate();if(t)return t;this.listenTo(this.model,"invalid",function(e,n){t=n}),this.model.set(this.key,this.getValue(),e);if(t)return t},validate:function(){var e=this.$el,t=null,r=this.getValue(),s=this.form?this.form.getValue():{},o=this.validators,u=i.helpers.getValidator;return o&&n.every(o,function(e){return t=u(e)(r,s),t?!1:!0}),t},trigger:function(e){return e==="focus"?this.hasFocus=!0:e==="blur"&&(this.hasFocus=!1),r.View.prototype.trigger.apply(this,arguments)}}),s.Text=s.Base.extend({tagName:"input",defaultValue:"",previousValue:"",events:{keyup:"determineChange",keypress:function(e){var t=this;setTimeout(function(){t.determineChange()},0)},select:function(e){this.trigger("select",this)},focus:function(e){this.trigger("focus",this)},blur:function(e){this.trigger("blur",this)}},initialize:function(e){s.Base.prototype.initialize.call(this,e);var t=this.schema,n="text";t&&t.editorAttrs&&t.editorAttrs.type&&(n=t.editorAttrs.type),t&&t.dataType&&(n=t.dataType),this.$el.attr("type",n)},render:function(){return this.setValue(this.value),this},determineChange:function(e){var t=this.$el.val(),n=t!==this.previousValue;n&&(this.previousValue=t,this.trigger("change",this))},getValue:function(){return this.$el.val()},setValue:function(e){this.$el.val(e)},focus:function(){if(this.hasFocus)return;this.$el.focus()},blur:function(){if(!this.hasFocus)return;this.$el.blur()},select:function(){this.$el.select()}}),s.Number=s.Text.extend({defaultValue:0,events:n.extend({},s.Text.prototype.events,{keypress:"onKeyPress"}),initialize:function(e){s.Text.prototype.initialize.call(this,e),this.$el.attr("type","number"),this.$el.attr("step","any")},onKeyPress:function(e){var t=this,n=function(){setTimeout(function(){t.determineChange()},0)};if(e.charCode===0){n();return}var r=this.$el.val()+String.fromCharCode(e.charCode),i=/^[0-9]*\.?[0-9]*?$/.test(r);i?n():e.preventDefault()},getValue:function(){var e=this.$el.val();return e===""?null:parseFloat(e,10)},setValue:function(e){e=function(){return n.isNumber(e)?e:n.isString(e)&&e!==""?parseFloat(e,10):null}(),n.isNaN(e)&&(e=null),s.Text.prototype.setValue.call(this,e)}}),s.Password=s.Text.extend({initialize:function(e){s.Text.prototype.initialize.call(this,e),this.$el.attr("type","password")}}),s.TextArea=s.Text.extend({tagName:"textarea"}),s.Checkbox=s.Base.extend({defaultValue:!1,tagName:"input",events:{click:function(e){this.trigger("change",this)},focus:function(e){this.trigger("focus",this)},blur:function(e){this.trigger("blur",this)}},initialize:function(e){s.Base.prototype.initialize.call(this,e),this.$el.attr("type","checkbox")},render:function(){return this.setValue(this.value),this},getValue:function(){return this.$el.prop("checked")},setValue:function(e){e&&this.$el.prop("checked",!0)},focus:function(){if(this.hasFocus)return;this.$el.focus()},blur:function(){if(!this.hasFocus)return;this.$el.blur()}}),s.Hidden=s.Base.extend({defaultValue:"",initialize:function(e){s.Text.prototype.initialize.call(this,e),this.$el.attr("type","hidden")},getValue:function(){return this.value},setValue:function(e){this.value=e},focus:function(){},blur:function(){}}),s.Select=s.Base.extend({tagName:"select",events:{change:function(e){this.trigger("change",this)},focus:function(e){this.trigger("focus",this)},blur:function(e){this.trigger("blur",this)}},initialize:function(e){s.Base.prototype.initialize.call(this,e);if(!this.schema||!this.schema.options)throw"Missing required 'schema.options'"},render:function(){return this.setOptions(this.schema.options),this},setOptions:function(e){var t=this;if(e instanceof r.Collection){var i=e;i.length>0?this.renderOptions(e):i.fetch({success:function(n){t.renderOptions(e)}})}else n.isFunction(e)?e(function(e){t.renderOptions(e)},t):this.renderOptions(e)},renderOptions:function(e){var t=this.$el,i;n.isString(e)?i=e:n.isArray(e)?i=this._arrayToHtml(e):e instanceof r.Collection&&(i=this._collectionToHtml(e)),t.html(i),this.setValue(this.value)},getValue:function(){return this.$el.val()},setValue:function(e){this.$el.val(e)},focus:function(){if(this.hasFocus)return;this.$el.focus()},blur:function(){if(!this.hasFocus)return;this.$el.blur()},_collectionToHtml:function(e){var t=[];e.each(function(e){t.push({val:e.id,label:e.toString()})});var n=this._arrayToHtml(t);return n},_arrayToHtml:function(e){var t=[];return n.each(e,function(e){if(n.isObject(e)){var r=e.val||e.val===0?e.val:"";t.push('")}else t.push("")}),t.join("")}}),s.Radio=s.Select.extend({tagName:"ul",className:"bbf-radio",events:{"change input[type=radio]":function(){this.trigger("change",this)},"focus input[type=radio]":function(){if(this.hasFocus)return;this.trigger("focus",this)},"blur input[type=radio]":function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(e.$("input[type=radio]:focus")[0])return;e.trigger("blur",e)},0)}},getValue:function(){return this.$("input[type=radio]:checked").val()},setValue:function(e){this.$("input[type=radio]").val([e])},focus:function(){if(this.hasFocus)return;var e=this.$("input[type=radio]:checked");if(e[0]){e.focus();return}this.$("input[type=radio]").first().focus()},blur:function(){if(!this.hasFocus)return;this.$("input[type=radio]:focus").blur()},_arrayToHtml:function(e){var t=[],r=this;return n.each(e,function(e,i){var s="
  • ";if(n.isObject(e)){var o=e.val||e.val===0?e.val:"";s+='',s+='"}else s+='',s+='";s+="
  • ",t.push(s)}),t.join("")}}),s.Checkboxes=s.Select.extend({tagName:"ul",className:"bbf-checkboxes",events:{"click input[type=checkbox]":function(){this.trigger("change",this)},"focus input[type=checkbox]":function(){if(this.hasFocus)return;this.trigger("focus",this)},"blur input[type=checkbox]":function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(e.$("input[type=checkbox]:focus")[0])return;e.trigger("blur",e)},0)}},getValue:function(){var e=[];return this.$("input[type=checkbox]:checked").each(function(){e.push(t(this).val())}),e},setValue:function(e){n.isArray(e)||(e=[e]),this.$("input[type=checkbox]").val(e)},focus:function(){if(this.hasFocus)return;this.$("input[type=checkbox]").first().focus()},blur:function(){if(!this.hasFocus)return;this.$("input[type=checkbox]:focus").blur()},_arrayToHtml:function(e){var t=[],r=this;return n.each(e,function(e,i){var s="
  • ";if(n.isObject(e)){var o=e.val||e.val===0?e.val:"";s+='',s+='"}else s+='',s+='";s+="
  • ",t.push(s)}),t.join("")}}),s.Object=s.Base.extend({hasNestedForm:!0,className:"bbf-object",initialize:function(e){this.value={},s.Base.prototype.initialize.call(this,e);if(!this.schema.subSchema)throw new Error("Missing required 'schema.subSchema' option for Object editor")},render:function(){return this.form=new i({schema:this.schema.subSchema,data:this.value,idPrefix:this.id+"_",fieldTemplate:"nestedField"}),this._observeFormEvents(),this.$el.html(this.form.render().el),this.hasFocus&&this.trigger("blur",this),this},getValue:function(){return this.form?this.form.getValue():this.value},setValue:function(e){this.value=e,this.render()},focus:function(){if(this.hasFocus)return;this.form.focus()},blur:function(){if(!this.hasFocus)return;this.form.blur()},remove:function(){this.form.remove(),r.View.prototype.remove.call(this)},validate:function(){return this.form.validate()},_observeFormEvents:function(){this.form.on("all",function(){var e=n.toArray(arguments);e[1]=this,this.trigger.apply(this,e)},this)}}),s.NestedModel=s.Object.extend({initialize:function(e){s.Base.prototype.initialize.call(this,e);if(!e.schema.model)throw'Missing required "schema.model" option for NestedModel editor'},render:function(){var e=this.value||{},t=this.key,n=this.schema.model,r=e.constructor===n?e:new n(e);return this.form=new i({model:r,idPrefix:this.id+"_",fieldTemplate:"nestedField"}),this._observeFormEvents(),this.$el.html(this.form.render().el),this.hasFocus&&this.trigger("blur",this),this},commit:function(){var e=this.form.commit();return e?(this.$el.addClass("error"),e):s.Object.prototype.commit.call(this)}}),s.Date=s.Base.extend({events:{"change select":function(){this.updateHidden(),this.trigger("change",this)},"focus select":function(){if(this.hasFocus)return;this.trigger("focus",this)},"blur select":function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(e.$("select:focus")[0])return;e.trigger("blur",e)},0)}},initialize:function(e){e=e||{},s.Base.prototype.initialize.call(this,e);var t=s.Date,r=new Date;this.options=n.extend({monthNames:t.monthNames,showMonthNames:t.showMonthNames},e),this.schema=n.extend({yearStart:r.getFullYear()-100,yearEnd:r.getFullYear()},e.schema||{}),this.value&&!n.isDate(this.value)&&(this.value=new Date(this.value));if(!this.value){var i=new Date;i.setSeconds(0),i.setMilliseconds(0),this.value=i}},render:function(){var e=this.options,r=this.schema,s=n.map(n.range(1,32),function(e){return'"}),o=n.map(n.range(0,12),function(t){var n=e.showMonthNames?e.monthNames[t]:t+1;return'"}),u=r.yearStart'+e+""}),f=t(i.templates.date({dates:s.join(""),months:o.join(""),years:a.join("")}));return this.$date=f.find('select[data-type="date"]'),this.$month=f.find('select[data-type="month"]'),this.$year=f.find('select[data-type="year"]'),this.$hidden=t(''),f.append(this.$hidden),this.setValue(this.value),this.setElement(f),this.$el.attr("id",this.id),this.hasFocus&&this.trigger("blur",this),this},getValue:function(){var e=this.$year.val(),t=this.$month.val(),n=this.$date.val();return!e||!t||!n?null:new Date(e,t,n)},setValue:function(e){this.$date.val(e.getDate()),this.$month.val(e.getMonth()),this.$year.val(e.getFullYear()),this.updateHidden()},focus:function(){if(this.hasFocus)return;this.$("select").first().focus()},blur:function(){if(!this.hasFocus)return;this.$("select:focus").blur()},updateHidden:function(){var e=this.getValue();n.isDate(e)&&(e=e.toISOString()),this.$hidden.val(e)}},{showMonthNames:!0,monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"]}),s.DateTime=s.Base.extend({events:{"change select":function(){this.updateHidden(),this.trigger("change",this)},"focus select":function(){if(this.hasFocus)return;this.trigger("focus",this)},"blur select":function(){if(!this.hasFocus)return;var e=this;setTimeout(function(){if(e.$("select:focus")[0])return;e.trigger("blur",e)},0)}},initialize:function(e){e=e||{},s.Base.prototype.initialize.call(this,e),this.options=n.extend({DateEditor:s.DateTime.DateEditor},e),this.schema=n.extend({minsInterval:15},e.schema||{}),this.dateEditor=new this.options.DateEditor(e),this.value=this.dateEditor.value},render:function(){function e(e){return e<10?"0"+e:e}var r=this.schema,s=n.map(n.range(0,24),function(t){return'"}),o=n.map(n.range(0,60,r.minsInterval),function(t){return'"}),u=t(i.templates.dateTime({date:'',hours:s.join(),mins:o.join()}));return u.find(".bbf-tmp").replaceWith(this.dateEditor.render().el),this.$hour=u.find('select[data-type="hour"]'),this.$min=u.find('select[data-type="min"]'),this.$hidden=u.find('input[type="hidden"]'),this.setValue(this.value),this.setElement(u),this.$el.attr("id",this.id),this.hasFocus&&this.trigger("blur",this),this},getValue:function(){var e=this.dateEditor.getValue(),t=this.$hour.val(),n=this.$min.val();return!e||!t||!n?null:(e.setHours(t),e.setMinutes(n),e)},setValue:function(e){n.isDate(e)||(e=new Date(e)),this.dateEditor.setValue(e),this.$hour.val(e.getHours()),this.$min.val(e.getMinutes()),this.updateHidden()},focus:function(){if(this.hasFocus)return;this.$("select").first().focus()},blur:function(){if(!this.hasFocus)return;this.$("select:focus").blur()},updateHidden:function(){var e=this.getValue();n.isDate(e)&&(e=e.toISOString()),this.$hidden.val(e)},remove:function(){this.dateEditor.remove(),s.Base.prototype.remove.call(this)}},{DateEditor:s.Date}),s}(),i.setTemplates=i.helpers.setTemplates,i.setTemplateCompiler=i.helpers.setTemplateCompiler,i.templates={},i.setTemplates({form:'
    {{fieldsets}}
    ',fieldset:"
    {{legend}}
      {{fields}}
    ",field:'
  • {{editor}}
    {{help}}
    {{error}}
  • ',nestedField:'
  • {{editor}}
    {{help}}
    {{error}}
  • ',list:'
      {{items}}
    ',listItem:'
  • {{editor}}
  • ',date:'
    ',dateTime:'
    {{date}}
    :
    ',"list.Modal":'
    {{summary}}
    '},{error:"bbf-error"}),i.VERSION="0.11.0",r.Form=i})(this)