⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form-field.js

📁 zapatec suite 最新版 20070204,非常棒的ajax widgets 工具包
💻 JS
📖 第 1 页 / 共 4 页
字号:
// $Id: form-field.js 7944 2007-08-22 10:59:14Z andrew $/** * * Copyright (c) 2004-2006 by Zapatec, Inc. * http://www.zapatec.com * 1700 MLK Way, Berkeley, California, * 94709, U.S.A. * All rights reserved. *//** * @private * The Zapatec.Form object constructor. *  It would put special marks near field(basing on form config). * * You always could retrieve reference to this object: * <pre> *	document.getElementById('yourField').zpFormField * </pre> * @param form {Object} reference to Zapatec.Form instance. @see Zapatec.Form * @param field {Object} reference to HTML form element. */Zapatec.Form.Field = function(objArgs){	// Call constructor of superclass	Zapatec.Form.SUPERconstructor.call(this, objArgs);};/** * Unique static id of the widget class. Gives ability for Zapatec#inherit to * determine and store path to this file correctly when it is included using * Zapatec#include. When this file is included using Zapatec#include or path * to this file is gotten using Zapatec#getPath, this value must be specified * as script id. * @private */Zapatec.Form.Field.id = "Zapatec.Form.Field";// Inherit SuperClassZapatec.inherit(Zapatec.Form.Field, Zapatec.Widget);/** * Configures form field. Gets called from parent init method. * * @private * @param {object} objArgs User configuration */Zapatec.Form.Field.prototype.configure = function(objArgs){	// Set defaults config options	this.defineConfigOption('theme', 		objArgs.formConfig && objArgs.formConfig.theme ? 		objArgs.formConfig.theme : ""	);	this.defineConfigOption('themePath', 		objArgs.formConfig && objArgs.formConfig.themePath ? 		objArgs.formConfig.themePath : Zapatec.Form.path + "../themes/"	);		if(!objArgs.lang && objArgs.formConfig.lang){		objArgs.lang = objArgs.formConfig.lang;	}	if(!objArgs.langCountryCode && objArgs.formConfig.langCountryCode){		objArgs.langCountryCode = objArgs.formConfig.langCountryCode;	}	if(!objArgs.langEncoding && objArgs.formConfig.langEncoding){		objArgs.langEncoding = objArgs.formConfig.langEncoding;	}	this.defineConfigOption('form');	this.defineConfigOption('formConfig', {});	this.defineConfigOption('field');	this.defineConfigOption('langId', "Zapatec.Form");	// Call parent method	Zapatec.Form.SUPERclass.configure.call(this, objArgs);	this.config.form = Zapatec.Widget.getElementById(this.config.form);	this.config.field = Zapatec.Widget.getElementById(this.config.field);};/** * Reconfigures the widget with new config options after it was initialized. * May be used to change look or behavior of the widget after it has loaded * the data. In the argument pass only values for changed config options. * There is no need to pass config options that were not changed. * * @param {object} objArgs Changes to user configuration */Zapatec.Form.Field.prototype.reconfigure = function(objArgs) {	// Call parent method	Zapatec.Form.SUPERclass.reconfigure.call(this, objArgs);};Zapatec.Form.Field.prototype.init = function(objArgs){	if (Zapatec.Form.Utils.ignoreField(objArgs.field) || objArgs.field.zpFormField) {		return null;	}		this.autoCompleteOptions = []; // stores values for autocompletion	this.form = null; // storing params in internal variables.	this.state = {}; // variable for storing internal variables	this.features = {}; // setup array of features	this.keyPressCounter = 0; // this variable indicates how many key was pressed during last 							  // Zapatec.Form.Field.DELAYED_INTERVAL period.	this.firstRun = true; // default value	this.chars = null;        // if field has zpFormMask - 	this.enteredValue = null; // it will use this arrays	this.dropDown = null; // if needed - this variable will be used	this.isBooleanField = false; // if this is boolean (boolean field can be 								 //only in two stated - checked on unchecked)	this.isEditing = false; // Determines if field is editing in a moment			// processing Widget functionality	Zapatec.Form.SUPERclass.init.call(this, objArgs);	this.field = this.config.field;	this.features = Zapatec.Form.Utils.getTokens(this.field.className, " ");	if(this.hasFeature("zpFormRequired")){		this.setFeature("zpFormRequired", true);	}	this.isBooleanField = (		this.field.nodeName.toLowerCase() == 'input' &&		(			this.field.type.toLowerCase() == 'radio' || 			this.field.type.toLowerCase() == 'checkbox'		)	);	var md = null;	// use new "zpFormAllowedChars" instead of deprecated "zpFormAllowed-"	if(md = this.field.className.match(/zpFormAllowed-(\S+)/)){		if(!this.features['zpFormAllowedChars']){			this.features['zpFormAllowedChars'] = "";		}		this.features['zpFormAllowedChars'] += '\\' + md[1].split('').join('\\');	}	if(		typeof(this.features['zpFormAllowedChars']) != 'undefined' &&		this.getFeature('zpFormAllowedChars') == null	){		var undef;		this.features['zpFormAllowedChars'] = undef;	}	// if this field has zpFormAutoComplete or zpFormAutoCompleteStrict - 	// extract autocomplete options	if(		(			this.hasFeature("zpFormAutoComplete") ||			this.hasFeature("zpFormAutoCompleteStrict")		) &&		this.field.nodeName.toUpperCase() == "SELECT"	){		var input = document.createElement('input');		for(var ii = 0; ii < this.field.attributes.length; ii++){			var attr = this.field.attributes[ii];			if(attr.name == 'class'){				input.className = this.field.getAttribute(attr.name);			} else {				input.setAttribute(attr.name, this.field.getAttribute(attr.name));			}		}		for(var ii = 0; ii < this.field.options.length; ii++){			this.autoCompleteOptions.push(this.field.options[ii].innerHTML);		}		if(this.field.selectedIndex != null){			var val = null;			if(				this.field.options[this.field.selectedIndex].value != null &&				this.field.options[this.field.selectedIndex].value != ""			){				val = this.field.options[this.field.selectedIndex].value;			} else {				val = this.field.options[this.field.selectedIndex].innerHTML;			}						input.value = val;			input.setAttribute("value", val);		}		Zapatec.Utils.insertAfter(this.field, input);		Zapatec.Utils.destroy(this.field);		input.type = 'text';		this.field = input;	}	if(		this.hasFeature("zpFormAutoComplete") ||		this.hasFeature("zpFormAutoCompleteStrict") ||		this.hasFeature("zpFormSuggest")	){		// disable browser tips		this.field.setAttribute("autocomplete", "off");		this.field.autoComplete = "off";	}	var self = this;	this.form = this.config.form;	if(!this.form){		// Form widget stub		this.form = {			container: {elements:[this.field]},			fireEvent: function(){},			validate: function(){return self.validate()},			toggleSubmits: function(){},			container: this.field.parentNode		};		if(this.field.parentNode){			Zapatec.Utils.addClass(this.field.parentNode, this.getClassName({prefix: "zpForm"}));		}	}		// initializing internal arrays for zpFormMask validation type	if(this.hasFeature("zpFormMask")){		// remove maxlength attribute if present.		// It makes no sense together with mask and avoids mask to work correctly		if(this.field.hasAttribute && this.field.hasAttribute("maxlength")){			this.field.setAttribute("maxlength", null);		}		var mask = this.getFeature("zpFormMask");		var maskChars = mask.split('');		this.chars = [];		this.enteredValue = [];		for(var ii = 0; ii < maskChars.length; ii++){			var tmp = null;			switch(maskChars[ii]){				case "0":					tmp = "[0-9]";					break;				case "L":					tmp = "[a-zA-Z]";					break;				case "A":					tmp = "[0-9a-zA-Z]";					break;				case "&":					tmp = ".";					break;				case "\\":					i++;					if(i >= maskChars.length)						break;					// fall through				default:					this.chars.push(maskChars[ii]);					this.enteredValue.push(maskChars[ii]);			}			if(tmp != null){				var re = new RegExp("^" + tmp + "$");				this.chars.push(re);				this.enteredValue.push(null);			}		}	}	// creating back reference	this.createProperty(this.field, "zpFormField", this);	// setting up special handlers for all events.	// Note: we need to get reference to Zapatec.Form.Field from field object, 	//	because this can be cloned field. In that case in IE cloned object 	//	will have eventlisteners from original object.	var oldOnKeyDown = this.field.onkeydown || function(){return true;};	Zapatec.Utils.createProperty(this.field, "onkeydown", function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;		var res = oldOnKeyDown();		return zpField.keydown(ev) && res;	});	var oldOnKeyPress = this.field.onkeypress || function(){return true;};	Zapatec.Utils.createProperty(this.field, "onkeypress", function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;		var res = oldOnKeyPress();		return zpField.keypress(ev) && res;	});	Zapatec.Utils.addEvent(this.field, 'keyup', function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;		return zpField.keyup(ev);	});	Zapatec.Utils.addEvent(this.field, 'focus', function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;		return zpField.focus(ev);	});	Zapatec.Utils.addEvent(this.field, 'blur', function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;		return zpField.blur(ev);	});	if(this.field.nodeName.toLowerCase() == 'select'){		Zapatec.Utils.addEvent(this.field, 'change', function(ev){			var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;			return zpField.valueChanged(ev);		});	}	// validate field when field value changes	var onChangeFunc = function(ev){		var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;    		return zpField.valueChanged(ev);	};	Zapatec.Utils.addEvent(this.field, 'keyup', onChangeFunc);	if(Zapatec.is_ie){		Zapatec.Utils.addEvent(this.field, 'paste', onChangeFunc);	} else if(Zapatec.is_gecko) {		Zapatec.Utils.addEvent(this.field, 'input', onChangeFunc);	} else {		Zapatec.Utils.addEvent(this.field, 'change', onChangeFunc);	}	if(this.isBooleanField){		onChangeFunc = function(ev){			var zpField = Zapatec.Utils.getTargetElement(ev).zpFormField;			return zpField.booleanChanged();		};		Zapatec.Utils.addEvent(this.field, 'change', onChangeFunc);		// IE doesn't fire onchange on first change		Zapatec.Utils.addEvent(this.field, 'click', onChangeFunc);	}	// Next some <span> elements, as IE doens't support multi-class selectors.	this.requiredMark = Zapatec.Utils.createElement('span');	this.requiredMark.className = Zapatec.Form.IGNORE_CLASSNAME;	this.requiredMark.id = "zpFormField" + this.id + "StatusImg1";	this.editingMark = this.requiredMark.appendChild(Zapatec.Utils.createElement('span'));	this.editingMark.className = Zapatec.Form.IGNORE_CLASSNAME;	this.editingMark.id = "zpFormField" + this.id + "StatusImg2";	this.emptyMark = this.editingMark.appendChild(Zapatec.Utils.createElement('span'));	this.emptyMark.className = Zapatec.Form.IGNORE_CLASSNAME;	this.emptyMark.id = "zpFormField" + this.id + "StatusImg3";	this.validMark = this.emptyMark.appendChild(Zapatec.Utils.createElement('span'));	this.validMark.className = Zapatec.Form.IGNORE_CLASSNAME;	this.validMark.id = "zpFormField" + this.id + "StatusImg4";	this.fetchingMark = this.validMark.appendChild(Zapatec.Utils.createElement('span'));	this.fetchingMark.className = Zapatec.Form.IGNORE_CLASSNAME;	this.fetchingMark.id = "zpFormField" + this.id + "StatusImg5";	// The innermost is the one we actually style.	this.statusImg = this.fetchingMark.appendChild(Zapatec.Utils.createElement('span'));	this.statusImg.className = Zapatec.Form.IGNORE_CLASSNAME + ' zpStatusImg';	this.statusImg.id = "zpFormField" + this.id + "StatusImg";	this.addCircularRef(this, "statusImg");	this.addCircularRef(this, "fetchingMark");	this.addCircularRef(this, "validMark");	this.addCircularRef(this, "emptyMark");	this.addCircularRef(this, "editingMark");	this.addCircularRef(this, "requiredMark");	// An error container.	this.errorText = Zapatec.Utils.createElement('span');	this.errorText.id = "zpFormField" + this.id + "ErrorText";	this.errorText.className = Zapatec.Form.IGNORE_CLASSNAME + ' zpFormError';		if(this.field.type && this.field.type.toLowerCase() == "hidden"){		// if this is hidden field - hide dependant elements		this.errorText.style.display = 'none';		this.requiredMark.style.display = 'none';	}	// Radio buttons and checkboxes needs some more functionality	if(this.isBooleanField){		// add custom CSS classes to checkboxes and radiobuttons		if(this.field.type.toLowerCase() == "checkbox"){			this.field.className += " zpFormCheckbox";			this.statusImg.className += " zpCheckboxStatusImg";		} else if(this.field.type.toLowerCase() == "radio"){			this.field.className += " zpFormRadio";			this.statusImg.className += " zpRadioStatusImg";		} else {			this.statusImg.className += " zpCommonStatusImg";		}	} else {		this.statusImg.className += " zpCommonStatusImg";	}	var lastNode = this.field;	// Attach the outermost <span> near the input field.	if(this.config.formConfig.statusImgPos == 'afterField'){		Zapatec.Utils.insertAfter(this.field, this.requiredMark);		lastNode = this.requiredMark;	} else if(this.config.formConfig.statusImgPos == 'beforeField'){		this.field.parentNode.insertBefore(this.requiredMark, this.field);	}	// Position it by the field if configured that way.	if(this.config.formConfig.showErrors == 'afterField'){		Zapatec.Utils.insertAfter(this.field, this.errorText);		lastNode = this.errorText;	} else if (this.config.formConfig.showErrors == 'beforeField'){		this.field.parentNode.insertBefore(this.errorText, this.field);	}	if(this.hasFeature("zpFormMultiple")){		this.createProperty(this.field, "zpLastNode", lastNode);	}	if(		this.hasFeature("zpFormSuggest") ||		this.hasFeature("zpFormAutoComplete") ||		this.hasFeature("zpFormAutoCompleteStrict")	){		if(typeof(Zapatec.AutoComplete) == 'undefined'){			Zapatec.Transport.loadJS({				url: Zapatec.zapatecPath + '../zpautocomplete/src/zpautocomplete-core.js',				async: true,				onLoad: function(){					self.initDropDown();				}			});		} else {			this.initDropDown();		}	}	if(this.field.value){		// if field has predefined value		this.ajaxValidate();		this.suggestValue();		this.ajaxFill();	}	this.setValueFromField(true);};// interval before last keystroke and sending request to server.Zapatec.Form.Field.DELAYED_INTERVAL = 1000;/** * @private * Create Zapatec.DropDown object */Zapatec.Form.Field.prototype.initDropDown = function(){	var self = this;	var arrow = Zapatec.Utils.createElement("span");	arrow.className = Zapatec.Form.IGNORE_CLASSNAME + " dropDownArrow";	arrow.id = "zpFormField" + this.id + "DropDownArrow";	this.createProperty(arrow, "onclick", function(ev){		self.field.focus(ev);		self.autoCompleteValue(self.getAutoCompleteOptions(true));		self.suggestValue(true);	});	Zapatec.Utils.insertAfter(this.field, arrow);		var tmpConfig = Zapatec.Utils.clone (this.config.formConfig.autoCompleteConfig);	if (!tmpConfig) {		tmpConfig = {};	}	tmpConfig.fields = [this.field];	tmpConfig.width = "auto";	tmpConfig.dataOnDemand = false;	tmpConfig.convertTip = function(tipObj){			return tipObj.title;	}	tmpConfig.selectTip = function(tipObj){			self.setValue(tipObj.title)			self.valueChanged();			if (self.field.onchange) {				self.field.onchange();			}		}		this.dropDown = new Zapatec.AutoComplete(tmpConfig);	this.dropDown.field = this.field;};/** * @private * This function is called when field value is changed using copy-paste. * For IE it is called when pasting clipboard into field, for FF on each field  * value change(including keystrokes), for other browser - on "onchange" event. */Zapatec.Form.Field.prototype.valueChanged = function(ev){	if(this.hasFeature("zpFormAllowedChars") || this.hasFeature("zpFormMask")){		this.setValueFromField();	} else {		this.validate();	}	if(!ev){		ev = window.event;	}		this.fireEvent("valueChanged", ev);	this.fireEvent("all", ev, "valueChanged");	this.form.fireEvent("valueChanged", ev);	this.form.fireEvent("all", ev, "valueChanged");		return true;};/** * @private * This function is called when checkbox or radio button is checked/unchecked. */Zapatec.Form.Field.prototype.booleanChanged = function(ev){	if(!this.isBooleanField){		return;	}	var elements = this.form.container.elements;		for(var ii = 0; ii < elements.length; ii++){		var el = elements[ii];		if(			el.name == this.field.name &&			el.zpFormField		){			if(!this.firstRun){				el.zpFormField.firstRun = false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -