+
+
+
+ /**
+ * Find any element that has been added to a form, using it's ID or name
+ * This can include framesets, columns etc. along with regular fields..
+ * @param {String} id - id or name to find.
+
+ * @return {Element} e - or false if nothing found.
+ */
+ findbyId : function(id)
+ {
+ var ret = false;
+ if (!id) {
+ return ret;
+ }
+ Roo.each(this.allItems, function(f){
+ if (f.id == id || f.name == id ){
+ ret = f;
+ return false;
+ }
+ });
+ return ret;
+ },
+
+
+
+ /**
+ * Render this form into the passed container. This should only be called once!
+ * @param {String/HTMLElement/Element} container The element this component should be rendered into
+ * @return {Form} this
+ */
+ render : function(ct)
+ {
+
+
+
+ ct = Roo.get(ct);
+ var o = this.autoCreate || {
+ tag: 'form',
+ method : this.method || 'POST',
+ id : this.id || Roo.id()
+ };
+ this.initEl(ct.createChild(o));
+
+ this.root.render(this.el);
+
+
+
+ this.items.each(function(f){
+ f.render('x-form-el-'+f.id);
+ });
+
+ if(this.buttons.length > 0){
+ // tables are required to maintain order and for correct IE layout
+ var tb = this.el.createChild({cls:'x-form-btns-ct', cn: {
+ cls:"x-form-btns x-form-btns-"+this.buttonAlign,
+ html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
+ }}, null, true);
+ var tr = tb.getElementsByTagName('tr')[0];
+ for(var i = 0, len = this.buttons.length; i < len; i++) {
+ var b = this.buttons[i];
+ var td = document.createElement('td');
+ td.className = 'x-form-btn-td';
+ b.render(tr.appendChild(td));
+ }
+ }
+ if(this.monitorValid){ // initialize after render
+ this.startMonitoring();
+ }
+ this.fireEvent('rendered', this);
+ return this;
+ },
+
+ /**
+ * Adds a button to the footer of the form - this <b>must</b> be called before the form is rendered.
+ * @param {String/Object} config A string becomes the button text, an object can either be a Button config
+ * object or a valid Roo.DomHelper element config
+ * @param {Function} handler The function called when the button is clicked
+ * @param {Object} scope (optional) The scope of the handler function
+ * @return {Roo.Button}
+ */
+ addButton : function(config, handler, scope){
+ var bc = {
+ handler: handler,
+ scope: scope,
+ minWidth: this.minButtonWidth,
+ hideParent:true
+ };
+ if(typeof config == "string"){
+ bc.text = config;
+ }else{
+ Roo.apply(bc, config);
+ }
+ var btn = new Roo.Button(null, bc);
+ this.buttons.push(btn);
+ return btn;
+ },
+
+ /**
+ * Adds a series of form elements (using the xtype property as the factory method.
+ * Valid xtypes are: TextField, TextArea .... Button, Layout, FieldSet, Column, (and 'end' to close a block)
+ * @param {Object} config
+ */
+
+ addxtype : function()
+ {
+ var ar = Array.prototype.slice.call(arguments, 0);
+ var ret = false;
+ for(var i = 0; i < ar.length; i++) {
+ if (!ar[i]) {
+ continue; // skip -- if this happends something invalid got sent, we
+ // should ignore it, as basically that interface element will not show up
+ // and that should be pretty obvious!!
+ }
+
+ if (Roo.form[ar[i].xtype]) {
+ ar[i].form = this;
+ var fe = Roo.factory(ar[i], Roo.form);
+ if (!ret) {
+ ret = fe;
+ }
+ fe.form = this;
+ if (fe.store) {
+ fe.store.form = this;
+ }
+ if (fe.isLayout) {
+
+ this.start(fe);
+ this.allItems.push(fe);
+ if (fe.items && fe.addxtype) {
+ fe.addxtype.apply(fe, fe.items);
+ delete fe.items;
+ }
+ this.end();
+ continue;
+ }
+
+
+
+ this.add(fe);
+ // console.log('adding ' + ar[i].xtype);
+ }
+ if (ar[i].xtype == 'Button') {
+ //console.log('adding button');
+ //console.log(ar[i]);
+ this.addButton(ar[i]);
+ this.allItems.push(fe);
+ continue;
+ }
+
+ if (ar[i].xtype == 'end') { // so we can add fieldsets... / layout etc.
+ alert('end is not supported on xtype any more, use items');
+ // this.end();
+ // //console.log('adding end');
+ }
+
+ }
+ return ret;
+ },
+
+ /**
+ * Starts monitoring of the valid state of this form. Usually this is done by passing the config
+ * option "monitorValid"
+ */
+ startMonitoring : function(){
+ if(!this.bound){
+ this.bound = true;
+ Roo.TaskMgr.start({
+ run : this.bindHandler,
+ interval : this.monitorPoll || 200,
+ scope: this
+ });
+ }
+ },
+
+ /**
+ * Stops monitoring of the valid state of this form
+ */
+ stopMonitoring : function(){
+ this.bound = false;
+ },
+
+ // private
+ bindHandler : function(){
+ if(!this.bound){
+ return false; // stops binding
+ }
+ var valid = true;
+ this.items.each(function(f){
+ if(!f.isValid(true)){
+ valid = false;
+ return false;
+ }
+ });
+ for(var i = 0, len = this.buttons.length; i < len; i++){
+ var btn = this.buttons[i];
+ if(btn.formBind === true && btn.disabled === valid){
+ btn.setDisabled(!valid);
+ }
+ }
+ this.fireEvent('clientvalidation', this, valid);
+ }
+
+
+
+
+
+
+
+
+});
+
+
+// back compat
+Roo.Form = Roo.form.Form;
+/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+// as we use this in bootstrap.
+Roo.namespace('Roo.form');
+ /**
+ * @class Roo.form.Action
+ * Internal Class used to handle form actions
+ * @constructor
+ * @param {Roo.form.BasicForm} el The form element or its id
+ * @param {Object} config Configuration options
+ */
+
+
+
+// define the action interface
+Roo.form.Action = function(form, options){
+ this.form = form;
+ this.options = options || {};
+};
+/**
+ * Client Validation Failed
+ * @const
+ */
+Roo.form.Action.CLIENT_INVALID = 'client';
+/**
+ * Server Validation Failed
+ * @const
+ */
+Roo.form.Action.SERVER_INVALID = 'server';
+ /**
+ * Connect to Server Failed
+ * @const
+ */
+Roo.form.Action.CONNECT_FAILURE = 'connect';
+/**
+ * Reading Data from Server Failed
+ * @const
+ */
+Roo.form.Action.LOAD_FAILURE = 'load';
+
+Roo.form.Action.prototype = {
+ type : 'default',
+ failureType : undefined,
+ response : undefined,
+ result : undefined,
+
+ // interface method
+ run : function(options){
+
+ },
+
+ // interface method
+ success : function(response){
+
+ },
+
+ // interface method
+ handleResponse : function(response){
+
+ },
+
+ // default connection failure
+ failure : function(response){
+
+ this.response = response;
+ this.failureType = Roo.form.Action.CONNECT_FAILURE;
+ this.form.afterAction(this, false);
+ },
+
+ processResponse : function(response){
+ this.response = response;
+ if(!response.responseText){
+ return true;
+ }
+ this.result = this.handleResponse(response);
+ return this.result;
+ },
+
+ // utility functions used internally
+ getUrl : function(appendParams){
+ var url = this.options.url || this.form.url || this.form.el.dom.action;
+ if(appendParams){
+ var p = this.getParams();
+ if(p){
+ url += (url.indexOf('?') != -1 ? '&' : '?') + p;
+ }
+ }
+ return url;
+ },
+
+ getMethod : function(){
+ return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
+ },
+
+ getParams : function(){
+ var bp = this.form.baseParams;
+ var p = this.options.params;
+ if(p){
+ if(typeof p == "object"){
+ p = Roo.urlEncode(Roo.applyIf(p, bp));
+ }else if(typeof p == 'string' && bp){
+ p += '&' + Roo.urlEncode(bp);
+ }
+ }else if(bp){
+ p = Roo.urlEncode(bp);
+ }
+ return p;
+ },
+
+ createCallback : function(){
+ return {
+ success: this.success,
+ failure: this.failure,
+ scope: this,
+ timeout: (this.form.timeout*1000),
+ upload: this.form.fileUpload ? this.success : undefined
+ };
+ }
+};
+
+Roo.form.Action.Submit = function(form, options){
+ Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
+};
+
+Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
+ type : 'submit',
+
+ haveProgress : false,
+ uploadComplete : false,
+
+ // uploadProgress indicator.
+ uploadProgress : function()
+ {
+ if (!this.form.progressUrl) {
+ return;
+ }
+
+ if (!this.haveProgress) {
+ Roo.MessageBox.progress("Uploading", "Uploading");
+ }
+ if (this.uploadComplete) {
+ Roo.MessageBox.hide();
+ return;
+ }
+
+ this.haveProgress = true;
+
+ var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
+
+ var c = new Roo.data.Connection();
+ c.request({
+ url : this.form.progressUrl,
+ params: {
+ id : uid
+ },
+ method: 'GET',
+ success : function(req){
+ //console.log(data);
+ var rdata = false;
+ var edata;
+ try {
+ rdata = Roo.decode(req.responseText)
+ } catch (e) {
+ Roo.log("Invalid data from server..");
+ Roo.log(edata);
+ return;
+ }
+ if (!rdata || !rdata.success) {
+ Roo.log(rdata);
+ Roo.MessageBox.alert(Roo.encode(rdata));
+ return;
+ }
+ var data = rdata.data;
+
+ if (this.uploadComplete) {
+ Roo.MessageBox.hide();
+ return;
+ }
+
+ if (data){
+ Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
+ Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
+ );
+ }
+ this.uploadProgress.defer(2000,this);
+ },
+
+ failure: function(data) {
+ Roo.log('progress url failed ');
+ Roo.log(data);
+ },
+ scope : this
+ });
+
+ },
+
+
+ run : function()
+ {
+ // run get Values on the form, so it syncs any secondary forms.
+ this.form.getValues();
+
+ var o = this.options;
+ var method = this.getMethod();
+ var isPost = method == 'POST';
+ if(o.clientValidation === false || this.form.isValid()){
+
+ if (this.form.progressUrl) {
+ this.form.findField('UPLOAD_IDENTIFIER').setValue(
+ (new Date() * 1) + '' + Math.random());
+
+ }
+
+
+ Roo.Ajax.request(Roo.apply(this.createCallback(), {
+ form:this.form.el.dom,
+ url:this.getUrl(!isPost),
+ method: method,
+ params:isPost ? this.getParams() : null,
+ isUpload: this.form.fileUpload,
+ formData : this.form.formData
+ }));
+
+ this.uploadProgress();
+
+ }else if (o.clientValidation !== false){ // client validation failed
+ this.failureType = Roo.form.Action.CLIENT_INVALID;
+ this.form.afterAction(this, false);
+ }
+ },
+
+ success : function(response)
+ {
+ this.uploadComplete= true;
+ if (this.haveProgress) {
+ Roo.MessageBox.hide();
+ }
+
+
+ var result = this.processResponse(response);
+ if(result === true || result.success){
+ this.form.afterAction(this, true);
+ return;
+ }
+ if(result.errors){
+ this.form.markInvalid(result.errors);
+ this.failureType = Roo.form.Action.SERVER_INVALID;
+ }
+ this.form.afterAction(this, false);
+ },
+ failure : function(response)
+ {
+ this.uploadComplete= true;
+ if (this.haveProgress) {
+ Roo.MessageBox.hide();
+ }
+
+ this.response = response;
+ this.failureType = Roo.form.Action.CONNECT_FAILURE;
+ this.form.afterAction(this, false);
+ },
+
+ handleResponse : function(response){
+ if(this.form.errorReader){
+ var rs = this.form.errorReader.read(response);
+ var errors = [];
+ if(rs.records){
+ for(var i = 0, len = rs.records.length; i < len; i++) {
+ var r = rs.records[i];
+ errors[i] = r.data;
+ }
+ }
+ if(errors.length < 1){
+ errors = null;
+ }
+ return {
+ success : rs.success,
+ errors : errors
+ };
+ }
+ var ret = false;
+ try {
+ var rt = response.responseText;
+ if (rt.match(/^\<!--\[CDATA\[/)) {
+ rt = rt.replace(/^\<!--\[CDATA\[/,'');
+ rt = rt.replace(/\]\]--\>$/,'');
+ }
+
+ ret = Roo.decode(rt);
+ } catch (e) {
+ ret = {
+ success: false,
+ errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
+ errors : []
+ };
+ }
+ return ret;
+
+ }
+});
+
+
+Roo.form.Action.Load = function(form, options){
+ Roo.form.Action.Load.superclass.constructor.call(this, form, options);
+ this.reader = this.form.reader;
+};
+
+Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
+ type : 'load',
+
+ run : function(){
+
+ Roo.Ajax.request(Roo.apply(
+ this.createCallback(), {
+ method:this.getMethod(),
+ url:this.getUrl(false),
+ params:this.getParams()
+ }));
+ },
+
+ success : function(response){
+
+ var result = this.processResponse(response);
+ if(result === true || !result.success || !result.data){
+ this.failureType = Roo.form.Action.LOAD_FAILURE;
+ this.form.afterAction(this, false);
+ return;
+ }
+ this.form.clearInvalid();
+ this.form.setValues(result.data);
+ this.form.afterAction(this, true);
+ },
+
+ handleResponse : function(response){
+ if(this.form.reader){
+ var rs = this.form.reader.read(response);
+ var data = rs.records && rs.records[0] ? rs.records[0].data : null;
+ return {
+ success : rs.success,
+ data : data
+ };
+ }
+ return Roo.decode(response.responseText);
+ }
+});
+
+Roo.form.Action.ACTION_TYPES = {
+ 'load' : Roo.form.Action.Load,
+ 'submit' : Roo.form.Action.Submit
+};/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.form.Layout
+ * @extends Roo.Component
+ * @children Roo.form.Column Roo.form.Row Roo.form.Field Roo.Button Roo.form.TextItem Roo.form.FieldSet
+ * Creates a container for layout and rendering of fields in an {@link Roo.form.Form}.
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+Roo.form.Layout = function(config){
+ var xitems = [];
+ if (config.items) {
+ xitems = config.items;
+ delete config.items;
+ }
+ Roo.form.Layout.superclass.constructor.call(this, config);
+ this.stack = [];
+ Roo.each(xitems, this.addxtype, this);
+
+};
+
+Roo.extend(Roo.form.Layout, Roo.Component, {
+ /**
+ * @cfg {String/Object} autoCreate
+ * A DomHelper element spec used to autocreate the layout (defaults to {tag: 'div', cls: 'x-form-ct'})
+ */
+ /**
+ * @cfg {String/Object/Function} style
+ * A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
+ * a function which returns such a specification.
+ */
+ /**
+ * @cfg {String} labelAlign (left|top|right)
+ * Valid values are "left," "top" and "right" (defaults to "left")
+ */
+ /**
+ * @cfg {Number} labelWidth
+ * Fixed width in pixels of all field labels (defaults to undefined)
+ */
+ /**
+ * @cfg {Boolean} clear
+ * True to add a clearing element at the end of this layout, equivalent to CSS clear: both (defaults to true)
+ */
+ clear : true,
+ /**
+ * @cfg {String} labelSeparator
+ * The separator to use after field labels (defaults to ':')
+ */
+ labelSeparator : ':',
+ /**
+ * @cfg {Boolean} hideLabels
+ * True to suppress the display of field labels in this layout (defaults to false)
+ */
+ hideLabels : false,
+
+ // private
+ defaultAutoCreate : {tag: 'div', cls: 'x-form-ct'},
+
+ isLayout : true,
+
+ // private
+ onRender : function(ct, position){
+ if(this.el){ // from markup
+ this.el = Roo.get(this.el);
+ }else { // generate
+ var cfg = this.getAutoCreate();
+ this.el = ct.createChild(cfg, position);
+ }
+ if(this.style){
+ this.el.applyStyles(this.style);
+ }
+ if(this.labelAlign){
+ this.el.addClass('x-form-label-'+this.labelAlign);
+ }
+ if(this.hideLabels){
+ this.labelStyle = "display:none";
+ this.elementStyle = "padding-left:0;";
+ }else{
+ if(typeof this.labelWidth == 'number'){
+ this.labelStyle = "width:"+this.labelWidth+"px;";
+ this.elementStyle = "padding-left:"+((this.labelWidth+(typeof this.labelPad == 'number' ? this.labelPad : 5))+'px')+";";
+ }
+ if(this.labelAlign == 'top'){
+ this.labelStyle = "width:auto;";
+ this.elementStyle = "padding-left:0;";
+ }
+ }
+ var stack = this.stack;
+ var slen = stack.length;
+ if(slen > 0){
+ if(!this.fieldTpl){
+ var t = new Roo.Template(
+ '<div class="x-form-item {5}">',
+ '<label for="{0}" style="{2}">{1}{4}</label>',
+ '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
+ '</div>',
+ '</div><div class="x-form-clear-left"></div>'
+ );
+ t.disableFormats = true;
+ t.compile();
+ Roo.form.Layout.prototype.fieldTpl = t;
+ }
+ for(var i = 0; i < slen; i++) {
+ if(stack[i].isFormField){
+ this.renderField(stack[i]);
+ }else{
+ this.renderComponent(stack[i]);
+ }
+ }
+ }
+ if(this.clear){
+ this.el.createChild({cls:'x-form-clear'});
+ }
+ },
+
+ // private
+ renderField : function(f){
+ f.fieldEl = Roo.get(this.fieldTpl.append(this.el, [
+ f.id, //0
+ f.fieldLabel, //1
+ f.labelStyle||this.labelStyle||'', //2
+ this.elementStyle||'', //3
+ typeof f.labelSeparator == 'undefined' ? this.labelSeparator : f.labelSeparator, //4
+ f.itemCls||this.itemCls||'' //5
+ ], true).getPrevSibling());
+ },
+
+ // private
+ renderComponent : function(c){
+ c.render(c.isLayout ? this.el : this.el.createChild());
+ },
+ /**
+ * Adds a object form elements (using the xtype property as the factory method.)
+ * Valid xtypes are: TextField, TextArea .... Button, Layout, FieldSet, Column
+ * @param {Object} config
+ */
+ addxtype : function(o)
+ {
+ // create the lement.
+ o.form = this.form;
+ var fe = Roo.factory(o, Roo.form);
+ this.form.allItems.push(fe);
+ this.stack.push(fe);
+
+ if (fe.isFormField) {
+ this.form.items.add(fe);
+ }
+
+ return fe;
+ }
+});
+
+
+/**
+ * @class Roo.form.Column
+ * @extends Roo.form.Layout
+ * @children Roo.form.Row Roo.form.Field Roo.Button Roo.form.TextItem Roo.form.FieldSet
+ * Creates a column container for layout and rendering of fields in an {@link Roo.form.Form}.
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+Roo.form.Column = function(config){
+ Roo.form.Column.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.form.Column, Roo.form.Layout, {
+ /**
+ * @cfg {Number/String} width
+ * The fixed width of the column in pixels or CSS value (defaults to "auto")
+ */
+ /**
+ * @cfg {String/Object} autoCreate
+ * A DomHelper element spec used to autocreate the column (defaults to {tag: 'div', cls: 'x-form-ct x-form-column'})
+ */
+
+ // private
+ defaultAutoCreate : {tag: 'div', cls: 'x-form-ct x-form-column'},
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.Column.superclass.onRender.call(this, ct, position);
+ if(this.width){
+ this.el.setWidth(this.width);
+ }
+ }
+});
+
+/**
+ * @class Roo.form.Row
+ * @extends Roo.form.Layout
+ * @children Roo.form.Column Roo.form.Row Roo.form.Field Roo.Button Roo.form.TextItem Roo.form.FieldSet
+ * Creates a row container for layout and rendering of fields in an {@link Roo.form.Form}.
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+
+
+Roo.form.Row = function(config){
+ Roo.form.Row.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.form.Row, Roo.form.Layout, {
+ /**
+ * @cfg {Number/String} width
+ * The fixed width of the column in pixels or CSS value (defaults to "auto")
+ */
+ /**
+ * @cfg {Number/String} height
+ * The fixed height of the column in pixels or CSS value (defaults to "auto")
+ */
+ defaultAutoCreate : {tag: 'div', cls: 'x-form-ct x-form-row'},
+
+ padWidth : 20,
+ // private
+ onRender : function(ct, position){
+ //console.log('row render');
+ if(!this.rowTpl){
+ var t = new Roo.Template(
+ '<div class="x-form-item {5}" style="float:left;width:{6}px">',
+ '<label for="{0}" style="{2}">{1}{4}</label>',
+ '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
+ '</div>',
+ '</div>'
+ );
+ t.disableFormats = true;
+ t.compile();
+ Roo.form.Layout.prototype.rowTpl = t;
+ }
+ this.fieldTpl = this.rowTpl;
+
+ //console.log('lw' + this.labelWidth +', la:' + this.labelAlign);
+ var labelWidth = 100;
+
+ if ((this.labelAlign != 'top')) {
+ if (typeof this.labelWidth == 'number') {
+ labelWidth = this.labelWidth
+ }
+ this.padWidth = 20 + labelWidth;
+
+ }
+
+ Roo.form.Column.superclass.onRender.call(this, ct, position);
+ if(this.width){
+ this.el.setWidth(this.width);
+ }
+ if(this.height){
+ this.el.setHeight(this.height);
+ }
+ },
+
+ // private
+ renderField : function(f){
+ f.fieldEl = this.fieldTpl.append(this.el, [
+ f.id, f.fieldLabel,
+ f.labelStyle||this.labelStyle||'',
+ this.elementStyle||'',
+ typeof f.labelSeparator == 'undefined' ? this.labelSeparator : f.labelSeparator,
+ f.itemCls||this.itemCls||'',
+ f.width ? f.width + this.padWidth : 160 + this.padWidth
+ ],true);
+ }
+});
+
+
+/**
+ * @class Roo.form.FieldSet
+ * @extends Roo.form.Layout
+ * @children Roo.form.Column Roo.form.Row Roo.form.Field Roo.Button Roo.form.TextItem
+ * Creates a fieldset container for layout and rendering of fields in an {@link Roo.form.Form}.
+ * @constructor
+ * @param {Object} config Configuration options
+ */
+Roo.form.FieldSet = function(config){
+ Roo.form.FieldSet.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.form.FieldSet, Roo.form.Layout, {
+ /**
+ * @cfg {String} legend
+ * The text to display as the legend for the FieldSet (defaults to '')
+ */
+ /**
+ * @cfg {String/Object} autoCreate
+ * A DomHelper element spec used to autocreate the fieldset (defaults to {tag: 'fieldset', cn: {tag:'legend'}})
+ */
+
+ // private
+ defaultAutoCreate : {tag: 'fieldset', cn: {tag:'legend'}},
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.FieldSet.superclass.onRender.call(this, ct, position);
+ if(this.legend){
+ this.setLegend(this.legend);
+ }
+ },
+
+ // private
+ setLegend : function(text){
+ if(this.rendered){
+ this.el.child('legend').update(text);
+ }
+ }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.form.VTypes
+ * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
+ * @static
+ */
+Roo.form.VTypes = function(){
+ // closure these in so they are only created once.
+ var alpha = /^[a-zA-Z_]+$/;
+ var alphanum = /^[a-zA-Z0-9_]+$/;
+ var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,24}$/;
+ var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+
+ // All these messages and functions are configurable
+ return {
+ /**
+ * The function used to validate email addresses
+ * @param {String} value The email address
+ */
+ email : function(v){
+ return email.test(v);
+ },
+ /**
+ * The error text to display when the email validation function returns false
+ * @type String
+ */
+ emailText : 'This field should be an e-mail address in the format "user@domain.com"',
+ /**
+ * The keystroke filter mask to be applied on email input
+ * @type RegExp
+ */
+ emailMask : /[a-z0-9_\.\-@]/i,
+
+ /**
+ * The function used to validate URLs
+ * @param {String} value The URL
+ */
+ url : function(v){
+ return url.test(v);
+ },
+ /**
+ * The error text to display when the url validation function returns false
+ * @type String
+ */
+ urlText : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
+
+ /**
+ * The function used to validate alpha values
+ * @param {String} value The value
+ */
+ alpha : function(v){
+ return alpha.test(v);
+ },
+ /**
+ * The error text to display when the alpha validation function returns false
+ * @type String
+ */
+ alphaText : 'This field should only contain letters and _',
+ /**
+ * The keystroke filter mask to be applied on alpha input
+ * @type RegExp
+ */
+ alphaMask : /[a-z_]/i,
+
+ /**
+ * The function used to validate alphanumeric values
+ * @param {String} value The value
+ */
+ alphanum : function(v){
+ return alphanum.test(v);
+ },
+ /**
+ * The error text to display when the alphanumeric validation function returns false
+ * @type String
+ */
+ alphanumText : 'This field should only contain letters, numbers and _',
+ /**
+ * The keystroke filter mask to be applied on alphanumeric input
+ * @type RegExp
+ */
+ alphanumMask : /[a-z0-9_]/i
+ };
+}();//<script type="text/javascript">
+
+/**
+ * @class Roo.form.FCKeditor
+ * @extends Roo.form.TextArea
+ * Wrapper around the FCKEditor http://www.fckeditor.net
+ * @constructor
+ * Creates a new FCKeditor
+ * @param {Object} config Configuration options
+ */
+Roo.form.FCKeditor = function(config){
+ Roo.form.FCKeditor.superclass.constructor.call(this, config);
+ this.addEvents({
+ /**
+ * @event editorinit
+ * Fired when the editor is initialized - you can add extra handlers here..
+ * @param {FCKeditor} this
+ * @param {Object} the FCK object.
+ */
+ editorinit : true
+ });
+
+
+};
+Roo.form.FCKeditor.editors = { };
+Roo.extend(Roo.form.FCKeditor, Roo.form.TextArea,
+{
+ //defaultAutoCreate : {
+ // tag : "textarea",style : "width:100px;height:60px;" ,autocomplete : "off"
+ //},
+ // private
+ /**
+ * @cfg {Object} fck options - see fck manual for details.
+ */
+ fckconfig : false,
+
+ /**
+ * @cfg {Object} fck toolbar set (Basic or Default)
+ */
+ toolbarSet : 'Basic',
+ /**
+ * @cfg {Object} fck BasePath
+ */
+ basePath : '/fckeditor/',
+
+
+ frame : false,
+
+ value : '',
+
+
+ onRender : function(ct, position)
+ {
+ if(!this.el){
+ this.defaultAutoCreate = {
+ tag: "textarea",
+ style:"width:300px;height:60px;",
+ autocomplete: "new-password"
+ };
+ }
+ Roo.form.FCKeditor.superclass.onRender.call(this, ct, position);
+ /*
+ if(this.grow){
+ this.textSizeEl = Roo.DomHelper.append(document.body, {tag: "pre", cls: "x-form-grow-sizer"});
+ if(this.preventScrollbars){
+ this.el.setStyle("overflow", "hidden");
+ }
+ this.el.setHeight(this.growMin);
+ }
+ */
+ //console.log('onrender' + this.getId() );
+ Roo.form.FCKeditor.editors[this.getId()] = this;
+
+
+ this.replaceTextarea() ;
+
+ },
+
+ getEditor : function() {
+ return this.fckEditor;
+ },
+ /**
+ * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
+ * @param {Mixed} value The value to set
+ */
+
+
+ setValue : function(value)
+ {
+ //console.log('setValue: ' + value);
+
+ if(typeof(value) == 'undefined') { // not sure why this is happending...
+ return;
+ }
+ Roo.form.FCKeditor.superclass.setValue.apply(this,[value]);
+
+ //if(!this.el || !this.getEditor()) {
+ // this.value = value;
+ //this.setValue.defer(100,this,[value]);
+ // return;
+ //}
+
+ if(!this.getEditor()) {
+ return;
+ }
+
+ this.getEditor().SetData(value);
+
+ //
+
+ },
+
+ /**
+ * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
+ * @return {Mixed} value The field value
+ */
+ getValue : function()
+ {
+
+ if (this.frame && this.frame.dom.style.display == 'none') {
+ return Roo.form.FCKeditor.superclass.getValue.call(this);
+ }
+
+ if(!this.el || !this.getEditor()) {
+
+ // this.getValue.defer(100,this);
+ return this.value;
+ }
+
+
+ var value=this.getEditor().GetData();
+ Roo.form.FCKeditor.superclass.setValue.apply(this,[value]);
+ return Roo.form.FCKeditor.superclass.getValue.call(this);
+
+
+ },
+
+ /**
+ * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
+ * @return {Mixed} value The field value
+ */
+ getRawValue : function()
+ {
+ if (this.frame && this.frame.dom.style.display == 'none') {
+ return Roo.form.FCKeditor.superclass.getRawValue.call(this);
+ }
+
+ if(!this.el || !this.getEditor()) {
+ //this.getRawValue.defer(100,this);
+ return this.value;
+ return;
+ }
+
+
+
+ var value=this.getEditor().GetData();
+ Roo.form.FCKeditor.superclass.setRawValue.apply(this,[value]);
+ return Roo.form.FCKeditor.superclass.getRawValue.call(this);
+
+ },
+
+ setSize : function(w,h) {
+
+
+
+ //if (this.frame && this.frame.dom.style.display == 'none') {
+ // Roo.form.FCKeditor.superclass.setSize.apply(this, [w, h]);
+ // return;
+ //}
+ //if(!this.el || !this.getEditor()) {
+ // this.setSize.defer(100,this, [w,h]);
+ // return;
+ //}
+
+
+
+ Roo.form.FCKeditor.superclass.setSize.apply(this, [w, h]);
+
+ this.frame.dom.setAttribute('width', w);
+ this.frame.dom.setAttribute('height', h);
+ this.frame.setSize(w,h);
+
+ },
+
+ toggleSourceEdit : function(value) {
+
+
+
+ this.el.dom.style.display = value ? '' : 'none';
+ this.frame.dom.style.display = value ? 'none' : '';
+
+ },
+
+
+ focus: function(tag)
+ {
+ if (this.frame.dom.style.display == 'none') {
+ return Roo.form.FCKeditor.superclass.focus.call(this);
+ }
+ if(!this.el || !this.getEditor()) {
+ this.focus.defer(100,this, [tag]);
+ return;
+ }
+
+
+
+
+ var tgs = this.getEditor().EditorDocument.getElementsByTagName(tag);
+ this.getEditor().Focus();
+ if (tgs.length) {
+ if (!this.getEditor().Selection.GetSelection()) {
+ this.focus.defer(100,this, [tag]);
+ return;
+ }
+
+
+ var r = this.getEditor().EditorDocument.createRange();
+ r.setStart(tgs[0],0);
+ r.setEnd(tgs[0],0);
+ this.getEditor().Selection.GetSelection().removeAllRanges();
+ this.getEditor().Selection.GetSelection().addRange(r);
+ this.getEditor().Focus();
+ }
+
+ },
+
+
+
+ replaceTextarea : function()
+ {
+ if ( document.getElementById( this.getId() + '___Frame' ) ) {
+ return ;
+ }
+ //if ( !this.checkBrowser || this._isCompatibleBrowser() )
+ //{
+ // We must check the elements firstly using the Id and then the name.
+ var oTextarea = document.getElementById( this.getId() );
+
+ var colElementsByName = document.getElementsByName( this.getId() ) ;
+
+ oTextarea.style.display = 'none' ;
+
+ if ( oTextarea.tabIndex ) {
+ this.TabIndex = oTextarea.tabIndex ;
+ }
+
+ this._insertHtmlBefore( this._getConfigHtml(), oTextarea ) ;
+ this._insertHtmlBefore( this._getIFrameHtml(), oTextarea ) ;
+ this.frame = Roo.get(this.getId() + '___Frame')
+ },
+
+ _getConfigHtml : function()
+ {
+ var sConfig = '' ;
+
+ for ( var o in this.fckconfig ) {
+ sConfig += sConfig.length > 0 ? '&' : '';
+ sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.fckconfig[o] ) ;
+ }
+
+ return '<input type="hidden" id="' + this.getId() + '___Config" value="' + sConfig + '" style="display:none" />' ;
+ },
+
+
+ _getIFrameHtml : function()
+ {
+ var sFile = 'fckeditor.html' ;
+ /* no idea what this is about..
+ try
+ {
+ if ( (/fcksource=true/i).test( window.top.location.search ) )
+ sFile = 'fckeditor.original.html' ;
+ }
+ catch (e) {
+ */
+
+ var sLink = this.basePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.getId() ) ;
+ sLink += this.toolbarSet ? ( '&Toolbar=' + this.toolbarSet) : '';
+
+
+ var html = '<iframe id="' + this.getId() +
+ '___Frame" src="' + sLink +
+ '" width="' + this.width +
+ '" height="' + this.height + '"' +
+ (this.tabIndex ? ' tabindex="' + this.tabIndex + '"' :'' ) +
+ ' frameborder="0" scrolling="no"></iframe>' ;
+
+ return html ;
+ },
+
+ _insertHtmlBefore : function( html, element )
+ {
+ if ( element.insertAdjacentHTML ) {
+ // IE
+ element.insertAdjacentHTML( 'beforeBegin', html ) ;
+ } else { // Gecko
+ var oRange = document.createRange() ;
+ oRange.setStartBefore( element ) ;
+ var oFragment = oRange.createContextualFragment( html );
+ element.parentNode.insertBefore( oFragment, element ) ;
+ }
+ }
+
+
+
+
+
+
+
+
+});
+
+//Roo.reg('fckeditor', Roo.form.FCKeditor);
+
+function FCKeditor_OnComplete(editorInstance){
+ var f = Roo.form.FCKeditor.editors[editorInstance.Name];
+ f.fckEditor = editorInstance;
+ //console.log("loaded");
+ f.fireEvent('editorinit', f, editorInstance);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//<script type="text/javascript">
+/**
+ * @class Roo.form.GridField
+ * @extends Roo.form.Field
+ * Embed a grid (or editable grid into a form)
+ * STATUS ALPHA
+ *
+ * This embeds a grid in a form, the value of the field should be the json encoded array of rows
+ * it needs
+ * xgrid.store = Roo.data.Store
+ * xgrid.store.proxy = Roo.data.MemoryProxy (data = [] )
+ * xgrid.store.reader = Roo.data.JsonReader
+ *
+ *
+ * @constructor
+ * Creates a new GridField
+ * @param {Object} config Configuration options
+ */
+Roo.form.GridField = function(config){
+ Roo.form.GridField.superclass.constructor.call(this, config);
+
+};
+
+Roo.extend(Roo.form.GridField, Roo.form.Field, {
+ /**
+ * @cfg {Number} width - used to restrict width of grid..
+ */
+ width : 100,
+ /**
+ * @cfg {Number} height - used to restrict height of grid..
+ */
+ height : 50,
+ /**
+ * @cfg {Object} xgrid (xtype'd description of grid) { xtype : 'Grid', dataSource: .... }
+ *
+ *}
+ */
+ xgrid : false,
+ /**
+ * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
+ * {tag: "input", type: "checkbox", autocomplete: "off"})
+ */
+ // defaultAutoCreate : { tag: 'div' },
+ defaultAutoCreate : { tag: 'input', type: 'hidden', autocomplete: 'new-password'},
+ /**
+ * @cfg {String} addTitle Text to include for adding a title.
+ */
+ addTitle : false,
+ //
+ onResize : function(){
+ Roo.form.Field.superclass.onResize.apply(this, arguments);
+ },
+
+ initEvents : function(){
+ // Roo.form.Checkbox.superclass.initEvents.call(this);
+ // has no events...
+
+ },
+
+
+ getResizeEl : function(){
+ return this.wrap;
+ },
+
+ getPositionEl : function(){
+ return this.wrap;
+ },
+
+ // private
+ onRender : function(ct, position){
+
+ this.style = this.style || 'overflow: hidden; border:1px solid #c3daf9;';
+ var style = this.style;
+ delete this.style;
+
+ Roo.form.GridField.superclass.onRender.call(this, ct, position);
+ this.wrap = this.el.wrap({cls: ''}); // not sure why ive done thsi...
+ this.viewEl = this.wrap.createChild({ tag: 'div' });
+ if (style) {
+ this.viewEl.applyStyles(style);
+ }
+ if (this.width) {
+ this.viewEl.setWidth(this.width);
+ }
+ if (this.height) {
+ this.viewEl.setHeight(this.height);
+ }
+ //if(this.inputValue !== undefined){
+ //this.setValue(this.value);
+
+
+ this.grid = new Roo.grid[this.xgrid.xtype](this.viewEl, this.xgrid);
+
+
+ this.grid.render();
+ this.grid.getDataSource().on('remove', this.refreshValue, this);
+ this.grid.getDataSource().on('update', this.refreshValue, this);
+ this.grid.on('afteredit', this.refreshValue, this);
+
+ },
+
+
+ /**
+ * Sets the value of the item.
+ * @param {String} either an object or a string..
+ */
+ setValue : function(v){
+ //this.value = v;
+ v = v || []; // empty set..
+ // this does not seem smart - it really only affects memoryproxy grids..
+ if (this.grid && this.grid.getDataSource() && typeof(v) != 'undefined') {
+ var ds = this.grid.getDataSource();
+ // assumes a json reader..
+ var data = {}
+ data[ds.reader.meta.root ] = typeof(v) == 'string' ? Roo.decode(v) : v;
+ ds.loadData( data);
+ }
+ // clear selection so it does not get stale.
+ if (this.grid.sm) {
+ this.grid.sm.clearSelections();
+ }
+
+ Roo.form.GridField.superclass.setValue.call(this, v);
+ this.refreshValue();
+ // should load data in the grid really....
+ },
+
+ // private
+ refreshValue: function() {
+ var val = [];
+ this.grid.getDataSource().each(function(r) {
+ val.push(r.data);
+ });
+ this.el.dom.value = Roo.encode(val);
+ }
+
+
+
+
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.form.DisplayField
+ * @extends Roo.form.Field
+ * A generic Field to display non-editable data.
+ * @cfg {Boolean} closable (true|false) default false
+ * @constructor
+ * Creates a new Display Field item.
+ * @param {Object} config Configuration options
+ */
+Roo.form.DisplayField = function(config){
+ Roo.form.DisplayField.superclass.constructor.call(this, config);
+
+ this.addEvents({
+ /**
+ * @event close
+ * Fires after the click the close btn
+ * @param {Roo.form.DisplayField} this
+ */
+ close : true
+ });
+};
+
+Roo.extend(Roo.form.DisplayField, Roo.form.TextField, {
+ inputType: 'hidden',
+ allowBlank: true,
+ readOnly: true,
+
+
+ /**
+ * @cfg {String} focusClass The CSS class to use when the checkbox receives focus (defaults to undefined)
+ */
+ focusClass : undefined,
+ /**
+ * @cfg {String} fieldClass The default CSS class for the checkbox (defaults to "x-form-field")
+ */
+ fieldClass: 'x-form-field',
+
+ /**
+ * @cfg {Function} valueRenderer The renderer for the field (so you can reformat output). should return raw HTML
+ */
+ valueRenderer: undefined,
+
+ width: 100,
+ /**
+ * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
+ * {tag: "input", type: "checkbox", autocomplete: "off"})
+ */
+
+ // defaultAutoCreate : { tag: 'input', type: 'hidden', autocomplete: 'off'},
+
+ closable : false,
+
+ onResize : function(){
+ Roo.form.DisplayField.superclass.onResize.apply(this, arguments);
+
+ },
+
+ initEvents : function(){
+ // Roo.form.Checkbox.superclass.initEvents.call(this);
+ // has no events...
+
+ if(this.closable){
+ this.closeEl.on('click', this.onClose, this);
+ }
+
+ },
+
+
+ getResizeEl : function(){
+ return this.wrap;
+ },
+
+ getPositionEl : function(){
+ return this.wrap;
+ },
+
+ // private
+ onRender : function(ct, position){
+
+ Roo.form.DisplayField.superclass.onRender.call(this, ct, position);
+ //if(this.inputValue !== undefined){
+ this.wrap = this.el.wrap();
+
+ this.viewEl = this.wrap.createChild({ tag: 'div', cls: 'x-form-displayfield'});
+
+ if(this.closable){
+ this.closeEl = this.wrap.createChild({ tag: 'div', cls: 'x-dlg-close'});
+ }
+
+ if (this.bodyStyle) {
+ this.viewEl.applyStyles(this.bodyStyle);
+ }
+ //this.viewEl.setStyle('padding', '2px');
+
+ this.setValue(this.value);
+
+ },
+/*
+ // private
+ initValue : Roo.emptyFn,
+
+ */
+
+ // private
+ onClick : function(){
+
+ },
+
+ /**
+ * Sets the checked state of the checkbox.
+ * @param {Boolean/String} checked True, 'true', '1', or 'on' to check the checkbox, any other value will uncheck it.
+ */
+ setValue : function(v){
+ this.value = v;
+ var html = this.valueRenderer ? this.valueRenderer(v) : String.format('{0}', v);
+ // this might be called before we have a dom element..
+ if (!this.viewEl) {
+ return;
+ }
+ this.viewEl.dom.innerHTML = html;
+ Roo.form.DisplayField.superclass.setValue.call(this, v);
+
+ },
+
+ onClose : function(e)
+ {
+ e.preventDefault();
+
+ this.fireEvent('close', this);
+ }
+});/*
+ *
+ * Licence- LGPL
+ *
+ */
+
+/**
+ * @class Roo.form.DayPicker
+ * @extends Roo.form.Field
+ * A Day picker show [M] [T] [W] ....
+ * @constructor
+ * Creates a new Day Picker
+ * @param {Object} config Configuration options
+ */
+Roo.form.DayPicker= function(config){
+ Roo.form.DayPicker.superclass.constructor.call(this, config);
+
+};
+
+Roo.extend(Roo.form.DayPicker, Roo.form.Field, {
+ /**
+ * @cfg {String} focusClass The CSS class to use when the checkbox receives focus (defaults to undefined)
+ */
+ focusClass : undefined,
+ /**
+ * @cfg {String} fieldClass The default CSS class for the checkbox (defaults to "x-form-field")
+ */
+ fieldClass: "x-form-field",
+
+ /**
+ * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
+ * {tag: "input", type: "checkbox", autocomplete: "off"})
+ */
+ defaultAutoCreate : { tag: "input", type: 'hidden', autocomplete: "new-password"},
+
+
+ actionMode : 'viewEl',
+ //
+ // private
+
+ inputType : 'hidden',
+
+
+ inputElement: false, // real input element?
+ basedOn: false, // ????
+
+ isFormField: true, // not sure where this is needed!!!!
+
+ onResize : function(){
+ Roo.form.Checkbox.superclass.onResize.apply(this, arguments);
+ if(!this.boxLabel){
+ this.el.alignTo(this.wrap, 'c-c');
+ }
+ },
+
+ initEvents : function(){
+ Roo.form.Checkbox.superclass.initEvents.call(this);
+ this.el.on("click", this.onClick, this);
+ this.el.on("change", this.onClick, this);
+ },
+
+
+ getResizeEl : function(){
+ return this.wrap;
+ },
+
+ getPositionEl : function(){
+ return this.wrap;
+ },
+
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.Checkbox.superclass.onRender.call(this, ct, position);
+
+ this.wrap = this.el.wrap({cls: 'x-form-daypick-item '});
+
+ var r1 = '<table><tr>';
+ var r2 = '<tr class="x-form-daypick-icons">';
+ for (var i=0; i < 7; i++) {
+ r1+= '<td><div>' + Date.dayNames[i].substring(0,3) + '</div></td>';
+ r2+= '<td><img class="x-menu-item-icon" src="' + Roo.BLANK_IMAGE_URL +'"></td>';
+ }
+
+ var viewEl = this.wrap.createChild( r1 + '</tr>' + r2 + '</tr></table>');
+ viewEl.select('img').on('click', this.onClick, this);
+ this.viewEl = viewEl;
+
+
+ // this will not work on Chrome!!!
+ this.el.on('DOMAttrModified', this.setFromHidden, this); //ff
+ this.el.on('propertychange', this.setFromHidden, this); //ie
+
+
+
+
+ },
+
+ // private
+ initValue : Roo.emptyFn,
+
+ /**
+ * Returns the checked state of the checkbox.
+ * @return {Boolean} True if checked, else false
+ */
+ getValue : function(){
+ return this.el.dom.value;
+
+ },
+
+ // private
+ onClick : function(e){
+ //this.setChecked(!this.checked);
+ Roo.get(e.target).toggleClass('x-menu-item-checked');
+ this.refreshValue();
+ //if(this.el.dom.checked != this.checked){
+ // this.setValue(this.el.dom.checked);
+ // }
+ },
+
+ // private
+ refreshValue : function()
+ {
+ var val = '';
+ this.viewEl.select('img',true).each(function(e,i,n) {
+ val += e.is(".x-menu-item-checked") ? String(n) : '';
+ });
+ this.setValue(val, true);
+ },
+
+ /**
+ * Sets the checked state of the checkbox.
+ * On is always based on a string comparison between inputValue and the param.
+ * @param {Boolean/String} value - the value to set
+ * @param {Boolean/String} suppressEvent - whether to suppress the checkchange event.
+ */
+ setValue : function(v,suppressEvent){
+ if (!this.el.dom) {
+ return;
+ }
+ var old = this.el.dom.value ;
+ this.el.dom.value = v;
+ if (suppressEvent) {
+ return ;
+ }
+
+ // update display..
+ this.viewEl.select('img',true).each(function(e,i,n) {
+
+ var on = e.is(".x-menu-item-checked");
+ var newv = v.indexOf(String(n)) > -1;
+ if (on != newv) {
+ e.toggleClass('x-menu-item-checked');
+ }
+
+ });
+
+
+ this.fireEvent('change', this, v, old);
+
+
+ },
+
+ // handle setting of hidden value by some other method!!?!?
+ setFromHidden: function()
+ {
+ if(!this.el){
+ return;
+ }
+ //console.log("SET FROM HIDDEN");
+ //alert('setFrom hidden');
+ this.setValue(this.el.dom.value);
+ },
+
+ onDestroy : function()
+ {
+ if(this.viewEl){
+ Roo.get(this.viewEl).remove();
+ }
+
+ Roo.form.DayPicker.superclass.onDestroy.call(this);
+ }
+
+});/*
+ * RooJS Library 1.1.1
+ * Copyright(c) 2008-2011 Alan Knowles
+ *
+ * License - LGPL
+ */
+
+
+/**
+ * @class Roo.form.ComboCheck
+ * @extends Roo.form.ComboBox
+ * A combobox for multiple select items.
+ *
+ * FIXME - could do with a reset button..
+ *
+ * @constructor
+ * Create a new ComboCheck
+ * @param {Object} config Configuration options
+ */
+Roo.form.ComboCheck = function(config){
+ Roo.form.ComboCheck.superclass.constructor.call(this, config);
+ // should verify some data...
+ // like
+ // hiddenName = required..
+ // displayField = required
+ // valudField == required
+ var req= [ 'hiddenName', 'displayField', 'valueField' ];
+ var _t = this;
+ Roo.each(req, function(e) {
+ if ((typeof(_t[e]) == 'undefined' ) || !_t[e].length) {
+ throw "Roo.form.ComboCheck : missing value for: " + e;
+ }
+ });
+
+
+};
+
+Roo.extend(Roo.form.ComboCheck, Roo.form.ComboBox, {
+
+
+ editable : false,
+
+ selectedClass: 'x-menu-item-checked',
+
+ // private
+ onRender : function(ct, position){
+ var _t = this;
+
+
+
+ if(!this.tpl){
+ var cls = 'x-combo-list';
+
+
+ this.tpl = new Roo.Template({
+ html : '<div class="'+cls+'-item x-menu-check-item">' +
+ '<img class="x-menu-item-icon" style="margin: 0px;" src="' + Roo.BLANK_IMAGE_URL + '">' +
+ '<span>{' + this.displayField + '}</span>' +
+ '</div>'
+
+ });
+ }
+
+
+ Roo.form.ComboCheck.superclass.onRender.call(this, ct, position);
+ this.view.singleSelect = false;
+ this.view.multiSelect = true;
+ this.view.toggleSelect = true;
+ this.pageTb.add(new Roo.Toolbar.Fill(), {
+
+ text: 'Done',
+ handler: function()
+ {
+ _t.collapse();
+ }
+ });
+ },
+
+ onViewOver : function(e, t){
+ // do nothing...
+ return;
+
+ },
+
+ onViewClick : function(doFocus,index){
+ return;
+
+ },
+ select: function () {
+ //Roo.log("SELECT CALLED");
+ },
+
+ selectByValue : function(xv, scrollIntoView){
+ var ar = this.getValueArray();
+ var sels = [];
+
+ Roo.each(ar, function(v) {
+ if(v === undefined || v === null){
+ return;
+ }
+ var r = this.findRecord(this.valueField, v);
+ if(r){
+ sels.push(this.store.indexOf(r))
+
+ }
+ },this);
+ this.view.select(sels);
+ return false;
+ },
+
+
+
+ onSelect : function(record, index){
+ // Roo.log("onselect Called");
+ // this is only called by the clear button now..
+ this.view.clearSelections();
+ this.setValue('[]');
+ if (this.value != this.valueBefore) {
+ this.fireEvent('change', this, this.value, this.valueBefore);
+ this.valueBefore = this.value;
+ }
+ },
+ getValueArray : function()
+ {
+ var ar = [] ;
+
+ try {
+ //Roo.log(this.value);
+ if (typeof(this.value) == 'undefined') {
+ return [];
+ }
+ var ar = Roo.decode(this.value);
+ return ar instanceof Array ? ar : []; //?? valid?
+
+ } catch(e) {
+ Roo.log(e + "\nRoo.form.ComboCheck:getValueArray invalid data:" + this.getValue());
+ return [];
+ }
+
+ },
+ expand : function ()
+ {
+
+ Roo.form.ComboCheck.superclass.expand.call(this);
+ this.valueBefore = typeof(this.value) == 'undefined' ? '' : this.value;
+ //this.valueBefore = typeof(this.valueBefore) == 'undefined' ? '' : this.valueBefore;
+
+
+ },
+
+ collapse : function(){
+ Roo.form.ComboCheck.superclass.collapse.call(this);
+ var sl = this.view.getSelectedIndexes();
+ var st = this.store;
+ var nv = [];
+ var tv = [];
+ var r;
+ Roo.each(sl, function(i) {
+ r = st.getAt(i);
+ nv.push(r.get(this.valueField));
+ },this);
+ this.setValue(Roo.encode(nv));
+ if (this.value != this.valueBefore) {
+
+ this.fireEvent('change', this, this.value, this.valueBefore);
+ this.valueBefore = this.value;
+ }
+
+ },
+
+ setValue : function(v){
+ // Roo.log(v);
+ this.value = v;
+
+ var vals = this.getValueArray();
+ var tv = [];
+ Roo.each(vals, function(k) {
+ var r = this.findRecord(this.valueField, k);
+ if(r){
+ tv.push(r.data[this.displayField]);
+ }else if(this.valueNotFoundText !== undefined){
+ tv.push( this.valueNotFoundText );
+ }
+ },this);
+ // Roo.log(tv);
+
+ Roo.form.ComboBox.superclass.setValue.call(this, tv.join(', '));
+ this.hiddenField.value = v;
+ this.value = v;
+ }
+
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.form.Signature
+ * @extends Roo.form.Field
+ * Signature field.
+ * @constructor
+ *
+ * @param {Object} config Configuration options
+ */
+
+Roo.form.Signature = function(config){
+ Roo.form.Signature.superclass.constructor.call(this, config);
+
+ this.addEvents({// not in used??
+ /**
+ * @event confirm
+ * Fires when the 'confirm' icon is pressed (add a listener to enable add button)
+ * @param {Roo.form.Signature} combo This combo box
+ */
+ 'confirm' : true,
+ /**
+ * @event reset
+ * Fires when the 'edit' icon is pressed (add a listener to enable add button)
+ * @param {Roo.form.ComboBox} combo This combo box
+ * @param {Roo.data.Record|false} record The data record returned from the underlying store (or false on nothing selected)
+ */
+ 'reset' : true
+ });
+};
+
+Roo.extend(Roo.form.Signature, Roo.form.Field, {
+ /**
+ * @cfg {Object} labels Label to use when rendering a form.
+ * defaults to
+ * labels : {
+ * clear : "Clear",
+ * confirm : "Confirm"
+ * }
+ */
+ labels : {
+ clear : "Clear",
+ confirm : "Confirm"
+ },
+ /**
+ * @cfg {Number} width The signature panel width (defaults to 300)
+ */
+ width: 300,
+ /**
+ * @cfg {Number} height The signature panel height (defaults to 100)
+ */
+ height : 100,
+ /**
+ * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to false)
+ */
+ allowBlank : false,
+
+ //private
+ // {Object} signPanel The signature SVG panel element (defaults to {})
+ signPanel : {},
+ // {Boolean} isMouseDown False to validate that the mouse down event (defaults to false)
+ isMouseDown : false,
+ // {Boolean} isConfirmed validate the signature is confirmed or not for submitting form (defaults to false)
+ isConfirmed : false,
+ // {String} signatureTmp SVG mapping string (defaults to empty string)
+ signatureTmp : '',
+
+
+ defaultAutoCreate : { // modified by initCompnoent..
+ tag: "input",
+ type:"hidden"
+ },
+
+ // private
+ onRender : function(ct, position){
+
+ Roo.form.Signature.superclass.onRender.call(this, ct, position);
+
+ this.wrap = this.el.wrap({
+ cls:'x-form-signature-wrap', style : 'width: ' + this.width + 'px', cn:{cls:'x-form-signature'}
+ });
+
+ this.createToolbar(this);
+ this.signPanel = this.wrap.createChild({
+ tag: 'div',
+ style: 'width: ' + this.width + 'px; height: ' + this.height + 'px; border: 0;'
+ }, this.el
+ );
+
+ this.svgID = Roo.id();
+ this.svgEl = this.signPanel.createChild({
+ xmlns : 'http://www.w3.org/2000/svg',
+ tag : 'svg',
+ id : this.svgID + "-svg",
+ width: this.width,
+ height: this.height,
+ viewBox: '0 0 '+this.width+' '+this.height,
+ cn : [
+ {
+ tag: "rect",
+ id: this.svgID + "-svg-r",
+ width: this.width,
+ height: this.height,
+ fill: "#ffa"
+ },
+ {
+ tag: "line",
+ id: this.svgID + "-svg-l",
+ x1: "0", // start
+ y1: (this.height*0.8), // start set the line in 80% of height
+ x2: this.width, // end
+ y2: (this.height*0.8), // end set the line in 80% of height
+ 'stroke': "#666",
+ 'stroke-width': "1",
+ 'stroke-dasharray': "3",
+ 'shape-rendering': "crispEdges",
+ 'pointer-events': "none"
+ },
+ {
+ tag: "path",
+ id: this.svgID + "-svg-p",
+ 'stroke': "navy",
+ 'stroke-width': "3",
+ 'fill': "none",
+ 'pointer-events': 'none'
+ }
+ ]
+ });
+ this.createSVG();
+ this.svgBox = this.svgEl.dom.getScreenCTM();
+ },
+ createSVG : function(){
+ var svg = this.signPanel;
+ var r = svg.select('#'+ this.svgID + '-svg-r', true).first().dom;
+ var t = this;
+
+ r.addEventListener('mousedown', function(e) { return t.down(e); }, false);
+ r.addEventListener('mousemove', function(e) { return t.move(e); }, false);
+ r.addEventListener('mouseup', function(e) { return t.up(e); }, false);
+ r.addEventListener('mouseout', function(e) { return t.up(e); }, false);
+ r.addEventListener('touchstart', function(e) { return t.down(e); }, false);
+ r.addEventListener('touchmove', function(e) { return t.move(e); }, false);
+ r.addEventListener('touchend', function(e) { return t.up(e); }, false);
+
+ },
+ isTouchEvent : function(e){
+ return e.type.match(/^touch/);
+ },
+ getCoords : function (e) {
+ var pt = this.svgEl.dom.createSVGPoint();
+ pt.x = e.clientX;
+ pt.y = e.clientY;
+ if (this.isTouchEvent(e)) {
+ pt.x = e.targetTouches[0].clientX;
+ pt.y = e.targetTouches[0].clientY;
+ }
+ var a = this.svgEl.dom.getScreenCTM();
+ var b = a.inverse();
+ var mx = pt.matrixTransform(b);
+ return mx.x + ',' + mx.y;
+ },
+ //mouse event headler
+ down : function (e) {
+ this.signatureTmp += 'M' + this.getCoords(e) + ' ';
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr('d', this.signatureTmp);
+
+ this.isMouseDown = true;
+
+ e.preventDefault();
+ },
+ move : function (e) {
+ if (this.isMouseDown) {
+ this.signatureTmp += 'L' + this.getCoords(e) + ' ';
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', this.signatureTmp);
+ }
+
+ e.preventDefault();
+ },
+ up : function (e) {
+ this.isMouseDown = false;
+ var sp = this.signatureTmp.split(' ');
+
+ if(sp.length > 1){
+ if(!sp[sp.length-2].match(/^L/)){
+ sp.pop();
+ sp.pop();
+ sp.push("");
+ this.signatureTmp = sp.join(" ");
+ }
+ }
+ if(this.getValue() != this.signatureTmp){
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.isConfirmed = false;
+ }
+ e.preventDefault();
+ },
+
+ /**
+ * Protected method that will not generally be called directly. It
+ * is called when the editor creates its toolbar. Override this method if you need to
+ * add custom toolbar buttons.
+ * @param {HtmlEditor} editor
+ */
+ createToolbar : function(editor){
+ function btn(id, toggle, handler){
+ var xid = fid + '-'+ id ;
+ return {
+ id : xid,
+ cmd : id,
+ cls : 'x-btn-icon x-edit-'+id,
+ enableToggle:toggle !== false,
+ scope: editor, // was editor...
+ handler:handler||editor.relayBtnCmd,
+ clickEvent:'mousedown',
+ tooltip: etb.buttonTips[id] || undefined, ///tips ???
+ tabIndex:-1
+ };
+ }
+
+
+ var tb = new Roo.Toolbar(editor.wrap.dom.firstChild);
+ this.tb = tb;
+ this.tb.add(
+ {
+ cls : ' x-signature-btn x-signature-'+id,
+ scope: editor, // was editor...
+ handler: this.reset,
+ clickEvent:'mousedown',
+ text: this.labels.clear
+ },
+ {
+ xtype : 'Fill',
+ xns: Roo.Toolbar
+ },
+ {
+ cls : ' x-signature-btn x-signature-'+id,
+ scope: editor, // was editor...
+ handler: this.confirmHandler,
+ clickEvent:'mousedown',
+ text: this.labels.confirm
+ }
+ );
+
+ },
+ //public
+ /**
+ * when user is clicked confirm then show this image.....
+ *
+ * @return {String} Image Data URI
+ */
+ getImageDataURI : function(){
+ var svg = this.svgEl.dom.parentNode.innerHTML;
+ var src = 'data:image/svg+xml;base64,'+window.btoa(svg);
+ return src;
+ },
+ /**
+ *
+ * @return {Boolean} this.isConfirmed
+ */
+ getConfirmed : function(){
+ return this.isConfirmed;
+ },
+ /**
+ *
+ * @return {Number} this.width
+ */
+ getWidth : function(){
+ return this.width;
+ },
+ /**
+ *
+ * @return {Number} this.height
+ */
+ getHeight : function(){
+ return this.height;
+ },
+ // private
+ getSignature : function(){
+ return this.signatureTmp;
+ },
+ // private
+ reset : function(){
+ this.signatureTmp = '';
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', '');
+ this.isConfirmed = false;
+ Roo.form.Signature.superclass.reset.call(this);
+ },
+ setSignature : function(s){
+ this.signatureTmp = s;
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', s);
+ this.setValue(s);
+ this.isConfirmed = false;
+ Roo.form.Signature.superclass.reset.call(this);
+ },
+ test : function(){
+// Roo.log(this.signPanel.dom.contentWindow.up())
+ },
+ //private
+ setConfirmed : function(){
+
+
+
+// Roo.log(Roo.get(this.signPanel.dom.contentWindow.r).attr('fill', '#cfc'));
+ },
+ // private
+ confirmHandler : function(){
+ if(!this.getSignature()){
+ return;
+ }
+
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#cfc');
+ this.setValue(this.getSignature());
+ this.isConfirmed = true;
+
+ this.fireEvent('confirm', this);
+ },
+ // private
+ // Subclasses should provide the validation implementation by overriding this
+ validateValue : function(value){
+ if(this.allowBlank){
+ return true;
+ }
+
+ if(this.isConfirmed){
+ return true;
+ }
+ return false;
+ }
+});/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+
+
+/**
+ * @class Roo.form.ComboBox
+ * @extends Roo.form.TriggerField
+ * A combobox control with support for autocomplete, remote-loading, paging and many other features.
+ * @constructor
+ * Create a new ComboBox.
+ * @param {Object} config Configuration options
+ */
+Roo.form.Select = function(config){
+ Roo.form.Select.superclass.constructor.call(this, config);
+
+};
+
+Roo.extend(Roo.form.Select , Roo.form.ComboBox, {
+ /**
+ * @cfg {String/HTMLElement/Element} transform The id, DOM node or element of an existing select to convert to a ComboBox
+ */
+ /**
+ * @cfg {Boolean} lazyRender True to prevent the ComboBox from rendering until requested (should always be used when
+ * rendering into an Roo.Editor, defaults to false)
+ */
+ /**
+ * @cfg {Boolean/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to:
+ * {tag: "input", type: "text", size: "24", autocomplete: "off"})
+ */
+ /**
+ * @cfg {Roo.data.Store} store The data store to which this combo is bound (defaults to undefined)
+ */
+ /**
+ * @cfg {String} title If supplied, a header element is created containing this text and added into the top of
+ * the dropdown list (defaults to undefined, with no header element)
+ */
+
+ /**
+ * @cfg {String/Roo.Template} tpl The template to use to render the output
+ */
+
+ // private
+ defaultAutoCreate : {tag: "select" },
+ /**
+ * @cfg {Number} listWidth The width in pixels of the dropdown list (defaults to the width of the ComboBox field)
+ */
+ listWidth: undefined,
+ /**
+ * @cfg {String} displayField The underlying data field name to bind to this CombBox (defaults to undefined if
+ * mode = 'remote' or 'text' if mode = 'local')
+ */
+ displayField: undefined,
+ /**
+ * @cfg {String} valueField The underlying data value name to bind to this CombBox (defaults to undefined if
+ * mode = 'remote' or 'value' if mode = 'local').
+ * Note: use of a valueField requires the user make a selection
+ * in order for a value to be mapped.
+ */
+ valueField: undefined,
+
+
+ /**
+ * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the
+ * field's data value (defaults to the underlying DOM element's name)
+ */
+ hiddenName: undefined,
+ /**
+ * @cfg {String} listClass CSS class to apply to the dropdown list element (defaults to '')
+ */
+ listClass: '',
+ /**
+ * @cfg {String} selectedClass CSS class to apply to the selected item in the dropdown list (defaults to 'x-combo-selected')
+ */
+ selectedClass: 'x-combo-selected',
+ /**
+ * @cfg {String} triggerClass An additional CSS class used to style the trigger button. The trigger will always get the
+ * class 'x-form-trigger' and triggerClass will be <b>appended</b> if specified (defaults to 'x-form-arrow-trigger'
+ * which displays a downward arrow icon).
+ */
+ triggerClass : 'x-form-arrow-trigger',
+ /**
+ * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop" for bottom-right
+ */
+ shadow:'sides',
+ /**
+ * @cfg {String} listAlign A valid anchor position value. See {@link Roo.Element#alignTo} for details on supported
+ * anchor positions (defaults to 'tl-bl')
+ */
+ listAlign: 'tl-bl?',
+ /**
+ * @cfg {Number} maxHeight The maximum height in pixels of the dropdown list before scrollbars are shown (defaults to 300)
+ */
+ maxHeight: 300,
+ /**
+ * @cfg {String} triggerAction The action to execute when the trigger field is activated. Use 'all' to run the
+ * query specified by the allQuery config option (defaults to 'query')
+ */
+ triggerAction: 'query',
+ /**
+ * @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and typeahead activate
+ * (defaults to 4, does not apply if editable = false)
+ */
+ minChars : 4,
+ /**
+ * @cfg {Boolean} typeAhead True to populate and autoselect the remainder of the text being typed after a configurable
+ * delay (typeAheadDelay) if it matches a known value (defaults to false)
+ */
+ typeAhead: false,
+ /**
+ * @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and sending the
+ * query to filter the dropdown list (defaults to 500 if mode = 'remote' or 10 if mode = 'local')
+ */
+ queryDelay: 500,
+ /**
+ * @cfg {Number} pageSize If greater than 0, a paging toolbar is displayed in the footer of the dropdown list and the
+ * filter queries will execute with page start and limit parameters. Only applies when mode = 'remote' (defaults to 0)
+ */
+ pageSize: 0,
+ /**
+ * @cfg {Boolean} selectOnFocus True to select any existing text in the field immediately on focus. Only applies
+ * when editable = true (defaults to false)
+ */
+ selectOnFocus:false,
+ /**
+ * @cfg {String} queryParam Name of the query as it will be passed on the querystring (defaults to 'query')
+ */
+ queryParam: 'query',
+ /**
+ * @cfg {String} loadingText The text to display in the dropdown list while data is loading. Only applies
+ * when mode = 'remote' (defaults to 'Loading...')
+ */
+ loadingText: 'Loading...',
+ /**
+ * @cfg {Boolean} resizable True to add a resize handle to the bottom of the dropdown list (defaults to false)
+ */
+ resizable: false,
+ /**
+ * @cfg {Number} handleHeight The height in pixels of the dropdown list resize handle if resizable = true (defaults to 8)
+ */
+ handleHeight : 8,
+ /**
+ * @cfg {Boolean} editable False to prevent the user from typing text directly into the field, just like a
+ * traditional select (defaults to true)
+ */
+ editable: true,
+ /**
+ * @cfg {String} allQuery The text query to send to the server to return all records for the list with no filtering (defaults to '')
+ */
+ allQuery: '',
+ /**
+ * @cfg {String} mode Set to 'local' if the ComboBox loads local data (defaults to 'remote' which loads from the server)
+ */
+ mode: 'remote',
+ /**
+ * @cfg {Number} minListWidth The minimum width of the dropdown list in pixels (defaults to 70, will be ignored if
+ * listWidth has a higher value)
+ */
+ minListWidth : 70,
+ /**
+ * @cfg {Boolean} forceSelection True to restrict the selected value to one of the values in the list, false to
+ * allow the user to set arbitrary text into the field (defaults to false)
+ */
+ forceSelection:false,
+ /**
+ * @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
+ * if typeAhead = true (defaults to 250)
+ */
+ typeAheadDelay : 250,
+ /**
+ * @cfg {String} valueNotFoundText When using a name/value combo, if the value passed to setValue is not found in
+ * the store, valueNotFoundText will be displayed as the field text if defined (defaults to undefined)
+ */
+ valueNotFoundText : undefined,
+
+ /**
+ * @cfg {String} defaultValue The value displayed after loading the store.
+ */
+ defaultValue: '',
+
+ /**
+ * @cfg {Boolean} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
+ */
+ blockFocus : false,
+
+ /**
+ * @cfg {Boolean} disableClear Disable showing of clear button.
+ */
+ disableClear : false,
+ /**
+ * @cfg {Boolean} alwaysQuery Disable caching of results, and always send query
+ */
+ alwaysQuery : false,
+
+ //private
+ addicon : false,
+ editicon: false,
+
+ // element that contains real text value.. (when hidden is used..)
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.Field.prototype.onRender.call(this, ct, position);
+
+ if(this.store){
+ this.store.on('beforeload', this.onBeforeLoad, this);
+ this.store.on('load', this.onLoad, this);
+ this.store.on('loadexception', this.onLoadException, this);
+ this.store.load({});
+ }
+
+
+
+ },
+
+ // private
+ initEvents : function(){
+ //Roo.form.ComboBox.superclass.initEvents.call(this);
+
+ },
+
+ onDestroy : function(){
+
+ if(this.store){
+ this.store.un('beforeload', this.onBeforeLoad, this);
+ this.store.un('load', this.onLoad, this);
+ this.store.un('loadexception', this.onLoadException, this);
+ }
+ //Roo.form.ComboBox.superclass.onDestroy.call(this);
+ },
+
+ // private
+ fireKey : function(e){
+ if(e.isNavKeyPress() && !this.list.isVisible()){
+ this.fireEvent("specialkey", this, e);
+ }
+ },
+
+ // private
+ onResize: function(w, h){
+
+ return;
+
+
+ },
+
+ /**
+ * Allow or prevent the user from directly editing the field text. If false is passed,
+ * the user will only be able to select from the items defined in the dropdown list. This method
+ * is the runtime equivalent of setting the 'editable' config option at config time.
+ * @param {Boolean} value True to allow the user to directly edit the field text
+ */
+ setEditable : function(value){
+
+ },
+
+ // private
+ onBeforeLoad : function(){
+
+ Roo.log("Select before load");
+ return;
+
+ this.innerList.update(this.loadingText ?
+ '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
+ //this.restrictHeight();
+ this.selectedIndex = -1;
+ },
+
+ // private
+ onLoad : function(){
+
+
+ var dom = this.el.dom;
+ dom.innerHTML = '';
+ var od = dom.ownerDocument;
+
+ if (this.emptyText) {
+ var op = od.createElement('option');
+ op.setAttribute('value', '');
+ op.innerHTML = String.format('{0}', this.emptyText);
+ dom.appendChild(op);
+ }
+ if(this.store.getCount() > 0){
+
+ var vf = this.valueField;
+ var df = this.displayField;
+ this.store.data.each(function(r) {
+ // which colmsn to use... testing - cdoe / title..
+ var op = od.createElement('option');
+ op.setAttribute('value', r.data[vf]);
+ op.innerHTML = String.format('{0}', r.data[df]);
+ dom.appendChild(op);
+ });
+ if (typeof(this.defaultValue != 'undefined')) {
+ this.setValue(this.defaultValue);
+ }
+
+
+ }else{
+ //this.onEmptyResults();
+ }
+ //this.el.focus();
+ },
+ // private
+ onLoadException : function()
+ {
+ dom.innerHTML = '';
+
+ Roo.log("Select on load exception");
+ return;
+
+ this.collapse();
+ Roo.log(this.store.reader.jsonData);
+ if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+ Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+ }
+
+
+ },
+ // private
+ onTypeAhead : function(){
+
+ },
+
+ // private
+ onSelect : function(record, index){
+ Roo.log('on select?');
+ return;
+ if(this.fireEvent('beforeselect', this, record, index) !== false){
+ this.setFromData(index > -1 ? record.data : false);
+ this.collapse();
+ this.fireEvent('select', this, record, index);
+ }
+ },
+
+ /**
+ * Returns the currently selected field value or empty string if no value is set.
+ * @return {String} value The selected value
+ */
+ getValue : function(){
+ var dom = this.el.dom;
+ this.value = dom.options[dom.selectedIndex].value;
+ return this.value;
+
+ },
+
+ /**
+ * Clears any text/value currently set in the field
+ */
+ clearValue : function(){
+ this.value = '';
+ this.el.dom.selectedIndex = this.emptyText ? 0 : -1;
+
+ },
+
+ /**
+ * Sets the specified value into the field. If the value finds a match, the corresponding record text
+ * will be displayed in the field. If the value does not match the data value of an existing item,
+ * and the valueNotFoundText config option is defined, it will be displayed as the default field text.
+ * Otherwise the field will be blank (although the value will still be set).
+ * @param {String} value The value to match
+ */
+ setValue : function(v){
+ var d = this.el.dom;
+ for (var i =0; i < d.options.length;i++) {
+ if (v == d.options[i].value) {
+ d.selectedIndex = i;
+ this.value = v;
+ return;
+ }
+ }
+ this.clearValue();
+ },
+ /**
+ * @property {Object} the last set data for the element
+ */
+
+ lastData : false,
+ /**
+ * Sets the value of the field based on a object which is related to the record format for the store.
+ * @param {Object} value the value to set as. or false on reset?
+ */
+ setFromData : function(o){
+ Roo.log('setfrom data?');
+
+
+
+ },
+ // private
+ reset : function(){
+ this.clearValue();
+ },
+ // private
+ findRecord : function(prop, value){
+
+ return false;
+
+ var record;
+ if(this.store.getCount() > 0){
+ this.store.each(function(r){
+ if(r.data[prop] == value){
+ record = r;
+ return false;
+ }
+ return true;
+ });
+ }
+ return record;
+ },
+
+ getName: function()
+ {
+ // returns hidden if it's set..
+ if (!this.rendered) {return ''};
+ return !this.hiddenName && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
+
+ },
+
+
+
+
+ // private
+ onEmptyResults : function(){
+ Roo.log('empty results');
+ //this.collapse();
+ },
+
+ /**
+ * Returns true if the dropdown list is expanded, else false.
+ */
+ isExpanded : function(){
+ return false;
+ },
+
+ /**
+ * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
+ * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+ * @param {String} value The data value of the item to select
+ * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+ * selected item if it is not currently in view (defaults to true)
+ * @return {Boolean} True if the value matched an item in the list, else false
+ */
+ selectByValue : function(v, scrollIntoView){
+ Roo.log('select By Value');
+ return false;
+
+ if(v !== undefined && v !== null){
+ var r = this.findRecord(this.valueField || this.displayField, v);
+ if(r){
+ this.select(this.store.indexOf(r), scrollIntoView);
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /**
+ * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
+ * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+ * @param {Number} index The zero-based index of the list item to select
+ * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+ * selected item if it is not currently in view (defaults to true)
+ */
+ select : function(index, scrollIntoView){
+ Roo.log('select ');
+ return ;
+
+ this.selectedIndex = index;
+ this.view.select(index);
+ if(scrollIntoView !== false){
+ var el = this.view.getNode(index);
+ if(el){
+ this.innerList.scrollChildIntoView(el, false);
+ }
+ }
+ },
+
+
+
+ // private
+ validateBlur : function(){
+
+ return;
+
+ },
+
+ // private
+ initQuery : function(){
+ this.doQuery(this.getRawValue());
+ },
+
+ // private
+ doForce : function(){
+ if(this.el.dom.value.length > 0){
+ this.el.dom.value =
+ this.lastSelectionText === undefined ? '' : this.lastSelectionText;
+
+ }
+ },
+
+ /**
+ * Execute a query to filter the dropdown list. Fires the beforequery event prior to performing the
+ * query allowing the query action to be canceled if needed.
+ * @param {String} query The SQL query to execute
+ * @param {Boolean} forceAll True to force the query to execute even if there are currently fewer characters
+ * in the field than the minimum specified by the minChars config option. It also clears any filter previously
+ * saved in the current store (defaults to false)
+ */
+ doQuery : function(q, forceAll){
+
+ Roo.log('doQuery?');
+ if(q === undefined || q === null){
+ q = '';
+ }
+ var qe = {
+ query: q,
+ forceAll: forceAll,
+ combo: this,
+ cancel:false
+ };
+ if(this.fireEvent('beforequery', qe)===false || qe.cancel){
+ return false;
+ }
+ q = qe.query;
+ forceAll = qe.forceAll;
+ if(forceAll === true || (q.length >= this.minChars)){
+ if(this.lastQuery != q || this.alwaysQuery){
+ this.lastQuery = q;
+ if(this.mode == 'local'){
+ this.selectedIndex = -1;
+ if(forceAll){
+ this.store.clearFilter();
+ }else{
+ this.store.filter(this.displayField, q);
+ }
+ this.onLoad();
+ }else{
+ this.store.baseParams[this.queryParam] = q;
+ this.store.load({
+ params: this.getParams(q)
+ });
+ this.expand();
+ }
+ }else{
+ this.selectedIndex = -1;
+ this.onLoad();
+ }
+ }
+ },
+
+ // private
+ getParams : function(q){
+ var p = {};
+ //p[this.queryParam] = q;
+ if(this.pageSize){
+ p.start = 0;
+ p.limit = this.pageSize;
+ }
+ return p;
+ },
+
+ /**
+ * Hides the dropdown list if it is currently expanded. Fires the 'collapse' event on completion.
+ */
+ collapse : function(){
+
+ },
+
+ // private
+ collapseIf : function(e){
+
+ },
+
+ /**
+ * Expands the dropdown list if it is currently hidden. Fires the 'expand' event on completion.
+ */
+ expand : function(){
+
+ } ,
+
+ // private
+
+
+ /**
+ * @cfg {Boolean} grow
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMin
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMax
+ * @hide
+ */
+ /**
+ * @hide
+ * @method autoSize
+ */
+
+ setWidth : function()
+ {
+
+ },
+ getResizeEl : function(){
+ return this.el;
+ }
+});//<script type="text/javasscript">
+
+
+/**
+ * @class Roo.DDView
+ * A DnD enabled version of Roo.View.
+ * @param {Element/String} container The Element in which to create the View.
+ * @param {String} tpl The template string used to create the markup for each element of the View
+ * @param {Object} config The configuration properties. These include all the config options of
+ * {@link Roo.View} plus some specific to this class.<br>
+ * <p>
+ * Drag/drop is implemented by adding {@link Roo.data.Record}s to the target DDView. If copying is
+ * not being performed, the original {@link Roo.data.Record} is removed from the source DDView.<br>
+ * <p>
+ * The following extra CSS rules are needed to provide insertion point highlighting:<pre><code>