#9
Este es el codigo de mis select, ahora te explico.
La dependencia entres combos es muy sencilla. Cada combo se instancia y se almacena la referencia de su instancia en el atributo data de el mismo.
Cada combo tiene varios atributos importantes: data-mcontrol-name="" data-mcontrol-dependency="" y data-mcontrol-dependency-injection="". ¿ Por qué ?, por que son combos generados dinámicamente y a mi no se me ocurre otra forma de conectar unos con otros, que indicandole a un combo en el nivel en el que esta, con el data-mcontrol-dependency-injection="". Es decir, si se generan en una tabla 10 registros, y dinamicamente se generan dos combos por cada registro. En el registro uno tendremos :
Combo1
data-mcontrol-name="ControlX" data-mcontrol-dependency-injection="0" data-mcontrol-dependency=""
Combo2
data-mcontrol-name="ControlY" data-mcontrol-dependency-injection="0" data-mcontrol-dependency="ControlX"
¿ Esto que va a hacer ?. Cuando ControlY se instancie, va a buscar la instancia llamada ControlX0, y le metera un método onChange, para cuando el ControlX cambie, Y lo detected, obtenga el elemento seleccionado y haga la petición al servidor con ese elemento seleccionado.
Esto funciona bien, de hecho, los combos relacionados que son estáticos funciona perfectamente, son los dinámicos los que no tiran.
MSelect = function(control, defs, row) {
var _this = this;
this.element = $(control);
this.defs = defs;
this.apids = this.defs.apids || "";
this.field = this.defs.findField;
this.dependency = this.element.attr("data-mcontrol-dependency");
this.injection = this.element.attr("data-mcontrol-dependency-injection");
this.dependencyQuery = "";
this.dependencyFindField = this.defs["dependencyFindField"];
this.datasource = [];
this.initValue = (this.element.attr('data-mcontrol-init-value') !== undefined) ?
$(row).find(".mtd[data-initfield]").attr('data-initfield') : null;
this.prechargeValue = $(control).attr('data-mcontrol-precharge-value');
this.constructor();
};
MSelect.prototype = {
_selectPrechargeValue : function () {
var _this = this;
if (_this.prechargeValue !== undefined && _this.prechargeValue !== "")
_this.element.find("option[value=" + _this.prechargeValue + "]").prop("selected", true);
},
/**
*
*/
_loadData : function() {
var _this = this;
if (_this.apids !== "") {
var completeQuery = "?";
if (_this.initValue !== undefined && _this.initValue !== null)
completeQuery += "idCompany=" + _this.initValue.split("-")[0];
if (_this.dependencyQuery !== "")
completeQuery += (completeQuery.length > 1) ? '&' + _this.dependencyQuery : _this.dependencyQuery;
$.getJSON("list/" + _this.apids + ".json" + completeQuery, function(data) {
_this.datasource = [];
_this.element.empty();
_this.datasource.push({value : "", member : " " });
if (data.length != 0){
$.each(data, function(i, e) {
_this.datasource.push({
value : e[_this.defs.value],
member : e[_this.defs.member]
});
});
}
_this._paintData();
_this._selectPrechargeValue();
});
}else
{
$.each(_this.defs["data"], function(i, e) {
_this.datasource.push({
value : e["value"],
member : e["member"]
});
});
_this._paintData();
_this._selectPrechargeValue();
}
},
_paintData : function() {
var _this = this;
$.each(_this.datasource, function(i, e) {
var opt = $('<option value=' + e['value'] + '>'
+ e['member'] + '</option>');
_this.element.append(opt);
});
},
getControlType : function () {
return 'mselect';
},
clear : function() {
var _this = this;
_this.element.empty();
},
getFindField : function() {
var _this = this;
return _this.field;
},
getSelectedItem : function() {
var _this = this;
return _this.element.val();
},
getSelectedMember : function() {
var _this = this;
return _this.element.find ('option:selected').text ();
},
getExtraFindField : function() {
var _this = this;
if (_this.defs["extrafindfield"])
return _this.defs["extrafindfield"];
},
getDependencyFindField : function () {
var _this = this;
return _this.dependencyFindField;
},
resetSelectedValue : function () {
var _this = this;
_this._selectPrechargeValue();
_this.element.triggerHandler('change');
},
clean : function () {
var _this = this;
_this.element.val('');
},
constructor : function() {
var _this = this;
/// SUPER IMPORTANTE
/// Este bloque de código contiene toda la lógica de la dependencia entres controles de tipo combos
/// Porfavor, antes de tocar nada avisar a @delamata
///
/// El primero paso comprueba que si el control que se está instancido
if (_this.dependency != undefined && _this.dependency !== "" &&
_this.injection != undefined && _this.injection !== "") {
var dependencies = _this.dependency.split("-");
var lastDependency = "[data-mcontrol-name=" + dependencies [dependencies.length - 1] + "][data-mcontrol-dependency-injection=" + _this.injection + "]"; // Control always depend of the last dependency control
$(lastDependency).on('change', function () {
// Se limpia la cadena con la que se filtra
_this.dependencyQuery = "";
var lastDepenObj = $(lastDependency).data(dependencies [dependencies.length - 1] + _this.injection);
if (lastDepenObj.getSelectedItem() !== null && lastDepenObj.getSelectedItem() !== "") {
// Se genera la nueva cadena de búsqueda en función de los valores de las dependencias
$.each(dependencies, function (index, dependencyField) {
var completeDependencyControlName = dependencyField + _this.injection;
var controlObj = $("[data-mcontrol-name=" + dependencyField + "][data-mcontrol-dependency-injection=" + _this.injection + "]").data(completeDependencyControlName);
_this.dependencyQuery += (controlObj.getSelectedItem() !== "") ?
controlObj.getDependencyFindField() + "=" + controlObj.getSelectedItem() : "";
if (index != dependencies.length - 1) {
_this.dependencyQuery += "&";
}
});
_this._loadData();
}else
{
_this.element.empty();
_this.element.triggerHandler ('change');
}
});
}else
{
_this._loadData();
_this._combosRelations();
}
}
}