include("lib.prototype"); include("lib.tristate"); include("fitbank.proc.clases"); include("fitbank.formulario"); include("fitbank.util"); include("fitbank.logger"); include("fitbank.ui.estatus"); include("fitbank.ui.tabs"); include("fitbank.ui.teclas"); include("lib.fastclick"); /** * Espacio horizontal que se debe guardar para poner barras de scroll */ var WIDTH_SPACE_NORMAL = 20; /** * Espacio vertical que se debe guardar para poner barras de scroll * (contando tambien barras de herramientas, de teclas, etc). */ var HEIGHT_SPACE_NORMAL = 200; /** * Espacio vertical que se debe guardar para poner barras de scroll * (contando tambien barras de herramientas, etc) menos las teclas. * Para mostrar aplicaciones remotas unicamente */ var HEIGHT_SPACE_NO_KEYS = 80; /** * Espacio vertical que se debe guardar para poner barras de scroll * (contando tambien barras de herramientas, etc) menos las teclas. * Para mostrar aplicaciones remotas unicamente */ var HEIGHT_SPACE_REMOTE = 30; /** * Class Contexto - Contiene información sobre el contexto en que se ejecuta un * formulario. */ var Contexto = Class.create( { widthSpace: WIDTH_SPACE_NORMAL, heightSpace: HEIGHT_SPACE_NORMAL, /** * Id del contexto. */ id: null, /** * Indica si el contexto actual, es para un entorno remoto. */ isRemoteContext: window.location.pathname.endsWith("entornolimpio.html"), /** * Formulario. */ formulario: null, /** * Elemento FORM que contiene los campos. */ form: null, /** * Elemento donde se carga el contexto. */ elemento: null, /** * Lista Valores actualmente visibles. */ listaValores: null, /** * Es un contexto secundario. */ secundario: false, /** * Subcontextos. */ subContextos: $A(), /** * Si el contexto es remoto, contiene el iframe del formulario. */ remoto: null, /** * Variables del contexto. */ vars: {}, /** * Elementos en su estado original (al cargar o despues de una peticion). */ originalElements: {}, /** * Guarda la navegación para cuando se utiliza ReturnLink. */ navegacion: $A(), /** * Variable que indica si se deben guardar los webpages en cache para esta * sesion web. */ saveWebpagesInCache: Parametros['fitbank.cacheWebpages.ENABLED'] == "true", /** * Guarda un registro de formularios previamente cargados (carga en cache) * Valido unicamente para la sesion web actual. * * Se reinicia en cada nueva sesion. */ webpagesCache: $H(), //Constructor, llamado automáticamente por Prototype. initialize: function(elemento, secundario) { this.elemento = $(elemento); this.secundario = secundario; this.reset(); }, reset: function(keepContent) { this.id = Math.round(Math.random() * 10000); this.formulario = new Formulario(); this.subContextos = $A(); this.consultar = this._consultar; this.mantener = this._mantener; this.limpiar = this._limpiar; this.ayudar = this._ayudar; this.menuRapido = this._menuRapido; this.mostrarVersion = this._mostrarVersion; this.recargar = this._recargar; this.calcular = this._calcular; if (!keepContent) { this.elemento.update(""); } this.elemento.removeClassName("remote"); this.remoto = null; ListaFormularios.cargar(); this.widthSpace = WIDTH_SPACE_NORMAL; this.heightSpace = this.isRemoteContext ? HEIGHT_SPACE_REMOTE : HEIGHT_SPACE_NORMAL; }, resize: function(contenedor) { var resizeElement = document.onresize ? document : window; if (!contenedor.visible()) { contenedor.resize.stop(); return; } if(!Mobile) { contenedor.setStyle({ maxWidth: ($(document.body).getWidth() - this.widthSpace) + "px", maxHeight: ($(document.body).getHeight() - this.heightSpace) + "px" }); } if (!contenedor.resize) { contenedor.resize = Event.on(resizeElement, "resize", this.resize.bind(this, contenedor)); } }, /** * Revisa si existen cambios pendientes en el formulario y pregunta si se * quiere continuar. Devuelve true si se cancela la acción. False en caso * de que no existan cambios. */ revisarCambios: function() { return Parametros['fitbank.revisarCambios.ENABLED'] == "true" && Util.checkForChanges(this.originalElements) && !confirm(Util.getMensaje(Mensajes, "fitbank.contexto.CAMBIOS")); }, /** * Devuelve las opciones indicadas con los defaults para los campos no * especificados. * * @private */ _default: function(opciones) { return Object.extend({ subsistema: null, transaccion: null, campos: null, nameMap: null, objetoJS: null, action: null, fields: null, consulta: true, reset: true, registro: 0, fullQuery: false }, opciones); }, /** * Carga un formulario. Las opciones que acepta son las siguientes: * *
*
subsistema
(String) Subsistema
*
transaccion
(String) Transaccion
*
campos
(Objeto) Indica los campos que se van a cargar en el próximo * formulario, en la forma { "nameOtroFormulario": valor, ... }
*
nameMap
(Objeto) Es el mapa de nombres de campos en la forma * { "nameFormularioDestino": "nameFormularioActual", ... } * para poder tener links de regreso
*
objetoJS
En Caso de que el link quiera mandar un objeto JS
*
action
(String) Acción extra a ser ejecutada: "NEXT", "PREV", "END"
*
fields
(Objeto) Es el mapa de nombres de campos en la forma * { "nameFormularioActual": "id", ... }
*
consulta
(boolean) Indica si se consulta despues de cargar el * formulario, solo sirve si se paso la opcion campos
*
registro
(int) Registro destino de la carga de campos
*
* * @param opciones (Object) objeto con las opciones */ cargar: function(opciones) { if (this._revisarBloqueo() || this.revisarCambios()) { return; } // Soportar llamada con muchos parámetros if (Object.isString(opciones)) { Logger.warning("Se está llamando a Contexto#cargar incorrectamente"); var n = Object.isString(arguments[1]) ? 2 : 1; opciones = { subsistema: arguments[0], transaccion: arguments[1], campos: arguments[n++], nameMap: arguments[n++], objetoJS: arguments[n++] } if (n == 1) { opciones.st = opciones.subsistema; } } var pt = $("entorno-pt"); if (opciones.st) { opciones.st = opciones.st.replace(/[^\d]/g, ""); if (opciones.st.length <= 2) { Estatus.mensaje("Ingrese por lo menos 3 digitos.", null, "error"); pt && Form.Element.activate("entorno-pt"); return; } opciones.subsistema = opciones.st.substring(0, 2); opciones.transaccion = opciones.st.substring(2, 6); opciones.st = null; } opciones = this._default(opciones); while (opciones.transaccion.length < 4) { opciones.transaccion = 0 + opciones.transaccion; } // Información necesaria para los links de regreso if (opciones.nameMap) { this.navegacion.push({ subsistema: this.formulario.subsistema, transaccion: this.formulario.transaccion, nameMap: opciones.nameMap, objetoJS: opciones.objetoJS }); } else if (opciones.nameMap == null || typeof opciones.nameMap == "undefined") { this.navegacion.clear(); } if (!this.secundario && pt) { pt.value = opciones.subsistema + "-" + opciones.transaccion; } this._obtener(opciones); }, _revisarBloqueo: function() { if (Entorno.bloqueado()) { Estatus.mensaje("Por favor espere a que el proceso actual termine.", null, "warning"); return true; } else { return false; } }, /** * @private */ _obtener: function(opciones) { if (opciones.reset) { this.reset(true); } var cargandoTexto = Mobile ? "Cargando..." : "Cargando formulario..."; this.idProceso = Estatus.iniciarProceso(cargandoTexto); //Obtener informacion del formulario desde cache var cache = this.webpagesCache.get(opciones.subsistema + opciones.transaccion); var request; if (cache) { this.id = cache.contexto; this.mostrarForm(opciones, cache.respuesta); request = null; } else { request = new Ajax.Request('proc/' + (opciones.tipo || GeneralRequestTypes.FORM), { parameters: { _contexto: this.id, _subs: opciones.subsistema, _tran: opciones.transaccion, _values: Object.toJSON(opciones.values), _fields: Object.toJSON(opciones.fields), _action: opciones.action }, onSuccess: this.mostrarForm.bind(this, opciones), onFailure: this.onError.bind(this), onException: rethrow }); } Estatus.getProceso(this.idProceso).setRequest(request); }, /** * @private */ mostrarFormSimple: function(opciones, respuesta) { var json = respuesta.responseJSON; this.formulario = new Formulario(Object.extend({ subsistema: this.subsystem, transaccion: this.transaction }, json)); this.elemento.update(this._crearTitulo(json)); document.title = json.titulo + " - FitBank"; var contenedor = new Element("div", { className: "entorno-html" }).update(json.html); this.resize(contenedor); this.elemento.insert(contenedor); this._initFormularioSimple.bind(this).defer(respuesta, opciones); }, /** * @private */ mostrarForm: function(opciones, respuesta) { var json = respuesta.responseJSON; opciones = this._default(opciones); // Cargar variables del contexto que vienen del transporte db $H(json && json.db).keys().each(function(key) { this[key] = json.db[key]; }, this); this.accountingDate = new Date(this.accountingDate); var original = this.formulario; this.formulario = new Formulario(Object.extend({ subsistema: this.subsystem, transaccion: this.transaction }, json)); // Copiar estados originales if (!opciones.reset) { this.formulario.consultado = original.consultado; } ListaFormularios.cargar(json.navigation); var contenedor; if (this.secundario) { contenedor = this.elemento; } else { contenedor = new Element("div", { className: "entorno-html" }); this.resize(contenedor); this.elemento.update(this._crearTitulo(json)); document.title = json.titulo + " - FitBank"; } if(Mobile) { FastClick.attach(contenedor); FastClick.attach($('entorno-teclas')); } contenedor.insert(json.html); //Limpiar datepickers del formulario anterior if(!Mobile) { datePickerController && datePickerController.cleanUp(); //En este punto ya está disponible la información de idioma. //Configurar a todos los datepickers con el idioma del formulario. datePickerController && datePickerController.setGlobalOptions({ lang: (this.language || "es").toLowerCase() }); } if (!this.secundario) { this.elemento.insert(contenedor); } //Guardar la respuesta del formulario en cache if (this.saveWebpagesInCache) { this.webpagesCache.set(this.subsystem + this.transaction, { contexto: this.id, respuesta: respuesta }); } this._initFormulario.bind(this).defer(respuesta, opciones); }, /** * @private */ _crearTitulo: function(json) { var div = new Element("div", { className: "entorno-formulario-titulo" }); div.update(json.titulo); return div; }, /** * Inicializa un formulario remoto * * @param src dirección de la página a la que se hace el post * @param id Id del elemento * @param consultar si es true hace una consulta previa. * @param post usar POST o GET. * @param hideKeys Muestra o no las teclas de F1...F12 * @param initRemoto Especifica si se debe iniciar un proceso y mostrar la * animación en la barra de estado. * @param expand Indica si se va a expandir el iFrame en todo el entorno */ initRemoto: function(src, id, consultar, post, hideKeys, initRemoto, expand) { this.remoto = $(id); this.remoto.on("load", c._registrarRemoto.bind(c)); var callback = (function() { var params = $H({ _subs: this.formulario.subsistema, _tran: this.formulario.transaccion, _contexto: this.id }); if (initRemoto) { var cargandoTextoExterno = Mobile ? "Carga externa..." : "Cargando formulario externo..."; this.idInicial = Estatus.iniciarProceso(cargandoTextoExterno); } else { Estatus.mensaje("Formulario externo activo", null, false); } var files = Form.getInputs(this.form, "file"); var action = this.form.action; var separador = src.indexOf("?") > 0 ? "&" : "?"; this.form.onsubmit = "return true;"; this.form.method = post ? "POST" : "GET"; this.form.enctype = post && files.length ? "multipart/form-data" : ""; this.form.action = src + separador + params.toQueryString(); this.form.target = id; this.form.submit(); this.form.action = action; this.form.onsubmit = "return false;"; }).bind(this); if (consultar) { this.consultar.bind(this).defer(null, Function.defer.bind(callback)); } else { callback.defer(); } if (hideKeys) { Teclas.esconder(); this.heightSpace = this.HEIGHT_SPACE_NO_KEYS; } if (expand) { var interval = setInterval(function() { if (!c.remoto) { clearInterval(interval); return; } c.remoto.setStyle({ width: ($(document.body).getWidth() - c.widthSpace - 10) + "px", height: ($(document.body).getHeight() - c.heightSpace - 10) + "px" }); }, 1000); this.resize(this.form.up()); } }, /** * Registra un formulario remoto. * * @private */ _registrarRemoto: function() { this.elemento.addClassName("remote"); var cw = Util.getContentWindow(this.remoto); this.consultar = cw.consultar; this.mantener = cw.mantener; this.limpiar = cw.limpiar; this.recargar = cw.recargar; this.ayudar = cw.ayudar; this.menuRapido = cw.menuRapido; this.calcular = cw.calcular; var proceso = c.idInicial; cw.addStatusListener && cw.addStatusListener(function(mensaje, iniciar, cod) { if (iniciar) { proceso = Estatus.iniciarProceso(mensaje); } else { Estatus.finalizarProceso(mensaje, proceso, cod != 0 ? "error" : ""); } }); cw.addTransactionListener && cw.addTransactionListener(function(st, t) { st = Object.isString(t) ? st + ":" + t : st; st = st.replace(/[^\d]/g, ""); var subs = st.substring(0, 2); var tran = st.substring(2, 6); var pt = $("entorno-pt"); if (pt) { pt.value = subs + "-" + tran; } }); }, /** * Inicializa el formulario * * @private */ _initFormularioSimple: function(respuesta, opciones) { this.form = this.elemento.select("form")[0]; Tabs.reset(); this.loadValues(respuesta); this.$$("*[registro]").each(function(elemento) { elemento.removeAttribute("id"); elemento.removeAttribute("name"); }); var tables = c.$$("table"); document.on("scroll", function() { tables.each(function(elemento) { if (elemento.viewportOffset().top < 0) { elemento.addClassName("fixed"); } else { elemento.removeClassName("fixed"); } }); }); }, /** * Inicializa el formulario * * @private */ _initFormulario: function(respuesta, opciones) { var json = respuesta.responseJSON; this.form = this.elemento.select("form")[0]; Tabs.reset(opciones === true || opciones && opciones.mantenerTab); this.$$("input, select, textarea, button").each(function(elemento) { elemento.on("focus", (function(e) { elemento.focused = true; this.formulario.controlConFoco = elemento.name; this.formulario.registroActivo = elemento.registro; }).bind(this)); elemento.on("blur", (function(e) { elemento.focused = false; }).bind(this)); elemento.focused = false; // Para llamar formateadores con valores completos var change = (function(e) { e.options = e.options || {}; if (e.options.load) { return; } // Solo llamar una vez este onchange por evento if (elemento._disparando) { return; } elemento._disparando = true; (function() { elemento._disparando = false; elemento._processValue(e.options); this.calcular(); }).bind(this).defer(); }).bind(this); var blur = (function(e) { e.options = e.options || {}; if (e.options.load) { return; } (function() { elemento._processValue(e.options); this.calcular(); }).bind(this).defer(); }).bind(this); elemento.on("blur", blur); elemento.on("change", change); // Para llamar formateadores con valores parciales y asegurarse que // se dispare onchange si se cambio el valor. Bug de Chrome: 92492 elemento.on("keyup", (function(e) { if (elemento._processValue({ partial: true }) && !elemento.onblurchange) { elemento.onblurchange = elemento.on("blur", function() { elemento.fireDOMEvent("change", { generated: false }); elemento.onblurchange.stop(); elemento.onblurchange = null; }); } }).bind(this)); if (elemento.type == "checkbox") { Util.initCheckBox(elemento); } if (elemento.tagName.toLowerCase() == "select") { Util.initComboBox(elemento); } elemento.originalTabIndex = elemento.getAttribute("tabindex-original"); }, this); this.$$("*[registro]").each(function(elemento) { elemento.registro = parseInt(elemento.getAttribute("registro")) || 0; }); this.$$("tr.clonada input").each(function(input) { var tr = input.up("tr"); input.on("blur", function() { tr.removeClassName("selected"); }); input.on("focus", function() { tr.addClassName("selected"); }); }); $H(json.values).each(function(pair) { var name = pair.key; var obj = pair.value; this.$N(name).each(function(element, n) { if (element.widget) { element = element.widget; } element.setDisabled(obj.disabled[n]); }, this); }, this); if (!this.isRemoteContext) { Teclas.mostrar(); } this.formulario.jsInicial(); this.loadValues(respuesta); this.formulario.evalFormulas(); this.calcular(); (function () { this.formulario.jsInicialWebPage(); var firstFocus = this.$N(this.formulario.firstFocus, 0); if (firstFocus) { Form.Element.activate(firstFocus); } if (opciones.campos) { opciones.campos = $H(opciones.campos); opciones.campos.keys().each(function(campo) { c.$N(campo, opciones.registro).changeValue(opciones.campos.get(campo)); }, this); if (opciones.consulta) { this.consultar.bind(this).defer(); } } if (opciones.posLink) { this._checkError(opciones.posLink.curry(opciones), Util.getMensaje(Mensajes, 'fitbank.contexto.ERROR_POSLINK')); } //Registrar los campos y sus valores originales en la carga del formulario this.originalElements = Util.getOriginalElements(); this._checkError.defer(this.formulario.posCargar.bind(this.formulario), Util.getMensaje(Mensajes, 'fitbank.contexto.ERROR_POSCARGAR')); }).bind(this).defer(); this._mostrarControlesTablaDinamica(); this._mostrarMensajeTablaDinamica(Util.getMensaje(Mensajes, 'fitbank.contexto.dynamictable.PERFORM_QUERY'), this.consultar.bind(this)); //Si el container es oculto, ocultar su titulo tambien. $$("fieldset .oculto").each(function (elemento) { elemento.up("fieldset").addClassName("oculto"); }); Mobile && Mobile.initForm(); }, _checkError: function(funcion, mensaje) { var res; var stacktrace = null; if (!funcion) { return false; } try { res = funcion(); } catch(e) { res = false; stacktrace = e && e.stack; } if (res === false) { Estatus.mensaje(mensaje, stacktrace, "error"); return true; } else if (res && res.length > 1) { Estatus.mensaje(res, stacktrace, "error"); return true; } return false; }, /** * Revisa que no existan campos sin validarse. **/ _validar: function() { var errorElements = []; this.$$('tr.delete-record').each(function(row) { row.getElementsBySelector('.error').each(function(element) { element.removeClassName('error'); errorElements.push(element); }); }); this.$$(".error-required").each(function(e) { Validar.ok(e, "required"); }, this); var errors = this.$$(".error"); if (errors && errors.length) { Estatus.mensaje(Validar.getMessage(errors[0]) || Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_VALIDACION"), null, "error"); errorElements.each(function(element) { element && element.addClassName('error'); }); return true; } errorElements.each(function(element) { element && element.addClassName('error'); }); return false; }, /** * Quita el foco del elemento y lo regresa al terminar de procesar el thread. */ refrescarFoco: function() { var controlConFoco = this.formulario.controlConFoco; var registroActivo = this.formulario.registroActivo; var elemento = this.$(controlConFoco, registroActivo); if (elemento && elemento.blur) { elemento.blur(); Form.Element.activate.defer(elemento); } }, /** * Hace un mantenimiento con el formulario del contexto actual. */ setupAutoScroll: function() { document.on("scroll", (function() { var el = document.body; var scrollPos = el.scrollHeight - el.clientHeight - el.scrollTop; if (scrollPos < 500 && !Entorno.bloqueado()) { this.consultar.bind(this).defer(1, null, true); } }).bind(this)); }, /** * Obtiene una lista de contextos y subcontextos en orden. */ _getContextos: function(behaviorType) { var contextos = []; this.subContextos.each(function(contexto) { if (contexto.adjunto[behaviorType] == AttachedBehavior.BEFORE) { contextos.push(contexto); } }); contextos.push(this); this.subContextos.each(function(contexto) { if (contexto.adjunto[behaviorType] == AttachedBehavior.AFTER) { contextos.push(contexto); } }); contextos.reverse(); return contextos; }, /** * Hace una consulta con el formulario del contexto actual. */ _consultar: function(paginacion, callback, fullQuery) { if (paginacion && this.formulario.paginacion != Paginacion.HABILITADA) { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.PAGINACION_NO_HABILITADA"), null, "error"); return; } if (this._revisarBloqueo() || this._checkError(this.formulario.preConsultar, Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_PRE_CONSULTA")) || this._validar()) { return; } if (!this.formulario.query) { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_NO_APLICA_CONSULTA"), null, "error"); return; } if (!this.formulario.fullQuery && fullQuery) { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_NO_APLICA_FULLQUERY"), null, "error"); return; } this.formulario.consultando = true; var contextos = this._getContextos("queryBehavior"); var submit = (function() { if (!contextos.length) { this.formulario.consultando = false; //Registrar los campos y sus valores luego de la consulta this.originalElements = Util.getOriginalElements(); this._resetearTablaDinamica(); if (this._checkError(this.formulario.posConsultar, Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_POS_CONSULTA"))) { return; } this.formulario.consultado = true; if (!fullQuery) { this.formulario.evalFormulasWithElements(); callback && callback(); this.calcular(); var queryFocus = this.$N(this.formulario.queryFocus, 0); if (queryFocus) { queryFocus.focus(); } this._mostrarMensajeTablaDinamica(Util.getMensaje(Mensajes, "fitbank.contexto.dynamictable.NO_RECORDS")); } } else { Enlace.submit(contextos.pop(), { tipo: GeneralRequestTypes.CONSULTA, paginacion: paginacion, callback: submit, fullQuery: fullQuery }); } }).bind(this); submit(); }, /** * Hace un mantenimiento con el formulario del contexto actual. */ _mantener: function(callback) { if (this.formulario.requiresQuery && !this.formulario.consultado) { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_REQUIERE_CONSULTA"), null, "error"); return; } if (!this.formulario.store) { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_NO_APLICA_MANTENIMIENTO"), null, "error"); return; } if (this._revisarBloqueo() || this._checkError(this.formulario.preMantener, Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_PRE_MANTENIMIENTO")) || this._validar()) { return; } this.formulario.manteniendo = true; var contextos = this._getContextos("storeBehavior"); var submit = (function() { if (!contextos.length) { this.formulario.manteniendo = false; //Registrar los campos y sus valores luego del mantenimiento this.originalElements = Util.getOriginalElements(); if (this._checkError(this.formulario.posMantener, Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_POS_MANTENIMIENTO"))) { return; } this.formulario.evalFormulasWithElements(); callback && callback(); this.calcular(); if (this.formulario.postQuery) { this.consultar.bind(this).defer(0); } this._resetearTablaDinamica(); } else { Enlace.submit(contextos.pop(), { tipo: GeneralRequestTypes.MANTENIMIENTO, callback: submit }); } }).bind(this); submit(); }, /** * Limpia el formulario en el contexto actual */ _limpiar: function() { if (c.formulario.clean) { if (!this._revisarBloqueo()) { this._obtener(this._default({ tipo: GeneralRequestTypes.LIMPIAR, subsistema: c.subsystem, transaccion: c.transaction, reset: false })); } } else { Estatus.mensaje(Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_NO_APLICA_LIMPIEZA"), null, "error"); } }, /** * Recarga el formulario */ _recargar: function() { if (!this._revisarBloqueo()) { this._obtener({ subsistema: this.subsystem, transaccion: this.transaction, tipo: GeneralRequestTypes.RECARGAR }); } }, /** * Llama al proceso BorrarCache, que recarga el formulario actual sin * traerlo desde la cache de formularios. */ borrarCache: function() { if (this.revisarCambios() || this._revisarBloqueo() || !this.subsystem || !this.form) { return; } //Borrar cache de webpages en el explorador. this.webpagesCache = $H(); //Borrar cache de webpages en el servidor. this._obtener({ subsistema: this.subsystem, transaccion: this.transaction, tipo: GeneralRequestTypes.BORRAR_CACHE }); }, /** * Carga los values del response simplemente. * * @private */ loadValues: function(response, error, opciones) { if (!response.responseJSON) { var msj = Util.getMensaje(Mensajes, "fitbank.contexto.RESPUESTA_VACIA"); Estatus.mensaje(msj, null, 'error'); return; } this.cargando = true; if (opciones && opciones.fullQuery) { var newHtml = new Element("div").update(response.responseJSON.html); var newTbodies = newHtml.select("tbody"); var curTbodies = this.$$("tbody"); for (var i = 0; i < newTbodies.length; i++) { curTbodies[i].insert({ bottom: newTbodies[i].innerHTML }); } } $H(response.responseJSON.values).each((function(pair) { var name = pair.key; var obj = pair.value; this.$N(name).each(function(element, n) { element.changeValue(obj.values[n], { load: true }); if (element.widget) { element = element.widget; } !error && element.setDisabled(obj.disabled[n]); if (obj.error[n] && obj.error[n].id) { Validar.error(element, obj.error[n].mensaje, obj.error[n].id); if (obj.error[n].id == "required") { Logger.debug("Requerido: " + element.name); } } if (obj.classNames && obj.classNames[n]) { obj.classNames[n].split(" ").each(function(className) { element.addClassName(className); }); } element.fire("widget:init"); }, this); }).bindTryCatch(this)); if (opciones && opciones.drawHtml) { this.mostrarForm(opciones, response); } this.cargando = false; this._ready(response, error); }, /** * Maneja mensajes de error. */ onError: function(response) { var json = response.responseJSON; if (!json) { Estatus.finalizarProceso(Util.getMensaje(Mensajes, "fitbank.contexto.SIN_RESPUESTA", null, "error"), this.idProceso, "error"); this.elemento.update(""); } else { this.loadValues(response, "error"); } }, /** * Función llamada al terminar de cargar un formulario. * * @param response La respuesta * @param error Boolean que indica si hubo error */ _ready: function(response, error) { var json = response.responseJSON; if (error) { Estatus.finalizarProceso(json.mensajeUsuario || Util.getMensaje(Mensajes, "fitbank.contexto.ERROR_CARGANDO", null, "error"), this.idProceso, error && "error", json.stack); } else { Estatus.finalizarProceso(json.mensajeUsuario || Util.getMensaje(Mensajes, "fitbank.contexto.CARGADO"), this.idProceso, (Mobile?"processing":"ok")); } Estatus.registrar(response); }, /** * Función que ejecuta calculos. */ _calcular: function() { this.formulario.calcular(); }, /** * Función que muestra ventana emergente de ayuda */ _ayudar: function() { var ventana = new Ventana({ titulo: "Ayuda", contenido: "Cargando...", w: 500, h: 300, verFondo: false }); new Ajax.Updater(ventana.contenido, "../MANUAL/manuales/" + c.subsystem + c.transaction + ".html"); ventana.ver(); }, /** * Función que muestra ventana emergente del menu */ _menuRapido: function() { Menu.menuRapido.alternar(); }, /** * Función que muestra ventana emergente de version del sistema */ _mostrarVersion: function() { var divVersion = $('entorno-barra-version'); if (divVersion) { var versionContent = new Element("div", { id: 'barra-botones-version' }); if (divVersion.textContent) { var libraries = divVersion.textContent.split(','); //Para casos donde solo viene el esquema (versiones anteriores) if (libraries.length == 1) { var libraryDiv = new Element("div", { 'class': 'barra-botones-library' }).update("Esquema: " + libraries[0]); versionContent.insert(libraryDiv); } else { libraries.each(function(library) { var libraryName = library.split("=")[0]; var libraryVersion = library.split("=")[1]; var libraryNameDiv = new Element("div").update(libraryName); var libraryVersionDiv = new Element("div").update(libraryVersion); var libraryDiv = new Element("div", { 'class': 'barra-botones-library' }); libraryDiv.insert(libraryNameDiv); libraryDiv.insert(libraryVersionDiv); versionContent.insert(libraryDiv) }); } } else { var libraryDiv = new Element("div", { 'class': 'barra-botones-library' }).update(Util.getMensaje(Mensajes, "fitbank.contexto.NO_EXISTE_VERSION")); versionContent.insert(libraryDiv); } var ventana = new Ventana({ titulo: "Versión", contenido: versionContent }); ventana.ver(); } }, /** * Muestra un mensaje bajo tablas dinamicas * * @param mensaje Mensaje a mostrar * @param funcion Funcion JS a ejecutarse al hacer click en el mensaje * @param dynamicTable Elemento de la tabla dinamica a ocupar (opcional) */ _mostrarMensajeTablaDinamica: function(mensaje, funcion, dynamicTable) { if (!dynamicTable) { $$("div.dynamic-table-container > table").each((function (tableElement) { this._mostrarMensajeTablaDinamica(mensaje, funcion, tableElement); }).bind(this)); return; } var bodyElement = dynamicTable.down("tbody"); if (bodyElement && bodyElement.select("tr.show").length == 0) { var labelElement = new Element("label").update(mensaje); if (funcion) { labelElement.observe("click", funcion); } var td = new Element("td", { colspan: "100%", align: "center" }); td.insert(labelElement); var tr = new Element("tr", { 'class': "message" }); tr.insert(td); bodyElement.insert({ bottom: tr }); } }, /** * Agrega botones de control sobre tablas dinamicas */ _mostrarControlesTablaDinamica: function() { $$("div.dynamic-table-container > table.showControls > thead").each((function(element) { var tr = element.select("tr"); //Agregar los controles unicamente a tablas con cabeceras if (tr && tr.length > 0) { var addRowButton = new Element("button", { 'class':'addRow', onmouseover: "window.status=title='" + Util.getMensaje(Mensajes, "fitbank.contexto.controls.ADD_ROW") + "';" }).observe("click", (function(e) { var element = Event.element(e); var dynamicTable = element.up('table'); var messageElement = dynamicTable.down('tbody tr.message'); if (messageElement) { element = dynamicTable.down('tbody tr'); this._resetearTablaDinamica(dynamicTable); } else { element = dynamicTable.down('tbody tr[class^=\'clonada show\'] + tr[class=\'clonada par\'], tr[class^=\'clonada par show\'] + tr[class=\'clonada\']'); } if (element) { element.addClassName('show new-record'); //Buscar el primer elemento visible modificable y asignarle el foco var focusElement = element.select("input[type!=hidden][readonly!=\'\']")[0]; if (focusElement) { this.$$(' .current-focus').invoke('removeClassName','current-focus'); focusElement.addClassName('current-focus'); focusElement.activate(); } } }).bind(this)); var cloneRowButton = new Element("button", { 'class':'cloneRow', onmouseover: "window.status=title='" + Util.getMensaje(Mensajes, "fitbank.contexto.controls.CLONE_ROW") + "';" }).observe("click", (function(e) { var element = Event.element(e); var dynamicTable = element.up('table'); var messageElement = dynamicTable.down('tbody tr.message'); if (!messageElement) { element = dynamicTable.down('tbody tr[class^=\'clonada show\'] + tr[class=\'clonada par\'], tr[class^=\'clonada par show\'] + tr[class=\'clonada\']'); if (element) { var cloneRow = this.$$(' .current-focus')[0].up('tr.clonada'); if (cloneRow) { var index = 0; var copyCount = 0; cloneRow.select('input').each(function (cloneElement) { var targetElement = element.select('input')[index]; if (cloneElement.name == targetElement.name) { targetElement.changeValue(cloneElement.value); copyCount++; } index++; }); if (copyCount == index) { element.addClassName("show new-record"); //Buscar el primer elemento visible modificable y asignarle el foco var focusElement = element.select("input[type!=hidden][readonly!=\'\']")[0]; if (focusElement) { this.$$(' .current-focus').invoke('removeClassName','current-focus'); focusElement.addClassName('current-focus'); focusElement.activate(); } } else { element.select("input[type!=hidden]").each(function(el) { el.changeValue(''); }); } } } } }).bind(this)); var removeRowButton = new Element("button", { 'class':'removeRow', onmouseover: "window.status=title='" + Util.getMensaje(Mensajes, "fitbank.contexto.controls.REMOVE_ROW") + "';" }).observe("click", (function(e) { var element = Event.element(e); var dynamicTable = element.up('table'); var clearElement = dynamicTable.down('input.current-focus'); if (clearElement) { clearElement = clearElement.up('tr.clonada'); } if (clearElement) { //Borrar la fila unicamente si es nueva if (!clearElement.hasClassName('new-record')) { //Si no es nueva pero tiene un delete-record, activarlo if (clearElement.select('td.delete-record').length > 0) { var deleteRecord = clearElement.select('td.delete-record input[type=checkbox]')[0]; if (deleteRecord) { deleteRecord.setChecked(true); } } return; } clearElement.removeClassName('show'); clearElement.removeClassName('new-record'); clearElement.select("input[type!=hidden]").each(function(element) { if (element.hasClassName('pk-disabled')) { element.readOnly = false; } if (element.hasClassName('delete-record')) { element.setDisabled(true); } element.changeValue(''); }); //Buscar la siguiente fila visible para ubicar el foco var nextRow = clearElement.next("tr.show"); var previousRow = clearElement.previous("tr.show"); var focusElement = null; //Buscar el primer elemento visible modificable del registro anterior y asignarle el foco if (nextRow) { focusElement = nextRow.select("input[type!=hidden][readonly!=\'\']")[0]; } else if (previousRow) { focusElement = previousRow.select("input[type!=hidden][readonly!=\'\']")[0]; } if (focusElement) { this.$$(' .current-focus').invoke('removeClassName','current-focus'); focusElement.addClassName('current-focus'); focusElement.activate(); } } var nexElement = dynamicTable.down('tbody tr.show'); if (!nexElement) { this._resetearTablaDinamica(dynamicTable); this._mostrarMensajeTablaDinamica(Util.getMensaje(Mensajes, "fitbank.contexto.dynamictable.PERFORM_QUERY"), this.consultar.bind(this), dynamicTable); } }).bind(this)); var td = new Element("td", { colspan: "100%", align: "right", 'class': "table-controls" }); td.insert(addRowButton); td.insert(cloneRowButton); td.insert(removeRowButton); tr = tr.reverse()[0]; tr.insert(td) } }).bind(this)); }, /** * Controla los estilos para elementos de tablas dinamicas */ _resetearTablaDinamica: function(dynamicTable) { if (!dynamicTable) { $$("div.dynamic-table-container > table").each((function (tableElement) { this._resetearTablaDinamica(tableElement); }).bind(this)); return; } var tableBody = dynamicTable.down("tbody"); if (!tableBody) { return; } var bodyRows = tableBody.select("tr"); bodyRows.each(function (element) { if (element.hasClassName("show")) { element.removeClassName("show"); } if (element.hasClassName("message")) { element.remove(); } var tdElements = element.select("td .show"); var showRow = tdElements.length > 0; if (showRow) { tdElements.invoke("removeClassName", "show"); element.addClassName("show"); element.removeClassName('new-record'); dynamicTable.removeClassName("oculto"); dynamicTable.up("fieldset") && dynamicTable.up("fieldset").removeClassName("oculto"); } }); }, /** * Borra todos los campos indicados. * * @param a * Primer parámetro (se pueden pasar más parametros tambien) */ borrar: function(a) { a.split(",").each(function(e) { this.$(e).value = ''; }, this); }, /** * Obtiene el elemento (o elementos) referenciados por el name y el * registro. Si hay un solo elemento no devuelve un array si no el elemento * en sí. * * @param name * Nombre del elemento. * @param registro * Opcional, el numero de registro que se quiere obtener. * * @return Un elemento o un array de elementos */ $: function(name, registro) { var e = this.$W(name, registro); return Object.isArray(e) && e.length == 1 ? e[0] : e; }, /** * Obtiene un array de los elementos referenciados por el name y el * registro. * * @param name * Nombre del elemento. * @param registro * Opcional, el numero de registro que se quiere obtener. * * @return Un array de elementos incluso si hay un solo elemento */ $N: function(name, registro) { return $N(this.form, name, registro); }, /** * Obtiene un array de los valores de los elementos referenciados por el * name y el registro. * * @param name * Nombre del elemento. * @param registro * Opcional, el numero de registro que se quiere obtener. * * @return Un array de valores incluso si hay un solo valor */ $V: function(name, registro) { return $V(this.form, name, registro); }, /** * Obtiene un array de los widgets visible de los elementos referenciados por el * name y el registro. * * @param name * Nombre del elemento. * @param registro * Opcional, el numero de registro que se quiere obtener. * * @return Un array de valores incluso si hay un solo valor */ $W: function(name, registro) { return $W(this.form, name, registro); }, /** * Obtiene un array de los elementos que cumplen con el selector. * * @param selector * Un selector CSS * * @return Un array de elementos */ $$: function(selector) { return this.form.select(selector); } });