Ver Mensaje Individual
  #15 (permalink)  
Antiguo 17/06/2008, 10:18
netoec84
 
Fecha de Ingreso: julio-2004
Ubicación: Quito
Mensajes: 123
Antigüedad: 19 años, 10 meses
Puntos: 0
Respuesta: APORTE: Selects Dependientes con Prototype (AJAX)

Cita:
Iniciado por GatorV Ver Mensaje
Hola netoec84,

Primero te pido si escribes correctamente mi nombre, segundo, para pre-seleccionar dos opciones, yo extendería la clase dependantSelectAJAX para que aceptara un tercer parámetro al cargar los datos, ya que si usas directamente selectOption va a tratar de seleccionar el valor cuando no tiene datos, es por eso que debes esperar al evento onreadystatechange de AJAX para preseleccionar los datos.

Saludos.
Mil disculpas GatorV, voy a prestar mas atención al momento de escribir. Ahora te cuento que no hice precisamente lo que me comentas pero la clase quedo algo asi: incluyendo los cambios anteriores... lo que no se si es da algun problema al no seguir tus sugerencias... lo dejo para ver si le puedes dar una mirada y mas que todo para la gente si le sirve

Código:
var DataStore = Class.create(Enumerable, {
	initialize: function( store ) {
		if( store == null ) {
			store = [];
		}
		
		this._store = store;
	},
	
	addItem: function( text, value ) {
		if( value == null ) {
			value = text;
		}
		
		this._store.push( {text: text, value: value } );
	},
	
	removeItem: function( idx ) {
		this._store.splice( idx, 1 );
	},
	
	clear: function() {
		this._store = [];
	},
	
	size: function() {
		return this._store.length;
	},
	
	inspect: function() {
		alert( this._store.inspect() );
	},
	
	_each: function(iterator) {
		for (var i = 0; i < this._store.length; i++) {
			var value = this._store[i];
			
			iterator(value);
		}
	}
});

var HTMLSelect = Class.create({
	initialize: function( element ) {
		this.element = $(element);
		this.element.onchange = this.onChange.bindAsEventListener(this);
		this.element.onclick = this.onClick.bindAsEventListener(this);
		this.element.onfocus = this.onFocus.bindAsEventListener(this);
		
		var store = new DataStore();
		var opts = this.element.options;
		for(var i = 0; i < opts.length; i++ ) {
			var el = opts[i];
			store.addItem( el.text, el.value );
		}
		
		this.store = store;
	},
	
	setStore: function( ds ) {
		this.store = ds;
	},
	
	reload: function() {
		this.empty();
		
		var num = 0;
		this.store.each(function(item) {
			this.addOption(item.text, item.value);
			num++;
		}.bind(this));
	},
	
	onChange: function(e) {},
	onClick: function(e) {},
	onFocus: function(e) {},
	onEmpty: function() { 
		this.element.style.display = 'none';
		return true; 
	},
	
	selectIndex: function( index ) {
		this.element.selectedIndex = index;
	},
	
	selectOption: function( option ) {
		var size = this.element.length;
		var found = false;
		for(i = 0; i < size; i++) {
			var el = this.element.options[i].text;
			if( el == option ) {
				found = true;
				break;
			}
		}
		
		if( found ) {
			this.selectIndex(i);
			this.onChange();
		}
	},
	
	countOptions: function() {
		return this.element.length;
	},
	
	getSelectedOption: function() {
		var op = this.element.options[this.element.selectedIndex];
		return { value: op.value, text: op.text };
	},
	
	getValue: function() {
		var op = this.element.options[this.element.selectedIndex];
		var ret = "";
		
		ret = op.value;
		if( ret == "" ) {
			ret = op.text;
		}
		
		return ret;
	},
	
	empty: function() {
		if( this.onEmpty() ) {
			this._empty();
		}
	},
	
	addOption: function( text, value ) {
		if( value == null ) {
			value = text;
		}
		
		var op = new Option( text, value );
		var idx = this.element.length;
		this.element.options[idx] = op;
		
		return idx;
	},
	
	deleteOption: function( index ) {
		if( this.element.length > 0 && index > 0 ) {
			this.element.options[index] = null;
		}
	},
	
	selectAllOptions: function() {
		var size = this.element.length - 1;
		for(i = size; i>=0; i--) {
			this.element.options[i].selected = true;
		}
	},
	
	getSelectedOptions: function() {
		var texts = [];
		var size = this.element.length - 1;
		for(i = size; i>=0; i--) {
			if( this.element.options[i].selected === true ) {
				texts.push(this.element.options[i].text);
			}
		}
		
		return texts;
	},
	
	_empty: function() {
		this.element.style.display = 'none';
		this.element.options.length = 0;
	}
});

var dependantSelectAJAX = Class.create(HTMLSelect, {
	initialize: function( $super, select, child, url, selected) {
		$super( select );
		if( typeof( select ) == "string" ) {
			this.name = select;
		} else {
			this.name = select.name;
		}
		
		this.child = child;
		this.url = url;
		this.selected = selected;
	},
	
	onChange: function(e) {
		this.child.empty();
		var value = this.getValue();
		
		if( value != "" ) {
			var request = new Ajax.Request( this.url, {
				method: 'get',
				parameters: {controlName: this.name, selectedId: value},
				onSuccess: function( transport ) {
					var store = transport.responseText.evalJSON(true);
					if( typeof store.error != "undefined" ) {
						alert( store.error );
					} else {
						this.child.setStore(new DataStore(store));
						this.child.reload();
						var size = this.child.countOptions();
						if( size == 1 ) {
							//this.child.onChange(); 
							this.child.element.style.display = 'inline';
						}
						else if (size == 0) {
							this.child.element.style.display = 'none';
						}
						else
						{
							if (typeof this.child.selected != 'undefined' )
							{
								this.child.selectOption(this.child.selected);								
							}
							this.child.element.style.display = 'inline';
						} 
					}
				}.bind(this),
				
				onFalure: function(t) {
					alert( "Error in request" );
				}
			});
		}
	},

	onEmpty: function() {
		this.child.empty();
		this.child.element.style.display = 'none';
		return true;
	}
});
__________________
Guia Telefonica
ecuadorMusical.com