From 142fc9d3b58203862f3eaa1579021ffbd32460c9 Mon Sep 17 00:00:00 2001 From: lechevarria-teknei Date: Wed, 12 Apr 2023 12:44:13 +0200 Subject: [PATCH 01/18] =?UTF-8?q?Cambiar=20nombre=20de=20bot=C3=B3n=20y=20?= =?UTF-8?q?funci=C3=B3n=20en=20ejemplo=20de=20feedback=20para=20establecer?= =?UTF-8?q?=20el=20texto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x21aAppWar/WebContent/WEB-INF/views/patrones/feedback.jsp | 2 +- x21aStatics/WebContent/x21a/scripts/x21aApp/feedback.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x21aAppWar/WebContent/WEB-INF/views/patrones/feedback.jsp b/x21aAppWar/WebContent/WEB-INF/views/patrones/feedback.jsp index 6d17d55f0..5c0a14201 100644 --- a/x21aAppWar/WebContent/WEB-INF/views/patrones/feedback.jsp +++ b/x21aAppWar/WebContent/WEB-INF/views/patrones/feedback.jsp @@ -115,7 +115,7 @@
- + diff --git a/x21aStatics/WebContent/x21a/scripts/x21aApp/feedback.js b/x21aStatics/WebContent/x21a/scripts/x21aApp/feedback.js index 593985bac..d2db336b4 100644 --- a/x21aStatics/WebContent/x21a/scripts/x21aApp/feedback.js +++ b/x21aStatics/WebContent/x21a/scripts/x21aApp/feedback.js @@ -31,7 +31,7 @@ jQuery(function($) { $('#boton_create').click(feedback_create); $('#boton_destroy').click(feedback_destroy); - $('#boton_set').click(feedback_set); + $('#boton_setText').click(feedback_setText); $('#boton_setOptions').click(feedback_setOptions); $('#boton_setType').click(feedback_setType); $('#boton_setImgClass').click(feedback_setImgClass); @@ -73,7 +73,7 @@ jQuery(function($) { $('#boton_destroy').attr('disabled',true); $('#boton_create').attr('disabled',false); } - function feedback_set(){ + function feedback_setText(){ $('#feedback').rup_feedback('set','Este es un ejemplo de Feedback'); } function feedback_setOptions(){ From b344b45f8cf7a05a6bdd023e1c4e71f37eb7f0ad Mon Sep 17 00:00:00 2001 From: Xabi Date: Wed, 12 Apr 2023 13:10:52 +0200 Subject: [PATCH 02/18] =?UTF-8?q?Corregir=20versi=C3=B3n=20y=20nombre=20de?= =?UTF-8?q?=20propiedad=20en=20el=20pom?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x21aEAR/pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x21aEAR/pom.xml b/x21aEAR/pom.xml index 4e5b0a716..5b589afc0 100644 --- a/x21aEAR/pom.xml +++ b/x21aEAR/pom.xml @@ -11,8 +11,8 @@ UTF-8 - 5.2.0-SNAPSHOT - 4.0.0 + 5.2.0-RELEASE + 4.0.0 4.3.22.RELEASE 4.2.11.RELEASE 1.2.11 @@ -26,22 +26,22 @@ com.ejie.hdiv hdiv-config - ${com.ejie.hdiv.version} + ${com.ejie.hdiv.ce.version} com.ejie.hdiv hdiv-core - ${com.ejie.hdiv.version} + ${com.ejie.hdiv.ce.version} com.ejie.hdiv hdiv-services - ${com.ejie.hdiv.version} + ${com.ejie.hdiv.ce.version} com.ejie.hdiv hdiv-spring-mvc - ${com.ejie.hdiv.version} + ${com.ejie.hdiv.ce.version} commons-dbcp From 6e59137d5b1e28639f75b593ca528f667c0b5726 Mon Sep 17 00:00:00 2001 From: Xabi Date: Fri, 14 Apr 2023 14:47:21 +0200 Subject: [PATCH 03/18] =?UTF-8?q?Cambiar=20endpoint=20de=20eliminaci=C3=B3?= =?UTF-8?q?n=20m=C3=BAltiple?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Es necesario utilizar el mismo mapeo del filtro porque el state que recibirá será el de este. --- x21aAppWar/src/com/ejie/x21a/control/IberdokController.java | 3 ++- .../src/com/ejie/x21a/control/TableAlumnoController.java | 3 ++- .../com/ejie/x21a/control/TableDynamicColumnsController.java | 2 +- .../src/com/ejie/x21a/control/TableMultiPkController.java | 2 +- .../src/com/ejie/x21a/control/TableUsuarioController.java | 4 ++-- .../src/com/ejie/x21a/control/TableX21aAlumnoController.java | 2 +- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/x21aAppWar/src/com/ejie/x21a/control/IberdokController.java b/x21aAppWar/src/com/ejie/x21a/control/IberdokController.java index 58bbead90..8d5e8933e 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/IberdokController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/IberdokController.java @@ -25,6 +25,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @@ -229,7 +230,7 @@ public class IberdokController { * @return Lista de los identificadores de los registros eliminados. */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value = HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param = "filter") IberdokFile filterIberdokFile, diff --git a/x21aAppWar/src/com/ejie/x21a/control/TableAlumnoController.java b/x21aAppWar/src/com/ejie/x21a/control/TableAlumnoController.java index f87de274b..0401a7af6 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/TableAlumnoController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/TableAlumnoController.java @@ -45,6 +45,7 @@ import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -350,7 +351,7 @@ public String getCreateForm(Model model) { * @return alumnoList */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value=HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param="filter") Alumno filterAlumno, diff --git a/x21aAppWar/src/com/ejie/x21a/control/TableDynamicColumnsController.java b/x21aAppWar/src/com/ejie/x21a/control/TableDynamicColumnsController.java index d7674a08f..92cf8bdd8 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/TableDynamicColumnsController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/TableDynamicColumnsController.java @@ -329,7 +329,7 @@ public String getTableInlineEdit ( * @return Lista de los identificadores de los registros eliminados. */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value=HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param="filter") Usuario filterUsuario, diff --git a/x21aAppWar/src/com/ejie/x21a/control/TableMultiPkController.java b/x21aAppWar/src/com/ejie/x21a/control/TableMultiPkController.java index 2a712e677..368712c48 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/TableMultiPkController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/TableMultiPkController.java @@ -345,7 +345,7 @@ public String getFormEdit(Model model) { * */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value = HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param="filter") MultiPk filterMultiPk, diff --git a/x21aAppWar/src/com/ejie/x21a/control/TableUsuarioController.java b/x21aAppWar/src/com/ejie/x21a/control/TableUsuarioController.java index c1e70665a..96c14e51c 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/TableUsuarioController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/TableUsuarioController.java @@ -1214,7 +1214,7 @@ public String getMultiFilterForm2 ( * @return Lista de los identificadores de los registros eliminados. */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value=HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param="filter") Usuario filterUsuario, @@ -1237,7 +1237,7 @@ public String getMultiFilterForm2 ( * @return Lista de los identificadores de los registros eliminados. */ @UDALink(name = "deleteAll2") - @PostMapping(value = "/{bis}/deleteAll") + @PostMapping(value = "{bis}/filter", params = "deleteAll") @ResponseStatus(value=HttpStatus.OK) public @ResponseBody List removeMultiple2( @RequestJsonBody(param="filter") Usuario2 filterUsuario, diff --git a/x21aAppWar/src/com/ejie/x21a/control/TableX21aAlumnoController.java b/x21aAppWar/src/com/ejie/x21a/control/TableX21aAlumnoController.java index b3f9bb35e..bbbdba073 100644 --- a/x21aAppWar/src/com/ejie/x21a/control/TableX21aAlumnoController.java +++ b/x21aAppWar/src/com/ejie/x21a/control/TableX21aAlumnoController.java @@ -280,7 +280,7 @@ public String getTableEditForm ( * */ @UDALink(name = "deleteAll") - @RequestMapping(value = "/deleteAll", method = RequestMethod.POST) + @PostMapping(value = "/filter", params = "deleteAll") @ResponseStatus(value = HttpStatus.OK) public @ResponseBody List removeMultiple( @RequestJsonBody(param="filter") X21aAlumno filterX21aAlumno, From 1fb1fec51ecaf7f3bbf8bf0f9abf6958941e1a1e Mon Sep 17 00:00:00 2001 From: Xabi Date: Fri, 14 Apr 2023 15:09:07 +0200 Subject: [PATCH 04/18] =?UTF-8?q?Actualizar=20est=C3=A1ticos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- x21aStatics/WebContent/rup/js/rup.js | 30 +++++++++---------- x21aStatics/WebContent/rup/js/rup.min.js | 2 +- .../WebContent/rup/js/src/rup.combo.js | 2 +- x21aStatics/WebContent/rup/js/src/rup.form.js | 8 +++++ .../WebContent/rup/js/src/rup.select.js | 4 ++- .../rup/js/src/rup_table/rup.table.buttons.js | 2 +- .../js/src/rup_table/rup.table.editForm.js | 8 ++--- .../js/src/rup_table/rup.table.inlineEdit.js | 8 ++--- 8 files changed, 37 insertions(+), 27 deletions(-) diff --git a/x21aStatics/WebContent/rup/js/rup.js b/x21aStatics/WebContent/rup/js/rup.js index 84c20965c..a1ae47536 100644 --- a/x21aStatics/WebContent/rup/js/rup.js +++ b/x21aStatics/WebContent/rup/js/rup.js @@ -7796,24 +7796,24 @@ eval("/* WEBPACK VAR INJECTION */(function(__webpack_amd_options__) {/* globals /***/ }), /***/ "./node_modules/webpack/buildin/global.js": -/*!************************************************!*\ - !*** ./node_modules/webpack/buildin/global.js ***! - \************************************************/ +/*!***********************************!*\ + !*** (webpack)/buildin/global.js ***! + \***********************************/ /*! no static exports found */ /***/ (function(module, exports) { -eval("function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\nvar g; // This works in non-strict mode\n\ng = function () {\n return this;\n}();\n\ntry {\n // This works if eval is allowed (see CSP)\n g = g || new Function(\"return this\")();\n} catch (e) {\n // This works if the window reference is available\n if ((typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) === \"object\") g = window;\n} // g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\n\nmodule.exports = g;\n\n//# sourceURL=webpack://rup/./node_modules/webpack/buildin/global.js?"); +eval("function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\nvar g; // This works in non-strict mode\n\ng = function () {\n return this;\n}();\n\ntry {\n // This works if eval is allowed (see CSP)\n g = g || new Function(\"return this\")();\n} catch (e) {\n // This works if the window reference is available\n if ((typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) === \"object\") g = window;\n} // g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\n\nmodule.exports = g;\n\n//# sourceURL=webpack://rup/(webpack)/buildin/global.js?"); /***/ }), /***/ "./node_modules/webpack/buildin/module.js": -/*!************************************************!*\ - !*** ./node_modules/webpack/buildin/module.js ***! - \************************************************/ +/*!***********************************!*\ + !*** (webpack)/buildin/module.js ***! + \***********************************/ /*! no static exports found */ /***/ (function(module, exports) { -eval("module.exports = function (module) {\n if (!module.webpackPolyfill) {\n module.deprecate = function () {};\n\n module.paths = []; // module.parent = undefined by default\n\n if (!module.children) module.children = [];\n Object.defineProperty(module, \"loaded\", {\n enumerable: true,\n get: function get() {\n return module.l;\n }\n });\n Object.defineProperty(module, \"id\", {\n enumerable: true,\n get: function get() {\n return module.i;\n }\n });\n module.webpackPolyfill = 1;\n }\n\n return module;\n};\n\n//# sourceURL=webpack://rup/./node_modules/webpack/buildin/module.js?"); +eval("module.exports = function (module) {\n if (!module.webpackPolyfill) {\n module.deprecate = function () {};\n\n module.paths = []; // module.parent = undefined by default\n\n if (!module.children) module.children = [];\n Object.defineProperty(module, \"loaded\", {\n enumerable: true,\n get: function get() {\n return module.l;\n }\n });\n Object.defineProperty(module, \"id\", {\n enumerable: true,\n get: function get() {\n return module.i;\n }\n });\n module.webpackPolyfill = 1;\n }\n\n return module;\n};\n\n//# sourceURL=webpack://rup/(webpack)/buildin/module.js?"); /***/ }), @@ -8402,7 +8402,7 @@ eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPAC /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(jQuery, global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/* eslint-disable no-useless-escape */\n\n/*!\r\n * Copyright 2016 E.J.I.E., S.A.\r\n *\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n */\n//Modificado \"jquery.ui.selectmenu.js\" línea 70\n//Modificado \"jquery.ui.selectmenu.js\" línea 438-442\n//Modificado \"jquery.ui.selectmenu.js\" línea 270 [jQuery 1.8 compatible]\n//Modificado \"jquery.multiselect.js\" línea 53 [Estilo flecha como combos\n//Añadido\t \"jquery.multiselect.js\" línea 65 [Id al componete]\n//Modificado \"jquery.multiselect.js\" línea 581 [jQuery 1.8 compatible]\n//Modificadro \"IE Fixes\" (evitar problemas con elementos deshabilitados en IE)\n//Arregos para resaltado con el teclado (UDA - focus): líneas 446-448, 494-496, 519-522\n\n/**\r\n * Permite al usuario recuperar un elemento de una gran lista de elementos o de varias listas dependientes de forma sencilla y ocupando poco espacio en la interfaz.\r\n *\r\n * @deprecated since version 5.1.0\r\n * @summary Componente RUP Combo.\r\n * @module rup_combo\r\n * @see El componente está basado en el plugin {@link http://jqueryui.com/selectmenu/|jQuery UI Selectmenu}. Para mas información acerca de las funcionalidades y opciones de configuración pinche {@link http://api.jqueryui.com/selectmenu/|aquí}.\r\n * @example\r\n * $(\"#idCombo\").rup_combo({\r\n *\tsource : \"comboSimple/remote\",\r\n *\tsourceParam : {label:\"desc\"+$.rup_utils.capitalizedLang(), value:\"code\", style:\"css\"}\r\n * });\r\n */\n\n/*global define */\n\n/*global jQuery */\n(function (factory) {\n if (true) {\n // AMD. Register as an anonymous module.\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./rup.base */ \"./src/rup.base.js\"), __webpack_require__(/*! ./core/ui/jquery.ui.selectmenu */ \"./src/core/ui/jquery.ui.selectmenu.js\"), __webpack_require__(/*! ./core/ui/jquery.multiselect */ \"./src/core/ui/jquery.multiselect.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($) {\n //****************************************************************************************************************\n // DEFINICIÓN BASE DEL PATRÁN (definición de la variable privada que contendrá los métodos y la función de jQuery)\n //****************************************************************************************************************\n var rup_combo = {};\n var FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.functionNotSupportedError');\n var FUNCTION_NOT_SUPPORTED_ERROR_TITLE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.error'); //Se configura el arranque de UDA para que alberge el nuevo patrón\n\n $.extend($.rup.iniRup, $.rup.rupSelectorObjectConstructor('rup_combo', rup_combo)); //*******************************\n // DEFINICIÓN DE MÉTODOS PÚBLICOS\n //*******************************\n\n $.fn.rup_combo('extend', {\n /**\r\n * Método utilizado para obtener el valor del componente. Este método es el utilizado por el resto de componentes RUP para estandarizar la obtención del valor del Combo.\r\n *\r\n * @function getRupValue\r\n * @return {string | number} - Devuelve el valor actual del componente seleccionado por el usuario.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"getRupValue\");\r\n */\n getRupValue: function getRupValue() {\n var $self = $(this),\n settings = $self.data('settings'),\n retObj,\n arrayTMP,\n wrapObj = {},\n name;\n name = $self.attr('name');\n\n if (name) {\n arrayTMP = $self.attr('name').split('.');\n }\n\n if (settings.submitAsJSON) {\n //\t\t\t\t\tarrayTMP = $self.attr(\"name\").split(\".\");\n //\t\t\t\t\tprop = arrayTMP[arrayTMP.length-1];\n //\t\t\t\t\tvalueArray = $self.rup_combo(\"value\");\n //\t\t\t\t\tvalueArray_length = valueArray.length;\n //\t\t\t\t\treturnArray = [];\n //\t\t\t\tfor(var i=0; i 1 && settings.legacyWrapMode === false ? wrapObj : retObj;\n },\n\n /**\r\n * Método utilizado para asignar el valor al componente. Este método es el utilizado por \r\n * el resto de componentes RUP para estandarizar la asignación del valor al Combo.\r\n *\r\n * @function setRupValue\r\n * @param {string | number} param - Valor que se va a asignar al componente.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"setRupValue\", \"Si\");\r\n */\n setRupValue: function setRupValue(param) {\n var $self = $(this),\n settings = $self.data('settings'); //Tipo de combo\n\n if (this.length === 0 || settings !== undefined && !settings.multiselect) {\n //Simple > selectmenu\n $.data(this[0], 'setRupValue', param.toString());\n $(this).rup_combo('select', param.toString());\n } else {\n //Multiple > multiselect\n $(this).multiselect('uncheckAll');\n $(this).rup_combo('select', settings.readAsString === true ? param.split(',') : param);\n $(this).multiselect('refresh');\n }\n },\n\n /**\r\n * Método que limpia el valor seleccionado en el combo. En el caso de selección múltiple los valores seleccionados.\r\n *\r\n * @function clear\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"clear\");\r\n */\n clear: function clear() {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n $(this).rup_combo('select', 0);\n } else {\n //Multiple > multiselect\n $(this).multiselect('uncheckAll');\n }\n },\n\n /**\r\n * Método que lanza el evento change del componente.\r\n *\r\n * @function change\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"change\");\r\n */\n change: function change() {\n //Tipo de combo\n if ($(this).data('settings').change) {\n $(this).data('settings').change();\n }\n },\n\n /**\r\n * Realiza una reinicizalización del estado del componente.\r\n *\r\n * @function reset\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"reset\");\r\n */\n reset: function reset() {\n var $self = $(this);\n $self.rup_combo('select', $self.find('option[selected]').attr('value'));\n },\n\n /**\r\n * Reinicia por completo el componente, incluyendo sus ajustes. \r\n *\r\n * @function hardReset\r\n * @since UDA 5.0.3\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"hardReset\");\r\n */\n hardReset: function hardReset() {\n var $self = $(this),\n settings = $self.data('settings');\n settings.disabled = undefined;\n settings.selected = undefined;\n settings.inputValue = undefined;\n settings.ultimaLlamada = undefined;\n settings.ultimosValores = undefined;\n $self.rup_combo('select', '');\n },\n\n /**\r\n * Selecciona todos los elementos en el caso de tratarse de un combo multilesección.\r\n *\r\n * @function checkAll\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"checkAll\");\r\n */\n checkAll: function checkAll() {\n //Tipo de combo\n if ($(this).data('settings').multiselect) {\n //Multiple > multiselect\n $(this).multiselect('checkAll');\n } else {\n //Simple > selectmenu\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Selecciona el elemento enviado como parámetro. En caso de ser un numérico se selecciona por la posición (comenzando en 0) y si es un literal se selecciona por el valor. En el caso de selección múltiple el parámetro será un array.\r\n *\r\n * @function select\r\n * @param {string | number | string[] | number[]} param - Parámetro utilzado para determinar los elementos a seleccionar.\r\n * @example\r\n * // Simple\r\n * $(\"#idCombo\").rup_combo(\"select\", 2);\r\n * // Multiple\r\n * $(\"#idCombo\").rup_combo(\"select\", [0,2]);\r\n */\n select: function select(param) {\n var data = $(this).data(); // Asigna el valor recibido como el seleccionado (evita problemas con los enlazados).\n\n if (param != undefined && param != '') {\n data.setRupValue = param;\n data.settings.selected = param;\n } //Tipo de combo\n\n\n if (this.length === 0 || !data.settings.multiselect) {\n //Simple > selectmenu\n this._setElement($(this), param); //Cargar elemento\n\n } else {\n //Multiple > multiselect\n this._setElement($(this), param, true);\n }\n },\n\n /**\r\n * Selecciona el elemento del combo que contiene como texto el indicado. En caso de no existir el texto a buscar el combo no sufrirá cambios En el caso de selección múltiple el parámetro será un array.\r\n *\r\n * @function selectLabel\r\n * @param {string | string[]} param - Parámetro utilzado para determinar los elementos a seleccionar.\r\n * @example\r\n * // Simple\r\n * $(\"#idCombo\").rup_combo(\"selectLabel\", \"No\");\r\n * // Multiple\r\n * $(\"#idCombo\").rup_combo(\"selectLabel\", [\"No\",\"Si\"]);\r\n */\n selectLabel: function selectLabel(param) {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n var elementSet = this._selectLabel($(this), param, true); //Cargar elemento\n //Si se ha cargado un elemento válido\n\n\n if (elementSet) {\n //Lanzar cambio para que se recarguen hijos\n var hijos = $(this).data('childs');\n\n if (hijos !== undefined) {\n for (var i = 0; i < hijos.length; i = i + 1) {\n $('#' + hijos[i]).rup_combo('reload');\n }\n }\n }\n } else {\n //Multiple > multiselect\n for (var _i = 0; _i < param.length; _i++) {\n $('input[name=\\'multiselect_' + $(this).attr('id') + '\\'][title=\\'' + param[_i] + '\\']').attr('checked', true);\n } //Actualizar literal de elementos seleccionados\n\n\n $(this).multiselect('update');\n }\n },\n\n /**\r\n * Método que devuelve el valor seleccionado en el combo. En caso de ser el valor vació, o sin selección, el valor devuelto es el asociado al “blank”. En el caso de la selección múltiple se devolverá un array.\r\n *\r\n * @function value\r\n * @return {string | string[]} - Valor del elemento o elementos seleccionados.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"value\");\r\n */\n value: function value() {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n return $(this).selectmenu('value');\n } else {\n //Multiple > multiselect\n var retorno = [],\n checked = $(this).multiselect('getChecked');\n\n for (var i = 0; i < checked.length; i++) {\n retorno.push($(checked[i]).val());\n }\n\n return retorno;\n }\n },\n\n /**\r\n * Método que devuelve el label asociado al valor seleccionado en el combo. En el caso de la selección múltiple se devolverá un array.\r\n *\r\n * @function label\r\n * @return {string | string[]} - Texto del elemento o elementos seleccionado.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"label\");\r\n */\n label: function label() {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n return this[0].options[$(this).selectmenu('index')].text;\n } else {\n //Multiple > multiselect\n var retorno = [],\n checked = $(this).multiselect('getChecked');\n\n for (var i = 0; i < checked.length; i++) {\n retorno.push($(checked[i]).next().text());\n }\n\n return retorno;\n }\n },\n\n /**\r\n * Devuelve el índice de la opción seleccionada en el combo (empezando en 0). En el caso de la selección múltiple se devolverá un array.\r\n *\r\n * @function index\r\n * @return {number | number[]} - Índice del elemento o elementos seleccionados.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"index\");\r\n */\n index: function index() {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n return $(this).selectmenu('index');\n } else {\n //Multiple > multiselect\n var retorno = [],\n checked = $(this).rup_combo('value'),\n options = $(this).find('option');\n\n for (var i = 0; i < options.length; i++) {\n if ($.inArray($(options[i]).val(), checked) !== -1) {\n retorno.push(i);\n }\n }\n\n return retorno;\n }\n },\n\n /**\r\n * Deshabilita el combo.\r\n *\r\n * @function disable\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"disable\");\r\n */\n disable: function disable() {\n //Tipo de combo\n var $self = $(this);\n $('#' + $(this).attr('id') + '-button').attr('tabindex', -1); // Añadimos el handler del evento focus para evitar que adquiera el foco cuando está deshabilitado\n\n $('#' + $(this).attr('id') + '-button').on('focus.rup_combo', function () {\n $('#' + $self.attr('id') + '-button').blur();\n return false;\n });\n\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n $(this).selectmenu('disable');\n } else {\n //Multiple > multiselect\n $(this).multiselect('disable');\n }\n },\n\n /**\r\n * Habilita el combo.\r\n *\r\n * @function enable\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"enable\");\r\n */\n enable: function enable() {\n //Tipo de combo\n var settings = $(this).data('settings'); // Eliminamos el handler del evento focus para evitar que adquiera el foco cuando está deshabilitado\n\n $('#' + $(this).attr('id') + '-button').off('focus.rup_combo');\n $('#' + $(this).attr('id') + '-button').attr('tabindex', settings.tabindex ? settings.tabindex : 0);\n\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n $(this).selectmenu('enable');\n } else {\n //Multiple > multiselect\n $(this).multiselect('enable');\n }\n },\n\n /**\r\n * Indica si el combo está deshabilitado o no.\r\n *\r\n * @function isDisabled\r\n * @param {boolean} - Devuelve si el combo está deshabilitado o no.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"isDisabled\");\r\n */\n isDisabled: function isDisabled() {\n if ($(this).attr('aria-disabled') === 'false') {\n return false;\n } else {\n return true;\n }\n },\n\n /**\r\n * Indica si un rup_combo ya ha sido inicializado sobre el elemento con el identificador provisto.\r\n *\r\n * @function isInitialized\r\n * @since UDA 5.0.3\r\n * @return {boolean} - Indica si ya ha sido inicializado un combo sobre el elemento.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"isInitialized\");\r\n */\n isInitialized: function isInitialized() {\n return $(this).attr('ruptype') === 'combo' ? true : false;\n },\n\n /**\r\n * Vacía y deshabilita el combo sobre el que se aplica así como todos los combos que depende de él. Su uso principalmente es interno para las peticiones remotas.\r\n *\r\n * @function disableChild\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"disableChild\");\r\n */\n disableChild: function disableChild() {\n if ($(this).hasClass('rup_combo')) {\n if ($(this).attr('multiple') === 'multiple') {\n $(this).rup_combo('setRupValue', []);\n } else {\n $(this).rup_combo('setRupValue', '');\n }\n } //Vaciar combo, deshabilitarlo\n\n\n $(this).empty();\n\n if ($(this).data('settings').blank) {\n $(this).append('');\n }\n\n $(this).rup_combo('disable'); // Eliminar valor seleccionado.\n\n $(this).data('settings').selected = undefined; //Eliminar texto que se muestra\n\n $('#' + $(this).attr('id') + '-button span:first-child').text(''); //Propagar evento de selección a hijos (recursivo)\n\n var hijos = $(this).data('childs');\n\n if (hijos !== undefined) {\n for (var i = 0; i < hijos.length; i = i + 1) {\n $('#' + hijos[i]).rup_combo('disableChild');\n }\n }\n },\n\n /**\r\n * Deshabilita una opción de un combo multiselección.\r\n *\r\n * @function disableOpt\r\n * @param {string} optValue - Value del option que queremos deshabilitar.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"disableOpt\", \"opt1\");\r\n */\n disableOpt: function disableOpt(optValue) {\n if ($(this).data('settings').multiselect) {\n //Deshabilitar select\n this.find('[value=\\'' + optValue + '\\']').attr('disabled', 'disabled');\n var obj = $('#rup-multiCombo_' + $(this).attr('id')).find('[value=\\'' + optValue + '\\']'); //Deshabilitar input\n\n obj.attr('disabled', 'disabled'); //Estilos línea (label)\n\n obj.parent().css('color', 'grey'); //Si pertenece a OptGroup y es el último en deshabilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(),\n inputs = li.nextUntil('li.ui-multiselect-optgroup-label').find('input'),\n allDisabled = true;\n\n for (var i = 0; i < inputs.length; i++) {\n if (!inputs[i].disabled) {\n allDisabled = false;\n break;\n }\n }\n\n if (allDisabled) {\n //Estilos optGroup\n li.css('color', 'grey');\n li.children('a').remove();\n li.children('span').not('.rup-combo_multiOptgroupLabel').remove();\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Deshabilita varias opciones del combo. Las opciones se identifican mediante un array.\r\n *\r\n * @function disableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a deshabilitar.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"disableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n disableOptArr: function disableOptArr(optValueArr) {\n if ($(this).data('settings').multiselect) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_combo('disableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita una opción de un combo multiselección.\r\n *\r\n * @function enableOpt\r\n * @param {string} enableOpt - Value del option que queremos habilitar.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"enableOpt\", \"opt1\");\r\n */\n enableOpt: function enableOpt(optValue) {\n if ($(this).data('settings').multiselect) {\n //Habilitar select\n this.find('[value=\\'' + optValue + '\\']').removeAttr('disabled');\n var obj = $('#rup-multiCombo_' + $(this).attr('id')).find('[value=\\'' + optValue + '\\']'); //Habilitar input\n\n obj.removeAttr('disabled'); //Estilos línea (label)\n\n obj.parent().css('color', 'black'); //Si pertenece a OptGroup y es el primero en habilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(); //Estilos optGroup\n\n if (li.children('a').length === 0) {\n li.css('color', 'black');\n\n this._generateOptGroupLabel(li, $(this).data('settings').multiOptgroupIconText);\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita varias opciones del combo. Las opciones se identifican mediante un array.\r\n *\r\n * @function enableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a habilitar.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"enableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n enableOptArr: function enableOptArr(optValueArr) {\n if ($(this).data('settings').multiselect) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_combo('enableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Refresca los valores asociados al combo.\r\n *\r\n * @function refresh\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"refresh\");\r\n */\n refresh: function refresh() {\n //Tipo de combo\n if (this.length === 0 || !$(this).data('settings').multiselect) {\n //Simple > selectmenu\n return $(this).selectmenu();\n } else {\n //Multiple > multiselect\n $(this).multiselect('refresh'); //Modificar literal en optgroups y asociarle el evento de \"seleccionar/deseleccionar\"\n\n var multiOptgroupIconText = $(this).data('settings').multiOptgroupIconText,\n self = this;\n $.each($('#rup-multiCombo_' + $(this).attr('id')).find('.ui-multiselect-optgroup-label'), function (index, object) {\n self._generateOptGroupLabel(object, multiOptgroupIconText);\n }); //Titles de botones por defecto\n\n $('#rup-multiCombo_' + $(this).attr('id')).find('.ui-multiselect-all').attr('title', $.rup.i18n.base.rup_combo.multiselect.checkAllTitle).rup_tooltip();\n $('#rup-multiCombo_' + $(this).attr('id')).find('.ui-multiselect-none').attr('title', $.rup.i18n.base.rup_combo.multiselect.uncheckAllTitle).rup_tooltip(); //Deseleccionar todos\n\n return $(this).multiselect('uncheckAll');\n }\n },\n\n /**\r\n * Realiza una recarga de los combos.\r\n *\r\n * @function reload\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"reload\");\r\n */\n reload: function reload() {\n if (this.length !== 0) {\n var settings = $(this).data('settings'),\n source,\n setRupValue,\n wasInited = false;\n $('#' + settings.id).removeClass('inited');\n wasInited = !!1; // Vaciar, quitar el valor y deshabilitar el combo.\n\n if (!$('#' + settings.id).rup_combo('isDisabled')) {\n $('#' + settings.id).rup_combo('disableChild');\n }\n\n if (_typeof(settings.source) === 'object' || _typeof(settings.sourceGroup) === 'object') {\n //LOCAL\n $('#' + settings.id).removeClass('inited');\n source = settings.source[this._getParentsValues(settings.parent, false, settings.multiValueToken, settings.loadFromSelect)];\n\n if (source !== undefined) {\n if (settings.blank != null) {\n var isOptgroup = false; // Comprobamos si el value es un objeto. En caso de serlo esto nos indicara que se trata de un combo tipo 'optgroup'.\n\n $.each(settings.sourceGroup, function (key, value) {\n if (_typeof(value) === 'object' && value !== null) {\n isOptgroup = true;\n return false;\n }\n }); // Si es un combo tipo 'optgroup' se establece una propiedad para que despues \n // en el metodo '_parseOptGroupLOCAL' se gestione correctamente.\n\n if (isOptgroup) {\n settings.blankDone = false;\n }\n } //Parsear datos\n\n\n this._parseLOCAL(source, settings, $('#' + settings.id)); //Crear combo\n\n\n this._makeCombo(settings); // Evento de finalizacion de carga (necesario para trabajar con el manteniminto)\n\n\n if (settings.onLoadSuccess !== null) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n } //Lanzar cambio para que se recarguen hijos\n\n\n $('#' + settings.id).trigger('change');\n setRupValue = $.data($('#' + settings.id)[0], 'setRupValue');\n\n if (setRupValue) {\n //Vaciar combo, quitarle valor y deshabilitar\n $('#' + settings.id).rup_combo('select', setRupValue);\n }\n }\n\n multiChange(settings);\n\n if (wasInited) {\n $('#' + settings.id).addClass('inited');\n }\n } else if (typeof settings.source === 'string' || typeof settings.sourceGroup === 'string') {\n //REMOTO\n var data = this._getParentsValues(settings.parent, true),\n rupCombo = this;\n\n if (data === null) {\n return false;\n } //Se para la petición porque algún padre no tiene el dato cargado\n\n\n if (settings.ultimaLlamada === undefined || settings.ultimaLlamada === '' || settings.ultimaLlamada !== data || settings.disabledCache) {\n //si es la misma busqueda, no tiene sentido volver a intentarlo.\n $.rup_ajax({\n url: rupCombo._generateUrl(settings, data),\n dataType: 'json',\n contentType: 'application/json',\n beforeSend: function beforeSend(xhr) {\n rupCombo._ajaxBeforeSend(xhr, settings);\n\n $('#' + settings.id).removeClass('inited');\n },\n success: function success(data) {\n if (settings.blank != null) {\n var isOptgroup = false; // Comprobamos si el value es un objeto. En caso de serlo esto nos indicara que se trata de un combo tipo 'optgroup'.\n\n $.each(data[0], function (key, value) {\n if (_typeof(value) === 'object' && value !== null) {\n isOptgroup = true;\n return false;\n }\n }); // Si es un combo tipo 'optgroup' se establece una propiedad para que despues \n // en el metodo '_parseOptGroupREMOTE' se gestione correctamente.\n\n if (isOptgroup) {\n settings.blankDone = false;\n }\n }\n\n rupCombo._ajaxSuccess(data, settings, $('#' + settings.id)); // Evento de finalizacion de carga (necesario para trabajar con el manteniminto)\n\n\n if (settings.onLoadSuccess !== null) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n }\n\n multiChange(settings);\n\n if (wasInited) {\n $('#' + settings.id).addClass('inited');\n }\n\n settings.ultimosValores = data;\n $('#' + settings.id).triggerHandler('comboAjaxSuccess', [data]);\n },\n error: function error(xhr, textStatus, errorThrown) {\n if (settings.onLoadError !== null) {\n jQuery(settings.onLoadError(xhr, textStatus, errorThrown));\n } else {\n rupCombo._ajaxError(xhr, textStatus, errorThrown);\n }\n }\n });\n settings.ultimaLlamada = data;\n } else if (settings.ultimosValores !== undefined) {\n //Si la ultima llamada cogio los datos, no hace falta ir al controller los coge del componente.\n if (settings.blank != null) {\n var isOptgroup = false; // Comprobamos si el value es un objeto. En caso de serlo esto nos indicara que se trata de un combo tipo 'optgroup'.\n\n $.each(settings.ultimosValores[0], function (key, value) {\n if (_typeof(value) === 'object' && value !== null) {\n isOptgroup = true;\n return false;\n }\n }); // Si es un combo tipo 'optgroup' se establece una propiedad para que despues \n // en el metodo '_parseOptGroupREMOTE' se gestione correctamente.\n\n if (isOptgroup) {\n settings.blankDone = false;\n }\n }\n\n rupCombo._ajaxSuccess(settings.ultimosValores, settings, $('#' + settings.id)); // Evento de finalizacion de carga (necesario para trabajar con el manteniminto)\n\n\n if (settings.onLoadSuccess !== null) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n }\n\n multiChange(settings);\n\n if (wasInited) {\n $('#' + settings.id).addClass('inited');\n }\n\n $('#' + settings.id).triggerHandler('comboAjaxSuccess', [settings.ultimosValores]);\n } //delete rupCombo;\n\n } else if (typeof settings.source === 'function' || typeof settings.sourceGroup === 'function') {\n //Se lanza la funcion que obtiene los valores a mostrar\n $('#' + settings.id).removeClass('inited');\n jQuery(settings.source);\n\n this._makeCombo(settings);\n\n multiChange(settings);\n\n if (wasInited) {\n $('#' + settings.id).addClass('inited');\n }\n }\n }\n },\n\n /**\r\n * Ordena alfanumericamente y en orden ascendente el combo sobre el que se aplica. Se invoca por defecto al cargarse los combos a no ser que se cambie el valor del atributo ordered en la creación.\r\n *\r\n * @function order\r\n * @param {boolean} orderedByValue - Indica si la búsqueda es por texto (por defecto) o si la búsqueda es por el valor.\r\n * @param {boolean} orderAsNumber - Indica si se debe ordenar como valores numéricos en vez de alfabéticos.\r\n * @param {boolean} skipFirst - Determina si se debe obviar el primer elemento.\r\n * @example\r\n * $(\"#idCombo\").rup_combo(\"order\", orderedByValue, orderAsNumber, skipFirst);\r\n */\n order: function order(orderedByValue, orderAsNumber, skipFirst) {\n var combo = $(this),\n options = $('option', combo),\n arrVals = [],\n skippedValue = null; //Comprobar que se ha obtenido el combo deseado\n\n if (combo.length > 0) {\n //Guardar elemento seleccionado\n var selectedVal = combo.rup_combo('value'); //Obtener elementos combo\n\n options.each(function () {\n //Omitir posible opción vacía\n if (skipFirst) {\n skipFirst = false;\n skippedValue = {\n val: $(this).val(),\n text: $(this).text()\n };\n return true;\n }\n\n arrVals.push({\n val: $(this).val(),\n text: $(this).text(),\n clazz: $(this).attr('class')\n });\n }); //Ordenar elementos (segun parametros, por defecto de texto)\n\n if (!orderedByValue) {\n if (!orderAsNumber) {\n arrVals.sort(function (a, b) {\n return a.text.localeCompare(b.text);\n });\n } else {\n arrVals.sort(function (a, b) {\n return a.text - b.text;\n });\n }\n } else {\n if (!orderAsNumber) {\n arrVals.sort(function (a, b) {\n if (a.val > b.val) {\n return 1;\n } else if (a.val == b.val) {\n return 0;\n } else {\n return -1;\n }\n });\n } else {\n arrVals.sort(function (a, b) {\n return a.val - b.val;\n });\n }\n } //Actualizar combo con elementos ordenados\n\n\n for (var i = 0, l = arrVals.length; i < l; i++) {\n $(options[i]).val(arrVals[i].val).text(arrVals[i].text);\n\n if (arrVals[i].clazz) {\n $(options[i]).attr('class', arrVals[i].clazz);\n }\n } //Añadir opción vacía al inicio\n\n\n if (skippedValue) {\n combo.prepend($('');\n }\n\n if (isInited) {\n $('#' + settings.id).removeClass('inited');\n }\n },\n\n /**\r\n * Procesa la respuesta de la petición AJAX en el caso de que se haya producido un error en la misma.\r\n *\r\n * @function _ajaxError\r\n * @private\r\n * @param {object} xhr - Objeto xhr enviado en la respuesta.\r\n * @param {string} textStatus - Cadena identificadora del error que se ha producido en la petición.\r\n * @param {object} errorThrown - Objeto error correspondiente al que se ha producido en la petición.\r\n * @param {object} settings - Objeto de propiedades de configuración con el que se ha inicializado el componente.\r\n */\n _ajaxError: function _ajaxError(xhr) {\n if (xhr.responseText !== null) {\n $.rup.showErrorToUser(xhr.responseText);\n } else {\n $.rup.showErrorToUser($.rup.i18n.base.rup_combo.ajaxError);\n }\n },\n\n /**\r\n * Crea la etiqueta correspondiente a una agrupación.\r\n *\r\n * @function _generateOptGroupLabel\r\n * @private\r\n * @param {jQuery} object - Referencia al propio componente.\r\n * @param {string} multiOptgroupIconText - Prefijo de los option group.\r\n */\n _generateOptGroupLabel: function _generateOptGroupLabel(object, multiOptgroupIconText) {\n //Texto A > SPAN\n $(object).append($('').text($(object).children('a').text()).addClass('rup-combo_multiOptgroupLabel'));\n $(object).children('a').remove();\n $(object).append($('').text(' ['));\n $(object).append($('').text(multiOptgroupIconText ? $.rup.i18n.base.rup_combo.multiselect.optGroupSelect : '').prepend($('').addClass('ui-icon ui-icon-check rup-combo_multiOptgroupIcon')).attr('title', $.rup.i18n.base.rup_combo.multiselect.optGroupSelectTitle).rup_tooltip({\n applyToPortal: true\n }).click(function () {\n var inputs = $(object).nextUntil('li.ui-multiselect-optgroup-label').find('input');\n\n for (var i = 0; i < inputs.length; i++) {\n if (!inputs[i].disabled) {\n inputs[i].checked = false;\n }\n }\n }));\n $(object).append($('').text(' | '));\n $(object).append($('').text(multiOptgroupIconText ? $.rup.i18n.base.rup_combo.multiselect.optGroupDeselect : '').prepend($('').addClass('ui-icon ui-icon-closethick rup-combo_multiOptgroupIcon')).attr('title', $.rup.i18n.base.rup_combo.multiselect.optGroupDeselectTitle).rup_tooltip({\n applyToPortal: true\n }).click(function () {\n var inputs = $(object).nextUntil('li.ui-multiselect-optgroup-label').find('input');\n\n for (var i = 0; i < inputs.length; i++) {\n if (!inputs[i].disabled) {\n inputs[i].checked = true;\n }\n }\n }));\n $(object).append($('').text(' ]'));\n },\n\n /**\r\n * Devuelve los li de los elementos seleccionados en un combo multiselección.\r\n *\r\n * @function _selectedOptionLiMultiselect\r\n * @private\r\n * @param {object} settings - Objeto de propiedades de configuración con el que se ha inicializado el componente.\r\n * @return {jQuery | jQuery[]} - Objetos jQuery con referencias a los elementos seleccionados.\r\n */\n _selectedOptionLiMultiselect: function _selectedOptionLiMultiselect() {\n return this._optionLis.eq(this._selectedIndex());\n },\n\n /**\r\n * Devuelve el li del elemento que contiene el foco en un combo multiselección.\r\n *\r\n * @function _focusedOptionLiMultiselect\r\n * @private\r\n * @param {object} settings - Objeto de propiedades de configuración con el que se ha inicializado el componente.\r\n * @return {jQuery} - Objeto jQuery con referencia al elemento que contiene el foco.\r\n */\n _focusedOptionLiMultiselect: function _focusedOptionLiMultiselect(settings) {\n var multiselectSettings = $('#' + settings.id).data('echMultiselect');\n var $elem;\n jQuery.each(multiselectSettings.inputs, function (index, elem) {\n if ($(elem).parent().has('.ui-state-hover')) {\n $elem = $(elem);\n }\n });\n return $elem;\n },\n\n /**\r\n * Procesa los eventos de introducción de caracteres de teclado por parte del usuario.\r\n *\r\n * @function _typeAheadMultiselect\r\n * @private\r\n * @param {number} code - Código ASCII correspondiente al caracter introducido por el usuario.\r\n * @param {object} eventType - Objeto event de jQuery.\r\n * @param {object} settings - Objeto de propiedades de configuración con el que se ha inicializado el componente.\r\n */\n _typeAheadMultiselect: function _typeAheadMultiselect(code, eventType, settings) {\n var self = this,\n c = String.fromCharCode(code).toLowerCase(),\n matchee = null,\n nextIndex = null; // Clear any previous timer if present\n\n if (self._typeAhead_timer) {\n window.clearTimeout(self._typeAhead_timer);\n self._typeAhead_timer = undefined;\n } // Store the character typed\n\n\n self._typeAhead_chars = (self._typeAhead_chars === undefined ? '' : self._typeAhead_chars).concat(c); // Detect if we are in cyciling mode or direct selection mode\n\n if (self._typeAhead_chars.length < 2 || self._typeAhead_chars.substr(-2, 1) === c && self._typeAhead_cycling) {\n self._typeAhead_cycling = true; // Match only the first character and loop\n\n matchee = c;\n } else {\n // We won't be cycling anymore until the timer expires\n self._typeAhead_cycling = false; // Match all the characters typed\n\n matchee = self._typeAhead_chars;\n } // We need to determine the currently active index, but it depends on\n // the used context: if it's in the element, we want the actual\n // selected index, if it's in the menu, just the focused one\n // I copied this code from _moveSelection() and _moveFocus()\n // respectively --thg2k\n\n\n var selectedIndex = (eventType !== 'focus' ? this._selectedOptionLiMultiselect(settings).data('index') : this._focusedOptionLiMultiselect(settings).data('index')) || 0;\n var multiselectSettings = $('#' + settings.id).data('echMultiselect');\n\n for (var i = 0; i < multiselectSettings.inputs.length; i++) {\n var thisText = multiselectSettings.inputs.eq(i).next('span').text().substr(0, matchee.length).toLowerCase();\n\n if (thisText === matchee) {\n if (self._typeAhead_cycling) {\n if (nextIndex === null) nextIndex = i;\n\n if (i > selectedIndex) {\n nextIndex = i;\n break;\n }\n } else {\n nextIndex = i;\n }\n }\n }\n\n if (nextIndex !== null) {\n // Why using trigger() instead of a direct method to select the\n // index? Because we don't what is the exact action to do, it\n // depends if the user is typing on the element or on the popped\n // up menu\n multiselectSettings.inputs.eq(nextIndex).parent().trigger('mouseover');\n multiselectSettings.inputs.eq(nextIndex).trigger(eventType);\n }\n\n self._typeAhead_timer = window.setTimeout(function () {\n self._typeAhead_timer = undefined;\n self._typeAhead_chars = undefined;\n self._typeAhead_cycling = undefined;\n }, settings.typeAhead);\n },\n\n /**\r\n * Gestiona los parámetros a añadir en la URL para que Hdiv permita la llamada.\r\n *\r\n * @function _generateUrl\r\n * @since UDA 5.2.0\r\n * @private\r\n * @param {object} settings - Configuración del componente.\r\n * @param {string} [data] - Valores de los identificadores de los padres en caso de ser enlazados.\r\n */\n _generateUrl: function _generateUrl(settings, data) {\n var _settings$inlineEdit, _settings$inlineEdit2, _settings$inlineEdit3, _settings$inlineEdit4;\n\n var $form = (_settings$inlineEdit = settings.inlineEdit) !== null && _settings$inlineEdit !== void 0 && _settings$inlineEdit.$auxForm ? (_settings$inlineEdit2 = settings.inlineEdit) === null || _settings$inlineEdit2 === void 0 ? void 0 : _settings$inlineEdit2.$auxForm : $('#' + settings.id).closest('form');\n var name = (_settings$inlineEdit3 = settings.inlineEdit) !== null && _settings$inlineEdit3 !== void 0 && _settings$inlineEdit3.auxSiblingFieldName ? (_settings$inlineEdit4 = settings.inlineEdit) === null || _settings$inlineEdit4 === void 0 ? void 0 : _settings$inlineEdit4.auxSiblingFieldName : settings.name;\n var source = settings.source ? settings.source : settings.sourceGroup;\n\n if ($form.length === 1) {\n var url = source + '?_MODIFY_HDIV_STATE_=' + $.fn.getHDIV_STATE(undefined, $form);\n\n if (data) {\n // Escapa los caracteres '#' para evitar problemas en la petición.\n url += \"&\" + data.replaceAll('#', '%23');\n }\n\n return url + '&MODIFY_FORM_FIELD_NAME=' + name;\n } else {\n return source;\n }\n },\n\n /**\r\n * Generar source local a partir del HTML.\r\n *\r\n * @function _generateLocalSource\r\n * @since UDA 5.2.0\r\n * @private\r\n * @param {object} settings - Ajustes del componente.\r\n */\n _generateLocalSource: function _generateLocalSource(settings) {\n var optionData = {};\n $.each($(\"#\" + this[0].id + ' option'), function (index, option) {\n var _optionData$idPadre$l, _optionData$idPadre, _optionData;\n\n var idPadre = $(option).data('idpadre');\n var optionDataLength = (_optionData$idPadre$l = (_optionData$idPadre = optionData[idPadre]) === null || _optionData$idPadre === void 0 ? void 0 : _optionData$idPadre.length) !== null && _optionData$idPadre$l !== void 0 ? _optionData$idPadre$l : (_optionData = optionData) === null || _optionData === void 0 ? void 0 : _optionData.length;\n\n if (idPadre && !optionDataLength > 0) {\n optionData[idPadre] = [];\n optionDataLength = 0;\n } else if (!idPadre && !optionDataLength > 0) {\n optionData = [];\n optionDataLength = 0;\n }\n\n if (idPadre) {\n optionData[idPadre][optionDataLength] = {};\n optionData[idPadre][optionDataLength].label = $(option).text();\n optionData[idPadre][optionDataLength].value = option.value;\n } else {\n optionData[optionDataLength] = {};\n optionData[optionDataLength].label = $(option).text();\n optionData[optionDataLength].value = option.value;\n }\n });\n\n if (settings.parent) {\n settings.source = optionData; // Vaciar el combo para evitar problemas de duplicidad.\n\n $('#' + settings.id).empty();\n } // Almacenar los valores generados.\n\n\n $('#' + settings.id).data('values', optionData);\n },\n\n /**\r\n * Método de inicialización del componente.\r\n *\r\n * @function _init\r\n * @private\r\n * @param {object} args - Parámetros de inicialización del componente.\r\n */\n _init: function _init(args) {\n var _this = this;\n\n global.initRupI18nPromise.then(function () {\n if (args.length > 1) {\n $.rup.errorGestor($.rup.i18nParse($.rup.i18n.base, 'rup_global.initError') + $(_this).attr('id'));\n } else {\n var _$$val;\n\n //Se recogen y cruzan las paremetrizaciones del objeto\n var settings = $.extend({}, $.fn.rup_combo.defaults, args[0]),\n html,\n loadAsLocal = false,\n isValidableElem = false,\n attrsJson = {},\n attrs; // Cargar el identificador del padre del patrón.\n\n settings.id = $.rup_utils.escapeId($(_this).attr('id'));\n settings.name = $(_this).attr('name'); // Comprobar en caso de ser enlazado, que los combos sobre los que depende hayan sido inicializados.\n\n if (settings.parent && Array.isArray(settings.parent) && !settings.parentsInitialized) {\n var parentsDeferred = [];\n var parentsInitialized = true;\n $.each(settings.parent, function (key, id) {\n if (!$('#' + id).rup_combo(\"isInitialized\")) {\n var parentDeferred = $.Deferred();\n parentsDeferred.push(parentDeferred); // Inicializarse cuando el padre o padres lo hayan hecho. El evento se adjunta al label en vez de al combo porque este último es convertido más adelante y pierde el evento.\n\n $('label[for=\"' + id + '\"]').on('comboIsInitialized', function () {\n // Desligar evento del elemento.\n $(this).off('comboIsInitialized'); // Resolver promesa.\n\n parentDeferred.resolve();\n });\n parentsInitialized = false;\n }\n });\n\n if (!parentsInitialized) {\n $.when.apply($, parentsDeferred).done(function () {\n // Añadir parámetro para indicar que la inicialización del componente ya puede llevarse a cabo de manera segura.\n settings.parentsInitialized = true; // Inicializar componente.\n\n $('#' + settings.id).rup_combo(settings);\n });\n return false;\n }\n } // Se sobreescribe el change:\n\n\n if (settings.change) {\n settings.userChange = settings.change;\n }\n\n if (settings.userChange) {\n settings.change = function () {\n if ($('#' + settings.id).is('.inited')) {\n settings.userChange();\n }\n };\n } //Se recoge el tabindex indicado en el elemento\n\n\n settings.tabindex = $(_this).attr('tabindex'); //Sobreescribir literales por defecto para multicombo\n\n $.extend($.ech.multiselect.prototype.options, $.rup.i18n.base.rup_combo.multiselect); // Definir el elemento del DOM sobre el que se añadirá el componente siempre y cuando no se haya definido ya en los parámetros de inicialización\n\n if (settings.appendTo != undefined) {\n if (settings.appendTo.length == 0 || settings.appendTo.length == undefined) {\n console.error($.rup_utils.format(jQuery.rup.i18nParse(jQuery.rup.i18n.base, 'rup_combo.appendToError'), settings.id));\n settings.appendTo = $('#' + settings.id).parent();\n }\n } else {\n settings.appendTo = $('#' + settings.id).parent();\n } //Si no se recibe identificador para el acceso a literales se usa el ID del objeto\n\n\n if (!settings.i18nId) {\n settings.i18nId = settings.id;\n } //Guardar valor del INPUT\n\n\n var savedInputValue = (_$$val = $('#' + settings.id).val()) !== null && _$$val !== void 0 ? _$$val : $('#' + settings.id).prop('value');\n settings.inputValue = savedInputValue == \"\" ? undefined : savedInputValue;\n attrs = $(_this).prop('attributes');\n\n for (var i = 0; i < attrs.length; i++) {\n attrsJson[attrs[i].name] = attrs[i].value;\n }\n\n $.extend(attrsJson, {\n name: settings.name,\n ruptype: 'combo'\n }); //Contenido combo\n\n html = $('').attr(attrsJson).addClass('rup_combo');\n\n if ($(_this).hasClass('validableElem')) {\n isValidableElem = true;\n html.addClass('validableElem');\n }\n\n if ($(_this).hasClass('customelement')) {\n isValidableElem = true;\n html.addClass('customelement');\n }\n\n if (settings.firstLoad === null && $(_this).is('select') && settings.loadFromSelect) {\n loadAsLocal = true;\n }\n\n if (settings.parent) {\n //DEPENDIENTE\n //Guardar referencia a hijos en cada uno de los padres (propagación de carga)\n $.map(settings.parent, function (item) {\n var childsArray = $('#' + item).data('childs') === undefined ? [] : $('#' + item).data('childs');\n childsArray[childsArray.length] = settings.id;\n $('#' + item).data('childs', childsArray);\n });\n\n if (settings.loadFromSelect === false) {\n if (settings.firstLoad !== null) {\n _this._parseLOCAL(settings.firstLoad, settings, html);\n } //Crear combo y deshabilitarlo\n\n\n $('#' + settings.id).replaceWith(html);\n } else {\n $('#' + settings.id).attr('ruptype', 'combo').removeClass().addClass('rup_combo');\n\n if (isValidableElem) {\n $('#' + settings.id).removeClass().addClass('validableElem');\n } // Generar source local a partir del HTML (solo dependientes).\n\n\n _this._generateLocalSource(settings);\n }\n\n _this._makeCombo(settings);\n\n if (!($(_this).is('select') && settings.loadFromSelect)) {\n $('#' + settings.id).rup_combo('disable');\n } else {\n var options = $(_this).find('option');\n var vacio = true;\n\n for (var _i2 = 0; _i2 < options.length; _i2 = _i2 + 1) {\n if ($(options[_i2]).attr('value') !== '') {\n vacio = false;\n break;\n }\n }\n\n if (vacio) {\n $('#' + settings.id).rup_combo('disable');\n }\n } //Almacenar los settings\n\n\n $('#' + settings.id).data('settings', settings); //Comprobar si los padres ya tienen datos seleccionados (si son LOCALES puede suceder)\n\n if (_this._getParentsValues(settings.parent) !== null && settings.firstLoad === null && settings.loadFromSelect === false) {\n $('#' + settings.id).rup_combo('reload');\n }\n\n multiChange(settings);\n $('#' + settings.id).addClass('inited');\n } else if (_typeof(settings.source) === 'object' || _typeof(settings.sourceGroup) === 'object' || loadAsLocal) {\n //LOCAL\n if (settings.blank != null) {\n var isOptgroup = false; // Comprobamos si el value es un objeto. En caso de serlo esto nos indicara que se trata de un combo tipo 'optgroup'.\n\n $.each(settings.sourceGroup, function (key, value) {\n if (_typeof(value) === 'object' && value !== null) {\n isOptgroup = true;\n return false;\n }\n }); // Si es un combo tipo 'optgroup' se establece una propiedad para que despues \n // en el metodo '_parseOptGroupLOCAL' se gestione correctamente.\n\n if (isOptgroup) {\n settings.blankDone = false;\n }\n } //Parsear datos\n\n\n if (settings.loadFromSelect === false) {\n if (settings.source) {\n _this._parseLOCAL(settings.firstLoad !== null ? settings.firstLoad : settings.source, settings, html);\n } else {\n settings.ordered = false;\n\n _this._parseOptGroupLOCAL(settings.firstLoad !== null ? settings.firstLoad : settings.sourceGroup, settings, html);\n }\n\n $('#' + settings.id).replaceWith(html);\n } else {\n $('#' + settings.id).attr('ruptype', 'combo').removeClass().addClass('rup_combo');\n\n if (isValidableElem) {\n $('#' + settings.id).removeClass().addClass('validableElem');\n } // Generar source local a partir del HTML (solo dependientes).\n\n\n _this._generateLocalSource(settings);\n } //Crear combo\n\n\n _this._makeCombo(settings);\n\n if (settings.onLoadSuccess !== null) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n } //Almacenar los settings\n\n\n $('#' + settings.id).data('settings', settings);\n multiChange(settings);\n $('#' + settings.id).addClass('inited');\n } else if (typeof settings.source === 'string' || typeof settings.sourceGroup === 'string') {\n //REMOTO\n var rupCombo = _this,\n self = _this;\n $.rup_ajax({\n url: rupCombo._generateUrl(settings),\n dataType: 'json',\n contentType: 'application/json',\n beforeSend: function beforeSend(xhr) {\n rupCombo._ajaxBeforeSend(xhr, settings, html);\n },\n success: function success(data) {\n if (settings.blank != null) {\n var isOptgroup = false; // Comprobamos si el value es un objeto. En caso de serlo esto nos indicara que se trata de un combo tipo 'optgroup'.\n\n $.each(data[0], function (key, value) {\n if (_typeof(value) === 'object' && value !== null) {\n isOptgroup = true;\n return false;\n }\n }); // Si es un combo tipo 'optgroup' se establece una propiedad para que despues \n // en el metodo '_parseOptGroupREMOTE' se gestione correctamente.\n\n if (isOptgroup) {\n settings.blankDone = false;\n }\n }\n\n rupCombo._ajaxSuccess(data, settings, html);\n\n if (settings.onLoadSuccess !== null) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n }\n\n multiChange(settings);\n $('#' + settings.id).addClass('inited'); // Evento que se ejecuta cuando la carga de datos ha sido satisfactoria.\n\n $('#' + settings.id).triggerHandler('comboAjaxLoadSuccess', [data]);\n },\n error: function error(xhr, textStatus, errorThrown) {\n if (settings.onLoadError !== null) {\n jQuery(settings.onLoadError(xhr, textStatus, errorThrown));\n } else {\n self._ajaxError(xhr, textStatus, errorThrown);\n }\n }\n }); // delete rupCombo;\n //Almacenar los settings\n\n $('#' + settings.id).data('settings', settings);\n } else if (typeof settings.source === 'function' || typeof settings.sourceGroup === 'function') {\n jQuery(settings.source);\n\n _this._makeCombo(settings); //Almacenar los settings\n\n\n $('#' + settings.id).data('settings', settings);\n multiChange(settings);\n $('#' + settings.id).addClass('inited');\n } //Asociar evento CHANGE para propagar cambios a los hijos\n\n\n $('#' + settings.id).on('change', function () {\n // En caso de modificarse el valor del select, se actualiza el valor del rup.combo (con esta accion se recargan tambien los hijos)\n if (!settings.multiselect) {\n $('#' + settings.id).rup_combo('select', $('#' + settings.id).val());\n } else {\n $('#' + settings.id).rup_combo('select', $('#' + settings.id).rup_combo('getRupvalue'));\n } //Lanzar cambio para que se recarguen hijos, si los tiene\n\n\n var hijos = $(this).data('childs');\n\n if (hijos !== undefined) {\n for (var _i3 = 0; _i3 < hijos.length; _i3 = _i3 + 1) {\n $('#' + hijos[_i3]).rup_combo('reload');\n }\n }\n }); //Borrar referencia\n // delete html;\n //Ocultar posibles elementos de fechas/horas\n\n $('#' + settings.id).next('a').click(function () {\n $('#ui-datepicker-div').hide();\n }); //Se audita el componente\n\n $.rup.auditComponent('rup_combo', 'init'); // Comunicar la inicialización del componente.\n\n $('label[for=\"' + settings.id + '\"]').triggerHandler('comboIsInitialized');\n }\n })[\"catch\"](function (error) {\n console.error('Error al inicializar el componente:\\n', error);\n });\n }\n }); // Creamos un método para añadir el change a los multiselect\n\n var multiChange = function multiChange(settings) {\n if (settings.multiselect) {\n $('#' + settings.id).on('multiselectopen', function () {\n if (!settings.opened) {\n settings.lastMultiValue = $('#' + settings.id).rup_combo('getRupValue');\n }\n\n settings.opened = !!1;\n });\n $('#' + settings.id).on('multiselectclose', function () {\n var changed = settings.lastMultiValue.toString() != $('#' + settings.id).rup_combo('getRupValue').toString();\n\n if (settings.change && changed && settings.opened) {\n settings.change();\n }\n\n settings.opened = !!0;\n });\n }\n }; //******************************************************\n // DEFINICIÓN DE LA CONFIGURACION POR DEFECTO DEL PATRON\n //******************************************************\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener los elementos a mostrar.\r\n *\r\n * @callback jQuery.rup_combo~onLoadError\r\n * @param {Object} xhr - Objeto XHR que contiene la respuesta de la petición realizada.\r\n * @param {string} textStatus - Texto que identifica el error producido.\r\n * @param {Object} errorThrown - Objeto error que contiene las propiedades del error devuelto en la petición.\r\n */\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener los elementos a mostrar.\r\n *\r\n * @callback jQuery.rup_combo~onLoadSuccess\r\n * @param {jQuery} self - Referencia al objeto jQuery del propio combo.\r\n */\n\n /**\r\n * @description Opciones por defecto de configuración del componente.\r\n *\r\n * @name defaults\r\n *\r\n * @property {jQuery.rup_combo~onLoadError} [onLoadError] - Función de callback a ejecutar en caso de que se produzca un error en la petición de obtención de la lista de elementos a mostrar.\r\n * @property {number} [width=200] - Determina el tamaño del combo. Su valor por defecto es 200 para la selección simple. En el caso de selección múltiple su declaración es obligatoria. Puede establecerse un porcentaje para que el combo sea responsivo.\r\n * @property {string} [blank=null] - Se utiliza para declarar un valor independiente de la lógica de negocio y en ocasiones se representa como \"Seleccione un elemento\". Permite establecer un mensaje independiente por cada combo haciendo uso de $.rup.i18n.app.id._blank (sustituyendo id por el propio de cada combo) o uno genérico por aplicación haciendo uso de $.rup.i18n.app.rup_combo.blank. En caso de no definir ninguno, se usará el genérico de UDA, $.rup.i18n.base.rup_combo.blankNotDefined.\r\n * @property {string} [style=dropdown] - Tipo de visualización de la lista de opciones del combo.\r\n * @property {boolean} [showValue=false] - Determina si el combo debe mostrar el valor asociado concatenado al literal (sólo selección simple).\r\n * @property {string} [token=\"|\"] - Define el separador a utilizar cuando se muestra el valor asociado al combo concatenado al literal.\r\n * @property {string} [multiValueToken=\"##\"] - Define el separador a utilizar en combos enlazados locales.\r\n * @property {boolean} [ordered=true] - Indica si el combo debe ordenarse.\r\n * @property {boolean} [orderedByValue=false] - Indica si el la ordenación del combo debe realizarse por el valor de los elementos en lugar de por el texto.\r\n * @property {jQuery.rup_combo~onLoadSuccess} [onLoadSuccess=null] - Función de callback a ejecutar en el caso de que la petición de carga de datos se haya producido correctamente.\r\n * @property {boolean} [loadFromSelect=false] - Determina si se debe de utilizar los elementos option del elemento html sobre el que se inicializa el componente para inicializar los datos del elemento.\r\n * @property {boolean} [multiselect=false] - Indica si el combo permite la selección múltiple.\r\n * @property {boolean} [multiOptgroupIconText=false] - Indica si se desea que en la selección múltiple con grupos, el nombre del grupo tenga descripción en los iconos para seleccionar/deseleccionar los elementos del grupo.\r\n * @property {object} [position={my: 'left top', at: 'left bottom', of: $(\"#comboMulti\")}] - Define la posición del menú. La tercera opción hace referencia al elemento sobre el que se posicionará el menú y su uso es opcional (se usará el botón del combo por defecto si no se define). Más información en https://github.com/ehynds/jquery-ui-multiselect-widget/wiki/Options#available-options.\r\n * @property {boolean} [positionMenuByOffset=false] - Ofrece la posibilidad de posicionar el menú del combo con multiselección a partir del método .offset() en caso de ser 'true' o por el método .position() en caso de ser 'false'. Esta propiedad sólo será usada si la propiedad 'position' es definida con un valor vacío.\r\n * @property {boolean} [submitAsString=false] - Indica si el envío de los elementos seleccionados en la selección múltiple se realiza como un literal separados por coma.\r\n * @property {boolean} [submitAsJSON=false] - Indica si el envío de los elementos seleccionados en la selección múltiple se realiza como un array JSON donde el nombre del mapa será el nombre del combo. En el caso de que el nombre contenga notación dot se tomará el último literal. Ej: [{id:1}, {id:2}, …].\r\n * @property {boolean} [readAsString=false] - Determina si la asignación de un valor inicial se va a realizar a partir de un string con los ids de los elementos separados por comas en vez de un array de json.\r\n * @property {boolean} [rowStriping=false] - Indica si se debe aplicar un estilo diferente a las filas pares e impares para poder distinguirlas mediante un color diferente.\r\n * @property {number} [typeAhead=false] - Especifica en milisegundos el tiempo de espera que toma el componente antes de procesar los eventos de escritura realizados por el usuario.\r\n * @property {number} [legacyWrapMode=false] - Determina si se emplea el método obsoleto a la hora de empaquetar en objetos json los elementos seleccionados. Su propósito es mantener la retrocompatibilidad.\r\n * @property {function} [open=function( event, ui )] - Calcula el ancho del combo y se lo aplica al menú que despliega al pulsar sobre el.\r\n */\n\n\n $.fn.rup_combo.defaults = {\n onLoadError: null,\n width: 200,\n blank: null,\n style: 'dropdown',\n showValue: false,\n token: '|',\n multiValueToken: '##',\n ordered: true,\n orderedByValue: false,\n firstLoad: null,\n onLoadSuccess: null,\n loadFromSelect: false,\n multiselect: false,\n multiOptgroupIconText: true,\n position: {\n my: 'left top',\n at: 'left bottom'\n },\n positionMenuByOffset: false,\n submitAsString: false,\n submitAsJSON: false,\n readAsString: false,\n rowStriping: false,\n typeAhead: 1000,\n legacyWrapMode: false,\n open: function open(event) {\n var comboId = $.rup_utils.escapeId(this.id);\n var anchoCombo = $('#' + comboId + '-button').outerWidth(); // Si es un combo multiselect\n\n if (this.multiple) {\n $('#rup-multiCombo_' + comboId).outerWidth(anchoCombo);\n event.stopPropagation();\n } // Si es un combo normal\n else {\n $('#' + comboId + '-menu').parent('div').outerWidth(anchoCombo);\n $('#' + comboId + '-menu').outerWidth(anchoCombo);\n event.stopPropagation();\n $(document).trigger('mousedown.multiselect');\n }\n }\n };\n});\n\nfunction optGroupRemoteHTML($, optGroup, html, self, settings) {\n $.each(optGroup, function (key, elemGroup) {\n html.append($('').attr('label', key));\n html = $(html).children('optgroup:last-child');\n\n self._parseREMOTE(elemGroup, settings, html, key);\n\n html = $(html).parent();\n });\n return html;\n}\n\nfunction optGroupHTML($, optGroup, html, settings, self) {\n $.each(optGroup, function (key, elemGroup) {\n if (typeof elemGroup[0] !== 'string') {\n html.append($('').attr('label', $.rup.i18nParse($.rup.i18n.app[settings.i18nId], key)));\n } else {\n html.append($('').attr('label', key));\n }\n\n html = $(html).children('optgroup:last-child');\n\n self._parseLOCAL(elemGroup, settings, html);\n\n html = $(html).parent();\n });\n return html;\n}\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://rup/./src/rup.combo.js?"); /***/ }), @@ -8468,7 +8468,7 @@ eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_FAC /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function($, global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * Copyright 2013 E.J.I.E., S.A.\r\n *\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n */\n\n/**\r\n * Permite al usuario introducir datos en una serie de campos para ser enviados al servidor y ser procesados.\r\n *\r\n * @summary Componente RUP Form.\r\n * @module rup_form\r\n * @example\r\n * var properties={\r\n * // Propiedades de configuración\r\n * };\r\n *\r\n * $(\"#formulario\").rup_form(properties);\r\n */\n(function (factory) {\n if (true) {\n // AMD. Register as an anonymous module.\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./core/utils/jquery.form */ \"./src/core/utils/jquery.form.js\"), __webpack_require__(/*! ./core/utils/form2object */ \"./src/core/utils/form2object.js\"), __webpack_require__(/*! ./rup.base */ \"./src/rup.base.js\"), __webpack_require__(/*! ./rup.validate */ \"./src/rup.validate.js\"), __webpack_require__(/*! ./rup.message */ \"./src/rup.message.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function (jQuery) {\n //*********************************************\n // ESPECIFICACÍON DE LOS TIPOS BASE DEL PATRÓN\n //*********************************************\n //*****************************************************************************************************************\n // DEFINICIÓN BASE DEL PATRÓN (definición de la variable privada que contendrá los métodos y la función de jQuery)\n //*****************************************************************************************************************\n var rup_form = {}; //Se configura el arranque de UDA para que alberge el nuevo patrón\n\n $.extend($.rup.iniRup, $.rup.rupSelectorObjectConstructor('rup_form', rup_form)); //********************************\n // DEFINICIÓN DE MÉTODOS PÚBLICOS\n //********************************\n\n $.fn.rup_form('extend', {\n /**\r\n * Realiza la misma función que ajaxSubmit. Se mantiene para asegurar la retrocompatibilidad con versiones anteriores.\r\n *\r\n * @function ajaxFormSubmit\r\n * @param {object} options - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxFormSubmit\", options);\r\n */\n ajaxFormSubmit: function ajaxFormSubmit(options) {\n var $self = this; // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.ajaxSubmit(options);\n },\n\n /**\r\n * Realiza el envío del formulario. La configuración de este método es la misma que la de ajaxForm.\r\n *\r\n * @function ajaxSubmit\r\n * @param {object} argOptions - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxSubmit\", options);\r\n */\n ajaxSubmit: function ajaxSubmit(argOptions) {\n var $self = this,\n options = $.extend(true, {}, $.fn.rup_form.defaults, argOptions); // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.rup_form('configureOptions', options);\n\n if (options.formValidationRequired) {\n $self.rup_validate(options.validate);\n\n if ($self.valid()) {\n $(this).ajaxSubmit(options);\n }\n } else {\n // Necesario utilizar $(this) para invocar al ajaxSubmit del plugin subyacente\n $(this).ajaxSubmit(options);\n }\n },\n\n /**\r\n * Realiza el envío del formulario. La configuración de este método es la misma que la de ajaxForm.\r\n *\r\n * @function ajaxNotSubmit\r\n * @param {object} argOptions - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxNotSubmit\", options);\r\n */\n ajaxNotSubmit: function ajaxNotSubmit(argOptions) {\n var $self = this,\n options = $.extend(true, {}, $.fn.rup_form.defaults, argOptions); // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.rup_form('configureOptions', options);\n\n if (options.formValidationRequired) {\n $self.submit();\n\n if ($self.valid()) {\n $(this).ajaxSubmit(options);\n }\n } else {\n // Necesario utilizar $(this) para invocar al ajaxSubmit del plugin subyacente\n $(this).ajaxSubmit(options);\n }\n },\n\n /**\r\n * Elimina la configuración realizada por el componente sobre el formulario html.\r\n *\r\n * @function destroy\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"destroy\");\r\n */\n destroy: function destroy() {\n var $self = this;\n $self.removeClass('rup_form');\n $.removeData($self[0]);\n $self.ajaxFormUnbind();\n $self.off();\n },\n\n /**\r\n * Serializa el contenido del formulario en un query string.\r\n *\r\n * @function formSerialize\r\n * @return {string} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"formSerialize\");\r\n */\n formSerialize: function formSerialize() {\n var $self = this,\n element,\n ruptype,\n fieldArray = [];\n $.each($self.formToArray(), function (key, obj) {\n element = $('[name=\\'' + obj.name + '\\']', self);\n ruptype = element.attr('ruptype');\n\n if (ruptype !== undefined) {\n obj.value = element['rup_' + ruptype]('getRupValue');\n fieldArray.push(obj);\n } else {\n fieldArray.push(obj);\n }\n });\n return $.param(fieldArray);\n },\n\n /**\r\n * Realiza la serialización de campos del formulario en un objeto json.\r\n *\r\n * @function formToJson\r\n * @return {string} - Retorna un objeto con el formato {nombre1:valor1, nombre2:valor2…nombreN:valorN}.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"formToJson\");\r\n */\n formToJson: function formToJson() {\n if (this[0]) {\n return window.form2object(this[0]);\n } else {\n return {};\n }\n },\n\n /**\r\n * Realiza la serialización de campos del formulario en un query string\r\n *\r\n * @function fieldSerialize\r\n * @return {string} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form .specialFields\").rup_form(\"fieldSerialize\");\r\n */\n fieldSerialize: function fieldSerialize() {\n var a = [];\n this.each(function () {\n var n = $(this).attr('name');\n\n if (!n) {\n return;\n }\n\n var v = $(this).rup_form('fieldValue');\n\n if (v && v.constructor == Array) {\n for (var i = 0, max = v.length; i < max; i++) {\n a.push({\n name: n,\n value: v[i]\n });\n }\n } else if (v !== null && typeof v != 'undefined') {\n a.push({\n name: $(this).attr('name'),\n value: v\n });\n }\n });\n return $.param(a);\n },\n\n /**\r\n * Devuelve un array con el valor de los campos indicados.\r\n *\r\n * @function fieldValue\r\n * @return {string[]} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form .specialFields\").rup_form(\"fieldValue\");\r\n */\n fieldValue: function fieldValue() {\n var valuesArray = [],\n value;\n this.each(function () {\n var ruptype = $(this).attr('ruptype');\n\n if (ruptype !== undefined) {\n value = $(this)['rup_' + ruptype]('getRupValue');\n valuesArray.push(value);\n } else {\n $.merge(valuesArray, $(this).fieldValue());\n }\n });\n return valuesArray;\n },\n\n /**\r\n * Inicializa el formulario con su estado inicial invocando al método reset nativo.\r\n *\r\n * @function resetForm\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"resetForm\");\r\n */\n resetForm: function resetForm() {\n return this.each(function () {\n $(this).resetForm();\n });\n },\n\n /**\r\n * Limpia los elementos del formulario.\r\n *\r\n * @function clearForm\r\n * @param {boolean} includeHidden - Determina si se deben de limpiar también los elementos hidden que existen en el formulario.\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * // Limpiar los campos del formulario\r\n * jQuery(\"#form\").rup_form(\"clearForm\");\r\n * // Limpiar los campos del formulario inlcuyendo los campos hidden\r\n * jQuery(\"#form\").rup_form(\"clearForm\", true);\r\n */\n clearForm: function clearForm(includeHidden) {\n return this.each(function () {\n $('input,select,textarea', this).rup_form('clearFields', includeHidden);\n });\n },\n\n /**\r\n * Limpia los campos especificados mediante el selector de jQuery.\r\n *\r\n * @function clearFields\r\n * @param {boolean} includeHidden - Determina si se deben de limpiar también los elementos hidden que existen en el formulario.\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * // Limpiar los campos del formulario\r\n * jQuery(\"#form .specialFields\").rup_form(\"clearFields\");\r\n * // Limpiar los campos del formulario inlcuyendo los campos hidden\r\n * jQuery(\"#form .specialFields\").rup_form(\"clearFields\", true);\r\n */\n clearFields: function clearFields(includeHidden) {\n return this.each(function () {\n var ruptype = $(this).attr('ruptype');\n\n if (ruptype === undefined || ruptype !== 'combo') {\n $(this).clearFields(includeHidden);\n } else {\n $(this).rup_combo('clear');\n }\n });\n },\n\n /**\r\n * Función de inicialización del componente. Es un método de uso interno. No debería de invocarse de manera directa.\r\n *\r\n * @function configureOptions\r\n * @param {object} settings - Propiedades de configuración\r\n */\n configureOptions: function configureOptions(settings) {\n var $self = this,\n hasFileInputs,\n beforeSendUserEvent,\n beforeSubmitUserEvent;\n\n if (settings.url !== null) {\n $self.attr('action', settings.url);\n }\n\n hasFileInputs = $('input[type=file]:enabled', $self).length > 0;\n\n if (settings.useJsonIfPossible && !hasFileInputs) {\n settings.contentType = 'application/json';\n } else {\n settings.contentType = 'multipart/form-data';\n } // BeforeSend\n\n\n beforeSendUserEvent = settings.beforeSend;\n\n settings.beforeSend = function (xhr, ajaxOptions) {\n var ret = true;\n\n if (typeof beforeSendUserEvent === \"function\") {\n ret = beforeSendUserEvent.call(this, xhr, ajaxOptions);\n }\n\n if (ret === false) {\n return false;\n } else if (ret !== 'skip') {\n if (ajaxOptions.contentType !== false && ajaxOptions.contentType.indexOf('application/json') !== -1) {\n var jsonData = $self.rup_form('formToJson');\n\n if (settings.multimodel !== null) {\n xhr.setRequestHeader('RUP_MULTI_ENTITY', 'true');\n jsonData.rupEntityMapping = settings.multimodel;\n }\n\n if (ajaxOptions.extraData !== undefined && ajaxOptions.extraData !== null) {\n $.extend(jsonData, ajaxOptions.extraData);\n }\n\n ajaxOptions.data = $.toJSON(jsonData);\n }\n }\n }; // BeforeSubmit\n\n\n beforeSubmitUserEvent = settings.beforeSubmit;\n\n settings.beforeSubmit = function (arr, $form, options) {\n var httpMethod, error_user, hasFileInputs;\n\n if (typeof beforeSubmitUserEvent === \"function\") {\n if (beforeSubmitUserEvent.call(this, arr, $form, options) === false) {\n return false;\n }\n }\n\n hasFileInputs = jQuery('input:file', $form).length > 0; // Implementacion para realizar la emulacion de xhr al utilizar iframes\n\n if (!$.rup.browser.xhrFileUploadSupport && hasFileInputs || options.iframe === true) {\n // Configuracion necesaria para permitir con iframes el uso de metodos http diferentes a GET o POST\n httpMethod = settings.type !== undefined ? settings.type : options.type;\n\n if ($.inArray(httpMethod.toUpperCase(), $.rup.IFRAME_ONLY_SUPPORTED_METHODS) === -1) {\n options.extraData = $.extend({}, options.extraData, {\n '_method': httpMethod.toUpperCase()\n });\n } //Se valida la presencia de portal y, llegados al caso, se adecuan las llamadas ajax para trabajar con portales\n\n\n options.url = $.rup_utils.setNoPortalParam(options.url); // Envio del parametro emulate_iframe_http_status para activar la emulacion en el lado servidor\n\n options.extraData = $.extend({}, options.extraData, {\n '_emulate_iframe_http_status': 'true'\n });\n options.url = options.url + (options.url.match('\\\\?') === null ? '?' : '&') + '_emulate_iframe_http_status=true'; // Callback de error por defecto a ejecutar cuando se produzca un error al utilizar la emulacion\n\n error_user = options.error;\n\n options.error = function (xhr, textStatus, errorThrown) {\n var errorText = $.rup.rupAjaxDefaultError(xhr, textStatus, errorThrown); // Si se ha producido un error de los tratados lo mostramos\n\n if (error_user != null) {\n $(error_user(xhr, textStatus, errorThrown));\n } else {\n if (errorText) {\n $.rup.showErrorToUser(errorText);\n }\n }\n };\n }\n };\n\n settings.formValidationRequired = settings.validate !== undefined; // Configuracion de las validaciones\n\n if (settings.formValidationRequired) {\n if (settings.error === undefined) {\n settings.error = function (a) {\n try {\n var json = JSON.parse(a.responseText);\n $self.validate().invalid = json.rupErrorFields;\n $self.validate().submited = json.rupErrorFields;\n $self.validate().showErrors(json.rupErrorFields);\n\n if (json.rupFeedback !== undefined && $self.validate().settings.feedback !== undefined) {\n $self.validate().settings.feedback.rup_feedback('set', $.rup_utils.printMsg(json.rupFeedback.message), json.rupFeedback.style !== undefined ? json.rupFeedback.style : null);\n }\n } catch (ex) {\n $self.validate().settings.feedback.rup_feedback('set', a.responseText, 'error');\n }\n };\n }\n\n settings.validate.submitHandler = function (form) {\n jQuery(form).ajaxSubmit($(form).data('ajaxSettings'));\n };\n\n settings.validate.feedback = settings.feedback;\n }\n\n $self.data('ajaxSettings', settings);\n $self.data('settings', settings);\n }\n }); //********************************\n // DEFINICIÓN DE MÉTODOS PRIVADOS\n //********************************\n\n $.fn.rup_form('extend', {});\n $.fn.rup_form('extend', {\n /**\r\n * Función de inicialización del componente.\r\n *\r\n * @function _init\r\n * @private\r\n * @param {object} args - Propiedades de configuración.\r\n */\n _init: function _init(args) {\n var _this = this;\n\n global.initRupI18nPromise.then(function () {\n var $self = _this,\n settings; // Determinamos si se ha introducido configuracion para el componente validacion.\n // Settings de configuracion\n\n settings = $.extend(true, {}, $.fn.rup_form.defaults, args[0]); // Anadimos al formulario el class rup_form para identificarlo como componente formulario.\n\n $self.addClass('rup_form');\n $self.attr('ruptype', 'form');\n $self.rup_form('configureOptions', settings); // En caso de que no sehaya configurado el componente validacion se realiza la llamada al plugin jquery.form.\n\n if (settings.formValidationRequired) {\n $self.rup_validate(settings.validate);\n } else {\n $self.ajaxForm(settings);\n } //Se audita el componente\n\n\n $.rup.auditComponent('rup_form', 'init');\n })[\"catch\"](function (error) {\n console.error('Error al inicializar el componente:\\n', error);\n });\n }\n }); //*******************************************************\n // DEFINICIÓN DE LA CONFIGURACION POR DEFECTO DEL PATRON\n //*******************************************************\n\n /**\r\n * Función de callback que será invocada antes de realizarse la serialización del formulario.\r\n *\r\n * @callback jQuery.rup_form~beforeSerialize\r\n * @param {jQuery} $form - Referencia del objeto jQuery del formulario.\r\n * @param {object} options - Opciones de configuración con las que se ha inicializado el componente.\r\n * @return {boolean} - En caso de devolver false se cancela el envío del formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * beforeSerialize: function($form, options) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocada antes de realizarse el envío del formulario.\r\n *\r\n * @callback jQuery.rup_form~beforeSubmit\r\n * @param {object[]} arr - Array que contiene la información introducida en el formulario. El array tiene el siguiente formato : [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]\r\n * @param {jQuery} $form - Referencia del objeto jQuery del formulario.\r\n * @param {object} options - Opciones de configuración con las que se ha inicializado el componente.\r\n * @return {boolean} - En caso de devolver false se cancela el envío del formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * beforeSubmit: function(arr, $form, options) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocada cuando se produzca un error.\r\n *\r\n * @callback jQuery.rup_form~error\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * error: function() { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocado cuando se reciba la respuesta del formulario.\r\n *\r\n * @callback jQuery.rup_form~suceess\r\n * @param {string} responseText - Texto identificador de la respuesta obtenida.\r\n * @param {string} statusText - Código de respuesta http.\r\n * @param {object} xhr - Objeto xhr con la respuesta enviada del servidor.\r\n * @param {jQuery} $form - Referencia jQuery al componente formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * suceess: function(responseText, statusText, xhr, $form) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocado cuando se reciba la respuesta del formulario.\r\n *\r\n * @callback jQuery.rup_form~uploadProgress\r\n * @param {Event} event - Objeto Event procedente del navegador.\r\n * @param {Integer} position - Numero que determina el contenido enviado.\r\n * @param {Integer} total - Numero que identifica el total del contenido a enviar.\r\n * @param {Integer} percentComplete - Numero que identifica el porcentaje actual completado en el proceso de envío.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * uploadProgress: function(event, position, total, percentComplete) { ... }\r\n * });\r\n */\n\n /**\r\n * Opciones por defecto de configuración del componente.\r\n * @name defaults\r\n *\r\n * @property {jQuery.rup_form~beforeSerialize} [beforeSerialize=null] - Función de callback que será invocada antes de realizarse la serialización del formulario. Permite la modificación de los datos del formulario antes de que estos sean recuperados para su procesado por el componente.\r\n * @property {jQuery.rup_form~beforeSubmit} [beforeSubmit=null] - Función de callback que será invocada antes de realizarse el envío del formulario. Permite acceder a la información que será enviada al formulario. En caso de retornar false no se realizará en envío.\r\n * @property {boolean} [clearForm=null] - Propiedad booleana que determina si el formulario debe de limpiarse después de realizar el envío.\r\n * @property {object} [data] - Mediante esta propiedad es posible especificar parámetros extra que sean enviados alservidor.\r\n * @property {string} [dataType] - Tipo de datos esperados en la respuesta. Los valores posibles son null, xml, json y script.\r\n * @property {jQuery.rup_form~error} [error] - Función de callback que será invocada cuando se produzca un error.\r\n * @property {boolean} [forceSync=false] - Propiedad booleana. En caso de ser true elimina la corta espera que se produce antes de enviar el formulario cuando se envían ficheros o se utiliza la opción de iframe. La espera se utiliza para permitir al navegador actualizar modificaciones realizadas en el DOM antes de que se realice el\r\n envío de los datos.\r\n * @property {boolean} [iframe=false] - Determina si el formulario debe de ser enviado siempre mediante un iframe.\r\n * @property {string} [iframeSrc] - Propiedad de texto que deberá ser utlizada siempre en conjunción con la propiedad iframe. Por defecto, about:blank. Por defecto para páginas que utlicen el protocolo https, javascript:false.\r\n * @property {string} [iframeTarget=null] - Identifica el iframe que será utilizado como target en la respuesta en los envíos de ficheros. Por defecto, el componente creará un iframe temporal para capturar la respuesta del envío de ficheros.\r\n * @property {boolean | object} [multimodel=false] - Permite especificar la configuración que se deberá de aplicar a la hora de realizar el envío de varias entidades en la misma petición. La configuración de este parámetro se detalla en el apartado 9.2.\r\n * @property {boolean} [replaceTarget=false] - Opcionalmente se utililiza junto con la opción target. En caso de ser true el elemento identificado en la opción target será reemplazado. En caso de ser false solo su contenido será reemplazado.\r\n * @property {boolean} [resetForm=false] - Propiedad booleana que determina si el formulario debe ser inicializado al realizarse el envío del mismo.\r\n * @property {bolean} [semantic=false] - Propiedad booleana que determina si los campos del formulario deben ser enviado en estricto orden semántico. Por defecto la serialización normal del formulario se realiza en orden semántico exceptuando los campos img.\r\n * @property {jQuery.rup_form~suceess} [suceess] - Método callback que será invocado cuando se reciba la respuesta del formulario.\r\n * @property {string | jQuery | Element} [target] - Identifica los elementos de la página que deberán ser actualizados con la respuesta del servidor. El target puede ser indicado mediante un selector de jQuery, un objeto de jQuery o un objeto DOM.\r\n * @property {string} [type] - Detemina el método con el que se enviará el formulario, GET o POST. Por defecto el valor de la propiedad method indicada en el formulario o GET en caso de no encontrarse.\r\n * @property {jQuery.rup_form~uploadProgress} [uploadProgress=null] - Método que será invocado con información de progreso del envío del formulario (en caso de estar soportado por el navegador).\r\n * @property {string} [url] - URL a la cual se realizará en envío del formulario. Por defecto el valor indicado en la propiedad action del formulario.\r\n * @property {boolean} [useJsonIfPossible=true] - Mediante este parámetro se especifica al componente que debe de utilizar el formato application/json como prioridad (siempre que sea posible) al realizar el envío del formulario.\r\n */\n\n $.fn.rup_form.defaults = {\n ajaxForm: null,\n feedback: null,\n multimodel: null,\n useJsonIfPossible: true // En caso de ser posible realizar en envío mediante json se enviarán los datos en este formato.\n\n };\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://rup/./src/rup.form.js?"); +eval("/* WEBPACK VAR INJECTION */(function($, global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\r\n * Copyright 2013 E.J.I.E., S.A.\r\n *\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n */\n\n/**\r\n * Permite al usuario introducir datos en una serie de campos para ser enviados al servidor y ser procesados.\r\n *\r\n * @summary Componente RUP Form.\r\n * @module rup_form\r\n * @example\r\n * var properties={\r\n * // Propiedades de configuración\r\n * };\r\n *\r\n * $(\"#formulario\").rup_form(properties);\r\n */\n(function (factory) {\n if (true) {\n // AMD. Register as an anonymous module.\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./core/utils/jquery.form */ \"./src/core/utils/jquery.form.js\"), __webpack_require__(/*! ./core/utils/form2object */ \"./src/core/utils/form2object.js\"), __webpack_require__(/*! ./rup.base */ \"./src/rup.base.js\"), __webpack_require__(/*! ./rup.validate */ \"./src/rup.validate.js\"), __webpack_require__(/*! ./rup.message */ \"./src/rup.message.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function (jQuery) {\n //*********************************************\n // ESPECIFICACÍON DE LOS TIPOS BASE DEL PATRÓN\n //*********************************************\n //*****************************************************************************************************************\n // DEFINICIÓN BASE DEL PATRÓN (definición de la variable privada que contendrá los métodos y la función de jQuery)\n //*****************************************************************************************************************\n var rup_form = {}; //Se configura el arranque de UDA para que alberge el nuevo patrón\n\n $.extend($.rup.iniRup, $.rup.rupSelectorObjectConstructor('rup_form', rup_form)); //********************************\n // DEFINICIÓN DE MÉTODOS PÚBLICOS\n //********************************\n\n $.fn.rup_form('extend', {\n /**\r\n * Realiza la misma función que ajaxSubmit. Se mantiene para asegurar la retrocompatibilidad con versiones anteriores.\r\n *\r\n * @function ajaxFormSubmit\r\n * @param {object} options - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxFormSubmit\", options);\r\n */\n ajaxFormSubmit: function ajaxFormSubmit(options) {\n var $self = this; // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.ajaxSubmit(options);\n },\n\n /**\r\n * Realiza el envío del formulario. La configuración de este método es la misma que la de ajaxForm.\r\n *\r\n * @function ajaxSubmit\r\n * @param {object} argOptions - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxSubmit\", options);\r\n */\n ajaxSubmit: function ajaxSubmit(argOptions) {\n var $self = this,\n options = $.extend(true, {}, $.fn.rup_form.defaults, argOptions); // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.rup_form('configureOptions', options);\n\n if (options.formValidationRequired) {\n $self.rup_validate(options.validate);\n\n if ($self.valid()) {\n $(this).ajaxSubmit(options);\n }\n } else {\n // Necesario utilizar $(this) para invocar al ajaxSubmit del plugin subyacente\n $(this).ajaxSubmit(options);\n }\n },\n\n /**\r\n * Realiza el envío del formulario. La configuración de este método es la misma que la de ajaxForm.\r\n *\r\n * @function ajaxNotSubmit\r\n * @param {object} argOptions - Opciones de configuración.\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"ajaxNotSubmit\", options);\r\n */\n ajaxNotSubmit: function ajaxNotSubmit(argOptions) {\n var $self = this,\n options = $.extend(true, {}, $.fn.rup_form.defaults, argOptions); // Actiavamos la gestión de las peticiones AJAX mediante la función $.rup_ajax.\n\n $.set_uda_ajax_mode_on();\n $self.rup_form('configureOptions', options);\n\n if (options.formValidationRequired) {\n $self.submit();\n\n if ($self.valid()) {\n $(this).ajaxSubmit(options);\n }\n } else {\n // Necesario utilizar $(this) para invocar al ajaxSubmit del plugin subyacente\n $(this).ajaxSubmit(options);\n }\n },\n\n /**\r\n * Elimina la configuración realizada por el componente sobre el formulario html.\r\n *\r\n * @function destroy\r\n * @example\r\n * var options = {};\r\n * jQuery(\"#form\").rup_form(\"destroy\");\r\n */\n destroy: function destroy() {\n var $self = this;\n $self.removeClass('rup_form');\n $.removeData($self[0]);\n $self.ajaxFormUnbind();\n $self.off();\n },\n\n /**\r\n * Serializa el contenido del formulario en un query string.\r\n *\r\n * @function formSerialize\r\n * @return {string} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"formSerialize\");\r\n */\n formSerialize: function formSerialize() {\n var $self = this,\n element,\n ruptype,\n fieldArray = [];\n $.each($self.formToArray(), function (key, obj) {\n element = $('[name=\\'' + obj.name + '\\']', self);\n ruptype = element.attr('ruptype');\n\n if (ruptype !== undefined) {\n obj.value = element['rup_' + ruptype]('getRupValue');\n fieldArray.push(obj);\n } else {\n fieldArray.push(obj);\n }\n });\n return $.param(fieldArray);\n },\n\n /**\r\n * Realiza la serialización de campos del formulario en un objeto json.\r\n *\r\n * @function formToJson\r\n * @return {string} - Retorna un objeto con el formato {nombre1:valor1, nombre2:valor2…nombreN:valorN}.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"formToJson\");\r\n */\n formToJson: function formToJson() {\n if (this[0]) {\n return window.form2object(this[0]);\n } else {\n return {};\n }\n },\n\n /**\r\n * Realiza la serialización de campos del formulario en un query string\r\n *\r\n * @function fieldSerialize\r\n * @return {string} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form .specialFields\").rup_form(\"fieldSerialize\");\r\n */\n fieldSerialize: function fieldSerialize() {\n var a = [];\n this.each(function () {\n var n = $(this).attr('name');\n\n if (!n) {\n return;\n }\n\n var v = $(this).rup_form('fieldValue');\n\n if (v && v.constructor == Array) {\n for (var i = 0, max = v.length; i < max; i++) {\n a.push({\n name: n,\n value: v[i]\n });\n }\n } else if (v !== null && typeof v != 'undefined') {\n a.push({\n name: $(this).attr('name'),\n value: v\n });\n }\n });\n return $.param(a);\n },\n\n /**\r\n * Devuelve un array con el valor de los campos indicados.\r\n *\r\n * @function fieldValue\r\n * @return {string[]} - Retorna una cadena de texto con el formato nombre1=valor1&nombre2=valor2.\r\n * @example\r\n * jQuery(\"#form .specialFields\").rup_form(\"fieldValue\");\r\n */\n fieldValue: function fieldValue() {\n var valuesArray = [],\n value;\n this.each(function () {\n var ruptype = $(this).attr('ruptype');\n\n if (ruptype !== undefined) {\n value = $(this)['rup_' + ruptype]('getRupValue');\n valuesArray.push(value);\n } else {\n $.merge(valuesArray, $(this).fieldValue());\n }\n });\n return valuesArray;\n },\n\n /**\r\n * Inicializa el formulario con su estado inicial invocando al método reset nativo.\r\n *\r\n * @function resetForm\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * jQuery(\"#form\").rup_form(\"resetForm\");\r\n */\n resetForm: function resetForm() {\n //Los rup select no se limpiaban con el reset nativo, por lo tanto, se usa el metodo clear\n $('#' + $(this).attr('id') + ' select').each(function (index, element) {\n if ($(element).attr('ruptype') == 'select') {\n $(element).rup_select('clear');\n }\n });\n return this.each(function () {\n $(this).resetForm();\n });\n },\n\n /**\r\n * Limpia los elementos del formulario.\r\n *\r\n * @function clearForm\r\n * @param {boolean} includeHidden - Determina si se deben de limpiar también los elementos hidden que existen en el formulario.\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * // Limpiar los campos del formulario\r\n * jQuery(\"#form\").rup_form(\"clearForm\");\r\n * // Limpiar los campos del formulario inlcuyendo los campos hidden\r\n * jQuery(\"#form\").rup_form(\"clearForm\", true);\r\n */\n clearForm: function clearForm(includeHidden) {\n return this.each(function () {\n $('input,select,textarea', this).rup_form('clearFields', includeHidden);\n });\n },\n\n /**\r\n * Limpia los campos especificados mediante el selector de jQuery.\r\n *\r\n * @function clearFields\r\n * @param {boolean} includeHidden - Determina si se deben de limpiar también los elementos hidden que existen en el formulario.\r\n * @return {jQuery} - Retorna el propio componente.\r\n * @example\r\n * // Limpiar los campos del formulario\r\n * jQuery(\"#form .specialFields\").rup_form(\"clearFields\");\r\n * // Limpiar los campos del formulario inlcuyendo los campos hidden\r\n * jQuery(\"#form .specialFields\").rup_form(\"clearFields\", true);\r\n */\n clearFields: function clearFields(includeHidden) {\n return this.each(function () {\n var ruptype = $(this).attr('ruptype');\n\n if (ruptype === undefined || ruptype !== 'combo') {\n $(this).clearFields(includeHidden);\n } else {\n $(this).rup_combo('clear');\n }\n });\n },\n\n /**\r\n * Función de inicialización del componente. Es un método de uso interno. No debería de invocarse de manera directa.\r\n *\r\n * @function configureOptions\r\n * @param {object} settings - Propiedades de configuración\r\n */\n configureOptions: function configureOptions(settings) {\n var $self = this,\n hasFileInputs,\n beforeSendUserEvent,\n beforeSubmitUserEvent;\n\n if (settings.url !== null) {\n $self.attr('action', settings.url);\n }\n\n hasFileInputs = $('input[type=file]:enabled', $self).length > 0;\n\n if (settings.useJsonIfPossible && !hasFileInputs) {\n settings.contentType = 'application/json';\n } else {\n settings.contentType = 'multipart/form-data';\n } // BeforeSend\n\n\n beforeSendUserEvent = settings.beforeSend;\n\n settings.beforeSend = function (xhr, ajaxOptions) {\n var ret = true;\n\n if (typeof beforeSendUserEvent === \"function\") {\n ret = beforeSendUserEvent.call(this, xhr, ajaxOptions);\n }\n\n if (ret === false) {\n return false;\n } else if (ret !== 'skip') {\n if (ajaxOptions.contentType !== false && ajaxOptions.contentType.indexOf('application/json') !== -1) {\n var jsonData = $self.rup_form('formToJson');\n\n if (settings.multimodel !== null) {\n xhr.setRequestHeader('RUP_MULTI_ENTITY', 'true');\n jsonData.rupEntityMapping = settings.multimodel;\n }\n\n if (ajaxOptions.extraData !== undefined && ajaxOptions.extraData !== null) {\n $.extend(jsonData, ajaxOptions.extraData);\n }\n\n ajaxOptions.data = $.toJSON(jsonData);\n }\n }\n }; // BeforeSubmit\n\n\n beforeSubmitUserEvent = settings.beforeSubmit;\n\n settings.beforeSubmit = function (arr, $form, options) {\n var httpMethod, error_user, hasFileInputs;\n\n if (typeof beforeSubmitUserEvent === \"function\") {\n if (beforeSubmitUserEvent.call(this, arr, $form, options) === false) {\n return false;\n }\n }\n\n hasFileInputs = jQuery('input:file', $form).length > 0; // Implementacion para realizar la emulacion de xhr al utilizar iframes\n\n if (!$.rup.browser.xhrFileUploadSupport && hasFileInputs || options.iframe === true) {\n // Configuracion necesaria para permitir con iframes el uso de metodos http diferentes a GET o POST\n httpMethod = settings.type !== undefined ? settings.type : options.type;\n\n if ($.inArray(httpMethod.toUpperCase(), $.rup.IFRAME_ONLY_SUPPORTED_METHODS) === -1) {\n options.extraData = $.extend({}, options.extraData, {\n '_method': httpMethod.toUpperCase()\n });\n } //Se valida la presencia de portal y, llegados al caso, se adecuan las llamadas ajax para trabajar con portales\n\n\n options.url = $.rup_utils.setNoPortalParam(options.url); // Envio del parametro emulate_iframe_http_status para activar la emulacion en el lado servidor\n\n options.extraData = $.extend({}, options.extraData, {\n '_emulate_iframe_http_status': 'true'\n });\n options.url = options.url + (options.url.match('\\\\?') === null ? '?' : '&') + '_emulate_iframe_http_status=true'; // Callback de error por defecto a ejecutar cuando se produzca un error al utilizar la emulacion\n\n error_user = options.error;\n\n options.error = function (xhr, textStatus, errorThrown) {\n var errorText = $.rup.rupAjaxDefaultError(xhr, textStatus, errorThrown); // Si se ha producido un error de los tratados lo mostramos\n\n if (error_user != null) {\n $(error_user(xhr, textStatus, errorThrown));\n } else {\n if (errorText) {\n $.rup.showErrorToUser(errorText);\n }\n }\n };\n }\n };\n\n settings.formValidationRequired = settings.validate !== undefined; // Configuracion de las validaciones\n\n if (settings.formValidationRequired) {\n if (settings.error === undefined) {\n settings.error = function (a) {\n try {\n var json = JSON.parse(a.responseText);\n $self.validate().invalid = json.rupErrorFields;\n $self.validate().submited = json.rupErrorFields;\n $self.validate().showErrors(json.rupErrorFields);\n\n if (json.rupFeedback !== undefined && $self.validate().settings.feedback !== undefined) {\n $self.validate().settings.feedback.rup_feedback('set', $.rup_utils.printMsg(json.rupFeedback.message), json.rupFeedback.style !== undefined ? json.rupFeedback.style : null);\n }\n } catch (ex) {\n $self.validate().settings.feedback.rup_feedback('set', a.responseText, 'error');\n }\n };\n }\n\n settings.validate.submitHandler = function (form) {\n jQuery(form).ajaxSubmit($(form).data('ajaxSettings'));\n };\n\n settings.validate.feedback = settings.feedback;\n }\n\n $self.data('ajaxSettings', settings);\n $self.data('settings', settings);\n }\n }); //********************************\n // DEFINICIÓN DE MÉTODOS PRIVADOS\n //********************************\n\n $.fn.rup_form('extend', {});\n $.fn.rup_form('extend', {\n /**\r\n * Función de inicialización del componente.\r\n *\r\n * @function _init\r\n * @private\r\n * @param {object} args - Propiedades de configuración.\r\n */\n _init: function _init(args) {\n var _this = this;\n\n global.initRupI18nPromise.then(function () {\n var $self = _this,\n settings; // Determinamos si se ha introducido configuracion para el componente validacion.\n // Settings de configuracion\n\n settings = $.extend(true, {}, $.fn.rup_form.defaults, args[0]); // Anadimos al formulario el class rup_form para identificarlo como componente formulario.\n\n $self.addClass('rup_form');\n $self.attr('ruptype', 'form');\n $self.rup_form('configureOptions', settings); // En caso de que no sehaya configurado el componente validacion se realiza la llamada al plugin jquery.form.\n\n if (settings.formValidationRequired) {\n $self.rup_validate(settings.validate);\n } else {\n $self.ajaxForm(settings);\n } //Se audita el componente\n\n\n $.rup.auditComponent('rup_form', 'init');\n })[\"catch\"](function (error) {\n console.error('Error al inicializar el componente:\\n', error);\n });\n }\n }); //*******************************************************\n // DEFINICIÓN DE LA CONFIGURACION POR DEFECTO DEL PATRON\n //*******************************************************\n\n /**\r\n * Función de callback que será invocada antes de realizarse la serialización del formulario.\r\n *\r\n * @callback jQuery.rup_form~beforeSerialize\r\n * @param {jQuery} $form - Referencia del objeto jQuery del formulario.\r\n * @param {object} options - Opciones de configuración con las que se ha inicializado el componente.\r\n * @return {boolean} - En caso de devolver false se cancela el envío del formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * beforeSerialize: function($form, options) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocada antes de realizarse el envío del formulario.\r\n *\r\n * @callback jQuery.rup_form~beforeSubmit\r\n * @param {object[]} arr - Array que contiene la información introducida en el formulario. El array tiene el siguiente formato : [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]\r\n * @param {jQuery} $form - Referencia del objeto jQuery del formulario.\r\n * @param {object} options - Opciones de configuración con las que se ha inicializado el componente.\r\n * @return {boolean} - En caso de devolver false se cancela el envío del formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * beforeSubmit: function(arr, $form, options) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocada cuando se produzca un error.\r\n *\r\n * @callback jQuery.rup_form~error\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * error: function() { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocado cuando se reciba la respuesta del formulario.\r\n *\r\n * @callback jQuery.rup_form~suceess\r\n * @param {string} responseText - Texto identificador de la respuesta obtenida.\r\n * @param {string} statusText - Código de respuesta http.\r\n * @param {object} xhr - Objeto xhr con la respuesta enviada del servidor.\r\n * @param {jQuery} $form - Referencia jQuery al componente formulario.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * suceess: function(responseText, statusText, xhr, $form) { ... }\r\n * });\r\n */\n\n /**\r\n * Función de callback que será invocado cuando se reciba la respuesta del formulario.\r\n *\r\n * @callback jQuery.rup_form~uploadProgress\r\n * @param {Event} event - Objeto Event procedente del navegador.\r\n * @param {Integer} position - Numero que determina el contenido enviado.\r\n * @param {Integer} total - Numero que identifica el total del contenido a enviar.\r\n * @param {Integer} percentComplete - Numero que identifica el porcentaje actual completado en el proceso de envío.\r\n * @example\r\n * $(\"#form\").rup_form({\r\n * uploadProgress: function(event, position, total, percentComplete) { ... }\r\n * });\r\n */\n\n /**\r\n * Opciones por defecto de configuración del componente.\r\n * @name defaults\r\n *\r\n * @property {jQuery.rup_form~beforeSerialize} [beforeSerialize=null] - Función de callback que será invocada antes de realizarse la serialización del formulario. Permite la modificación de los datos del formulario antes de que estos sean recuperados para su procesado por el componente.\r\n * @property {jQuery.rup_form~beforeSubmit} [beforeSubmit=null] - Función de callback que será invocada antes de realizarse el envío del formulario. Permite acceder a la información que será enviada al formulario. En caso de retornar false no se realizará en envío.\r\n * @property {boolean} [clearForm=null] - Propiedad booleana que determina si el formulario debe de limpiarse después de realizar el envío.\r\n * @property {object} [data] - Mediante esta propiedad es posible especificar parámetros extra que sean enviados alservidor.\r\n * @property {string} [dataType] - Tipo de datos esperados en la respuesta. Los valores posibles son null, xml, json y script.\r\n * @property {jQuery.rup_form~error} [error] - Función de callback que será invocada cuando se produzca un error.\r\n * @property {boolean} [forceSync=false] - Propiedad booleana. En caso de ser true elimina la corta espera que se produce antes de enviar el formulario cuando se envían ficheros o se utiliza la opción de iframe. La espera se utiliza para permitir al navegador actualizar modificaciones realizadas en el DOM antes de que se realice el\r\n envío de los datos.\r\n * @property {boolean} [iframe=false] - Determina si el formulario debe de ser enviado siempre mediante un iframe.\r\n * @property {string} [iframeSrc] - Propiedad de texto que deberá ser utlizada siempre en conjunción con la propiedad iframe. Por defecto, about:blank. Por defecto para páginas que utlicen el protocolo https, javascript:false.\r\n * @property {string} [iframeTarget=null] - Identifica el iframe que será utilizado como target en la respuesta en los envíos de ficheros. Por defecto, el componente creará un iframe temporal para capturar la respuesta del envío de ficheros.\r\n * @property {boolean | object} [multimodel=false] - Permite especificar la configuración que se deberá de aplicar a la hora de realizar el envío de varias entidades en la misma petición. La configuración de este parámetro se detalla en el apartado 9.2.\r\n * @property {boolean} [replaceTarget=false] - Opcionalmente se utililiza junto con la opción target. En caso de ser true el elemento identificado en la opción target será reemplazado. En caso de ser false solo su contenido será reemplazado.\r\n * @property {boolean} [resetForm=false] - Propiedad booleana que determina si el formulario debe ser inicializado al realizarse el envío del mismo.\r\n * @property {bolean} [semantic=false] - Propiedad booleana que determina si los campos del formulario deben ser enviado en estricto orden semántico. Por defecto la serialización normal del formulario se realiza en orden semántico exceptuando los campos img.\r\n * @property {jQuery.rup_form~suceess} [suceess] - Método callback que será invocado cuando se reciba la respuesta del formulario.\r\n * @property {string | jQuery | Element} [target] - Identifica los elementos de la página que deberán ser actualizados con la respuesta del servidor. El target puede ser indicado mediante un selector de jQuery, un objeto de jQuery o un objeto DOM.\r\n * @property {string} [type] - Detemina el método con el que se enviará el formulario, GET o POST. Por defecto el valor de la propiedad method indicada en el formulario o GET en caso de no encontrarse.\r\n * @property {jQuery.rup_form~uploadProgress} [uploadProgress=null] - Método que será invocado con información de progreso del envío del formulario (en caso de estar soportado por el navegador).\r\n * @property {string} [url] - URL a la cual se realizará en envío del formulario. Por defecto el valor indicado en la propiedad action del formulario.\r\n * @property {boolean} [useJsonIfPossible=true] - Mediante este parámetro se especifica al componente que debe de utilizar el formato application/json como prioridad (siempre que sea posible) al realizar el envío del formulario.\r\n */\n\n $.fn.rup_form.defaults = {\n ajaxForm: null,\n feedback: null,\n multimodel: null,\n useJsonIfPossible: true // En caso de ser posible realizar en envío mediante json se enviarán los datos en este formato.\n\n };\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://rup/./src/rup.form.js?"); /***/ }), @@ -8546,7 +8546,7 @@ eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPAC /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(jQuery, global, $) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/* eslint-disable no-useless-escape */\n\n/*!\r\n * Copyright 2021 E.J.I.E., S.A.\r\n *\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n */\n\n/**\r\n * Permite al usuario recuperar un elemento de una gran lista de elementos o de\r\n * varias listas dependientes de forma sencilla y ocupando poco espacio en la\r\n * interfaz.\r\n * \r\n * @summary Componente RUP Select.\r\n * @module rup_select\r\n * @see El componente está basado en el plugin\r\n * {@link https://select2.org//|Select2}. Para mas información acerca de\r\n * las funcionalidades y opciones de configuración pinche\r\n * {@link https://select2.org//|aquí}.\r\n * @example $(\"#idSelect\").rup_select({ source : \"selectSimple/remote\",\r\n * sourceParam : {label:\"desc\"+$.rup_utils.capitalizedLang(),\r\n * value:\"code\", style:\"css\"} });\r\n */\n\n/* global define */\n\n/* global jQuery */\n(function (factory) {\n if (true) {\n // AMD. Register as an anonymous module.\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./rup.base */ \"./src/rup.base.js\"), __webpack_require__(/*! select2 */ \"./node_modules/select2/dist/js/select2.js\"), __webpack_require__(/*! ./external/select2MultiCheckboxes */ \"./src/external/select2MultiCheckboxes.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($) {\n // ****************************************************************************************************************\n // DEFINICIÓN BASE DEL PATRÁN (definición de la variable privada que\n // contendrá los métodos y la función de jQuery)\n // ****************************************************************************************************************\n var rup_select = {};\n var FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.functionNotSupportedError');\n var FUNCTION_NOT_SUPPORTED_ERROR_TITLE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.error'); // Se configura el arranque de UDA para que alberge el nuevo patrón\n\n $.extend($.rup.iniRup, $.rup.rupSelectorObjectConstructor('rup_select', rup_select)); // *******************************\n // DEFINICIÓN DE MÉTODOS PÚBLICOS\n // *******************************\n\n $.fn.rup_select('extend', {\n /**\r\n * Método utilizado para obtener el valor del componente. Este método es\r\n * el utilizado por el resto de componentes RUP para estandarizar la\r\n * obtención del valor del select.\r\n * \r\n * @function getRupValue\r\n * @return {string | number} - Devuelve el valor actual del componente\r\n * seleccionado por el usuario.\r\n * @example $(\"#idSelect\").rup_select(\"getRupValue\");\r\n */\n getRupValue: function getRupValue() {\n var $self = $(this),\n settings = $self.data('settings'),\n value;\n var values = $self.select2('data');\n\n if (values == undefined || values.length == 0) {\n value = '';\n } else if (values.length == 1) {\n value = values[0].id;\n } else {\n value = [];\n $.each(values, function (ind, elem) {\n value.push(elem.id);\n });\n }\n\n if (settings !== undefined && settings.submitAsJSON !== undefined && settings.submitAsJSON) {\n var name = $self.attr('name');\n\n if (name == undefined) {\n name = $self.attr('id');\n }\n\n return jQuery.rup_utils.getRupValueAsJson(name, value);\n }\n\n return value;\n },\n\n /**\r\n * Método utilizado para asignar el valor al componente. Este método es\r\n * el utilizado por el resto de componentes RUP para estandarizar la\r\n * asignación del valor al Select.\r\n * \r\n * @function setRupValue\r\n * @param {string |\r\n * number} param - Valor que se va a asignar al componente.\r\n * @example $(\"#idSelect\").rup_select('setRupValue', 'Si');\r\n */\n setRupValue: function setRupValue(param) {\n var $self = $(this),\n settings = $self.data('settings'); // Tipo de select\n\n if (this.length === 0 || settings !== undefined && !settings.multiple) {\n var texto = undefined; // normal.\n // Simple\n\n if (settings !== undefined && settings.data === undefined && settings.options !== undefined) {\n // si\n // es\n // remoto\n // crear\n // el\n // option\n var data = {};\n\n if (settings.groups) {\n data = $.grep(settings.optionsGroups, function (v) {\n return v.nid === param || v.id == param;\n });\n } else {\n data = $.grep(settings.options, function (v) {\n return v.nid === param || v.id == param;\n });\n }\n\n if (data[0] !== undefined) {\n if ($('#' + settings.id).find(\"option[value='\" + data[0].id + \"']\").length == 0) {\n data = data[0];\n\n _this._createOption(settings, data);\n\n param = data.id; // mantenga el cifrado\n\n texto = data.text;\n } else {\n param = data[0].id; // mantenga el cifrado\n\n texto = data[0].text;\n }\n }\n }\n\n var dataSelect2 = $self.data('select2');\n\n if (dataSelect2 !== undefined) {\n if (dataSelect2.$selection.find('input').length == 1) {\n dataSelect2.$selection.find('input').val('');\n }\n\n var $search = dataSelect2.dropdown.$search || dataSelect2.selection.$search;\n\n if ($search != undefined && texto !== undefined) {\n //sifnifica que esta abierto\n var lis = dataSelect2.dropdown.$dropdown.find('li');\n var selectedDate = $.grep(lis, function (v) {\n return $(v).text() === texto;\n });\n lis.attr('aria-selected', false);\n $(selectedDate).attr('aria-selected', true);\n }\n\n $self.val(param).trigger('change');\n $('#' + settings.id).rup_select('change');\n }\n } else {\n // Multiple > multiselect - falta\n if (_typeof(param) === 'object' && settings.options !== undefined) {\n // si\n // es\n // remoto\n // crear\n // el\n // option\n var arrayDatos = [];\n $.each(param, function (key, value) {\n var data = {};\n\n if (settings.groups) {\n data = $.grep(settings.optionsGroups, function (v) {\n return v.nid === value || v.id == value;\n });\n } else {\n data = $.grep(settings.options, function (v) {\n return v.nid === value || v.id == value;\n });\n }\n\n if (data[0] != undefined && $('#' + settings.id).find(\"option[value='\" + data[0].id + \"']\").length == 0) {\n data = data[0];\n\n _this._createOption(settings, data);\n\n arrayDatos.push(data.id);\n } else {\n arrayDatos.push(value);\n }\n });\n $('#' + settings.id).val(arrayDatos).trigger('change');\n }\n }\n },\n\n /**\r\n * Método que limpia el valor seleccionado en el select. En el caso de\r\n * selección múltiple los valores seleccionados.\r\n * \r\n * @function clear\r\n * @example $(\"#idSelect\").rup_select(\"clear\");\r\n */\n clear: function clear() {\n var $self = $(this); // init de select\n\n if (this.length > 0) {\n // Simple y multi\n if ($self.data('settings').blank !== undefined) {\n $self.val($self.data('settings').blank).trigger('change');\n } else {\n $self.val(null).trigger('change');\n }\n }\n },\n\n /**\r\n * Método que lanza el evento change del componente.\r\n * \r\n * @function change\r\n * @example $(\"#idSelect\").rup_select(\"change\");\r\n */\n change: function change() {\n // Tipo de select\n if ($(this).data('settings').change) {\n $(this).data('settings').change();\n }\n },\n\n /**\r\n * Selecciona todos los elementos en el caso de tratarse de un select\r\n * multilesección.\r\n * \r\n * @function checkAll\r\n * @example $(\"#idSelect\").rup_select(\"checkAll\");\r\n */\n checkAll: function checkAll() {\n // Tipo de select\n if ($(this).data('settings').multiple) {\n // Multiple > multiselect\n var selectedItems = [];\n var allOptions = $(\"#\" + $(this)[0].id + \" option\");\n allOptions.each(function () {\n selectedItems.push($(this).val());\n });\n $(this).rup_select('setRupValue', selectedItems);\n } else {\n // Simple > selectmenu\n alert('Función no soportada.');\n }\n },\n\n /**\r\n * Selecciona el elemento del select que contiene como texto el\r\n * indicado. En caso de no existir el texto a buscar el se no sufrirá\r\n * cambios En el caso de selección múltiple el parámetro será un array.\r\n * \r\n * @function selectByLabel\r\n * @param {string |\r\n * string[]} param - Parámetro utilzado para determinar los\r\n * elementos a seleccionar.\r\n * @example // Simple $(\"#idSelect\").rup_select(\"selectByLabel\", \"No\"); //\r\n * Multiple $(\"#idSelect\").rup_select(\"selectByLabel\",\r\n * [\"No\",\"Si\"]);\r\n */\n selectByLabel: function selectByLabel(param) {\n // Tipo de select\n var settings = $(this).data('settings');\n\n if (settings.options !== undefined) {\n var options = settings.options;\n\n if (settings.groups) {\n options = settings.optionsGroups;\n }\n\n if (!settings.multiple) {\n // Simple > selectmenu\n var data = $.grep(options, function (v) {\n return v.text === param;\n });\n\n if (data[0] !== undefined) {\n $(this).rup_select('setRupValue', data[0].id);\n }\n } else {\n // Ejemplo\n // $('#idSelect').rup_select('selectByLabel',['php_value','java_value'])\n var datos = [];\n $.each(param, function (key, value) {\n var data = $.grep(options, function (v) {\n return v.text === value;\n });\n\n if (data[0] !== undefined) {\n datos.push(data[0].id);\n }\n });\n $(this).rup_select('setRupValue', datos);\n }\n }\n },\n\n /**\r\n * Selecciona el elemento enviado como parámetro. En caso de ser un numérico se selecciona por la posición (comenzando en 0) y si es un literal se selecciona por el valor. En el caso de selección múltiple el parámetro será un array.\r\n *\r\n * @function select\r\n * @param {string | number | string[] | number[]} param - Parámetro utilzado para determinar los elementos a seleccionar.\r\n * @example\r\n * // Simple\r\n * $(\"#idSelect\").rup_select(\"select\", 2);\r\n * // Multiple\r\n * $(\"#idSelect\").rup_select(\"select\", [0,2]);\r\n */\n select: function select(param) {\n var settings = $(this).data().settings;\n var datas = settings.data || settings.options;\n\n if (settings.groups) {\n datas = settings.optionsGroups;\n }\n\n if (settings.multiple) {\n var datos = [];\n $.each(param, function (key, value) {\n if (datas.length >= value) {\n datos.push(datas[value].id);\n }\n });\n $(this).rup_select('setRupValue', datos);\n } else {\n if (datas.length >= param) {\n $(this).rup_select('setRupValue', datas[param].id);\n }\n }\n },\n\n /**\r\n * Método que devuelve el label asociado al valor seleccionado en el\r\n * select. En el caso de la selección múltiple se devolverá un array.\r\n * \r\n * @function label\r\n * @return {string | string[]} - Texto del elemento o elementos\r\n * seleccionado.\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n label: function label() {\n // Tipo de select\n var data = $(this).select2('data');\n\n if (!$(this).data('settings').multiple) {\n return data[0].text;\n } else {\n // Multiple > multiselect\n var retorno = [];\n\n for (var i = 0; i < data.length; i++) {\n retorno.push(data[i].text);\n }\n\n return retorno;\n }\n },\n\n /**\r\n * Devuelve el índice de la opción seleccionada en el select (empezando\r\n * en 1). En el caso de la selección múltiple se devolverá un array.\r\n * \r\n * @function index\r\n * @return {number | number[]} - Índice del elemento o elementos\r\n * seleccionados.\r\n * @example $(\"#idSelect\").rup_select(\"index\");\r\n */\n index: function index() {\n // Tipo de select\n var settings = $(this).data('settings');\n\n if (settings.options !== undefined) {\n var options = settings.options;\n\n if (settings.groups) {\n options = settings.optionsGroups;\n }\n\n var count = 0;\n var data = $(this).select2('data');\n\n if (!settings.multiple) {\n // Simple > selectmenu\n $.each(options, function (key, value) {\n if (settings.blank !== value.id.toString()) {\n count = count + 1;\n }\n\n if (value.id.toString() === data[0].id.toString()) {\n return false;\n }\n });\n } else {\n var listaCount = [];\n $.each(data, function (key, value) {\n count = 0;\n $.each(options, function (cont, valor) {\n if (settings.blank !== value.id.toString()) {\n count = count + 1;\n }\n\n if (value.id.toString() === valor.id.toString()) {\n listaCount.push(count);\n return false;\n }\n });\n });\n return listaCount;\n }\n\n return count;\n }\n },\n\n /**\r\n * Deshabilita el select.\r\n * \r\n * @function disable\r\n * @example $(\"#idSelect\").rup_select(\"disable\");\r\n */\n disable: function disable() {\n // Tipo de select\n var $self = $(this);\n $self.prop(\"disabled\", true);\n },\n\n /**\r\n * Habilita el select.\r\n * \r\n * @function enable\r\n * @example $(\"#idSelect\").rup_select(\"enable\");\r\n */\n enable: function enable() {\n var $self = $(this);\n $self.prop(\"disabled\", false);\n },\n\n /**\r\n * Indica si el select está deshabilitado o no.\r\n * \r\n * @function isDisabled\r\n * @param {boolean} -\r\n * Devuelve si el select está deshabilitado o no.\r\n * @example $(\"#idSelect\").rup_select(\"isDisabled\");\r\n */\n isDisabled: function isDisabled() {\n if ($(this).attr('disabled') === 'disabled') {\n return true;\n } else {\n return false;\n }\n },\n\n /**\r\n * Realiza una recarga de los select.\r\n * \r\n * @function reload\r\n * @example $(\"#idSelect\").rup_select(\"reload\");\r\n */\n reload: function reload(removeOptions) {\n var settings = $(this).data('settings');\n $(this).select2(\"destroy\");\n\n if (removeOptions) {\n $(this).find('option').remove();\n }\n\n $(this).rup_select(settings);\n },\n\n /**\r\n * Cambia el source del select y recarga el componente para que este\r\n * comience a usarlo.\r\n * \r\n * @function setSource\r\n * @param {string}\r\n * source - Source desde el cual se obtendran los datos a\r\n * sourceParam - Se puede cambiar los parámetros de la cabecera..\r\n * @example $(\"#idSelect\").rup_select(\"setSource\", source, sourceParam);\r\n */\n setSource: function setSource(source, sourceParam) {\n if (source !== undefined && source !== '') {\n var $self = $(this);\n var settings = $self.data().settings;\n var dataSelect2 = $self.data('select2');\n\n if ($self.data().settings.data === undefined) {\n // remoto\n dataSelect2.dataAdapter.ajaxOptions.url = source;\n\n if (sourceParam != undefined) {\n dataSelect2.dataAdapter.ajaxOptions.headers = $.toJSON(sourceParam);\n }\n } else {\n // local\n settings.data = source;\n settings.options = undefined;\n $self.data('settings', settings);\n\n if (dataSelect2.$selection != undefined) {\n dataSelect2.$selection.find('input').val('');\n }\n\n $self.empty();\n\n if (settings.data !== undefined && settings.autocomplete) {\n $.each(settings.data, function () {\n _this._createOption(settings, this);\n });\n } else {\n $self.select2({\n data: settings.data\n });\n }\n }\n }\n },\n\n /**\r\n * Método que devuelve los datos, de los elementos seleccionados.\r\n * \r\n * @function getDataSelected\r\n * @return {string | string[]} - Texto del elemento o elementos\r\n * seleccionado.\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n getDataSelected: function getDataSelected() {\n // Tipo de select\n var data = $(this).select2('data');\n\n if (!$(this).data('settings').multiple) {\n //Validar que venga el nid\n if (data[0] != undefined && data[0].nid == undefined && $(this).data('settings').options != undefined) {\n var seleccionado = $.grep($(this).data('settings').options, function (v, index) {\n return v.id === data[0].id;\n });\n\n if (seleccionado != undefined && seleccionado.length == 1) {\n data[0].nid = seleccionado[0].nid;\n }\n }\n\n return data[0];\n } else {\n return data;\n }\n },\n\n /**\r\n * Método que añade un option al select en local\r\n * \r\n * @function addOption\r\n * id:\tidentificador del nuevo option\r\n * text: texto del nuevo option\r\n * label: en Caso de ser grupos, el label donde se va a meter(obligatorio)\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n addOption: function addOption(id, text, label) {\n // Tipo de select\n var newOpt = new Option(id, text);\n\n if ($(this).data('settings').groups && label != undefined) {\n var options = $(this).data('select2').options.options;\n $(this).find('optgroup[label=\"' + label + '\"]').append(newOpt);\n var seleccionado = $.grep(options.data, function (v, index) {\n return v.text === label;\n });\n\n if (seleccionado != undefined && seleccionado.length == 1) {\n seleccionado[0].children[seleccionado[0].children.length] = {\n id: id,\n text: text\n };\n }\n } else {\n $(this).append(newOpt);\n }\n },\n\n /**\r\n * Deshabilita una opción de un select multiselección.\r\n *\r\n * @function disableOpt\r\n * @param {string} optValue - Value del option que queremos deshabilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"disableOpt\", \"opt1\");\r\n */\n disableOpt: function disableOpt(optValue) {\n if ($(this).data('settings').multiple) {\n //Deshabilitar select\n this.find('[value=\\'' + optValue + '\\']').attr('disabled', 'disabled'); //Si pertenece a OptGroup y es el último en deshabilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(),\n inputs = li.nextUntil('li.ui-multiselect-optgroup-label').find('input'),\n allDisabled = true;\n\n for (var i = 0; i < inputs.length; i++) {\n if (!inputs[i].disabled) {\n allDisabled = false;\n break;\n }\n }\n\n if (allDisabled) {\n //Estilos optGroup\n li.css('color', 'grey');\n li.children('a').remove();\n li.children('span').not('.rup-combo_multiOptgroupLabel').remove();\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Deshabilita varias opciones del select. Las opciones se identifican mediante un array.\r\n *\r\n * @function disableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a deshabilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"disableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n disableOptArr: function disableOptArr(optValueArr) {\n if ($(this).data('settings').multiple) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_select('disableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita una opción de un select multiselección.\r\n *\r\n * @function enableOpt\r\n * @param {string} enableOpt - Value del option que queremos habilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"enableOpt\", \"opt1\");\r\n */\n enableOpt: function enableOpt(optValue) {\n if ($(this).data('settings').multiple) {\n //Habilitar select\n this.find('[value=\\'' + optValue + '\\']').removeAttr('disabled');\n var obj = $('#rup-multiCombo_' + $(this).attr('id')).find('[value=\\'' + optValue + '\\']'); //Habilitar input\n\n obj.removeAttr('disabled'); //Estilos línea (label)\n\n obj.parent().css('color', 'black'); //Si pertenece a OptGroup y es el primero en habilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(); //Estilos optGroup\n\n if (li.children('a').length === 0) {\n li.css('color', 'black');\n\n this._generateOptGroupLabel(li, $(this).data('settings').multiOptgroupIconText);\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita varias opciones del select. Las opciones se identifican mediante un array.\r\n *\r\n * @function enableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a habilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"enableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n enableOptArr: function enableOptArr(optValueArr) {\n if ($(this).data('settings').multiple) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_select('enableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Ordena alfanumericamente y en orden ascendente el combo sobre el que se aplica. Se invoca por defecto al cargarse los combos a no ser que se cambie el valor del atributo ordered en la creación.\r\n *\r\n * @function order\r\n * @param {boolean} orderedByValue - Indica si la búsqueda es por texto (por defecto) o si la búsqueda es por el valor.\r\n * @param {boolean} orderAsNumber - Indica si se debe ordenar como valores numéricos en vez de alfabéticos.\r\n * @param {boolean} skipFirst - Determina si se debe obviar el primer elemento.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"order\", orderedByValue, orderAsNumber, skipFirst);\r\n */\n order: function order(groups, orderedByValue, orderAsNumber) {\n /* Get options */\n var selector = $(this).data('select2') || $(this).parent().data('select2');\n var settings = selector.options.options;\n\n if (groups) {\n $(this).find('optgroup').each(function () {\n $(this).rup_select('order', false, orderedByValue, orderAsNumber);\n }); //Order children\n\n if (settings.data != undefined) {\n $(settings.data).each(function () {\n if (this.children != undefined && this.children.length > 0) {\n this.children = this.children.sort(function (a, b) {\n return a.text.localeCompare(b.text);\n });\n }\n });\n }\n } else {\n var selectList = $(this).find('option').not('[value=' + settings.blank + ']');\n var option = $(this).find('option[value=' + settings.blank + ']');\n /* Order by innerText (case insensitive) */\n\n selectList.sort(function (a, b) {\n return a.innerText.localeCompare(b.innerText);\n });\n /* Re-do select HTML */\n\n $(this).html(selectList);\n\n if (option.length == 1) {\n $(this).prepend(option);\n }\n }\n },\n\n /**\r\n * Lanza una búsqueda en el autocomplete con el parámetro indicado y el foco va a parar al input.\r\n *\r\n * @param {string} term - Cadena de texto utilizada para realizar la búsqueda.\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function search\r\n * \r\n * @example\r\n * $(\"#idSelect\").rup_select(\"search\", \"java\");\r\n */\n search: function search(term, notOthersClose) {\n var $search = $(this).data('select2').dropdown.$search || $(this).data('select2').mySelect.selection.$search;\n\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).data('select2').$container.find('input').val(term);\n\n if ($search != undefined) {\n $search.val(term);\n $search.trigger('keyup');\n }\n },\n\n /**\r\n * Permite consultar y modificar la configuración del componente.\r\n *\r\n * @param {string | object} optionName - Nombre de la propiedad que se desea gestionar o objeto de compuesto de varias propiedades.\r\n * @param {*} [value] - Corresponde al valor de la propiedad en caso de haberse especificado el nombre de la misma en el primér parámetro.\r\n * @param {*} aux - Parámetro extra de confirguración para la propiedad \"source\".\r\n * @function option\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", \"minLegth\", 2);\r\n * // Establecer varias propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", {minLegth:2, delay:1000});\r\n */\n option: function option(optionName, value, removeOptions) {\n var settings = $(this).data('settings');\n settings[optionName] = value;\n $(this).select2(\"destroy\");\n\n if (removeOptions) {\n $(this).find('option').remove();\n }\n\n $(this).rup_select(settings);\n },\n\n /**\r\n * Permite abrir el componente.\r\n *\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function open\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", true);\r\n */\n open: function open(notOthersClose) {\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).select2('open');\n },\n\n /**\r\n * Permite cerrar el componente.\r\n *\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function close\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", true);\r\n */\n close: function close(notOthersClose) {\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).select2('close');\n },\n\n /**\r\n * Elimina el autocomplete.\r\n *\r\n * @function destroy\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"destroy\");\r\n */\n destroy: function destroy(notRemoveOptions) {\n $(this).select2(\"destroy\");\n\n if (!notRemoveOptions) {\n $(this).find('option').remove();\n }\n }\n }); // *******************************\n // DEFINICIÓN DE MÉTODOS PRIVADOS\n // *******************************\n\n $.fn.rup_select('extend', {\n /**\r\n * Selecciona el elemento correspondiente al label indicado\r\n * \r\n * @function _selectLabel\r\n * @private\r\n * @param {object}\r\n * selector - Referencia al objeto jQuery del select.\r\n * @param {object}\r\n * param - Value correspondiente.\r\n */\n _selectLabel: function _selectLabel(selector, param) {\n var $option;\n\n for (var i = 0; i < $('option', selector).length; i = i + 1) {\n $option = jQuery(selector).find('option').eq(i);\n\n if (jQuery(selector).find('option').eq(i).text() === param) {\n $(selector).selectmenu('index', $option.prop('index'));\n return true;\n }\n }\n\n return false;\n },\n\n /**\r\n * Obtener la opción vacía a partir del fichero de internacionalización\r\n * de la aplicación o del fichero por defecto.\r\n * \r\n * @function _getBlankLabel\r\n * @private\r\n * @param {string}\r\n * id - Identificador del fichero\r\n */\n _getBlankLabel: function _getBlankLabel(id) {\n var app = $.rup.i18n.app; // Comprueba si el select tiene su propio texto personalizado\n\n if (app[id] && app[id]._blank) {\n return app[id]._blank;\n } // Comprueba si la aplicacion tiene un texto definido para todos los\n // blank\n else if (app.rup_select && app.rup_select.blank) {\n return app.rup_select.blank;\n } // Si no hay textos definidos para los blank obtiene el por defecto\n // de UDA\n\n\n return $.rup.i18n.base.rup_select.blankNotDefined;\n },\n\n /**\r\n * Obtener valores de los selects padres (si no están cargados o valores\r\n * 'vacíos' devuelve null). En caso de disponer de varios selects padres\r\n * se devolverán separados por un caracter delimitador.\r\n * \r\n * @function _getParentsValues\r\n * @private\r\n * @param {object[]}\r\n * settings - Array con los elementos de configuración.\r\n * @param {boolean}\r\n * remote - Determina si la fuente de datos es remota o no.\r\n * @return {string} - Devuelve los values seleccionados de los selects\r\n * padres.\r\n */\n _getParentsValues: function _getParentsValues(settings, remote, multiValueToken) {\n var retorno = '';\n var parent = [];\n\n if (settings.parent == undefined) {\n return '';\n }\n\n if (typeof settings.parent == 'string') {\n parent.push(settings.parent);\n } else {\n parent = settings.parent;\n }\n\n var parentsFull = 0;\n $.each(parent, function (idx, parentId) {\n if (parentId != undefined && $('#' + parentId).val() != null && $('#' + parentId).val().trim() !== '') {\n if (settings.blank == $('#' + parentId).val()) {\n retorno = '';\n } else {\n if (remote) {\n // PAra remoto\n retorno += $('#' + parentId).attr('name') + '=' + $('#' + parentId).val() + '&';\n } else {\n // PAra local\n if (retorno != '') {\n retorno = retorno + multiValueToken + $('#' + parentId).val();\n } else {\n retorno = $('#' + parentId).val();\n }\n }\n\n parentsFull = parentsFull + 1;\n }\n }\n });\n\n if (parentsFull < parent.length) {\n // si no estan todos los padres no\n // se busca.\n return '';\n } // Evitar & o multiValueToken finales\n\n\n if (retorno !== '' && remote) {\n retorno = retorno.substring(0, retorno.length - 1);\n }\n\n return retorno;\n },\n\n /**\r\n * Procesa el conjunto de registros devueltos por una petición sobre un\r\n * origen de datos local.\r\n * \r\n * @function _parseLOCAL\r\n * @private\r\n * @param {object[]}\r\n * data - Array de registros obtenidos a partir del origen de\r\n * datos.\r\n * @param {object}\r\n * i18nId - Opciones de idioma.\r\n * @param {jQuery}\r\n * isParent - Si tiene datos en forma parent.\r\n */\n _parseLOCAL: function _parseLOCAL(data, i18nId, isParent) {\n var text;\n var array = data;\n\n if (isParent) {\n // Si es padre llamar a la recursividad\n if (Array.isArray(data)) {\n data = data[0];\n }\n\n $.each(data, function (key, value) {\n data[key] = _this._parseLOCAL(data[key], i18nId, false);\n });\n } else {\n data = [];\n\n for (var i = 0; i < array.length; i = i + 1) {\n if (_typeof(array[i]) === 'object') {\n // multi-idioma\n if (array[i].i18nCaption) {\n text = $.rup.i18nParse($.rup.i18n.app[i18nId], array[i].i18nCaption);\n } else {\n text = array[i].text;\n }\n\n array[i].text = text;\n } else {\n // El id es el mismo que el texto.\n data[i] = {\n id: array[i],\n text: array[i]\n };\n }\n }\n\n if (data.length > 0) {\n // El id es el mismo que el texto.\n return data;\n }\n }\n\n return array;\n },\n\n /**\r\n * Procesa el conjunto de registros devueltos por una petición sobre un\r\n * origen de datos remoto.\r\n * \r\n * @function _parseRemoteGroup\r\n * @private\r\n * @param {object[]}\r\n * array - Array de registros obtenidos a partir del origen\r\n * de datos.\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n */\n _parseRemoteGroup: function _parseRemoteGroup(array, settings) {\n var item;\n var data = [];\n\n for (var i = 0; i < array.length; i = i + 1) {\n item = array[i];\n var key = Object.keys(item)[0];\n var dato = {};\n dato.text = key;\n dato.children = item[key];\n dato.id = \"group__\" + i;\n data.push(dato);\n }\n\n return data;\n },\n\n /**\r\n * Prepara la petición AJAX que se va a realizar para obtener los\r\n * registros a partir de un origen remoto. Se añaden las cabeceras RUP\r\n * correspondientes para realizar la serialización json de manera\r\n * correcta.\r\n * \r\n * @function _ajaxBeforeSend\r\n * @private\r\n * @param {object}\r\n * xhr - Objeto xhr que se va a enviar en la petición\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n * @param {jQuery}\r\n * html - Referencia al objeto jQuery que contiene los\r\n * elementos.\r\n */\n _ajaxBeforeSend: function _ajaxBeforeSend(xhr, settings, html) {\n // Crear select (vacío) y deshabilitarlo\n if (html !== undefined) {\n $('#' + settings.id).replaceWith(html);\n } // Si no es 'reload' se debe inicializar vacío\n\n\n $('#' + settings.id).rup_select('disable'); // LOADING...\n\n $('#' + settings.id + '-button span:first-child').removeClass(\"ui-icon ui-icon-triangle-1-s\").addClass('rup-select_loadingText').text($.rup.i18n.base.rup_select.loadingText);\n var icon = $('#' + settings.id + '-button span:last-child');\n $(icon).removeClass('ui-icon-triangle-1-s');\n $(icon).text(''); // Evita errores de visualización con el icono\n\n $(icon).addClass('rup-select_loading'); // Cabecera RUP\n\n xhr.setRequestHeader('RUP', $.toJSON(settings.sourceParam));\n },\n\n /**\r\n * Procesa la respuesta de la petición AJAX en el caso de que se haya\r\n * producido un error en la misma.\r\n * \r\n * @function _ajaxError\r\n * @private\r\n * @param {object}\r\n * xhr - Objeto xhr enviado en la respuesta.\r\n * @param {string}\r\n * textStatus - Cadena identificadora del error que se ha\r\n * producido en la petición.\r\n * @param {object}\r\n * errorThrown - Objeto error correspondiente al que se ha\r\n * producido en la petición.\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n */\n _ajaxError: function _ajaxError(xhr) {\n if (xhr.responseText !== null && xhr.responseTex !== undefined && xhr.responseText.length < 200) {\n $.rup.showErrorToUser(xhr.responseText);\n } else {\n $.rup.showErrorToUser($.rup.i18n.base.rup_select.ajaxError);\n }\n },\n\n /**\r\n * Carga la opción remoto.\r\n * \r\n * @function _loadRemote\r\n * @private\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con\r\n * el que se ha inicializado el componente.\r\n * @return {jQuery} - Objeto jQuery con referencia al elemento que\r\n * contiene el foco.\r\n */\n _loadRemote: function _loadRemote(settings, first) {\n var rupSelect = this;\n settings.ajax = {\n url: function url() {\n return rupSelect._generateUrl(settings, _this._getParentsValues(settings, true));\n },\n dataType: settings.dataType,\n processResults: function processResults(response) {\n // Require id y text, podemos permitir que no venga.\n if (settings.placeholder != undefined && !settings.multiple) {\n var elBlank = response.find(function (x) {\n return x.id == settings.blank;\n });\n\n if (elBlank == undefined && !settings.autocomplete) {\n response.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n }\n }\n\n if (settings.groups) {\n // PArsear para grupos.\n var results = [];\n $.each(response, function (index, value) {\n var key = Object.keys(value)[0];\n results[index] = {\n 'text': key,\n 'children': value[key]\n };\n });\n response = results;\n }\n\n settings.options = response;\n $('#' + settings.id).data('settings', settings);\n return {\n results: response\n };\n },\n cache: false,\n data: function data() {\n // Es necesario enviarlo vacío para que el componente subyacente no genere parámetros extra que Hdiv bloqueará.\n //se hará en el transport\n return _this._getParentsValues(settings, true);\n },\n error: function error(xhr, textStatus, errorThrown) {\n if (settings.onLoadError !== null) {\n jQuery(settings.onLoadError(xhr, textStatus, errorThrown));\n } else {\n if (textStatus != 'abort') {\n //Si se hacen 2 llamadas se cancela la primera.\n rupSelect._ajaxError(xhr, textStatus, errorThrown);\n }\n\n console.log(textStatus);\n }\n }\n };\n\n if (settings.selected || settings.autocomplete && settings.defaultValue != undefined) {\n settings.firstLoad = true;\n }\n\n if (settings.parent != undefined && ($('#' + settings.parent).val() == null || $('#' + settings.parent).val().trim() === '')) {\n settings.firstLoad = false;\n }\n\n var __cache = [];\n var __lastQuery = null;\n\n settings.ajax.transport = function (params, success, failure) {\n // retrieve the cached key or default to _ALL_\n var __cachekey = params.data || '_ALL_'; //Se actualiza el data, para mantener la misma función, con hdiv ya no se mandan los data\n\n\n if (!settings.autocomplete) {\n params.data = \"\";\n }\n\n var mySelect = $('#' + settings.id).data('select2');\n\n if (settings.autocomplete) {\n params.data.q = mySelect.$container.find('input').val();\n __cachekey = params.data.q;\n }\n\n if (__lastQuery !== __cachekey) {\n // remove caches not from last query\n __cache = [];\n }\n\n __lastQuery = __cachekey; //Si esta cacheado, no busca\n\n if (settings.cache == true && 'undefined' !== typeof __cache[__cachekey]) {\n // display the cached results\n success(__cache[__cachekey]);\n return;\n }\n\n mySelect.$results.find('li').addClass('disabledButtonsTable');\n mySelect.$selection.find('input').addClass('disabledButtonsTable');\n mySelect.$selection.find('input').blur(); //Si tiene padres deshabilitarlos\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"disable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"disable\");\n });\n }\n }\n\n var $request = undefined;\n\n if (settings.autocomplete) {\n //Meter busqueda accentFolding\n var term = '';\n term = params.data.q;\n term = term.replace(/%/g, '\\\\%').replace(/_/g, '\\\\_');\n params.data = $.extend({\n q: term,\n c: settings.contains\n }, settings.extraParams);\n }\n\n if (settings.parent) {\n var datosParent = _this._getParentsValues(settings, true);\n\n if (datosParent != '') {\n if (settings.autocomplete) {\n //añadir el data del padre\n var padres = datosParent.split('&'); //split por si tiene varios padres\t\n\n $.each(padres, function () {\n if (this !== undefined) {\n var cad = this.split('=');\n\n if (cad != undefined && cad.length > 0) {\n params.data[cad[0]] = cad[1];\n __cachekey = __cachekey + cad[1]; //se añade la parte del padre\n }\n }\n });\n }\n\n $request = $.ajax(params);\n }\n } else {\n $request = $.ajax(params);\n }\n\n if ($request != undefined) {\n $request.then(function (data) {\n // Vuelve la peticion\n // store data in cache\n __cache[__cachekey] = data; // display the results\n\n $('#' + settings.id).rup_select(\"enable\"); //Si tiene padres deshabilitarlos\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"enable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"enable\");\n });\n }\n }\n\n success(__cache[__cachekey]); // Actualizar seleccionado en la lista//css\n\n var positions = [];\n var valueSelect = $('#' + settings.id).rup_select('getRupValue');\n\n if (settings.groups) {\n var i;\n\n (function () {\n // Parseo de grupos para\n // seleccionar\n var allFacts = []; // grupos\n\n for (i = 0; i < data.length; i = i + 1) {\n if (_typeof(data[i]) === 'object') {\n $.each(data[i], function (key, value) {\n if (_typeof(value) === 'object') {\n $.each(value, function () {\n allFacts.push(this);\n });\n }\n });\n }\n }\n\n data = allFacts;\n settings.optionsGroups = data;\n })();\n }\n\n var seleccionado = $.grep(data, function (v, index) {\n if (v.id == valueSelect) {\n positions.push(index);\n }\n\n return v.nid == settings.selected || v.id == settings.selected;\n });\n\n if ($('#' + settings.id).rup_select('getRupValue') != '') {\n seleccionado = $.grep(data, function (v) {\n return v.id == $('#' + settings.id).rup_select('getRupValue');\n });\n } // Si es el mismo, no cambia porque esta abirendo\n\n\n var mySelect = $('#' + settings.id).data('select2');\n\n if (seleccionado !== undefined && seleccionado.length == 1 && $('#' + settings.id).rup_select('getRupValue') != seleccionado[0].id) {\n if (settings.multiple) {\n // Revisar varios selects\n $('#' + settings.id).rup_select('setRupValue', [seleccionado[0].id]);\n } else {\n $('#' + settings.id).rup_select('setRupValue', seleccionado[0].id);\n }\n\n $.each(positions, function (index, valor) {\n var $option = mySelect.$results.find('li')[valor];\n\n if ($option != undefined) {\n $($option).attr('aria-selected', 'true');\n }\n });\n } else {\n if (settings.autocomplete) {\n var valorInput = mySelect.selection.$selection.find('input').val();\n $('#' + settings.id).rup_select('setRupValue', settings.blank);\n mySelect.selection.$selection.find('input').val(valorInput);\n mySelect.selection.$selection.find('input').focus();\n } else {\n $('#' + settings.id).rup_select('setRupValue', settings.blank);\n }\n }\n\n if (settings.onLoadSuccess !== null && settings.onLoadSuccess !== undefined) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n }\n\n $('#' + settings.id).data('settings', settings);\n $('#' + settings.id).triggerHandler('selectAjaxSuccess', [data]);\n\n if (settings.firstLoad) {\n if (settings.autocomplete && settings.selected == undefined && settings.defaultValue != undefined && data != undefined && ($('#' + settings.id).rup_select('getRupValue') == '' || $('#' + settings.id).rup_select('getRupValue') == settings.blank)) {\n //setear el valor para el defaultValue\n var datos2 = $.grep(data, function (v) {\n return v.text.toUpperCase() === settings.defaultValue.toUpperCase();\n });\n\n if (datos2[0] != undefined) {\n $('#' + settings.id).rup_select('setRupValue', datos2[0].id);\n }\n }\n\n settings.firstLoad = false;\n settings.selected = '';\n }\n });\n $request.fail(failure);\n } else {\n // cerrar\n $('#' + settings.id).select2('close');\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"enable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"enable\");\n });\n }\n }\n }\n\n return $request;\n };\n\n if (settings.ajax !== undefined) {\n if (settings.data !== undefined) {\n // PAra añadir más parametros de\n // busqueda\n settings.ajax.data = settings.data;\n }\n\n if (settings.autocomplete) {\n //busqueda accentFolding\n var term = '';\n var mySelect = $('#' + settings.id).data('select2');\n\n if ($('input.select2-search__field') != undefined && $('input.select2-search__field').val() != undefined) {\n term = $('input.select2-search__field').val();\n }\n\n if (settings.contains == undefined) {\n settings.contains = true;\n }\n\n term = term.replace(/%/g, '\\\\%').replace(/_/g, '\\\\_');\n settings.ajax.data = $.extend({\n q: term,\n c: settings.contains\n }, settings.extraParams);\n }\n\n if (settings.sourceParam) {\n // modifica el header para parsear\n // la response\n settings.ajax.headers = {\n 'RUP': $.toJSON(settings.sourceParam)\n };\n }\n\n if (settings.processResults) {\n // modifica los results\n settings.ajax.processResults = settings.processResults;\n }\n }\n\n if (settings.multiple) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n if (settings.placeholder == undefined || settings.placeholder == '') {\n // si es vació se asigna el label\n settings.placeholder = rupSelect._getBlankLabel(settings.id);\n }\n\n if (settings.autocomplete) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n $('#' + settings.id).select2(settings);\n }\n }\n\n if (settings.firstLoad) {\n // ejecutar los datos\n var $el = $('#' + settings.id);\n\n var _mySelect = $el.data('select2');\n\n var $search = _mySelect.dropdown.$search || _mySelect.selection.$search;\n\n if (settings.autocomplete && settings.defaultValue != undefined) {\n _mySelect.$container.find('input').val(settings.defaultValue);\n }\n\n if ($search != undefined) {\n $search.trigger('keyup');\n $el.select2('close');\n } else {\n _mySelect.selection.trigger('toggle');\n\n $el.select2('close');\n }\n }\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _textIcon\r\n * @private\r\n * @param {object}\r\n * data - Dato que llega, por cada registro.\r\n */\n _textIcon: function _textIcon(data) {\n var stylePosition = 'M'; // B - Before , M - middle , A - After\n // adjust for custom placeholder values, restaurar\n\n if (data.stylePosition === undefined) {\n // usar la de defecto\n data.stylePosition = stylePosition;\n }\n\n var _span = $('');\n\n var icon = $('');\n\n if (data.imgStyle) {\n // en lugar d mdi,clase icon.\n _span.addClass(data.style);\n\n icon = $('');\n\n if (data.stylePosition.toUpperCase() === 'M') {\n data.stylePosition = 'B'; // en caso de ser span, no\n // admite texto en medio\n }\n }\n\n if (data.stylePosition.toUpperCase() === 'M') {\n icon.prepend(data.text);\n } else if (data.stylePosition.toUpperCase() === 'B') {\n _span.prepend(data.text);\n }\n\n _span.prepend(icon);\n\n if (data.stylePosition.toUpperCase() === 'A') {\n _span.prepend(data.text);\n }\n\n return _span;\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _createOption\r\n * @private\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n * @param {object}\r\n * data - Dato que llega, por cada registro.\r\n */\n _createOption: function _createOption(settings, data) {\n var newOption = new Option(data.text, data.id, false, false);\n\n if (data.style != null) {\n newOption.setAttribute('style', data.style);\n newOption.setAttribute('imgStyle', data.imgStyle);\n }\n\n $('#' + settings.id).append(newOption);\n },\n\n /**\r\n * Gestiona los parámetros a añadir en la URL para que Hdiv permita la llamada.\r\n *\r\n * @function _generateUrl\r\n * @since UDA 5.2.0\r\n * @private\r\n * @param {object} settings - Configuración del componente.\r\n * @param {string} [data] - Valores de búsqueda cuando tiene autocompletado e identificador de los padres en caso de ser enlazados.\r\n */\n _generateUrl: function _generateUrl(settings, data) {\n var _settings$inlineEdit, _settings$inlineEdit2, _settings$inlineEdit3, _settings$inlineEdit4;\n\n var $form = (_settings$inlineEdit = settings.inlineEdit) !== null && _settings$inlineEdit !== void 0 && _settings$inlineEdit.$auxForm ? (_settings$inlineEdit2 = settings.inlineEdit) === null || _settings$inlineEdit2 === void 0 ? void 0 : _settings$inlineEdit2.$auxForm : $('#' + settings.id).closest('form');\n var name = (_settings$inlineEdit3 = settings.inlineEdit) !== null && _settings$inlineEdit3 !== void 0 && _settings$inlineEdit3.auxSiblingFieldName ? (_settings$inlineEdit4 = settings.inlineEdit) === null || _settings$inlineEdit4 === void 0 ? void 0 : _settings$inlineEdit4.auxSiblingFieldName : settings.name;\n\n if ($form.length === 1) {\n var url = settings.url + '?_MODIFY_HDIV_STATE_=' + $.fn.getHDIV_STATE(undefined, $form);\n\n if (data) {\n // Escapa los caracteres '#' para evitar problemas en la petición.\n url += \"&\" + data.replaceAll('#', '%23');\n }\n\n return url + '&MODIFY_FORM_FIELD_NAME=' + name;\n } else {\n return settings.url;\n }\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _init\r\n * @private\r\n * @param {object}\r\n * args - Parámetros de inicialización del componente.\r\n */\n _init: function _init(args) {\n var _this2 = this;\n\n _this = this;\n global.initRupI18nPromise.then(function () {\n if (args.length > 1) {\n $.rup.errorGestor($.rup.i18nParse($.rup.i18n.base, 'rup_global.initError') + $(_this2).attr('id'));\n } else {\n // Se recogen y cruzan las paremetrizaciones del objeto\n var settings = $.extend({}, $.fn.rup_select.defaults, args[0]),\n html,\n loadAsLocal = false,\n isValidableElem = false,\n attrs; // Se recoge el tabindex indicado en el elemento\n\n settings.tabindex = $(_this2).attr('tabindex'); // Sobreescribir literales por defecto para\n // multiselect:REVISAR\n // $.extend($.ech.multiselect.prototype.options,\n // $.rup.i18n.base.rup_select.multiselect);\n // Se carga el identificador del padre del patron\n\n settings.id = $.rup_utils.escapeId($(_this2).attr('id'));\n\n if ($(_this2).attr('name') === undefined) {\n $(_this2).attr('name', settings.id);\n }\n\n settings.name = $(_this2).attr('name');\n $('#' + settings.id).attr('ruptype', 'select'); // Si no se recibe identificador para el acceso a literales\n // se usa el ID del objeto\n\n if (!settings.i18nId) {\n settings.i18nId = settings.id;\n } // Guardar valor del INPUT\n\n\n settings.inputValue = $('#' + settings.id).val() === null ? $('#' + settings.id).prop('value') : $('#' + settings.id).val();\n attrs = $(_this2).prop('attributes'); // Revisar apra el select\n\n if (settings.firstLoad === null && $(_this2).is('select') && settings.loadFromSelect) {\n loadAsLocal = true;\n } // Asociar evento CHANGE para propagar cambios a los hijos\n\n\n $('#' + settings.id).on('change', function () {}); // tratar placeHolder\n\n if (settings.placeholder !== undefined && typeof settings.placeholder == 'string') {\n if (!settings.allowClear) {\n settings.templateSelection = function (data, span) {\n if (data.id === settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return $('' + data.text + '');\n }\n\n chargedStyles(data);\n\n if (data.style != null && data.id !== settings.blank) {\n // adjust for custom placeholder values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n\n if (settings.placeholder == '') {\n // si es vació se\n // asigna el label\n settings.placeholder = _this2._getBlankLabel(settings.id);\n }\n\n if (settings.data !== undefined && !settings.multiple) {\n // y si\n // no\n // es\n // multiple\n if (settings.parent == undefined) {\n // Si no tiene padre se mete en todos los\n // valores, sino solo al data,\n settings.data.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n } else {\n $.each(settings.data, function (index, value) {\n value.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n });\n }\n }\n } else if ($('#' + settings.id).find('option').length == 0) {\n // revisar\n // y\n // crear\n // option\n // vacio.\n $('#' + settings.id).append(new Option(\"\", \"\"));\n }\n } // Crear mi template, myTemplate\n\n\n if (settings.myTemplate !== undefined) {\n settings.templateSelection = settings.myTemplate;\n }\n\n if (settings.templateResult === undefined) {\n if (settings.multiple && settings.udaSkill) {\n // Si es\n // multiple,\n // los\n // results\n // cambian\n // settings.templateSelection\n settings.templateSelection = function (data, span) {\n // Template de Uda\n return data.text;\n };\n } else {\n // si no es multiple\n if (settings.templateSelection !== undefined) {\n // mirar\n // los\n // iconos\n settings.templateResult = function (data, span) {\n chargedStyles(data);\n\n if (data.id === settings.blank) {\n return $('' + data.text + '');\n } else if (data.style != null && data.id !== settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n } else {\n settings.templateResult = function (data, span) {\n chargedStyles(data);\n\n if (data.style != null && data.id !== settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n\n settings.templateSelection = settings.templateResult;\n }\n }\n } // Borrar referencia\n // delete html;\n // Ocultar posibles elementos de fechas/horas\n\n\n $('#' + settings.id).next('a').click(function () {\n $('#ui-datepicker-div').hide();\n }); // Se audita el componente\n\n $.rup.auditComponent('rup_select', 'init'); // Añade clase Personalizada\n\n if (settings.customClasses) {\n $.each(settings.customClasses, function (index, value) {\n $('#' + settings.id + '-button' + ', #' + settings.id + '-menu').addClass(value);\n $('[for=' + settings.id + ']').addClass(value);\n });\n } // Si no se recibe identificador para el acceso a literales\n // se usa el ID del objeto\n\n\n if (!settings.i18nId) {\n settings.i18nId = settings.id;\n } // ORDEN\n\n\n var ordenFunction = function ordenFunction(data) {\n if (typeof data === 'string') {\n var dates = data.sort(function (a, b) {\n return a.text.localeCompare(b.text);\n });\n var mySettings = $('#' + settings.id).data('settings');\n mySettings.options = dates;\n $('#' + settings.id).data('settings', mySettings);\n return dates;\n }\n\n return data;\n };\n\n if (settings.data || settings.dataGroups) {\n // local y\n // groups\n if (settings.sortered === true) {\n // PAra añadir\n // ordenación, en local\n // hay que marcarlo\n settings.sorter = ordenFunction;\n } else if (settings.sortered !== false) {\n settings.sorter = settings.sortered;\n }\n\n if (settings.dataGroups === undefined) {\n // LOcal\n settings.data = _this2._parseLOCAL(settings.data, settings.i18nId, settings.parent);\n } else {\n // grupos\n var optionsGroups = [];\n\n for (var i = 0; i < settings.dataGroups.length; i = i + 1) {\n if (_typeof(settings.dataGroups[i]) === 'object') {\n settings.dataGroups[i].children = _this2._parseLOCAL(settings.dataGroups[i].children, settings.i18nId, settings.parent);\n\n for (var j = 0; j < settings.dataGroups[i].children.length; j = j + 1) {\n optionsGroups.push(settings.dataGroups[i].children[j]);\n }\n }\n }\n\n settings.optionsGroups = optionsGroups;\n settings.data = settings.dataGroups;\n }\n } else if (!settings.ajax && settings.url != null) {\n // remoto\n if (settings.sortered === undefined) {\n // PAra añadir\n // ordenación, en\n // remoto siempre se\n // ordena por\n // defecto.\n settings.sorter = ordenFunction;\n } else if (settings.sortered !== false) {\n settings.sorter = settings.sortered;\n }\n\n _this2._loadRemote(settings, true);\n } else {\n // por si viene cargado de un select\n settings.data = true;\n\n if (settings.parent) {\n //convertir el data, formato parent\t\n settings.data = [];\n $('#' + settings.id).find('option').each(function () {\n var idPadre = $(this).data('idpadre');\n\n if (idPadre != undefined) {\n //si no existe\n if (settings.data[idPadre] === undefined) {\n settings.data[idPadre] = [];\n\n if (settings.placeholder != undefined || settings.placeholder != '') {\n settings.data[idPadre].push({\n id: settings.blank,\n text: settings.placeholder\n });\n }\n }\n\n settings.data[idPadre].push({\n id: $(this).val(),\n text: $(this).text()\n });\n }\n });\n }\n } // Init eventos: El resto van en el propio subyacente\n // Change\n\n\n if (settings.change) {\n if (!settings.clean) {\n $('#' + settings.id).off('select2:clearing');\n $('#' + settings.id).on('select2:clearing', function (e) {\n settings.change(e);\n });\n }\n } // clean\n\n\n if (settings.clean) {\n $('#' + settings.id).off('select2:clearing');\n $('#' + settings.id).on('select2:clearing', function (e) {\n settings.clean(e);\n });\n } // event select\n\n\n $('#' + settings.id).off('select2:select');\n $('#' + settings.id).on('select2:select', function (e) {\n if (settings.autocomplete) {\n //Change input\n var mySelect2 = $('#' + settings.id).data('select2');\n var data = $(this).select2('data')[0];\n mySelect2.$selection.find('input').val(data.text);\n }\n\n if (settings.select) {\n settings.select(e);\n }\n\n if (settings.change) {\n settings.change(e);\n }\n });\n\n if (settings.data) {\n // local y groups\n if (settings.parent) {\n // si depende de otro selects.\n // Si es uno meterlo como string - local\n if (_typeof(settings.parent) == 'object' && settings.parent.length == 1) {\n settings.parent = settings.parent[0];\n }\n\n if (settings.dataParents === undefined) {\n // la\n // primera\n // vez carga\n // los datos\n // fijos.\n settings.dataParents = settings.data;\n }\n\n var valorValue = _this._getParentsValues(settings, false, settings.multiValueToken);\n\n if (valorValue != '') {\n valoresParent = settings.dataParents[valorValue];\n\n if (valoresParent == undefined && settings.dataParents[0] != undefined) {\n valoresParent = settings.dataParents[0][valorValue];\n }\n\n settings.data = valoresParent;\n\n if (settings.data == undefined) {\n settings.data = [];\n }\n }\n }\n\n if (settings.multiple) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n if (settings.placeholder == undefined || settings.placeholder == '') {\n // si es vació se asigna el label\n settings.placeholder = _this._getBlankLabel(settings.id);\n }\n\n if (settings.autocomplete) {\n //local y autocomplete\n if (settings.matcher == undefined && settings.accentFolding == false) {\n settings.matcher = udaMatcher;\n }\n\n $('#' + settings.id).select2MultiCheckboxes(settings);\n\n if (settings.defaultValue != undefined) {\n var mySelect2 = $('#' + settings.id).data('select2');\n mySelect2.$selection.find('input').val(settings.defaultValue);\n\n if (settings.selected == undefined && mySelect2.dataAdapter._dataToConvert != undefined && mySelect2.dataAdapter._dataToConvert.length > 0) {\n var data = $.grep(mySelect2.dataAdapter._dataToConvert, function (v) {\n return v.text.toUpperCase() === settings.defaultValue.toUpperCase();\n });\n\n if (data[0] != undefined) {\n settings.selected = data[0].id;\n }\n }\n }\n } else {\n $('#' + settings.id).select2(settings);\n } //Propiedad para deselecionar una mismo en simple.\n\n\n if (settings.deleteOnDeselect) {\n var _mySelect2 = $('#' + settings.id).data('select2');\n\n _mySelect2.on('close', function (e) {\n if (Object.keys(e).length === 1) {\n _mySelect2.$selection.find('input').val('');\n\n $('#' + settings.id).val(null).trigger('change');\n\n if (!settings.closeOnSelect) {\n $('#' + settings.id).select2('open');\n }\n }\n });\n }\n }\n\n if (settings.selected) {\n $('#' + settings.id).val(settings.selected).trigger('change');\n } // cargar los options\n\n\n settings.options = settings.data;\n } else {\n //Remotos\n //Propiedad para deselecionar una mismo en simple.\n if (settings.deleteOnDeselect) {\n var remotoSelect = $('#' + settings.id).data('select2');\n remotoSelect.on('close', function (e) {\n if (Object.keys(e).length === 1) {\n remotoSelect.$selection.find('input').val('');\n $('#' + settings.id).val(null).trigger('change');\n\n if (!settings.closeOnSelect) {\n $('#' + settings.id).select2('open');\n }\n }\n });\n }\n }\n\n if (settings.parent) {\n // si dependen de otros selects\n // Mirar si es simple o no\n var parent = [];\n\n if (typeof settings.parent == 'string') {\n parent.push(settings.parent);\n } else {\n // Si es uno meterlo como string -remoto\n if (settings.parent.length == 1) {\n settings.parent = settings.parent[0];\n parent.push(settings.parent);\n } else {\n parent = settings.parent;\n }\n } // Bucle para eventos Padres\n\n\n $.each(parent, function (idx, eventoPadre) {\n $('#' + eventoPadre).off('change.parent' + settings.id);\n $('#' + eventoPadre).on('change.parent' + settings.id, function () {\n // Cambios\n // para\n // los\n // hijos,onchange\n // del\n // padre\n // Si soy local\n if (settings.data !== undefined) {\n if (_typeof(settings.parent) == 'object') {\n // Si\n // tiene\n // más\n // de\n // un\n // padre\n var clave = '';\n var ClaveNoCifrar = '';\n\n if (settings.multiValueToken == undefined) {\n settings.multiValueToken = '';\n }\n\n $.each(settings.parent, function (ind, elem) {\n var val = $('#' + elem).rup_select('getRupValue');\n clave = clave + val + settings.multiValueToken;\n var dataSelected = $('#' + elem).rup_select(\"getDataSelected\");\n\n if (dataSelected !== undefined) {\n val = dataSelected.nid || dataSelected.id;\n ClaveNoCifrar = ClaveNoCifrar + val + settings.multiValueToken;\n }\n });\n clave = clave.substring(0, clave.length - settings.multiValueToken.length);\n ClaveNoCifrar = ClaveNoCifrar.substring(0, ClaveNoCifrar.length - settings.multiValueToken.length);\n var datosParents = settings.dataParents[0] || settings.dataParents;\n\n if (datosParents[clave] != undefined || datosParents[ClaveNoCifrar] != undefined) {\n // Datos\n // Cargados\n var valores = datosParents[clave] || datosParents[ClaveNoCifrar];\n settings.data = datosParents;\n $('#' + settings.id).rup_select(\"setSource\", valores);\n }\n } else {\n // si tiene un solo padre\n var val = $('#' + settings.parent).rup_select('getRupValue');\n\n if (val != settings.blank && val != '') {\n $('#' + settings.id).rup_select(\"enable\");\n var _valores = settings.dataParents[val];\n\n if (_valores == undefined && $('#' + settings.parent).rup_select(\"getDataSelected\") !== undefined) {\n var nid = $('#' + settings.parent).rup_select(\"getDataSelected\").nid;\n _valores = settings.dataParents[nid]; //si vine cifrado de un remoto.\n }\n\n settings.data = settings.dataParents;\n\n if (_valores == undefined) {\n // Si no\n // hay\n // valor,\n // se\n // inicializa\n _valores = [];\n }\n\n $('#' + settings.id).rup_select(\"setSource\", _valores);\n } else {\n //deshabilitamos el hijo\n $('#' + settings.id).rup_select(\"disable\");\n }\n } // Aseguramos el valor limpio al cambiar el\n // padre\n\n\n $('#' + settings.id).rup_select(\"setRupValue\", settings.blank);\n } else {\n // si soy Remoto\n var datosParent = _this._getParentsValues(settings, true); // Sola llamar si el padre tiene valor.\n\n\n if (datosParent != '') {\n $('#' + settings.id).rup_select(\"disable\"); // ejecutar los datos\n\n var $el = $('#' + settings.id);\n var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;\n\n if (settings.autocomplete) {\n $el.data('select2').$container.find('input').val('');\n }\n\n if ($search != undefined) {\n $search.trigger('keyup');\n $el.select2('close');\n }\n\n if ($(\"#\" + settings.id).val() != null && $(\"#\" + settings.id).val().trim() != '') {\n $(\"#\" + settings.id).val(null).trigger('change');\n }\n\n setTimeout($('#' + settings.id).rup_select(\"enable\"), 200);\n } else if ($(\"#\" + settings.id).val() != null && $(\"#\" + settings.id).val().trim() != '') {\n // Se llama al cambio del trigger.\n $(\"#\" + settings.id).val(null).trigger('change');\n $('#' + settings.id).rup_select(\"disable\");\n }\n }\n });\n }); // Fin funcion evento padre\n }\n\n $('#' + settings.id).data('settings', settings); //Si es remoto, el último evento es: selectAjaxSuccess\n\n $('#' + settings.id).triggerHandler('selectFinish', settings);\n }\n })[\"catch\"](function (error) {\n console.error('Error al inicializar el componente:\\n', error);\n });\n }\n }); // ******************************************************\n // DEFINICIÓN DE LA CONFIGURACION POR DEFECTO DEL PATRON\n // ******************************************************\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener\r\n * los elementos a mostrar.\r\n * \r\n * @callback jQuery.rup_select~onLoadError\r\n * @param {Object}\r\n * xhr - Objeto XHR que contiene la respuesta de la petición\r\n * realizada.\r\n * @param {string}\r\n * textStatus - Texto que identifica el error producido.\r\n * @param {Object}\r\n * errorThrown - Objeto error que contiene las propiedades del\r\n * error devuelto en la petición.\r\n */\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener\r\n * los elementos a mostrar.\r\n * \r\n * @callback jQuery.rup_select~onLoadSuccess\r\n * @param {jQuery}\r\n * self - Referencia al objeto jQuery del propio select.\r\n */\n\n /**\r\n * @description Opciones por defecto de configuración del componente.\r\n * \r\n * @name defaults\r\n * \r\n * @property {jQuery.rup_select~onLoadError} [onLoadError] - Función de\r\n * callback a ejecutar en caso de que se produzca un error en la\r\n * petición de obtención de la lista de elementos a mostrar.\r\n * @property {string} [width='100%'] - Determina el tamaño del componente \r\n * tanto en píxeles como en porcentaje. Su valor por defecto es '100%'.\r\n * @property {string} [blank=null] - Se utiliza para declarar un valor\r\n * independiente de la lógica de negocio y en ocasiones se\r\n * representa como \"Seleccione un elemento\". Permite establecer un\r\n * mensaje independiente por cada select haciendo uso de\r\n * $.rup.i18n.app.id._blank (sustituyendo id por el propio de cada\r\n * select) o uno genérico por aplicación haciendo uso de\r\n * $.rup.i18n.app.rup_select.blank. En caso de no definir ninguno,\r\n * se usará el genérico de UDA,\r\n * $.rup.i18n.base.rup_select.blankNotDefined.\r\n * @property {string} [token=\"|\"] - Define el separador a utilizar cuando se\r\n * muestra el valor asociado al select concatenado al literal.\r\n * @property {string} [multiValueToken=\"##\"] - Define el separador a\r\n * utilizar en selects enlazados locales.\r\n * @property {boolean} [ordered=true] - Indica si el select debe ordenarse.\r\n * @property {boolean} [orderedByValue=false] - Indica si el la ordenación\r\n * del seelct debe realizarse por el valor de los elementos en\r\n * lugar de por el texto.\r\n * @property {jQuery.rup_select~onLoadSuccess} [onLoadSuccess=null] - Función\r\n * de callback a ejecutar en el caso de que la petición de carga\r\n * de datos se haya producido correctamente.\r\n * @property {boolean} [loadFromSelect=false] - Determina si se debe de\r\n * utilizar los elementos option del elemento html sobre el que se\r\n * inicializa el componente para inicializar los datos del\r\n * elemento.\r\n * @property {boolean} [multiOptgroupIconText=false] - Indica si se desea\r\n * que en la selección múltiple con grupos, el nombre del grupo\r\n * tenga descripción en los iconos para seleccionar/deseleccionar\r\n * los elementos del grupo.\r\n * @property {boolean} [submitAsString=false] - Indica si el envío de los\r\n * elementos seleccionados en la selección múltiple se realiza\r\n * como un literal separados por coma.\r\n * @property {boolean} [submitAsJSON=false] - Indica si el envío de los\r\n * elementos seleccionados en la selección múltiple se realiza\r\n * como un array JSON donde el nombre del mapa será el nombre del\r\n * select. En el caso de que el nombre contenga notación dot se\r\n * tomará el último literal. Ej: [{id:1}, {id:2}, …].\r\n * @property {boolean} [readAsString=false] - Determina si la asignación de\r\n * un valor inicial se va a realizar a partir de un string con los\r\n * ids de los elementos separados por comas en vez de un array de\r\n * json.\r\n * @property {boolean} [rowStriping=false] - Indica si se debe aplicar un\r\n * estilo diferente a las filas pares e impares para poder\r\n * distinguirlas mediante un color diferente.\r\n * @property {number} [typeAhead=false] - Especifica en milisegundos el\r\n * tiempo de espera que toma el componente antes de procesar los\r\n * eventos de escritura realizados por el usuario.\r\n * @property {number} [legacyWrapMode=false] - Determina si se emplea el\r\n * método obsoleto a la hora de empaquetar en objetos json los\r\n * elementos seleccionados. Su propósito es mantener la\r\n * retrocompatibilidad.\r\n */\n\n $.fn.rup_select.defaults = {\n onLoadError: null,\n width: '100%',\n customClasses: ['select-material'],\n blank: \"-1\",\n minimumResultsForSearch: Infinity,\n submitAsJSON: false,\n dataType: 'json',\n cache: true,\n multiple: false,\n multiValueToken: '##'\n };\n});\n\nfunction chargedStyles(data) {\n if (data.style === undefined && data.element !== undefined) {\n // mirar estilo\n data.style = data.element.getAttribute('style');\n data.imgStyle = data.element.getAttribute('imgStyle');\n\n if (data.style == null || data.style == 'undefined') {\n data.style = undefined;\n }\n\n if (data.style == null || data.imgStyle == 'undefined') {\n data.imgStyle = undefined;\n }\n }\n}\n\nfunction udaMatcher(params, data) {\n // Always return the object if there is nothing to compare\n if ($.trim(params.term) === '') {\n return data;\n } // Do a recursive check for options with children\n\n\n if (data.children && data.children.length > 0) {\n // Clone the data object if there are children\n // This is required as we modify the object to remove any non-matches\n var match = $.extend(true, {}, data); // Check each child of the option\n\n for (var c = data.children.length - 1; c >= 0; c--) {\n var child = data.children[c];\n var matches = matcher(params, child); // If there wasn't a match, remove the object in the array\n\n if (matches == null) {\n match.children.splice(c, 1);\n }\n } // If any children matched, return the new object\n\n\n if (match.children.length > 0) {\n return match;\n } // If there were no matching children, check just the plain object\n\n\n return matcher(params, match);\n }\n\n var original = data.text.toUpperCase();\n var term = params.term.toUpperCase(); // Check if the text contains the term\n\n if (original.indexOf(term) > -1) {\n return data;\n } // If it doesn't contain the term, don't return anything\n\n\n return null;\n}\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\"), __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup.select.js?"); +eval("/* WEBPACK VAR INJECTION */(function(jQuery, global, $) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/* eslint-disable no-useless-escape */\n\n/*!\r\n * Copyright 2021 E.J.I.E., S.A.\r\n *\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n */\n\n/**\r\n * Permite al usuario recuperar un elemento de una gran lista de elementos o de\r\n * varias listas dependientes de forma sencilla y ocupando poco espacio en la\r\n * interfaz.\r\n * \r\n * @summary Componente RUP Select.\r\n * @module rup_select\r\n * @see El componente está basado en el plugin\r\n * {@link https://select2.org//|Select2}. Para mas información acerca de\r\n * las funcionalidades y opciones de configuración pinche\r\n * {@link https://select2.org//|aquí}.\r\n * @example $(\"#idSelect\").rup_select({ source : \"selectSimple/remote\",\r\n * sourceParam : {label:\"desc\"+$.rup_utils.capitalizedLang(),\r\n * value:\"code\", style:\"css\"} });\r\n */\n\n/* global define */\n\n/* global jQuery */\n(function (factory) {\n if (true) {\n // AMD. Register as an anonymous module.\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./rup.base */ \"./src/rup.base.js\"), __webpack_require__(/*! select2 */ \"./node_modules/select2/dist/js/select2.js\"), __webpack_require__(/*! ./external/select2MultiCheckboxes */ \"./src/external/select2MultiCheckboxes.js\")], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($) {\n // ****************************************************************************************************************\n // DEFINICIÓN BASE DEL PATRÓN (definición de la variable privada que\n // contendrá los métodos y la función de jQuery)\n // ****************************************************************************************************************\n var rup_select = {};\n var FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.functionNotSupportedError');\n var FUNCTION_NOT_SUPPORTED_ERROR_TITLE = $.rup.i18nParse($.rup.i18n.base, 'rup_global.error'); // Se configura el arranque de UDA para que alberge el nuevo patrón\n\n $.extend($.rup.iniRup, $.rup.rupSelectorObjectConstructor('rup_select', rup_select)); // *******************************\n // DEFINICIÓN DE MÉTODOS PÚBLICOS\n // *******************************\n\n $.fn.rup_select('extend', {\n /**\r\n * Método utilizado para obtener el valor del componente. Este método es\r\n * el utilizado por el resto de componentes RUP para estandarizar la\r\n * obtención del valor del select.\r\n * \r\n * @function getRupValue\r\n * @return {string | number} - Devuelve el valor actual del componente\r\n * seleccionado por el usuario.\r\n * @example $(\"#idSelect\").rup_select(\"getRupValue\");\r\n */\n getRupValue: function getRupValue() {\n var $self = $(this),\n settings = $self.data('settings'),\n value;\n var values = $self.select2('data');\n\n if (values == undefined || values.length == 0) {\n value = '';\n } else if (values.length == 1) {\n value = values[0].id;\n } else {\n value = [];\n $.each(values, function (ind, elem) {\n value.push(elem.id);\n });\n }\n\n if (settings !== undefined && settings.submitAsJSON !== undefined && settings.submitAsJSON) {\n var name = $self.attr('name');\n\n if (name == undefined) {\n name = $self.attr('id');\n }\n\n return jQuery.rup_utils.getRupValueAsJson(name, value);\n }\n\n return value;\n },\n\n /**\r\n * Método utilizado para asignar el valor al componente. Este método es\r\n * el utilizado por el resto de componentes RUP para estandarizar la\r\n * asignación del valor al Select.\r\n * \r\n * @function setRupValue\r\n * @param {string |\r\n * number} param - Valor que se va a asignar al componente.\r\n * @example $(\"#idSelect\").rup_select('setRupValue', 'Si');\r\n */\n setRupValue: function setRupValue(param) {\n var $self = $(this),\n settings = $self.data('settings'); // Tipo de select\n\n if (this.length === 0 || settings !== undefined && !settings.multiple) {\n var texto = undefined; // normal.\n // Simple\n\n if (settings !== undefined && settings.data === undefined && settings.options !== undefined) {\n // si\n // es\n // remoto\n // crear\n // el\n // option\n var data = {};\n\n if (settings.groups) {\n data = $.grep(settings.optionsGroups, function (v) {\n return v.nid === param || v.id == param;\n });\n } else {\n data = $.grep(settings.options, function (v) {\n return v.nid === param || v.id == param;\n });\n }\n\n if (data[0] !== undefined) {\n if ($('#' + settings.id).find(\"option[value='\" + data[0].id + \"']\").length == 0) {\n data = data[0];\n\n _this._createOption(settings, data);\n\n param = data.id; // mantenga el cifrado\n\n texto = data.text;\n } else {\n param = data[0].id; // mantenga el cifrado\n\n texto = data[0].text;\n }\n }\n }\n\n var dataSelect2 = $self.data('select2');\n\n if (dataSelect2 !== undefined) {\n if (dataSelect2.$selection.find('input').length == 1) {\n dataSelect2.$selection.find('input').val('');\n }\n\n var $search = dataSelect2.dropdown.$search || dataSelect2.selection.$search;\n\n if ($search != undefined && texto !== undefined) {\n //sifnifica que esta abierto\n var lis = dataSelect2.dropdown.$dropdown.find('li');\n var selectedDate = $.grep(lis, function (v) {\n return $(v).text() === texto;\n });\n lis.attr('aria-selected', false);\n $(selectedDate).attr('aria-selected', true);\n }\n\n $self.val(param).trigger('change');\n $('#' + settings.id).rup_select('change');\n }\n } else {\n // Multiple > multiselect - falta\n if (_typeof(param) === 'object' && settings.options !== undefined) {\n // si\n // es\n // remoto\n // crear\n // el\n // option\n var arrayDatos = [];\n $.each(param, function (key, value) {\n var data = {};\n\n if (settings.groups) {\n data = $.grep(settings.optionsGroups, function (v) {\n return v.nid === value || v.id == value;\n });\n } else {\n data = $.grep(settings.options, function (v) {\n return v.nid === value || v.id == value;\n });\n }\n\n if (data[0] != undefined && $('#' + settings.id).find(\"option[value='\" + data[0].id + \"']\").length == 0) {\n data = data[0];\n\n _this._createOption(settings, data);\n\n arrayDatos.push(data.id);\n } else {\n arrayDatos.push(value);\n }\n });\n $('#' + settings.id).val(arrayDatos).trigger('change');\n }\n }\n },\n\n /**\r\n * Método que limpia el valor seleccionado en el select. En el caso de\r\n * selección múltiple los valores seleccionados.\r\n * \r\n * @function clear\r\n * @example $(\"#idSelect\").rup_select(\"clear\");\r\n */\n clear: function clear() {\n var $self = $(this); // init de select\n\n if (this.length > 0) {\n // Simple y multi\n if ($self.data('settings').blank !== undefined) {\n $self.val($self.data('settings').blank).trigger('change');\n } else {\n $self.val(null).trigger('change');\n }\n }\n },\n\n /**\r\n * Método que lanza el evento change del componente.\r\n * \r\n * @function change\r\n * @example $(\"#idSelect\").rup_select(\"change\");\r\n */\n change: function change() {\n // Tipo de select\n if ($(this).data('settings').change) {\n $(this).data('settings').change();\n }\n },\n\n /**\r\n * Selecciona todos los elementos en el caso de tratarse de un select\r\n * multilesección.\r\n * \r\n * @function checkAll\r\n * @example $(\"#idSelect\").rup_select(\"checkAll\");\r\n */\n checkAll: function checkAll() {\n // Tipo de select\n if ($(this).data('settings').multiple) {\n // Multiple > multiselect\n var selectedItems = [];\n var allOptions = $(\"#\" + $(this)[0].id + \" option\");\n allOptions.each(function () {\n selectedItems.push($(this).val());\n });\n $(this).rup_select('setRupValue', selectedItems);\n } else {\n // Simple > selectmenu\n alert('Función no soportada.');\n }\n },\n\n /**\r\n * Selecciona el elemento del select que contiene como texto el\r\n * indicado. En caso de no existir el texto a buscar el se no sufrirá\r\n * cambios En el caso de selección múltiple el parámetro será un array.\r\n * \r\n * @function selectByLabel\r\n * @param {string |\r\n * string[]} param - Parámetro utilzado para determinar los\r\n * elementos a seleccionar.\r\n * @example // Simple $(\"#idSelect\").rup_select(\"selectByLabel\", \"No\"); //\r\n * Multiple $(\"#idSelect\").rup_select(\"selectByLabel\",\r\n * [\"No\",\"Si\"]);\r\n */\n selectByLabel: function selectByLabel(param) {\n // Tipo de select\n var settings = $(this).data('settings');\n\n if (settings.options !== undefined) {\n var options = settings.options;\n\n if (settings.groups) {\n options = settings.optionsGroups;\n }\n\n if (!settings.multiple) {\n // Simple > selectmenu\n var data = $.grep(options, function (v) {\n return v.text === param;\n });\n\n if (data[0] !== undefined) {\n $(this).rup_select('setRupValue', data[0].id);\n }\n } else {\n // Ejemplo\n // $('#idSelect').rup_select('selectByLabel',['php_value','java_value'])\n var datos = [];\n $.each(param, function (key, value) {\n var data = $.grep(options, function (v) {\n return v.text === value;\n });\n\n if (data[0] !== undefined) {\n datos.push(data[0].id);\n }\n });\n $(this).rup_select('setRupValue', datos);\n }\n }\n },\n\n /**\r\n * Selecciona el elemento enviado como parámetro. En caso de ser un numérico se selecciona por la posición (comenzando en 0) y si es un literal se selecciona por el valor. En el caso de selección múltiple el parámetro será un array.\r\n *\r\n * @function select\r\n * @param {string | number | string[] | number[]} param - Parámetro utilzado para determinar los elementos a seleccionar.\r\n * @example\r\n * // Simple\r\n * $(\"#idSelect\").rup_select(\"select\", 2);\r\n * // Multiple\r\n * $(\"#idSelect\").rup_select(\"select\", [0,2]);\r\n */\n select: function select(param) {\n var settings = $(this).data().settings;\n var datas = settings.data || settings.options;\n\n if (settings.groups) {\n datas = settings.optionsGroups;\n }\n\n if (settings.multiple) {\n var datos = [];\n $.each(param, function (key, value) {\n if (datas.length >= value) {\n datos.push(datas[value].id);\n }\n });\n $(this).rup_select('setRupValue', datos);\n } else {\n if (datas.length >= param) {\n $(this).rup_select('setRupValue', datas[param].id);\n }\n }\n },\n\n /**\r\n * Método que devuelve el label asociado al valor seleccionado en el\r\n * select. En el caso de la selección múltiple se devolverá un array.\r\n * \r\n * @function label\r\n * @return {string | string[]} - Texto del elemento o elementos\r\n * seleccionado.\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n label: function label() {\n // Tipo de select\n var data = $(this).select2('data');\n\n if (!$(this).data('settings').multiple) {\n return data[0].text;\n } else {\n // Multiple > multiselect\n var retorno = [];\n\n for (var i = 0; i < data.length; i++) {\n retorno.push(data[i].text);\n }\n\n return retorno;\n }\n },\n\n /**\r\n * Devuelve el índice de la opción seleccionada en el select (empezando\r\n * en 1). En el caso de la selección múltiple se devolverá un array.\r\n * \r\n * @function index\r\n * @return {number | number[]} - Índice del elemento o elementos\r\n * seleccionados.\r\n * @example $(\"#idSelect\").rup_select(\"index\");\r\n */\n index: function index() {\n // Tipo de select\n var settings = $(this).data('settings');\n\n if (settings.options !== undefined) {\n var options = settings.options;\n\n if (settings.groups) {\n options = settings.optionsGroups;\n }\n\n var count = 0;\n var data = $(this).select2('data');\n\n if (!settings.multiple) {\n // Simple > selectmenu\n $.each(options, function (key, value) {\n if (settings.blank !== value.id.toString()) {\n count = count + 1;\n }\n\n if (value.id.toString() === data[0].id.toString()) {\n return false;\n }\n });\n } else {\n var listaCount = [];\n $.each(data, function (key, value) {\n count = 0;\n $.each(options, function (cont, valor) {\n if (settings.blank !== value.id.toString()) {\n count = count + 1;\n }\n\n if (value.id.toString() === valor.id.toString()) {\n listaCount.push(count);\n return false;\n }\n });\n });\n return listaCount;\n }\n\n return count;\n }\n },\n\n /**\r\n * Deshabilita el select.\r\n * \r\n * @function disable\r\n * @example $(\"#idSelect\").rup_select(\"disable\");\r\n */\n disable: function disable() {\n // Tipo de select\n var $self = $(this);\n $self.prop(\"disabled\", true);\n },\n\n /**\r\n * Habilita el select.\r\n * \r\n * @function enable\r\n * @example $(\"#idSelect\").rup_select(\"enable\");\r\n */\n enable: function enable() {\n var $self = $(this);\n $self.prop(\"disabled\", false);\n },\n\n /**\r\n * Indica si el select está deshabilitado o no.\r\n * \r\n * @function isDisabled\r\n * @param {boolean} -\r\n * Devuelve si el select está deshabilitado o no.\r\n * @example $(\"#idSelect\").rup_select(\"isDisabled\");\r\n */\n isDisabled: function isDisabled() {\n if ($(this).attr('disabled') === 'disabled') {\n return true;\n } else {\n return false;\n }\n },\n\n /**\r\n * Realiza una recarga de los select.\r\n * \r\n * @function reload\r\n * @example $(\"#idSelect\").rup_select(\"reload\");\r\n */\n reload: function reload(removeOptions) {\n var settings = $(this).data('settings');\n $(this).select2(\"destroy\");\n\n if (removeOptions) {\n $(this).find('option').remove();\n }\n\n $(this).rup_select(settings);\n },\n\n /**\r\n * Cambia el source del select y recarga el componente para que este\r\n * comience a usarlo.\r\n * \r\n * @function setSource\r\n * @param {string}\r\n * source - Source desde el cual se obtendran los datos a\r\n * sourceParam - Se puede cambiar los parámetros de la cabecera..\r\n * @example $(\"#idSelect\").rup_select(\"setSource\", source, sourceParam);\r\n */\n setSource: function setSource(source, sourceParam) {\n if (source !== undefined && source !== '') {\n var $self = $(this);\n var settings = $self.data().settings;\n var dataSelect2 = $self.data('select2');\n\n if ($self.data().settings.data === undefined) {\n // remoto\n dataSelect2.dataAdapter.ajaxOptions.url = source;\n\n if (sourceParam != undefined) {\n dataSelect2.dataAdapter.ajaxOptions.headers = $.toJSON(sourceParam);\n }\n } else {\n // local\n settings.data = source;\n settings.options = undefined;\n $self.data('settings', settings);\n\n if (dataSelect2.$selection != undefined) {\n dataSelect2.$selection.find('input').val('');\n }\n\n $self.empty();\n\n if (settings.data !== undefined && settings.autocomplete) {\n $.each(settings.data, function () {\n _this._createOption(settings, this);\n });\n } else {\n $self.select2({\n data: settings.data\n });\n }\n }\n\n $self.rup_select('reload');\n }\n },\n\n /**\r\n * Método que devuelve los datos, de los elementos seleccionados.\r\n * \r\n * @function getDataSelected\r\n * @return {string | string[]} - Texto del elemento o elementos\r\n * seleccionado.\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n getDataSelected: function getDataSelected() {\n // Tipo de select\n var data = $(this).select2('data');\n\n if (!$(this).data('settings').multiple) {\n //Validar que venga el nid\n if (data[0] != undefined && data[0].nid == undefined && $(this).data('settings').options != undefined) {\n var seleccionado = $.grep($(this).data('settings').options, function (v, index) {\n return v.id === data[0].id;\n });\n\n if (seleccionado != undefined && seleccionado.length == 1) {\n data[0].nid = seleccionado[0].nid;\n }\n }\n\n return data[0];\n } else {\n return data;\n }\n },\n\n /**\r\n * Método que añade un option al select en local\r\n * \r\n * @function addOption\r\n * id:\tidentificador del nuevo option\r\n * text: texto del nuevo option\r\n * label: en Caso de ser grupos, el label donde se va a meter(obligatorio)\r\n * @example $(\"#idSelect\").rup_select(\"label\");\r\n */\n addOption: function addOption(id, text, label) {\n // Tipo de select\n var newOpt = new Option(id, text);\n\n if ($(this).data('settings').groups && label != undefined) {\n var options = $(this).data('select2').options.options;\n $(this).find('optgroup[label=\"' + label + '\"]').append(newOpt);\n var seleccionado = $.grep(options.data, function (v, index) {\n return v.text === label;\n });\n\n if (seleccionado != undefined && seleccionado.length == 1) {\n seleccionado[0].children[seleccionado[0].children.length] = {\n id: id,\n text: text\n };\n }\n } else {\n $(this).append(newOpt);\n }\n },\n\n /**\r\n * Deshabilita una opción de un select multiselección.\r\n *\r\n * @function disableOpt\r\n * @param {string} optValue - Value del option que queremos deshabilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"disableOpt\", \"opt1\");\r\n */\n disableOpt: function disableOpt(optValue) {\n if ($(this).data('settings').multiple) {\n //Deshabilitar select\n this.find('[value=\\'' + optValue + '\\']').attr('disabled', 'disabled'); //Si pertenece a OptGroup y es el último en deshabilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(),\n inputs = li.nextUntil('li.ui-multiselect-optgroup-label').find('input'),\n allDisabled = true;\n\n for (var i = 0; i < inputs.length; i++) {\n if (!inputs[i].disabled) {\n allDisabled = false;\n break;\n }\n }\n\n if (allDisabled) {\n //Estilos optGroup\n li.css('color', 'grey');\n li.children('a').remove();\n li.children('span').not('.rup-combo_multiOptgroupLabel').remove();\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Deshabilita varias opciones del select. Las opciones se identifican mediante un array.\r\n *\r\n * @function disableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a deshabilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"disableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n disableOptArr: function disableOptArr(optValueArr) {\n if ($(this).data('settings').multiple) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_select('disableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita una opción de un select multiselección.\r\n *\r\n * @function enableOpt\r\n * @param {string} enableOpt - Value del option que queremos habilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"enableOpt\", \"opt1\");\r\n */\n enableOpt: function enableOpt(optValue) {\n if ($(this).data('settings').multiple) {\n //Habilitar select\n this.find('[value=\\'' + optValue + '\\']').removeAttr('disabled');\n var obj = $('#rup-multiCombo_' + $(this).attr('id')).find('[value=\\'' + optValue + '\\']'); //Habilitar input\n\n obj.removeAttr('disabled'); //Estilos línea (label)\n\n obj.parent().css('color', 'black'); //Si pertenece a OptGroup y es el primero en habilitarse > Cambiar estilos optGroupLabel\n\n if ($(this).data('settings').sourceGroup != undefined) {\n //Obtener inicio optGroup\n var li = obj.parentsUntil('ul').last().prevAll('li.ui-multiselect-optgroup-label').first(); //Estilos optGroup\n\n if (li.children('a').length === 0) {\n li.css('color', 'black');\n\n this._generateOptGroupLabel(li, $(this).data('settings').multiOptgroupIconText);\n }\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Habilita varias opciones del select. Las opciones se identifican mediante un array.\r\n *\r\n * @function enableOptArr\r\n * @param {string[]} optValueArr - Array en el que se indican los values de las opciones a habilitar.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"enableOptArr\", [\"opt1\",\"opt2\"]);\r\n */\n enableOptArr: function enableOptArr(optValueArr) {\n if ($(this).data('settings').multiple) {\n for (var i = 0; i < optValueArr.length; i++) {\n $(this).rup_select('enableOpt', optValueArr[i]);\n }\n } else {\n $.rup.errorGestor(FUNCTION_NOT_SUPPORTED_ERROR_MESSAGE, FUNCTION_NOT_SUPPORTED_ERROR_TITLE);\n }\n },\n\n /**\r\n * Ordena alfanumericamente y en orden ascendente el combo sobre el que se aplica. Se invoca por defecto al cargarse los combos a no ser que se cambie el valor del atributo ordered en la creación.\r\n *\r\n * @function order\r\n * @param {boolean} orderedByValue - Indica si la búsqueda es por texto (por defecto) o si la búsqueda es por el valor.\r\n * @param {boolean} orderAsNumber - Indica si se debe ordenar como valores numéricos en vez de alfabéticos.\r\n * @param {boolean} skipFirst - Determina si se debe obviar el primer elemento.\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"order\", orderedByValue, orderAsNumber, skipFirst);\r\n */\n order: function order(groups, orderedByValue, orderAsNumber) {\n /* Get options */\n var selector = $(this).data('select2') || $(this).parent().data('select2');\n var settings = selector.options.options;\n\n if (groups) {\n $(this).find('optgroup').each(function () {\n $(this).rup_select('order', false, orderedByValue, orderAsNumber);\n }); //Order children\n\n if (settings.data != undefined) {\n $(settings.data).each(function () {\n if (this.children != undefined && this.children.length > 0) {\n this.children = this.children.sort(function (a, b) {\n return a.text.localeCompare(b.text);\n });\n }\n });\n }\n } else {\n var selectList = $(this).find('option').not('[value=' + settings.blank + ']');\n var option = $(this).find('option[value=' + settings.blank + ']');\n /* Order by innerText (case insensitive) */\n\n selectList.sort(function (a, b) {\n return a.innerText.localeCompare(b.innerText);\n });\n /* Re-do select HTML */\n\n $(this).html(selectList);\n\n if (option.length == 1) {\n $(this).prepend(option);\n }\n }\n },\n\n /**\r\n * Lanza una búsqueda en el autocomplete con el parámetro indicado y el foco va a parar al input.\r\n *\r\n * @param {string} term - Cadena de texto utilizada para realizar la búsqueda.\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function search\r\n * \r\n * @example\r\n * $(\"#idSelect\").rup_select(\"search\", \"java\");\r\n */\n search: function search(term, notOthersClose) {\n var $search = $(this).data('select2').dropdown.$search || $(this).data('select2').mySelect.selection.$search;\n\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).data('select2').$container.find('input').val(term);\n\n if ($search != undefined) {\n $search.val(term);\n $search.trigger('keyup');\n }\n },\n\n /**\r\n * Permite consultar y modificar la configuración del componente.\r\n *\r\n * @param {string | object} optionName - Nombre de la propiedad que se desea gestionar o objeto de compuesto de varias propiedades.\r\n * @param {*} [value] - Corresponde al valor de la propiedad en caso de haberse especificado el nombre de la misma en el primér parámetro.\r\n * @param {*} aux - Parámetro extra de confirguración para la propiedad \"source\".\r\n * @function option\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", \"minLegth\", 2);\r\n * // Establecer varias propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", {minLegth:2, delay:1000});\r\n */\n option: function option(optionName, value, removeOptions) {\n var settings = $(this).data('settings');\n settings[optionName] = value;\n $(this).select2(\"destroy\");\n\n if (removeOptions) {\n $(this).find('option').remove();\n }\n\n $(this).rup_select(settings);\n },\n\n /**\r\n * Permite abrir el componente.\r\n *\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function open\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", true);\r\n */\n open: function open(notOthersClose) {\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).select2('open');\n },\n\n /**\r\n * Permite cerrar el componente.\r\n *\r\n * @param {boolean} notOthersClose - Si deseas cerrar el resto de componentes.\r\n * @function close\r\n * @example\r\n * // Establecer una propiedad\r\n * $(\"#idSelect\").rup_select(\"option\", true);\r\n */\n close: function close(notOthersClose) {\n if (!notOthersClose) {\n $('.select2-hidden-accessible').select2('close');\n }\n\n $(this).select2('close');\n },\n\n /**\r\n * Elimina el autocomplete.\r\n *\r\n * @function destroy\r\n * @example\r\n * $(\"#idSelect\").rup_select(\"destroy\");\r\n */\n destroy: function destroy(notRemoveOptions) {\n $(this).select2(\"destroy\");\n\n if (!notRemoveOptions) {\n $(this).find('option').remove();\n }\n }\n }); // *******************************\n // DEFINICIÓN DE MÉTODOS PRIVADOS\n // *******************************\n\n $.fn.rup_select('extend', {\n /**\r\n * Selecciona el elemento correspondiente al label indicado\r\n * \r\n * @function _selectLabel\r\n * @private\r\n * @param {object}\r\n * selector - Referencia al objeto jQuery del select.\r\n * @param {object}\r\n * param - Value correspondiente.\r\n */\n _selectLabel: function _selectLabel(selector, param) {\n var $option;\n\n for (var i = 0; i < $('option', selector).length; i = i + 1) {\n $option = jQuery(selector).find('option').eq(i);\n\n if (jQuery(selector).find('option').eq(i).text() === param) {\n $(selector).selectmenu('index', $option.prop('index'));\n return true;\n }\n }\n\n return false;\n },\n\n /**\r\n * Obtener la opción vacía a partir del fichero de internacionalización\r\n * de la aplicación o del fichero por defecto.\r\n * \r\n * @function _getBlankLabel\r\n * @private\r\n * @param {string}\r\n * id - Identificador del fichero\r\n */\n _getBlankLabel: function _getBlankLabel(id) {\n var app = $.rup.i18n.app; // Comprueba si el select tiene su propio texto personalizado\n\n if (app[id] && app[id]._blank) {\n return app[id]._blank;\n } // Comprueba si la aplicacion tiene un texto definido para todos los\n // blank\n else if (app.rup_select && app.rup_select.blank) {\n return app.rup_select.blank;\n } // Si no hay textos definidos para los blank obtiene el por defecto\n // de UDA\n\n\n return $.rup.i18n.base.rup_select.blankNotDefined;\n },\n\n /**\r\n * Obtener valores de los selects padres (si no están cargados o valores\r\n * 'vacíos' devuelve null). En caso de disponer de varios selects padres\r\n * se devolverán separados por un caracter delimitador.\r\n * \r\n * @function _getParentsValues\r\n * @private\r\n * @param {object[]}\r\n * settings - Array con los elementos de configuración.\r\n * @param {boolean}\r\n * remote - Determina si la fuente de datos es remota o no.\r\n * @return {string} - Devuelve los values seleccionados de los selects\r\n * padres.\r\n */\n _getParentsValues: function _getParentsValues(settings, remote, multiValueToken) {\n var retorno = '';\n var parent = [];\n\n if (settings.parent == undefined) {\n return '';\n }\n\n if (typeof settings.parent == 'string') {\n parent.push(settings.parent);\n } else {\n parent = settings.parent;\n }\n\n var parentsFull = 0;\n $.each(parent, function (idx, parentId) {\n if (parentId != undefined && $('#' + parentId).val() != null && $('#' + parentId).val().trim() !== '') {\n if (settings.blank == $('#' + parentId).val()) {\n retorno = '';\n } else {\n if (remote) {\n // PAra remoto\n retorno += $('#' + parentId).attr('name') + '=' + $('#' + parentId).val() + '&';\n } else {\n // PAra local\n if (retorno != '') {\n retorno = retorno + multiValueToken + $('#' + parentId).val();\n } else {\n retorno = $('#' + parentId).val();\n }\n }\n\n parentsFull = parentsFull + 1;\n }\n }\n });\n\n if (parentsFull < parent.length) {\n // si no estan todos los padres no\n // se busca.\n return '';\n } // Evitar & o multiValueToken finales\n\n\n if (retorno !== '' && remote) {\n retorno = retorno.substring(0, retorno.length - 1);\n }\n\n return retorno;\n },\n\n /**\r\n * Procesa el conjunto de registros devueltos por una petición sobre un\r\n * origen de datos local.\r\n * \r\n * @function _parseLOCAL\r\n * @private\r\n * @param {object[]}\r\n * data - Array de registros obtenidos a partir del origen de\r\n * datos.\r\n * @param {object}\r\n * i18nId - Opciones de idioma.\r\n * @param {jQuery}\r\n * isParent - Si tiene datos en forma parent.\r\n */\n _parseLOCAL: function _parseLOCAL(data, i18nId, isParent) {\n var text;\n var array = data;\n\n if (isParent) {\n // Si es padre llamar a la recursividad\n if (Array.isArray(data)) {\n data = data[0];\n }\n\n $.each(data, function (key, value) {\n data[key] = _this._parseLOCAL(data[key], i18nId, false);\n });\n } else {\n data = [];\n\n for (var i = 0; i < array.length; i = i + 1) {\n if (_typeof(array[i]) === 'object') {\n // multi-idioma\n if (array[i].i18nCaption) {\n text = $.rup.i18nParse($.rup.i18n.app[i18nId], array[i].i18nCaption);\n } else {\n text = array[i].text;\n }\n\n array[i].text = text;\n } else {\n // El id es el mismo que el texto.\n data[i] = {\n id: array[i],\n text: array[i]\n };\n }\n }\n\n if (data.length > 0) {\n // El id es el mismo que el texto.\n return data;\n }\n }\n\n return array;\n },\n\n /**\r\n * Procesa el conjunto de registros devueltos por una petición sobre un\r\n * origen de datos remoto.\r\n * \r\n * @function _parseRemoteGroup\r\n * @private\r\n * @param {object[]}\r\n * array - Array de registros obtenidos a partir del origen\r\n * de datos.\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n */\n _parseRemoteGroup: function _parseRemoteGroup(array, settings) {\n var item;\n var data = [];\n\n for (var i = 0; i < array.length; i = i + 1) {\n item = array[i];\n var key = Object.keys(item)[0];\n var dato = {};\n dato.text = key;\n dato.children = item[key];\n dato.id = \"group__\" + i;\n data.push(dato);\n }\n\n return data;\n },\n\n /**\r\n * Prepara la petición AJAX que se va a realizar para obtener los\r\n * registros a partir de un origen remoto. Se añaden las cabeceras RUP\r\n * correspondientes para realizar la serialización json de manera\r\n * correcta.\r\n * \r\n * @function _ajaxBeforeSend\r\n * @private\r\n * @param {object}\r\n * xhr - Objeto xhr que se va a enviar en la petición\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n * @param {jQuery}\r\n * html - Referencia al objeto jQuery que contiene los\r\n * elementos.\r\n */\n _ajaxBeforeSend: function _ajaxBeforeSend(xhr, settings, html) {\n // Crear select (vacío) y deshabilitarlo\n if (html !== undefined) {\n $('#' + settings.id).replaceWith(html);\n } // Si no es 'reload' se debe inicializar vacío\n\n\n $('#' + settings.id).rup_select('disable'); // LOADING...\n\n $('#' + settings.id + '-button span:first-child').removeClass(\"ui-icon ui-icon-triangle-1-s\").addClass('rup-select_loadingText').text($.rup.i18n.base.rup_select.loadingText);\n var icon = $('#' + settings.id + '-button span:last-child');\n $(icon).removeClass('ui-icon-triangle-1-s');\n $(icon).text(''); // Evita errores de visualización con el icono\n\n $(icon).addClass('rup-select_loading'); // Cabecera RUP\n\n xhr.setRequestHeader('RUP', $.toJSON(settings.sourceParam));\n },\n\n /**\r\n * Procesa la respuesta de la petición AJAX en el caso de que se haya\r\n * producido un error en la misma.\r\n * \r\n * @function _ajaxError\r\n * @private\r\n * @param {object}\r\n * xhr - Objeto xhr enviado en la respuesta.\r\n * @param {string}\r\n * textStatus - Cadena identificadora del error que se ha\r\n * producido en la petición.\r\n * @param {object}\r\n * errorThrown - Objeto error correspondiente al que se ha\r\n * producido en la petición.\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n */\n _ajaxError: function _ajaxError(xhr) {\n if (xhr.responseText !== null && xhr.responseTex !== undefined && xhr.responseText.length < 200) {\n $.rup.showErrorToUser(xhr.responseText);\n } else {\n $.rup.showErrorToUser($.rup.i18n.base.rup_select.ajaxError);\n }\n },\n\n /**\r\n * Carga la opción remoto.\r\n * \r\n * @function _loadRemote\r\n * @private\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con\r\n * el que se ha inicializado el componente.\r\n * @return {jQuery} - Objeto jQuery con referencia al elemento que\r\n * contiene el foco.\r\n */\n _loadRemote: function _loadRemote(settings, first) {\n var rupSelect = this;\n settings.ajax = {\n url: function url() {\n return rupSelect._generateUrl(settings, _this._getParentsValues(settings, true));\n },\n dataType: settings.dataType,\n processResults: function processResults(response) {\n // Require id y text, podemos permitir que no venga.\n if (settings.placeholder != undefined && !settings.multiple) {\n var elBlank = response.find(function (x) {\n return x.id == settings.blank;\n });\n\n if (elBlank == undefined && !settings.autocomplete) {\n response.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n }\n }\n\n if (settings.groups) {\n // PArsear para grupos.\n var results = [];\n $.each(response, function (index, value) {\n var key = Object.keys(value)[0];\n results[index] = {\n 'text': key,\n 'children': value[key]\n };\n });\n response = results;\n }\n\n settings.options = response;\n $('#' + settings.id).data('settings', settings);\n return {\n results: response\n };\n },\n cache: false,\n data: function data() {\n // Es necesario enviarlo vacío para que el componente subyacente no genere parámetros extra que Hdiv bloqueará.\n //se hará en el transport\n return _this._getParentsValues(settings, true);\n },\n error: function error(xhr, textStatus, errorThrown) {\n if (settings.onLoadError !== null) {\n jQuery(settings.onLoadError(xhr, textStatus, errorThrown));\n } else {\n if (textStatus != 'abort') {\n //Si se hacen 2 llamadas se cancela la primera.\n rupSelect._ajaxError(xhr, textStatus, errorThrown);\n }\n\n console.log(textStatus);\n }\n }\n };\n\n if (settings.selected || settings.autocomplete && settings.defaultValue != undefined) {\n settings.firstLoad = true;\n }\n\n if (settings.parent != undefined && ($('#' + settings.parent).val() == null || $('#' + settings.parent).val().trim() === '')) {\n settings.firstLoad = false;\n }\n\n var __cache = [];\n var __lastQuery = null;\n\n settings.ajax.transport = function (params, success, failure) {\n // retrieve the cached key or default to _ALL_\n var __cachekey = params.data || '_ALL_'; //Se actualiza el data, para mantener la misma función, con hdiv ya no se mandan los data\n\n\n if (!settings.autocomplete) {\n params.data = \"\";\n }\n\n var mySelect = $('#' + settings.id).data('select2');\n\n if (settings.autocomplete) {\n params.data.q = mySelect.$container.find('input').val();\n __cachekey = params.data.q;\n }\n\n if (__lastQuery !== __cachekey) {\n // remove caches not from last query\n __cache = [];\n }\n\n __lastQuery = __cachekey; //Si esta cacheado, no busca\n\n if (settings.cache == true && 'undefined' !== typeof __cache[__cachekey]) {\n // display the cached results\n success(__cache[__cachekey]);\n return;\n }\n\n mySelect.$results.find('li').addClass('disabledButtonsTable');\n mySelect.$selection.find('input').addClass('disabledButtonsTable');\n mySelect.$selection.find('input').blur(); //Si tiene padres deshabilitarlos\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"disable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"disable\");\n });\n }\n }\n\n var $request = undefined;\n\n if (settings.autocomplete) {\n //Meter busqueda accentFolding\n var term = '';\n term = params.data.q;\n term = term.replace(/%/g, '\\\\%').replace(/_/g, '\\\\_');\n params.data = $.extend({\n q: term,\n c: settings.contains\n }, settings.extraParams);\n }\n\n if (settings.parent) {\n var datosParent = _this._getParentsValues(settings, true);\n\n if (datosParent != '') {\n if (settings.autocomplete) {\n //añadir el data del padre\n var padres = datosParent.split('&'); //split por si tiene varios padres\t\n\n $.each(padres, function () {\n if (this !== undefined) {\n var cad = this.split('=');\n\n if (cad != undefined && cad.length > 0) {\n params.data[cad[0]] = cad[1];\n __cachekey = __cachekey + cad[1]; //se añade la parte del padre\n }\n }\n });\n }\n\n $request = $.ajax(params);\n }\n } else {\n $request = $.ajax(params);\n }\n\n if ($request != undefined) {\n $request.then(function (data) {\n // Vuelve la peticion\n // store data in cache\n __cache[__cachekey] = data; // display the results\n\n $('#' + settings.id).rup_select(\"enable\"); //Si tiene padres deshabilitarlos\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"enable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"enable\");\n });\n }\n }\n\n success(__cache[__cachekey]); // Actualizar seleccionado en la lista//css\n\n var positions = [];\n var valueSelect = $('#' + settings.id).rup_select('getRupValue');\n\n if (settings.groups) {\n var i;\n\n (function () {\n // Parseo de grupos para\n // seleccionar\n var allFacts = []; // grupos\n\n for (i = 0; i < data.length; i = i + 1) {\n if (_typeof(data[i]) === 'object') {\n $.each(data[i], function (key, value) {\n if (_typeof(value) === 'object') {\n $.each(value, function () {\n allFacts.push(this);\n });\n }\n });\n }\n }\n\n data = allFacts;\n settings.optionsGroups = data;\n })();\n }\n\n var seleccionado = $.grep(data, function (v, index) {\n if (v.id == valueSelect) {\n positions.push(index);\n }\n\n return v.nid == settings.selected || v.id == settings.selected;\n });\n\n if ($('#' + settings.id).rup_select('getRupValue') != '') {\n seleccionado = $.grep(data, function (v) {\n return v.id == $('#' + settings.id).rup_select('getRupValue');\n });\n } // Si es el mismo, no cambia porque esta abirendo\n\n\n var mySelect = $('#' + settings.id).data('select2');\n\n if (seleccionado !== undefined && seleccionado.length == 1 && $('#' + settings.id).rup_select('getRupValue') != seleccionado[0].id) {\n if (settings.multiple) {\n // Revisar varios selects\n $('#' + settings.id).rup_select('setRupValue', [seleccionado[0].id]);\n } else {\n $('#' + settings.id).rup_select('setRupValue', seleccionado[0].id);\n }\n\n $.each(positions, function (index, valor) {\n var $option = mySelect.$results.find('li')[valor];\n\n if ($option != undefined) {\n $($option).attr('aria-selected', 'true');\n }\n });\n } else {\n if (settings.autocomplete) {\n var valorInput = mySelect.selection.$selection.find('input').val();\n $('#' + settings.id).rup_select('setRupValue', settings.blank);\n mySelect.selection.$selection.find('input').val(valorInput);\n mySelect.selection.$selection.find('input').focus();\n } else {\n $('#' + settings.id).rup_select('setRupValue', settings.blank);\n }\n }\n\n if (settings.onLoadSuccess !== null && settings.onLoadSuccess !== undefined) {\n jQuery(settings.onLoadSuccess($('#' + settings.id)));\n }\n\n $('#' + settings.id).data('settings', settings);\n $('#' + settings.id).triggerHandler('selectAjaxSuccess', [data]);\n\n if (settings.firstLoad) {\n if (settings.autocomplete && settings.selected == undefined && settings.defaultValue != undefined && data != undefined && ($('#' + settings.id).rup_select('getRupValue') == '' || $('#' + settings.id).rup_select('getRupValue') == settings.blank)) {\n //setear el valor para el defaultValue\n var datos2 = $.grep(data, function (v) {\n return v.text.toUpperCase() === settings.defaultValue.toUpperCase();\n });\n\n if (datos2[0] != undefined) {\n $('#' + settings.id).rup_select('setRupValue', datos2[0].id);\n }\n }\n\n settings.firstLoad = false;\n settings.selected = '';\n }\n });\n $request.fail(failure);\n } else {\n // cerrar\n $('#' + settings.id).select2('close');\n\n if (settings.parent) {\n if (typeof settings.parent === 'string') {\n $('#' + settings.parent).rup_select(\"enable\");\n } else {\n $.each(settings.parent, function (ind, elem) {\n $('#' + elem).rup_select(\"enable\");\n });\n }\n }\n }\n\n return $request;\n };\n\n if (settings.ajax !== undefined) {\n if (settings.data !== undefined) {\n // PAra añadir más parametros de\n // busqueda\n settings.ajax.data = settings.data;\n }\n\n if (settings.autocomplete) {\n //busqueda accentFolding\n var term = '';\n var mySelect = $('#' + settings.id).data('select2');\n\n if ($('input.select2-search__field') != undefined && $('input.select2-search__field').val() != undefined) {\n term = $('input.select2-search__field').val();\n }\n\n if (settings.contains == undefined) {\n settings.contains = true;\n }\n\n term = term.replace(/%/g, '\\\\%').replace(/_/g, '\\\\_');\n settings.ajax.data = $.extend({\n q: term,\n c: settings.contains\n }, settings.extraParams);\n }\n\n if (settings.sourceParam) {\n // modifica el header para parsear\n // la response\n settings.ajax.headers = {\n 'RUP': $.toJSON(settings.sourceParam)\n };\n }\n\n if (settings.processResults) {\n // modifica los results\n settings.ajax.processResults = settings.processResults;\n }\n }\n\n if (settings.multiple) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n if (settings.placeholder == undefined || settings.placeholder == '') {\n // si es vació se asigna el label\n settings.placeholder = rupSelect._getBlankLabel(settings.id);\n }\n\n if (settings.autocomplete) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n $('#' + settings.id).select2(settings);\n }\n }\n\n if (settings.firstLoad) {\n // ejecutar los datos\n var $el = $('#' + settings.id);\n\n var _mySelect = $el.data('select2');\n\n var $search = _mySelect.dropdown.$search || _mySelect.selection.$search;\n\n if (settings.autocomplete && settings.defaultValue != undefined) {\n _mySelect.$container.find('input').val(settings.defaultValue);\n }\n\n if ($search != undefined) {\n $search.trigger('keyup');\n $el.select2('close');\n } else {\n _mySelect.selection.trigger('toggle');\n\n $el.select2('close');\n }\n }\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _textIcon\r\n * @private\r\n * @param {object}\r\n * data - Dato que llega, por cada registro.\r\n */\n _textIcon: function _textIcon(data) {\n var stylePosition = 'M'; // B - Before , M - middle , A - After\n // adjust for custom placeholder values, restaurar\n\n if (data.stylePosition === undefined) {\n // usar la de defecto\n data.stylePosition = stylePosition;\n }\n\n var _span = $('');\n\n var icon = $('');\n\n if (data.imgStyle) {\n // en lugar d mdi,clase icon.\n _span.addClass(data.style);\n\n icon = $('');\n\n if (data.stylePosition.toUpperCase() === 'M') {\n data.stylePosition = 'B'; // en caso de ser span, no\n // admite texto en medio\n }\n }\n\n if (data.stylePosition.toUpperCase() === 'M') {\n icon.prepend(data.text);\n } else if (data.stylePosition.toUpperCase() === 'B') {\n _span.prepend(data.text);\n }\n\n _span.prepend(icon);\n\n if (data.stylePosition.toUpperCase() === 'A') {\n _span.prepend(data.text);\n }\n\n return _span;\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _createOption\r\n * @private\r\n * @param {object}\r\n * settings - Objeto de propiedades de configuración con el\r\n * que se ha inicializado el componente.\r\n * @param {object}\r\n * data - Dato que llega, por cada registro.\r\n */\n _createOption: function _createOption(settings, data) {\n var newOption = new Option(data.text, data.id, false, false);\n\n if (data.style != null) {\n newOption.setAttribute('style', data.style);\n newOption.setAttribute('imgStyle', data.imgStyle);\n }\n\n $('#' + settings.id).append(newOption);\n },\n\n /**\r\n * Gestiona los parámetros a añadir en la URL para que Hdiv permita la llamada.\r\n *\r\n * @function _generateUrl\r\n * @since UDA 5.2.0\r\n * @private\r\n * @param {object} settings - Configuración del componente.\r\n * @param {string} [data] - Valores de búsqueda cuando tiene autocompletado e identificador de los padres en caso de ser enlazados.\r\n */\n _generateUrl: function _generateUrl(settings, data) {\n var _settings$inlineEdit, _settings$inlineEdit2, _settings$inlineEdit3, _settings$inlineEdit4;\n\n var $form = (_settings$inlineEdit = settings.inlineEdit) !== null && _settings$inlineEdit !== void 0 && _settings$inlineEdit.$auxForm ? (_settings$inlineEdit2 = settings.inlineEdit) === null || _settings$inlineEdit2 === void 0 ? void 0 : _settings$inlineEdit2.$auxForm : $('#' + settings.id).closest('form');\n var name = (_settings$inlineEdit3 = settings.inlineEdit) !== null && _settings$inlineEdit3 !== void 0 && _settings$inlineEdit3.auxSiblingFieldName ? (_settings$inlineEdit4 = settings.inlineEdit) === null || _settings$inlineEdit4 === void 0 ? void 0 : _settings$inlineEdit4.auxSiblingFieldName : settings.name;\n\n if ($form.length === 1) {\n var url = settings.url + '?_MODIFY_HDIV_STATE_=' + $.fn.getHDIV_STATE(undefined, $form);\n\n if (data) {\n // Escapa los caracteres '#' para evitar problemas en la petición.\n url += \"&\" + data.replaceAll('#', '%23');\n }\n\n return url + '&MODIFY_FORM_FIELD_NAME=' + name;\n } else {\n return settings.url;\n }\n },\n\n /**\r\n * Método de inicialización del componente.\r\n * \r\n * @function _init\r\n * @private\r\n * @param {object}\r\n * args - Parámetros de inicialización del componente.\r\n */\n _init: function _init(args) {\n var _this2 = this;\n\n _this = this;\n global.initRupI18nPromise.then(function () {\n if (args.length > 1) {\n $.rup.errorGestor($.rup.i18nParse($.rup.i18n.base, 'rup_global.initError') + $(_this2).attr('id'));\n } else {\n // Se recogen y cruzan las paremetrizaciones del objeto\n var settings = $.extend({}, $.fn.rup_select.defaults, args[0]),\n html,\n loadAsLocal = false,\n isValidableElem = false,\n attrs; // Se recoge el tabindex indicado en el elemento\n\n settings.tabindex = $(_this2).attr('tabindex'); // Sobreescribir literales por defecto para\n // multiselect:REVISAR\n // $.extend($.ech.multiselect.prototype.options,\n // $.rup.i18n.base.rup_select.multiselect);\n // Se carga el identificador del padre del patron\n\n settings.id = $.rup_utils.escapeId($(_this2).attr('id'));\n\n if ($(_this2).attr('name') === undefined) {\n $(_this2).attr('name', settings.id);\n }\n\n settings.name = $(_this2).attr('name');\n $('#' + settings.id).attr('ruptype', 'select'); // Si no se recibe identificador para el acceso a literales\n // se usa el ID del objeto\n\n if (!settings.i18nId) {\n settings.i18nId = settings.id;\n } // Guardar valor del INPUT\n\n\n settings.inputValue = $('#' + settings.id).val() === null ? $('#' + settings.id).prop('value') : $('#' + settings.id).val();\n attrs = $(_this2).prop('attributes'); // Revisar apra el select\n\n if (settings.firstLoad === null && $(_this2).is('select') && settings.loadFromSelect) {\n loadAsLocal = true;\n } // Asociar evento CHANGE para propagar cambios a los hijos\n\n\n $('#' + settings.id).on('change', function () {}); // tratar placeHolder\n\n if (settings.placeholder !== undefined && typeof settings.placeholder == 'string') {\n if (!settings.allowClear) {\n settings.templateSelection = function (data, span) {\n if (data.id === settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return $('' + data.text + '');\n }\n\n chargedStyles(data);\n\n if (data.style != null && data.id !== settings.blank) {\n // adjust for custom placeholder values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n\n if (settings.placeholder == '') {\n // si es vació se\n // asigna el label\n settings.placeholder = _this2._getBlankLabel(settings.id);\n }\n\n if (settings.data !== undefined && !settings.multiple) {\n // y si\n // no\n // es\n // multiple\n if (settings.parent == undefined) {\n // Si no tiene padre se mete en todos los\n // valores, sino solo al data,\n settings.data.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n } else {\n $.each(settings.data, function (index, value) {\n value.unshift({\n id: settings.blank,\n text: settings.placeholder\n });\n });\n }\n }\n } else if ($('#' + settings.id).find('option').length == 0) {\n // revisar\n // y\n // crear\n // option\n // vacio.\n $('#' + settings.id).append(new Option(\"\", \"\"));\n }\n } // Crear mi template, myTemplate\n\n\n if (settings.myTemplate !== undefined) {\n settings.templateSelection = settings.myTemplate;\n }\n\n if (settings.templateResult === undefined) {\n if (settings.multiple && settings.udaSkill) {\n // Si es\n // multiple,\n // los\n // results\n // cambian\n // settings.templateSelection\n settings.templateSelection = function (data, span) {\n // Template de Uda\n return data.text;\n };\n } else {\n // si no es multiple\n if (settings.templateSelection !== undefined) {\n // mirar\n // los\n // iconos\n settings.templateResult = function (data, span) {\n chargedStyles(data);\n\n if (data.id === settings.blank) {\n return $('' + data.text + '');\n } else if (data.style != null && data.id !== settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n } else {\n settings.templateResult = function (data, span) {\n chargedStyles(data);\n\n if (data.style != null && data.id !== settings.blank) {\n // adjust\n // for\n // custom\n // placeholder\n // values,\n // restaurar\n return _this._textIcon(data);\n }\n\n return data.text;\n };\n\n settings.templateSelection = settings.templateResult;\n }\n }\n } // Borrar referencia\n // delete html;\n // Ocultar posibles elementos de fechas/horas\n\n\n $('#' + settings.id).next('a').click(function () {\n $('#ui-datepicker-div').hide();\n }); // Se audita el componente\n\n $.rup.auditComponent('rup_select', 'init'); // Añade clase Personalizada\n\n if (settings.customClasses) {\n $.each(settings.customClasses, function (index, value) {\n $('#' + settings.id + '-button' + ', #' + settings.id + '-menu').addClass(value);\n $('[for=' + settings.id + ']').addClass(value);\n });\n } // Si no se recibe identificador para el acceso a literales\n // se usa el ID del objeto\n\n\n if (!settings.i18nId) {\n settings.i18nId = settings.id;\n } // ORDEN\n\n\n var ordenFunction = function ordenFunction(data) {\n if (typeof data === 'string') {\n var dates = data.sort(function (a, b) {\n return a.text.localeCompare(b.text);\n });\n var mySettings = $('#' + settings.id).data('settings');\n mySettings.options = dates;\n $('#' + settings.id).data('settings', mySettings);\n return dates;\n }\n\n return data;\n };\n\n if (settings.data || settings.dataGroups) {\n // local y\n // groups\n if (settings.sortered === true) {\n // PAra añadir\n // ordenación, en local\n // hay que marcarlo\n settings.sorter = ordenFunction;\n } else if (settings.sortered !== false) {\n settings.sorter = settings.sortered;\n }\n\n if (settings.dataGroups === undefined) {\n // LOcal\n settings.data = _this2._parseLOCAL(settings.data, settings.i18nId, settings.parent);\n } else {\n // grupos\n var optionsGroups = [];\n\n for (var i = 0; i < settings.dataGroups.length; i = i + 1) {\n if (_typeof(settings.dataGroups[i]) === 'object') {\n settings.dataGroups[i].children = _this2._parseLOCAL(settings.dataGroups[i].children, settings.i18nId, settings.parent);\n\n for (var j = 0; j < settings.dataGroups[i].children.length; j = j + 1) {\n optionsGroups.push(settings.dataGroups[i].children[j]);\n }\n }\n }\n\n settings.optionsGroups = optionsGroups;\n settings.data = settings.dataGroups;\n }\n } else if (!settings.ajax && settings.url != null) {\n // remoto\n if (settings.sortered === undefined) {\n // PAra añadir\n // ordenación, en\n // remoto siempre se\n // ordena por\n // defecto.\n settings.sorter = ordenFunction;\n } else if (settings.sortered !== false) {\n settings.sorter = settings.sortered;\n }\n\n _this2._loadRemote(settings, true);\n } else {\n // por si viene cargado de un select\n settings.data = true;\n\n if (settings.parent) {\n //convertir el data, formato parent\t\n settings.data = [];\n $('#' + settings.id).find('option').each(function () {\n var idPadre = $(this).data('idpadre');\n\n if (idPadre != undefined) {\n //si no existe\n if (settings.data[idPadre] === undefined) {\n settings.data[idPadre] = [];\n\n if (settings.placeholder != undefined || settings.placeholder != '') {\n settings.data[idPadre].push({\n id: settings.blank,\n text: settings.placeholder\n });\n }\n }\n\n settings.data[idPadre].push({\n id: $(this).val(),\n text: $(this).text()\n });\n }\n });\n }\n } // Init eventos: El resto van en el propio subyacente\n // Change\n\n\n if (settings.change) {\n if (!settings.clean) {\n $('#' + settings.id).off('select2:clearing');\n $('#' + settings.id).on('select2:clearing', function (e) {\n settings.change(e);\n });\n }\n } // clean\n\n\n if (settings.clean) {\n $('#' + settings.id).off('select2:clearing');\n $('#' + settings.id).on('select2:clearing', function (e) {\n settings.clean(e);\n });\n } // event select\n\n\n $('#' + settings.id).off('select2:select');\n $('#' + settings.id).on('select2:select', function (e) {\n if (settings.autocomplete) {\n //Change input\n var mySelect2 = $('#' + settings.id).data('select2');\n var data = $(this).select2('data')[0];\n mySelect2.$selection.find('input').val(data.text);\n }\n\n if (settings.select) {\n settings.select(e);\n }\n\n if (settings.change) {\n settings.change(e);\n }\n });\n\n if (settings.data) {\n // local y groups\n if (settings.parent) {\n // si depende de otro selects.\n // Si es uno meterlo como string - local\n if (_typeof(settings.parent) == 'object' && settings.parent.length == 1) {\n settings.parent = settings.parent[0];\n }\n\n if (settings.dataParents === undefined) {\n // la\n // primera\n // vez carga\n // los datos\n // fijos.\n settings.dataParents = settings.data;\n }\n\n var valorValue = _this._getParentsValues(settings, false, settings.multiValueToken);\n\n if (valorValue != '') {\n valoresParent = settings.dataParents[valorValue];\n\n if (valoresParent == undefined && settings.dataParents[0] != undefined) {\n valoresParent = settings.dataParents[0][valorValue];\n }\n\n settings.data = valoresParent;\n\n if (settings.data == undefined) {\n settings.data = [];\n }\n }\n }\n\n if (settings.multiple) {\n $('#' + settings.id).select2MultiCheckboxes(settings);\n } else {\n if (settings.placeholder == undefined || settings.placeholder == '') {\n // si es vació se asigna el label\n settings.placeholder = _this._getBlankLabel(settings.id);\n }\n\n if (settings.autocomplete) {\n //local y autocomplete\n if (settings.matcher == undefined && settings.accentFolding == false) {\n settings.matcher = udaMatcher;\n }\n\n $('#' + settings.id).select2MultiCheckboxes(settings);\n\n if (settings.defaultValue != undefined) {\n var mySelect2 = $('#' + settings.id).data('select2');\n mySelect2.$selection.find('input').val(settings.defaultValue);\n\n if (settings.selected == undefined && mySelect2.dataAdapter._dataToConvert != undefined && mySelect2.dataAdapter._dataToConvert.length > 0) {\n var data = $.grep(mySelect2.dataAdapter._dataToConvert, function (v) {\n return v.text.toUpperCase() === settings.defaultValue.toUpperCase();\n });\n\n if (data[0] != undefined) {\n settings.selected = data[0].id;\n }\n }\n }\n } else {\n $('#' + settings.id).select2(settings);\n } //Propiedad para deselecionar una mismo en simple.\n\n\n if (settings.deleteOnDeselect) {\n var _mySelect2 = $('#' + settings.id).data('select2');\n\n _mySelect2.on('close', function (e) {\n if (Object.keys(e).length === 1) {\n _mySelect2.$selection.find('input').val('');\n\n $('#' + settings.id).val(null).trigger('change');\n\n if (!settings.closeOnSelect) {\n $('#' + settings.id).select2('open');\n }\n }\n });\n }\n }\n\n if (settings.selected) {\n $('#' + settings.id).val(settings.selected).trigger('change');\n } // cargar los options\n\n\n settings.options = settings.data;\n } else {\n //Remotos\n //Propiedad para deselecionar una mismo en simple.\n if (settings.deleteOnDeselect) {\n var remotoSelect = $('#' + settings.id).data('select2');\n remotoSelect.on('close', function (e) {\n if (Object.keys(e).length === 1) {\n remotoSelect.$selection.find('input').val('');\n $('#' + settings.id).val(null).trigger('change');\n\n if (!settings.closeOnSelect) {\n $('#' + settings.id).select2('open');\n }\n }\n });\n }\n }\n\n if (settings.parent) {\n // si dependen de otros selects\n // Mirar si es simple o no\n var parent = [];\n\n if (typeof settings.parent == 'string') {\n parent.push(settings.parent);\n } else {\n // Si es uno meterlo como string -remoto\n if (settings.parent.length == 1) {\n settings.parent = settings.parent[0];\n parent.push(settings.parent);\n } else {\n parent = settings.parent;\n }\n } // Bucle para eventos Padres\n\n\n $.each(parent, function (idx, eventoPadre) {\n $('#' + eventoPadre).off('change.parent' + settings.id);\n $('#' + eventoPadre).on('change.parent' + settings.id, function () {\n // Cambios\n // para\n // los\n // hijos,onchange\n // del\n // padre\n // Si soy local\n if (settings.data !== undefined) {\n if (_typeof(settings.parent) == 'object') {\n // Si\n // tiene\n // más\n // de\n // un\n // padre\n var clave = '';\n var ClaveNoCifrar = '';\n\n if (settings.multiValueToken == undefined) {\n settings.multiValueToken = '';\n }\n\n $.each(settings.parent, function (ind, elem) {\n var val = $('#' + elem).rup_select('getRupValue');\n clave = clave + val + settings.multiValueToken;\n var dataSelected = $('#' + elem).rup_select(\"getDataSelected\");\n\n if (dataSelected !== undefined) {\n val = dataSelected.nid || dataSelected.id;\n ClaveNoCifrar = ClaveNoCifrar + val + settings.multiValueToken;\n }\n });\n clave = clave.substring(0, clave.length - settings.multiValueToken.length);\n ClaveNoCifrar = ClaveNoCifrar.substring(0, ClaveNoCifrar.length - settings.multiValueToken.length);\n var datosParents = settings.dataParents[0] || settings.dataParents;\n\n if (datosParents[clave] != undefined || datosParents[ClaveNoCifrar] != undefined) {\n // Datos\n // Cargados\n var valores = datosParents[clave] || datosParents[ClaveNoCifrar];\n settings.data = datosParents;\n $('#' + settings.id).rup_select(\"setSource\", valores);\n }\n } else {\n // si tiene un solo padre\n var val = $('#' + settings.parent).rup_select('getRupValue');\n\n if (val != settings.blank && val != '') {\n $('#' + settings.id).rup_select(\"enable\");\n var _valores = settings.dataParents[val];\n\n if (_valores == undefined && $('#' + settings.parent).rup_select(\"getDataSelected\") !== undefined) {\n var nid = $('#' + settings.parent).rup_select(\"getDataSelected\").nid;\n _valores = settings.dataParents[nid]; //si vine cifrado de un remoto.\n }\n\n settings.data = settings.dataParents;\n\n if (_valores == undefined) {\n // Si no\n // hay\n // valor,\n // se\n // inicializa\n _valores = [];\n }\n\n $('#' + settings.id).rup_select(\"setSource\", _valores);\n } else {\n //deshabilitamos el hijo\n $('#' + settings.id).rup_select(\"disable\");\n }\n } // Aseguramos el valor limpio al cambiar el\n // padre\n\n\n $('#' + settings.id).rup_select(\"setRupValue\", settings.blank);\n } else {\n // si soy Remoto\n var datosParent = _this._getParentsValues(settings, true); // Sola llamar si el padre tiene valor.\n\n\n if (datosParent != '') {\n $('#' + settings.id).rup_select(\"disable\"); // ejecutar los datos\n\n var $el = $('#' + settings.id);\n var $search = $el.data('select2').dropdown.$search || $el.data('select2').selection.$search;\n\n if (settings.autocomplete) {\n $el.data('select2').$container.find('input').val('');\n }\n\n if ($search != undefined) {\n $search.trigger('keyup');\n $el.select2('close');\n }\n\n if ($(\"#\" + settings.id).val() != null && $(\"#\" + settings.id).val().trim() != '') {\n $(\"#\" + settings.id).val(null).trigger('change');\n }\n\n setTimeout($('#' + settings.id).rup_select(\"enable\"), 200);\n } else if ($(\"#\" + settings.id).val() != null && $(\"#\" + settings.id).val().trim() != '') {\n // Se llama al cambio del trigger.\n $(\"#\" + settings.id).val(null).trigger('change');\n $('#' + settings.id).rup_select(\"disable\");\n }\n }\n });\n }); // Fin funcion evento padre\n }\n\n $('#' + settings.id).data('settings', settings); //Si es remoto, el último evento es: selectAjaxSuccess\n\n $('#' + settings.id).triggerHandler('selectFinish', settings);\n }\n })[\"catch\"](function (error) {\n console.error('Error al inicializar el componente:\\n', error);\n });\n }\n }); // ******************************************************\n // DEFINICIÓN DE LA CONFIGURACION POR DEFECTO DEL PATRON\n // ******************************************************\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener\r\n * los elementos a mostrar.\r\n * \r\n * @callback jQuery.rup_select~onLoadError\r\n * @param {Object}\r\n * xhr - Objeto XHR que contiene la respuesta de la petición\r\n * realizada.\r\n * @param {string}\r\n * textStatus - Texto que identifica el error producido.\r\n * @param {Object}\r\n * errorThrown - Objeto error que contiene las propiedades del\r\n * error devuelto en la petición.\r\n */\n\n /**\r\n * Función a ejecutar en caso de producirse un error a la hora de obtener\r\n * los elementos a mostrar.\r\n * \r\n * @callback jQuery.rup_select~onLoadSuccess\r\n * @param {jQuery}\r\n * self - Referencia al objeto jQuery del propio select.\r\n */\n\n /**\r\n * @description Opciones por defecto de configuración del componente.\r\n * \r\n * @name defaults\r\n * \r\n * @property {jQuery.rup_select~onLoadError} [onLoadError] - Función de\r\n * callback a ejecutar en caso de que se produzca un error en la\r\n * petición de obtención de la lista de elementos a mostrar.\r\n * @property {string} [width='100%'] - Determina el tamaño del componente \r\n * tanto en píxeles como en porcentaje. Su valor por defecto es '100%'.\r\n * @property {string} [blank=null] - Se utiliza para declarar un valor\r\n * independiente de la lógica de negocio y en ocasiones se\r\n * representa como \"Seleccione un elemento\". Permite establecer un\r\n * mensaje independiente por cada select haciendo uso de\r\n * $.rup.i18n.app.id._blank (sustituyendo id por el propio de cada\r\n * select) o uno genérico por aplicación haciendo uso de\r\n * $.rup.i18n.app.rup_select.blank. En caso de no definir ninguno,\r\n * se usará el genérico de UDA,\r\n * $.rup.i18n.base.rup_select.blankNotDefined.\r\n * @property {string} [token=\"|\"] - Define el separador a utilizar cuando se\r\n * muestra el valor asociado al select concatenado al literal.\r\n * @property {string} [multiValueToken=\"##\"] - Define el separador a\r\n * utilizar en selects enlazados locales.\r\n * @property {boolean} [ordered=true] - Indica si el select debe ordenarse.\r\n * @property {boolean} [orderedByValue=false] - Indica si el la ordenación\r\n * del seelct debe realizarse por el valor de los elementos en\r\n * lugar de por el texto.\r\n * @property {jQuery.rup_select~onLoadSuccess} [onLoadSuccess=null] - Función\r\n * de callback a ejecutar en el caso de que la petición de carga\r\n * de datos se haya producido correctamente.\r\n * @property {boolean} [loadFromSelect=false] - Determina si se debe de\r\n * utilizar los elementos option del elemento html sobre el que se\r\n * inicializa el componente para inicializar los datos del\r\n * elemento.\r\n * @property {boolean} [multiOptgroupIconText=false] - Indica si se desea\r\n * que en la selección múltiple con grupos, el nombre del grupo\r\n * tenga descripción en los iconos para seleccionar/deseleccionar\r\n * los elementos del grupo.\r\n * @property {boolean} [submitAsString=false] - Indica si el envío de los\r\n * elementos seleccionados en la selección múltiple se realiza\r\n * como un literal separados por coma.\r\n * @property {boolean} [submitAsJSON=false] - Indica si el envío de los\r\n * elementos seleccionados en la selección múltiple se realiza\r\n * como un array JSON donde el nombre del mapa será el nombre del\r\n * select. En el caso de que el nombre contenga notación dot se\r\n * tomará el último literal. Ej: [{id:1}, {id:2}, …].\r\n * @property {boolean} [readAsString=false] - Determina si la asignación de\r\n * un valor inicial se va a realizar a partir de un string con los\r\n * ids de los elementos separados por comas en vez de un array de\r\n * json.\r\n * @property {boolean} [rowStriping=false] - Indica si se debe aplicar un\r\n * estilo diferente a las filas pares e impares para poder\r\n * distinguirlas mediante un color diferente.\r\n * @property {number} [typeAhead=false] - Especifica en milisegundos el\r\n * tiempo de espera que toma el componente antes de procesar los\r\n * eventos de escritura realizados por el usuario.\r\n * @property {number} [legacyWrapMode=false] - Determina si se emplea el\r\n * método obsoleto a la hora de empaquetar en objetos json los\r\n * elementos seleccionados. Su propósito es mantener la\r\n * retrocompatibilidad.\r\n */\n\n $.fn.rup_select.defaults = {\n onLoadError: null,\n width: '100%',\n customClasses: ['select-material'],\n blank: \"-1\",\n minimumResultsForSearch: Infinity,\n submitAsJSON: false,\n dataType: 'json',\n cache: true,\n multiple: false,\n multiValueToken: '##'\n };\n});\n\nfunction chargedStyles(data) {\n if (data.style === undefined && data.element !== undefined) {\n // mirar estilo\n data.style = data.element.getAttribute('style');\n data.imgStyle = data.element.getAttribute('imgStyle');\n\n if (data.style == null || data.style == 'undefined') {\n data.style = undefined;\n }\n\n if (data.style == null || data.imgStyle == 'undefined') {\n data.imgStyle = undefined;\n }\n }\n}\n\nfunction udaMatcher(params, data) {\n // Always return the object if there is nothing to compare\n if ($.trim(params.term) === '') {\n return data;\n } // Do a recursive check for options with children\n\n\n if (data.children && data.children.length > 0) {\n // Clone the data object if there are children\n // This is required as we modify the object to remove any non-matches\n var match = $.extend(true, {}, data); // Check each child of the option\n\n for (var c = data.children.length - 1; c >= 0; c--) {\n var child = data.children[c];\n var matches = matcher(params, child); // If there wasn't a match, remove the object in the array\n\n if (matches == null) {\n match.children.splice(c, 1);\n }\n } // If any children matched, return the new object\n\n\n if (match.children.length > 0) {\n return match;\n } // If there were no matching children, check just the plain object\n\n\n return matcher(params, match);\n }\n\n var original = data.text.toUpperCase();\n var term = params.term.toUpperCase(); // Check if the text contains the term\n\n if (original.indexOf(term) > -1) {\n return data;\n } // If it doesn't contain the term, don't return anything\n\n\n return null;\n}\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ./../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\"), __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup.select.js?"); /***/ }), @@ -8689,7 +8689,7 @@ eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_FAC /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/**\r\n * Genera los botones del table\r\n *\r\n * @summary \t\tExtensión del componente RUP Datatable\r\n * @module\t\t\t\"rup.table.buttons\"\r\n * @version 1.5.1\r\n * @license\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n * @copyright Copyright 2018 E.J.I.E., S.A.\r\n *\r\n */\n(function (factory) {\n if (true) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! datatables.net */ \"./node_modules/datatables.net/js/jquery.dataTables.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($) {\n return factory($, window, document);\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($, window, document, undefined) {\n 'use strict';\n\n var DataTable = $.fn.dataTable; // Used for namespacing events added to the document by each instance, so they\n // can be removed on destroy\n\n var _instCounter = 0; // Button namespacing counter for namespacing events on individual buttons\n\n var _buttonCounter = 0; // Default ID naming counter\n\n var _buttonIdCounter = 1;\n var _dtButtons = DataTable.ext.buttons;\n /**\r\n * Botones\r\n *\r\n * @name Buttons\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt\r\n * @param {object} config\r\n *\r\n */\n\n var Buttons = function Buttons(dt, config) {\n var idTable = dt.context[0].sTableId;\n var ctx = dt.context[0];\n ctx.ext = DataTable.ext;\n ctx.ext.buttons = {};\n ctx.ext.buttons.defaults = {\n buttons: ['addButton', 'editButton', 'cloneButton', 'deleteButton', 'reportsButton'],\n name: 'main',\n tabIndex: 0,\n dom: {\n container: {\n tag: 'div',\n className: 'dt-buttons row'\n },\n collection: {\n tag: 'div',\n className: 'dt-button-collection'\n },\n button: {\n tag: 'button',\n className: 'col-12 col-sm-auto btn-material',\n active: 'active',\n disabled: 'disabled'\n },\n buttonLiner: {\n tag: 'span',\n className: ''\n }\n }\n };\n ctx.ext.buttons.copyButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.copyButton');\n },\n id: idTable + 'copyButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'copyButton',\n request: {\n url: '/filter?clipboardReport=true',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'json',\n reportsExportAllColumns: false\n },\n init: function init(dt, node, config) {\n ctx.ext.buttons.copyButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCopyClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCopyClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.excelButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.excelButton');\n },\n id: idTable + 'excelButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'excelButton',\n request: {\n url: '/xlsxReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n reportsExportAllColumns: false,\n fileName: 'reportExcel',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeExcelClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterExcelClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.pdfButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.pdfButton');\n },\n id: idTable + 'pdfButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'pdfButton',\n request: {\n url: '/pdfReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/pdf',\n reportsExportAllColumns: false,\n fileName: 'reportPDF'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforePdfClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterPdfClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.odsButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.odsButton');\n },\n id: idTable + 'odsButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'odsButton',\n request: {\n url: '/odsReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/vnd.oasis.opendocument.spreadsheet',\n reportsExportAllColumns: false,\n fileName: 'reportODS',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeOdsClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterOdsClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.csvButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.csvButton');\n },\n id: idTable + 'csvButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'csvButton',\n request: {\n url: '/csvReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'text/csv',\n reportsExportAllColumns: false,\n fileName: 'reportCSV',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCsvClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCsvClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.addButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.add');\n },\n id: idTable + 'addButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnAdd order-1',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'add',\n init: function init(dt, button, config) {\n ctx.ext.buttons.addButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeAddClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterAddClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.editButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.edit');\n },\n id: idTable + 'editButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnEdit order-2',\n displayRegex: /^[1-9][0-9]*$/,\n // Se muestra siempre que sea un numero mayor a 0\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'edit',\n init: function init(dt, button, config) {\n ctx.ext.buttons.editButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeEditClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterEditClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.cloneButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.clone');\n },\n id: idTable + 'cloneButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnClone order-3',\n displayRegex: /^1$/,\n // Se muestra solo cuando sea igual a 1\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'clone',\n init: function init(dt, button, config) {\n ctx.ext.buttons.cloneButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCloneClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCloneClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.deleteButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.delete');\n },\n id: idTable + 'deleteButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnDelete order-4',\n displayRegex: /^[1-9][0-9]*$/,\n // Se muestra siempre que sea un numero mayor a 0\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'delete',\n init: function init(dt, button, config) {\n ctx.ext.buttons.deleteButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeDeleteClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterDeleteClick', [dt, button, config]);\n }\n };\n var listadoExports = ['copyButton', 'excelButton', 'pdfButton', 'odsButton', 'csvButton'];\n ctx.ext.buttons.reportsButton = {\n extend: 'collection',\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.main');\n },\n id: idTable + 'informes_01',\n className: 'btn-material-primary-medium-emphasis order-last ml-1 ml-lg-auto',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n autoClose: true,\n type: 'reports',\n reportsExportAllColumns: false,\n buttons: listadoExports\n }; // Almacena los identificadores de los botones personalizados.\n\n ctx.ext.buttons.custom = []; // Ajusta el tamaño de los botones por defecto en caso de que haya sido especificado en las preferencias\n\n if (ctx.oInit.buttons.size !== undefined) {\n $.each(ctx.ext.buttons, function (name, item) {\n if (item.className !== undefined) {\n if (ctx.oInit.buttons.size === 'lg') {\n item.className += \" btn-material-lg\";\n } else if (ctx.oInit.buttons.size === 'sm') {\n item.className += \" btn-material-sm\";\n }\n }\n });\n }\n\n if (ctx.oInit.buttons.blackListButtons !== undefined) {\n if (ctx.oInit.buttons.blackListButtons === 'all') {\n //si no se quiere ninguno se elimina\n listadoExports = [];\n ctx.ext.buttons.defaults.buttons = [];\n } else if (ctx.oInit.buttons.blackListButtons && ctx.oInit.buttons.blackListButtons.length > 0) {\n $.each(ctx.oInit.buttons.blackListButtons, function () {\n var name = this;\n var pos = $.inArray(name, listadoExports);\n\n if (pos >= 0) {\n listadoExports.splice(pos, 1);\n } //Resto de botones\n\n\n var posBoton = $.inArray(name, ctx.ext.buttons.defaults.buttons);\n\n if (posBoton >= 0) {\n ctx.ext.buttons.defaults.buttons.splice(posBoton, 1);\n }\n });\n }\n } // Añadir los botones de la edición en línea.\n\n\n if (!ctx.oInit.noEdit && ctx.oInit.inlineEdit !== undefined) {\n $.extend(ctx.ext.buttons, ctx.oInit.inlineEdit.myButtons);\n\n for (var nameButton in ctx.oInit.inlineEdit.myButtons) {\n ctx.ext.buttons.defaults.buttons.push(nameButton);\n }\n } // Añadir los botones personalizados.\n\n\n if (ctx.oInit.buttons.myButtons !== undefined) {\n $.extend(ctx.ext.buttons, ctx.oInit.buttons.myButtons);\n\n for (var _nameButton in ctx.oInit.buttons.myButtons) {\n ctx.ext.buttons.defaults.buttons.push(_nameButton);\n ctx.ext.buttons.custom.push(ctx.oInit.buttons.myButtons[_nameButton].id);\n }\n } // If there is no config set it to an empty object\n\n\n if (typeof config === 'undefined') {\n config = {};\n } // Allow a boolean true for defaults\n\n\n if (config === true) {\n config = {};\n } // For easy configuration of buttons an array can be given\n\n\n if (Array.isArray(config)) {\n config = {\n buttons: config\n };\n }\n\n this.c = $.extend(true, {}, ctx.ext.buttons.defaults, config); // Don't want a deep copy for the buttons\n\n if (config.buttons) {\n this.c.buttons = config.buttons;\n }\n\n this.s = {\n dt: new DataTable.Api(dt),\n buttons: [],\n listenKeys: '',\n namespace: 'dtb' + _instCounter++\n };\n this.dom = {\n container: $('<' + this.c.dom.container.tag + '>').addClass(this.c.dom.container.className).attr('id', ctx.sTableId + '_containerToolbar')\n };\n\n this._constructor();\n };\n\n $.extend(Buttons.prototype, {\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Public methods\r\n */\n\n /**\r\n * Get the action of a button\r\n *\r\n * @name action\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string} Button index\r\n * @return {function}\r\n *\r\n */\n\n /**\r\n * Set the action of a button\r\n *\r\n * @name action\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button element\r\n * @param {function} action Function to set\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n action: function action(node, _action) {\n var button = this._nodeToButton(node);\n\n if (_action === undefined) {\n return button.conf.action;\n }\n\n button.conf.action = _action;\n return this;\n },\n\n /**\r\n * Add an active class to the button to make to look active or get current\r\n * active state.\r\n *\r\n * @name active\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button element\r\n * @param {boolean} [flag] Enable / disable flag\r\n * @return {Buttons} Self for chaining or boolean for getter\r\n *\r\n */\n active: function active(node, flag) {\n var button = this._nodeToButton(node);\n\n var klass = this.c.dom.button.active;\n var jqNode = $(button.node);\n\n if (flag === undefined) {\n return jqNode.hasClass(klass);\n }\n\n jqNode.toggleClass(klass, flag === undefined ? true : flag);\n return this;\n },\n\n /**\r\n * Add a new button\r\n *\r\n * @name add\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config Button configuration object, base string name or function\r\n * @param {int|string} [idx] Button index for where to insert the button\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n add: function add(config, idx) {\n var buttons = this.s.buttons;\n\n if (typeof idx === 'string') {\n var split = idx.split('-');\n var base = this.s;\n\n for (var i = 0, ien = split.length - 1; i < ien; i++) {\n base = base.buttons[split[i] * 1];\n }\n\n buttons = base.buttons;\n idx = split[split.length - 1] * 1;\n }\n\n this._expandButton(buttons, config, false, idx);\n\n this._draw();\n\n return this;\n },\n\n /**\r\n * Get the container node for the buttons\r\n *\r\n * @name container\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {jQuery} Buttons node\r\n *\r\n */\n container: function container() {\n return this.dom.container;\n },\n\n /**\r\n * Disable a button\r\n *\r\n * @name disable\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n disable: function disable(node, contextMenu) {\n var button = this._nodeToButton(node);\n\n $(button.node).addClass(this.c.dom.button.disabled);\n\n if (contextMenu) {\n $('#' + button.node.id + '_contextMenuToolbar').addClass(this.c.dom.button.disabled);\n }\n\n return this;\n },\n\n /**\r\n * Destroy the instance, cleaning up event handlers and removing DOM\r\n * elements\r\n *\r\n * @name destroy\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n destroy: function destroy() {\n // Key event listener\n $('body').off('keyup.' + this.s.namespace); // Individual button destroy (so they can remove their own events if\n // needed). Take a copy as the array is modified by `remove`\n\n var buttons = this.s.buttons.slice();\n var i, ien;\n\n for (i = 0, ien = buttons.length; i < ien; i++) {\n this.remove(buttons[i].node);\n } // Container\n\n\n this.dom.container.remove(); // Remove from the settings object collection\n\n var buttonInsts = this.s.dt.settings()[0];\n\n for (i = 0, ien = buttonInsts.length; i < ien; i++) {\n if (buttonInsts.inst === this) {\n buttonInsts.splice(i, 1);\n break;\n }\n }\n\n return this;\n },\n\n /**\r\n * Enable / disable a button\r\n *\r\n * @name enable\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {boolean} [flag=true] Enable / disable flag\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n enable: function enable(node, flag, contextMenu) {\n if (flag === false) {\n return this.disable(node);\n }\n\n var button = this._nodeToButton(node);\n\n $(button.node).removeClass(this.c.dom.button.disabled);\n\n if (contextMenu) {\n $('#' + button.node.id + '_contextMenuToolbar').removeClass(this.c.dom.button.disabled);\n }\n\n return this;\n },\n\n /**\r\n * Get the instance name for the button set selector\r\n *\r\n * @name name\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {string} Instance name\r\n *\r\n */\n name: function name() {\n return this.c.name;\n },\n\n /**\r\n * Get a button's node\r\n *\r\n * @name node\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {jQuery} Button element\r\n *\r\n */\n node: function node(_node) {\n var button = this._nodeToButton(_node);\n\n return $(button.node);\n },\n\n /**\r\n * Set / get a processing class on the selected button\r\n *\r\n * @name processing\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} flag true to add, false to remove, undefined to get\r\n * @return {boolean|Buttons} Getter value or this if a setter.\r\n *\r\n */\n processing: function processing(node, flag) {\n var button = this._nodeToButton(node);\n\n if (flag === undefined) {\n return $(button.node).hasClass('processing');\n }\n\n $(button.node).toggleClass('processing', flag);\n return this;\n },\n\n /**\r\n * Remove a button.\r\n *\r\n * @name remove\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n remove: function remove(node) {\n var button = this._nodeToButton(node);\n\n var host = this._nodeToHost(node);\n\n var dt = this.s.dt; // Remove any child buttons first\n\n if (button.buttons.length) {\n for (var i = button.buttons.length - 1; i >= 0; i--) {\n this.remove(button.buttons[i].node);\n }\n } // Allow the button to remove event handlers, etc\n\n\n if (button.conf.destroy) {\n button.conf.destroy.call(dt.button(node), dt, $(node), button.conf);\n }\n\n this._removeKey(button.conf);\n\n $(button.node).remove();\n var idx = $.inArray(button, host);\n host.splice(idx, 1);\n return this;\n },\n\n /**\r\n * Get the text for a button\r\n *\r\n * @name text\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string} node Button index\r\n * @return {string} Button text\r\n *\r\n */\n\n /**\r\n * Set the text for a button\r\n *\r\n * @name text\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string|function} node Button index\r\n * @param {string} label Text\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n text: function text(node, label) {\n var button = this._nodeToButton(node);\n\n var buttonLiner = this.c.dom.collection.buttonLiner;\n var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ? buttonLiner.tag : this.c.dom.buttonLiner.tag;\n var dt = this.s.dt;\n var jqNode = $(button.node);\n\n var text = function text(opt) {\n return typeof opt === 'function' ? opt(dt, jqNode, button.conf) : opt;\n };\n\n if (label === undefined) {\n return text(button.conf.text);\n }\n\n button.conf.text = label;\n\n if (linerTag) {\n jqNode.children(linerTag).html(text(label));\n } else {\n jqNode.html(text(label));\n }\n\n return this;\n },\n\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Constructor\r\n */\n\n /**\r\n * Buttons constructor\r\n *\r\n * @name _constructor\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n */\n _constructor: function _constructor() {\n var that = this;\n var dt = this.s.dt;\n var dtSettings = dt.settings()[0];\n var buttons = this.c.buttons;\n\n if (!dtSettings._buttons) {\n dtSettings._buttons = [];\n }\n\n dtSettings._buttons.push({\n inst: this,\n name: this.c.name\n });\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n this.add(buttons[i]);\n }\n\n dt.on('destroy', function () {\n that.destroy();\n }); // Global key event binding to listen for button keys\n\n $('body').on('keyup.' + this.s.namespace, function (e) {\n if (!document.activeElement || document.activeElement === document.body) {\n // SUse a string of characters for fast lookup of if we need to\n // handle this\n var character = String.fromCharCode(e.keyCode).toLowerCase();\n\n if (that.s.listenKeys.toLowerCase().indexOf(character) !== -1) {\n that._keypress(character, e);\n }\n }\n });\n },\n\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Private methods\r\n */\n\n /**\r\n * Add a new button to the key press listener\r\n *\r\n * @name _addKey\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} conf Resolved button configuration object\r\n *\r\n */\n _addKey: function _addKey(conf) {\n if (conf.key) {\n this.s.listenKeys += $.isPlainObject(conf.key) ? conf.key.key : conf.key;\n }\n },\n\n /**\r\n * Insert the buttons into the container. Call without parameters!\r\n *\r\n * @name _draw\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} [container] Recursive only - Insert point\r\n * @param {array} [buttons] Recursive only - Buttons array\r\n *\r\n */\n _draw: function _draw(container, buttons) {\n if (!container) {\n container = this.dom.container;\n buttons = this.s.buttons;\n }\n\n container.children().detach();\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n container.append(buttons[i].inserter);\n container.append(' ');\n\n if (buttons[i].buttons && buttons[i].buttons.length) {\n this._draw(buttons[i].collection, buttons[i].buttons);\n }\n }\n },\n\n /**\r\n * Create buttons from an array of buttons\r\n *\r\n * @name _expandButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {array} attachTo Buttons array to attach to\r\n * @param {object} button Button definition\r\n * @param {boolean} inCollection true if the button is in a collection\r\n *\r\n */\n _expandButton: function _expandButton(attachTo, button, inCollection, attachPoint) {\n var dt = this.s.dt;\n var buttonCounter = 0;\n var buttons = !Array.isArray(button) ? [button] : button;\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n var conf = this._resolveExtends(buttons[i]);\n\n if (!conf) {\n continue;\n } // If the configuration is an array, then expand the buttons at this\n // point\n\n\n if (Array.isArray(conf)) {\n this._expandButton(attachTo, conf, inCollection, attachPoint);\n\n continue;\n }\n\n var built = this._buildButton(conf, inCollection);\n\n if (!built) {\n continue;\n }\n\n if (attachPoint !== undefined) {\n attachTo.splice(attachPoint, 0, built);\n attachPoint++;\n } else {\n attachTo.push(built);\n }\n\n if (built.conf.buttons) {\n var collectionDom = this.c.dom.collection;\n built.collection = $('<' + collectionDom.tag + '>').addClass(collectionDom.className).attr('role', 'menu');\n built.conf._collection = built.collection;\n\n this._expandButton(built.buttons, built.conf.buttons, true, attachPoint);\n } // init call is made here, rather than buildButton as it needs to\n // be selectable, and for that it needs to be in the buttons array\n\n\n if (conf.init) {\n conf.init.call(dt.button(built.node), dt, $(built.node), conf);\n }\n\n buttonCounter++;\n }\n },\n\n /**\r\n * Create an individual button\r\n *\r\n * @name _buildButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config Resolved button configuration\r\n * @param {boolean} inCollection `true` if a collection button\r\n * @return {jQuery} Created button node (jQuery)\r\n *\r\n */\n _buildButton: function _buildButton(config, inCollection) {\n var buttonDom = this.c.dom.button;\n var linerDom = this.c.dom.buttonLiner;\n var collectionDom = this.c.dom.collection;\n var dt = this.s.dt;\n var ctx = dt.settings()[0];\n\n var text = function text(opt) {\n return typeof opt === 'function' ? opt(dt, button, config) : opt;\n };\n\n if (inCollection && collectionDom.button) {\n buttonDom = collectionDom.button;\n }\n\n if (inCollection && collectionDom.buttonLiner) {\n linerDom = collectionDom.buttonLiner;\n } // Make sure that the button is available based on whatever requirements\n // it has. For example, Flash buttons require Flash\n\n\n if (config.available && !config.available(dt, config)) {\n return false;\n }\n\n var action = function action(e, dt, button, config) {\n config.action.call(dt.button(button), e, dt, button, config);\n $(dt.table().node()).triggerHandler('buttons-action.dt', [dt.button(button), dt, button, config]);\n };\n\n var button = $('<' + buttonDom.tag + '>').addClass(buttonDom.className).attr('tabindex', this.s.dt.settings()[0].iTabIndex).attr('aria-controls', this.s.dt.table().node().id).on('click.dtb', function (e) {\n e.preventDefault();\n\n if (!button.hasClass(buttonDom.disabled) && config.action) {\n action(e, dt, button, config);\n }\n\n button.blur();\n }); // Make `a` tags act like a link\n\n if (buttonDom.tag.toLowerCase() === 'a') {\n button.attr('href', '#');\n }\n\n if (linerDom.tag) {\n var liner = $('<' + linerDom.tag + '>').html(text(config.text)).addClass(linerDom.className);\n\n if (linerDom.tag.toLowerCase() === 'a') {\n liner.attr('href', '#');\n }\n\n button.append(liner);\n } else {\n button.html(text(config.text));\n }\n\n if (config.id) {\n button.attr('id', config.id);\n } else {\n // Se desactiva el acceso desde el contextMenu por no tener un id establecido\n config.insideContextMenu = false; // Se asigna un id dinamico en funcion del nombre del table al que pertenece\n\n config.id = ctx.sTableId + '_button_' + _buttonIdCounter++;\n button.attr('id', config.id);\n }\n\n if (config.className) {\n button.addClass(config.className);\n }\n\n if (config.titleAttr) {\n button.attr('title', text(config.titleAttr));\n }\n\n if (config.attr) {\n button.attr(config.attr);\n }\n\n if (!config.namespace) {\n config.namespace = '.dt-button-' + _buttonCounter++;\n }\n\n if (!config.icon) {\n // Comprueba si es alguno de los botones con iconos definidos por defecto\n switch (config.type) {\n case 'add':\n config.icon = 'mdi-plus';\n break;\n\n case 'edit':\n config.icon = 'mdi-playlist-edit';\n break;\n\n case 'clone':\n config.icon = 'mdi-content-copy';\n break;\n\n case 'delete':\n config.icon = 'mdi-trash-can-outline';\n break;\n\n case 'reports':\n config.icon = 'mdi-file-export';\n break;\n\n case 'copyButton':\n config.icon = 'mdi-clipboard-text-outline';\n break;\n\n case 'excelButton':\n config.icon = 'mdi-file-excel';\n break;\n\n case 'pdfButton':\n config.icon = 'mdi-file-pdf';\n break;\n\n case 'odsButton':\n config.icon = 'mdi-file';\n break;\n\n case 'csvButton':\n config.icon = 'mdi-file';\n break;\n\n default:\n config.icon = 'mdi-settings';\n }\n }\n\n var buttonContainer = this.c.dom.buttonContainer;\n var inserter;\n\n if (buttonContainer && buttonContainer.tag) {\n inserter = $('<' + buttonContainer.tag + '>').addClass(buttonContainer.className).append(button);\n } else {\n inserter = button;\n }\n\n this._addKey(config);\n\n return {\n conf: config,\n node: button.get(0),\n inserter: inserter,\n buttons: [],\n inCollection: inCollection,\n collection: null\n };\n },\n\n /**\r\n * Get the button object from a node (recursive)\r\n *\r\n * @name _nodeToButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {array} [buttons] Button array, uses base if not defined\r\n * @return {object} Button object\r\n *\r\n */\n _nodeToButton: function _nodeToButton(node, buttons) {\n if (!buttons) {\n buttons = this.s.buttons;\n }\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].node === node) {\n return buttons[i];\n }\n\n if (buttons[i].buttons.length) {\n var ret = this._nodeToButton(node, buttons[i].buttons);\n\n if (ret) {\n return ret;\n }\n }\n }\n },\n\n /**\r\n * Get container array for a button from a button node (recursive)\r\n *\r\n * @name _nodeToHost\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {array} [buttons] Button array, uses base if not defined\r\n * @return {array} Button's host array\r\n *\r\n */\n _nodeToHost: function _nodeToHost(node, buttons) {\n if (!buttons) {\n buttons = this.s.buttons;\n }\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].node === node) {\n return buttons;\n }\n\n if (buttons[i].buttons.length) {\n var ret = this._nodeToHost(node, buttons[i].buttons);\n\n if (ret) {\n return ret;\n }\n }\n }\n },\n\n /**\r\n * Handle a key press - determine if any button's key configured matches\r\n * what was typed and trigger the action if so.\r\n *\r\n * @name _keypress\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} character The character pressed\r\n * @param {object} e Key event that triggered this call\r\n *\r\n */\n _keypress: function _keypress(character, e) {\n // Check if this button press already activated on another instance of Buttons\n if (e._buttonsHandled) {\n return;\n }\n\n var run = function run(conf, node) {\n if (!conf.key) {\n return;\n }\n\n if (conf.key === character) {\n e._buttonsHandled = true;\n $(node).click();\n } else if ($.isPlainObject(conf.key)) {\n if (conf.key.key !== character) {\n return;\n }\n\n if (conf.key.shiftKey && !e.shiftKey) {\n return;\n }\n\n if (conf.key.altKey && !e.altKey) {\n return;\n }\n\n if (conf.key.ctrlKey && !e.ctrlKey) {\n return;\n }\n\n if (conf.key.metaKey && !e.metaKey) {\n return;\n } // Made it this far - it is good\n\n\n e._buttonsHandled = true;\n $(node).click();\n }\n };\n\n var recurse = function recurse(a) {\n for (var i = 0, ien = a.length; i < ien; i++) {\n run(a[i].conf, a[i].node);\n\n if (a[i].buttons.length) {\n recurse(a[i].buttons);\n }\n }\n };\n\n recurse(this.s.buttons);\n },\n\n /**\r\n * Remove a key from the key listener for this instance (to be used when a\r\n * button is removed)\r\n *\r\n * @name _removeKey\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} conf Button configuration\r\n *\r\n */\n _removeKey: function _removeKey(conf) {\n if (conf.key) {\n var character = $.isPlainObject(conf.key) ? conf.key.key : conf.key; // Remove only one character, as multiple buttons could have the\n // same listening key\n\n var a = this.s.listenKeys.split('');\n var idx = $.inArray(character, a);\n a.splice(idx, 1);\n this.s.listenKeys = a.join('');\n }\n },\n\n /**\r\n * Resolve a button configuration\r\n *\r\n * @name _resolveExtends\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string|function|object} conf Button config to resolve\r\n * @return {object} Button configuration\r\n *\r\n */\n _resolveExtends: function _resolveExtends(conf) {\n var dt = this.s.dt;\n var i, ien;\n var ctx = dt.context[0];\n var _dtButtonsTable = ctx.ext.buttons;\n _dtButtonsTable.collection = _dtButtons.collection;\n\n var toConfObject = function toConfObject(base) {\n var loop = 0; // Loop until we have resolved to a button configuration, or an\n // array of button configurations (which will be iterated\n // separately)\n\n while (!$.isPlainObject(base) && !Array.isArray(base)) {\n if (base === undefined) {\n return;\n }\n\n if (typeof base === 'function') {\n base = base(dt, conf);\n\n if (!base) {\n return false;\n }\n } else if (typeof base === 'string') {\n if (!_dtButtonsTable[base]) {\n throw 'Unknown button type: ' + base;\n }\n\n base = _dtButtonsTable[base];\n }\n\n loop++;\n\n if (loop > 30) {\n // Protect against misconfiguration killing the browser\n throw 'Buttons: Too many iterations';\n }\n }\n\n return Array.isArray(base) ? base : $.extend({}, base);\n };\n\n conf = toConfObject(conf);\n\n while (conf && conf.extend) {\n // Use `toConfObject` in case the button definition being extended\n // is itself a string or a function\n if (!_dtButtonsTable[conf.extend]) {\n throw 'Cannot extend unknown button type: ' + conf.extend;\n }\n\n var objArray = toConfObject(_dtButtonsTable[conf.extend]);\n\n if (Array.isArray(objArray)) {\n return objArray;\n } else if (!objArray) {\n // This is a little brutal as it might be possible to have a\n // valid button without the extend, but if there is no extend\n // then the host button would be acting in an undefined state\n return false;\n } // Stash the current class name\n\n\n var originalClassName = objArray.className;\n conf = $.extend({}, objArray, conf); // The extend will have overwritten the original class name if the\n // `conf` object also assigned a class, but we want to concatenate\n // them so they are list that is combined from all extended buttons\n\n if (originalClassName && conf.className !== originalClassName) {\n conf.className = originalClassName + ' ' + conf.className;\n } // Buttons to be added to a collection -gives the ability to define\n // if buttons should be added to the start or end of a collection\n\n\n var postfixButtons = conf.postfixButtons;\n\n if (postfixButtons) {\n if (!conf.buttons) {\n conf.buttons = [];\n }\n\n for (i = 0, ien = postfixButtons.length; i < ien; i++) {\n conf.buttons.push(postfixButtons[i]);\n }\n\n conf.postfixButtons = null;\n }\n\n var prefixButtons = conf.prefixButtons;\n\n if (prefixButtons) {\n if (!conf.buttons) {\n conf.buttons = [];\n }\n\n for (i = 0, ien = prefixButtons.length; i < ien; i++) {\n conf.buttons.splice(i, 0, prefixButtons[i]);\n }\n\n conf.prefixButtons = null;\n } // Although we want the `conf` object to overwrite almost all of\n // the properties of the object being extended, the `extend`\n // property should come from the object being extended\n\n\n conf.extend = objArray.extend;\n }\n\n return conf;\n }\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Statics\r\n */\n\n /**\r\n * Show / hide a background layer behind a collection\r\n *\r\n * @name Buttons.background\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} Flag to indicate if the background should be shown or\r\n * hidden\r\n * @param {string} Class to assign to the background\r\n *\r\n * @static\r\n *\r\n */\n\n Buttons.background = function (show, className, fade) {\n if (fade === undefined) {\n fade = 400;\n }\n\n if (show) {\n $('
').addClass(className).css('display', 'none').appendTo('body').fadeIn(fade);\n } else {\n $('body > div.' + className).fadeOut(fade, function () {\n $(this).removeClass(className).remove();\n });\n }\n };\n /**\r\n * Instance selector - select Buttons instances based on an instance selector\r\n * value from the buttons assigned to a DataTable. This is only useful if\r\n * multiple instances are attached to a DataTable.\r\n *\r\n * @name Buttons.instanceSelector\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string|int|array} Instance selector - see `instance-selector`\r\n * documentation on the DataTables site\r\n * @param {array} Button instance array that was attached to the DataTables\r\n * settings object\r\n * @return {array} Buttons instances\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.instanceSelector = function (group, buttons) {\n if (!group) {\n return $.map(buttons, function (v) {\n return v.inst;\n });\n }\n\n var ret = [];\n var names = $.map(buttons, function (v) {\n return v.name;\n }); // Flatten the group selector into an array of single options\n\n var process = function process(input) {\n if (Array.isArray(input)) {\n for (var i = 0, ien = input.length; i < ien; i++) {\n process(input[i]);\n }\n\n return;\n }\n\n if (typeof input === 'string') {\n if (input.indexOf(',') !== -1) {\n // String selector, list of names\n process(input.split(','));\n } else {\n // String selector individual name\n var idx = $.inArray(input.trim(), names);\n\n if (idx !== -1) {\n ret.push(buttons[idx].inst);\n }\n }\n } else if (typeof input === 'number') {\n // Index selector\n ret.push(buttons[input].inst);\n }\n };\n\n process(group);\n return ret;\n };\n /**\r\n * Button selector - select one or more buttons from a selector input so some\r\n * operation can be performed on them.\r\n *\r\n * @name Buttons.buttonSelector\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {array} Button instances array that the selector should operate on\r\n * @param {string|int|node|jQuery|array} Button selector - see\r\n * `button-selector` documentation on the DataTables site\r\n * @return {array} Array of objects containing `inst` and `idx` properties of\r\n * the selected buttons so you know which instance each button belongs to.\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.buttonSelector = function (insts, selector) {\n var ret = [];\n\n var nodeBuilder = function nodeBuilder(a, buttons, baseIdx) {\n var button;\n var idx;\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n button = buttons[i];\n\n if (button) {\n idx = baseIdx !== undefined ? baseIdx + i : i + '';\n a.push({\n node: button.node,\n name: button.conf.name,\n idx: idx\n });\n\n if (button.buttons) {\n nodeBuilder(a, button.buttons, idx + '-');\n }\n }\n }\n };\n\n var run = function run(selector, inst) {\n var i, ien;\n var buttons = [];\n nodeBuilder(buttons, inst.s.buttons);\n var nodes = $.map(buttons, function (v) {\n return v.node;\n });\n\n if (Array.isArray(selector) || selector instanceof $) {\n for (i = 0, ien = selector.length; i < ien; i++) {\n run(selector[i], inst);\n }\n\n return;\n }\n\n if (selector === null || selector === undefined || selector === '*') {\n // Select all\n for (i = 0, ien = buttons.length; i < ien; i++) {\n ret.push({\n inst: inst,\n node: buttons[i].node\n });\n }\n } else if (typeof selector === 'number') {\n // Main button index selector\n ret.push({\n inst: inst,\n node: inst.s.buttons[selector].node\n });\n } else if (typeof selector === 'string') {\n if (selector.indexOf(',') !== -1) {\n // Split\n var a = selector.split(',');\n\n for (i = 0, ien = a.length; i < ien; i++) {\n run(a[i].trim(), inst);\n }\n } else if (selector.match(/^\\d+(\\-\\d+)*$/)) {\n // Sub-button index selector\n var indexes = $.map(buttons, function (v) {\n return v.idx;\n });\n ret.push({\n inst: inst,\n node: buttons[$.inArray(selector, indexes)].node\n });\n } else if (selector.indexOf(':name') !== -1) {\n // Button name selector\n var name = selector.replace(':name', '');\n\n for (i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].name === name) {\n ret.push({\n inst: inst,\n node: buttons[i].node\n });\n }\n }\n } else {\n // jQuery selector on the nodes\n $(nodes).filter(selector).each(function () {\n ret.push({\n inst: inst,\n node: this\n });\n });\n }\n } else if (_typeof(selector) === 'object' && selector.nodeName) {\n // Node selector\n var idx = $.inArray(selector, nodes);\n\n if (idx !== -1) {\n ret.push({\n inst: inst,\n node: nodes[idx]\n });\n }\n }\n };\n\n for (var i = 0, ien = insts.length; i < ien; i++) {\n var inst = insts[i];\n run(selector, inst);\n }\n\n return ret;\n };\n /**\r\n * Version information\r\n *\r\n * @name Buttons.version\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @type {string}\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.version = '1.5.1';\n $.extend(_dtButtons, {\n collection: {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.collection');\n },\n className: 'buttons-collection',\n action: function action(e, dt, button, config) {\n var host = button;\n var collectionParent = $(button).parents('div.dt-button-collection');\n var hostPosition = {\n top: host.position().top + parseInt(host.css('marginTop'), 10),\n left: host.position().left + parseInt(host.css('marginLeft'), 10)\n };\n var tableContainer = $(dt.table().container());\n var multiLevel = false;\n var insertPoint = host; // Remove any old collection\n\n if (collectionParent.length) {\n multiLevel = $('.dt-button-collection').position();\n insertPoint = collectionParent;\n $('body').trigger('click.dtb-collection');\n }\n\n config._collection.addClass(config.collectionLayout).css('display', 'none').insertAfter(insertPoint).fadeIn(config.fade);\n\n var position = config._collection.css('position');\n\n if (multiLevel && position === 'absolute') {\n config._collection.css({\n top: multiLevel.top,\n left: multiLevel.left\n });\n } else if (position === 'absolute') {\n config._collection.css({\n top: hostPosition.top + host.outerHeight(),\n left: hostPosition.left\n }); // calculate overflow when positioned beneath\n\n\n var tableBottom = tableContainer.offset().top + tableContainer.height();\n\n var listBottom = hostPosition.top + host.outerHeight() + config._collection.outerHeight();\n\n var bottomOverflow = listBottom - tableBottom; // calculate overflow when positioned above\n\n var listTop = hostPosition.top - config._collection.outerHeight();\n\n var tableTop = tableContainer.offset().top;\n var topOverflow = tableTop - listTop; // if bottom overflow is larger, move to the top because it fits better\n\n if (bottomOverflow > topOverflow) {\n config._collection.css('top', hostPosition.top - config._collection.outerHeight() - 5);\n }\n\n var listRight = hostPosition.left + config._collection.outerWidth();\n\n var tableRight = tableContainer.offset().left + tableContainer.width();\n\n if (listRight > tableRight) {\n config._collection.css('left', hostPosition.left - (listRight - tableRight));\n }\n } else {\n // Fix position - centre on screen\n var top = config._collection.height() / 2;\n\n if (top > $(window).height() / 2) {\n top = $(window).height() / 2;\n }\n\n config._collection.css('marginTop', top * -1);\n }\n\n if (config.background) {\n // Si la tabla se encuentra en un dialogo insertamos el background dentro del dialogo\n if ($('div.rup-dialog').has('#' + dt.context[0].sTableId + '_wrapper').length ? true : false) {\n $('div.rup-dialog #' + dt.context[0].sTableId + '_wrapper').append('
');\n } // Si no usamos el funcionamiento por defecto\n else {\n Buttons.background(true, config.backgroundClassName, config.fade);\n }\n } // Need to break the 'thread' for the collection button being\n // activated by a click - it would also trigger this event\n\n\n setTimeout(function () {\n // This is bonkers, but if we don't have a click listener on the\n // background element, iOS Safari will ignore the body click\n // listener below. An empty function here is all that is\n // required to make it work...\n $('div.dt-button-background').on('click.dtb-collection', function () {});\n $('body').on('click.dtb-collection', function (e) {\n // andSelf is deprecated in jQ1.8, but we want 1.7 compat\n var back = $.fn.addBack ? 'addBack' : 'andSelf';\n\n if (!$(e.target).parents()[back]().filter(config._collection).length) {\n config._collection.fadeOut(config.fade, function () {\n config._collection.detach();\n });\n\n $('div.dt-button-background').off('click.dtb-collection'); // Si la tabla se encuentra en un dialogo eliminamos el background de dentro del dialogo\n\n if ($('div.rup-dialog').has('#' + dt.context[0].sTableId + '_wrapper').length ? true : false) {\n $('div.dt-button-background').remove();\n } // Si no usamos el funcionamiento por defecto\n else {\n Buttons.background(false, config.backgroundClassName, config.fade);\n }\n\n $('body').off('click.dtb-collection');\n dt.off('buttons-action.b-internal');\n }\n });\n }, 10); // Como el boton se posiciona de manera absoluta hay que establecerle la posicion\n // cada vez que se cambia el tamaño de la pantalla.\n\n $(window).on('resize.ajustarCollection', function () {\n if (!$('div.dt-button-collection').is(':visible')) {\n $(window).off('resize.ajustarCollection');\n } else {\n hostPosition = {\n top: host.position().top + parseInt(host.css('marginTop'), 10),\n left: host.position().left + parseInt(host.css('marginLeft'), 10)\n };\n\n config._collection.css({\n top: hostPosition.top + host.outerHeight(),\n left: hostPosition.left\n });\n }\n });\n\n if (config.autoClose) {\n dt.on('buttons-action.b-internal', function () {\n $('div.dt-button-background').click();\n });\n }\n },\n background: true,\n collectionLayout: '',\n backgroundClassName: 'dt-button-background',\n autoClose: false,\n fade: 400,\n attr: {\n 'aria-haspopup': true\n }\n },\n addButton: function addButton(dt, conf) {\n var ctx = dt.context[0];\n var collection = _dtButtons['collection'];\n _dtButtons = ctx.ext.buttons;\n _dtButtons.collection = collection;\n\n if (_dtButtons.addButton) {\n return 'addButton';\n }\n },\n editButton: function editButton(dt, conf) {\n if (_dtButtons.editButton) {\n return 'editButton';\n }\n },\n cloneButton: function cloneButton(dt, conf) {\n if (_dtButtons.cloneButton) {\n return 'cloneButton';\n }\n },\n deleteButton: function deleteButton(dt, conf) {\n if (_dtButtons.deleteButton) {\n return 'deleteButton';\n }\n },\n reportsButton: function reportsButton(dt, conf) {\n if (_dtButtons.reportsButton) {\n return 'reportsButton';\n }\n },\n pageLength: function pageLength(dt) {\n var lengthMenu = dt.settings()[0].aLengthMenu;\n var vals = Array.isArray(lengthMenu[0]) ? lengthMenu[0] : lengthMenu;\n var lang = Array.isArray(lengthMenu[0]) ? lengthMenu[1] : lengthMenu;\n\n var text = function text(dt) {\n return dt.i18n('rup_table.pageLength', {\n '-1': 'Show all rows',\n _: 'Show %d rows'\n }, dt.page.len());\n };\n\n return {\n extend: 'collection',\n text: text,\n className: 'buttons-page-length',\n autoClose: true,\n buttons: $.map(vals, function (val, i) {\n return {\n text: lang[i],\n className: 'button-page-length',\n action: function action(e, dt) {\n dt.page.len(val).draw();\n },\n init: function init(dt, node, conf) {\n var that = this;\n\n var fn = function fn() {\n that.active(dt.page.len() === val);\n };\n\n dt.on('length.dt' + conf.namespace, fn);\n fn();\n },\n destroy: function destroy(dt, node, conf) {\n dt.off('length.dt' + conf.namespace);\n }\n };\n }),\n init: function init(dt, node, conf) {\n var that = this;\n dt.on('length.dt' + conf.namespace, function () {\n that.text(text(dt));\n });\n },\n destroy: function destroy(dt, node, conf) {\n dt.off('length.dt' + conf.namespace);\n }\n };\n }\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables API\r\n *\r\n * For complete documentation, please refer to the docs/api directory or the\r\n * DataTables site\r\n */\n // Buttons group and individual button selector\n\n DataTable.Api.register('buttons()', function (group, selector) {\n // Argument shifting\n if (selector === undefined) {\n selector = group;\n group = undefined;\n }\n\n this.selector.buttonGroup = group;\n var res = this.iterator(true, 'table', function (ctx) {\n if (ctx._buttons) {\n return Buttons.buttonSelector(Buttons.instanceSelector(group, ctx._buttons), selector);\n }\n }, true);\n res._groupSelector = group;\n return res;\n }); // Individual button selector\n\n DataTable.Api.register('button()', function (group, selector) {\n // just run buttons() and truncate\n var buttons = this.buttons(group, selector);\n\n if (buttons.length > 1) {\n buttons.splice(1, buttons.length);\n }\n\n return buttons;\n }); // Active buttons\n\n DataTable.Api.registerPlural('buttons().active()', 'button().active()', function (flag) {\n if (flag === undefined) {\n return this.map(function (set) {\n return set.inst.active(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.active(set.node, flag);\n });\n }); // Get / set button action\n\n DataTable.Api.registerPlural('buttons().action()', 'button().action()', function (action) {\n if (action === undefined) {\n return this.map(function (set) {\n return set.inst.action(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.action(set.node, action);\n });\n }); // Enable / disable buttons\n\n DataTable.Api.register(['buttons().enable()', 'button().enable()'], function (flag, contextMenu) {\n return this.each(function (set) {\n set.inst.enable(set.node, flag, contextMenu);\n });\n }); // Disable buttons\n\n DataTable.Api.register(['buttons().disable()', 'button().disable()'], function (contextMenu) {\n return this.each(function (set) {\n set.inst.disable(set.node, contextMenu);\n });\n }); // Get button nodes\n\n DataTable.Api.registerPlural('buttons().nodes()', 'button().node()', function () {\n var jq = $(); // jQuery will automatically reduce duplicates to a single entry\n\n $(this.each(function (set) {\n jq = jq.add(set.inst.node(set.node));\n }));\n return jq;\n }); // Get / set button processing state\n\n DataTable.Api.registerPlural('buttons().processing()', 'button().processing()', function (flag) {\n if (flag === undefined) {\n return this.map(function (set) {\n return set.inst.processing(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.processing(set.node, flag);\n });\n }); // Get / set button text (i.e. the button labels)\n\n DataTable.Api.registerPlural('buttons().text()', 'button().text()', function (label) {\n if (label === undefined) {\n return this.map(function (set) {\n return set.inst.text(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.text(set.node, label);\n });\n }); // Trigger a button's action\n\n DataTable.Api.registerPlural('buttons().trigger()', 'button().trigger()', function () {\n return this.each(function (set) {\n set.inst.node(set.node).trigger('click');\n });\n }); // Get the container elements\n\n DataTable.Api.registerPlural('buttons().containers()', 'buttons().container()', function () {\n var jq = $();\n var groupSelector = this._groupSelector; // We need to use the group selector directly, since if there are no buttons\n // the result set will be empty\n\n this.iterator(true, 'table', function (ctx) {\n if (ctx._buttons) {\n var insts = Buttons.instanceSelector(groupSelector, ctx._buttons);\n\n for (var i = 0, ien = insts.length; i < ien; i++) {\n jq = jq.add(insts[i].container());\n }\n }\n });\n return jq;\n }); // Add a new button\n\n DataTable.Api.register('button().add()', function (idx, conf) {\n var ctx = this.context;\n var api = new DataTable.Api(ctx); // Don't use `this` as it could be empty - select the instances directly\n\n if (ctx.length) {\n var inst = Buttons.instanceSelector(this._groupSelector, ctx[0]._buttons);\n\n if (inst.length) {\n inst[0].add(conf, idx); // Nuevo botón al contextMenu\n\n _updateContextMenu(this[0].inst.s.buttons, api, ctx[0]);\n }\n }\n\n return this.button(this._groupSelector, idx);\n }); // Destroy the button sets selected\n\n DataTable.Api.register('buttons().destroy()', function () {\n this.pluck('inst').each(function (inst) {\n inst.destroy();\n });\n return this;\n }); // Remove a button\n\n DataTable.Api.registerPlural('buttons().remove()', 'buttons().remove()', function () {\n this.each(function (set) {\n set.inst.remove(set.node);\n });\n return this;\n }); // Information box that can be used by buttons\n\n var _infoTimer;\n\n DataTable.Api.register('buttons.info()', function (title, message, time) {\n var that = this;\n\n if (title === false) {\n $('#table_buttons_info').fadeOut(function () {\n $(this).remove();\n });\n clearTimeout(_infoTimer);\n _infoTimer = null;\n return this;\n }\n\n if (_infoTimer) {\n clearTimeout(_infoTimer);\n }\n\n if ($('#table_buttons_info').length) {\n $('#table_buttons_info').remove();\n }\n\n title = title ? '

' + title + '

' : '';\n $('
').html(title).append($('
')[typeof message === 'string' ? 'html' : 'append'](message)).css('display', 'none').appendTo('body').fadeIn();\n\n if (time !== undefined && time !== 0) {\n _infoTimer = setTimeout(function () {\n that.buttons.info(false);\n }, time);\n }\n\n return this;\n }); // Get data from the table for export - this is common to a number of plug-in\n // buttons so it is included in the Buttons core library\n\n DataTable.Api.register('buttons.exportData()', function (options) {\n if (this.context.length) {\n return _exportData(new DataTable.Api(this.context[0]), options);\n }\n }); // Get information about the export that is common to many of the export data\n // types (DRY)\n\n DataTable.Api.register('buttons.exportInfo()', function (conf) {\n if (!conf) {\n conf = {};\n }\n\n return {\n filename: _filename(conf),\n title: _title(conf),\n messageTop: _message(this, conf.message || conf.messageTop, 'top'),\n messageBottom: _message(this, conf.messageBottom, 'bottom')\n };\n }); // Gestiona las acciones de los botones\n\n DataTable.Api.register('buttons.actions()', function (dt, config) {\n var ctx = dt.settings()[0]; // Añade aquí las funciones de tus botones\n\n switch (config.type) {\n case 'add':\n ctx.oInit.buttons.myLastAction = 'add';\n\n if (ctx.oInit.formEdit !== undefined) {\n $.when(DataTable.Api().editForm.loadSaveDialogForm(ctx, 'POST')).then(function () {\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Limpiamos el formulario\n\n if ($(idTableDetail).find('form')[0] !== undefined) {\n $(idTableDetail).find('form')[0].reset();\n jQuery.each($('select.rup_combo', $(idTableDetail)), function (index, elem) {\n jQuery(elem).rup_combo('refresh');\n });\n\n if (ctx.multiselection.numSelected > 0) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.checkSelectedElems'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n // Abrimos el formulario\n if (ctx.oInit.seeker !== undefined && ctx.oInit.seeker.activate) {\n DataTable.Api().seeker.limpiarSeeker(dt, ctx); // Y deselecionamos los checks y seekers\n } else {\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt); // Y deselecionamos los checks y seekers\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx); // Y deselecionamos los checks y seekers\n }\n }\n\n DataTable.Api().editForm.openSaveDialog('POST', dt, null, ctx.oInit.formEdit.customTitle);\n }\n });\n } else {\n DataTable.Api().editForm.openSaveDialog('POST', dt, null, ctx.oInit.formEdit.customTitle);\n }\n } else {\n $.rup_messages('msgError', {\n title: 'Error grave',\n message: '

Falta definir \"detailForm\" en la inicialización de la tabla.

'\n });\n }\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.currentPos = undefined;\n DataTable.Api().inlineEdit.add(dt, ctx);\n }\n\n break;\n\n case 'edit':\n // Abrimos el formulario\n ctx.oInit.buttons.myLastAction = 'edit';\n\n if (ctx.oInit.formEdit !== undefined) {\n // Se busca el idRow con el último seleccionado. En caso de no existir, será el primero.\n $.when(DataTable.Api().editForm.getRowSelected(dt, 'PUT')).then(function (rowInfo) {\n if (ctx.oInit.formEdit.$navigationBar === undefined || ctx.oInit.formEdit.$navigationBar.funcionParams === undefined || ctx.oInit.formEdit.$navigationBar.funcionParams[4] === undefined || dt.page() + 1 === Number(ctx.oInit.formEdit.$navigationBar.funcionParams[4])) {\n DataTable.Api().editForm.openSaveDialog('PUT', dt, rowInfo.line, ctx.oInit.formEdit.customTitle);\n }\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.currentPos = undefined;\n ctx.oInit.inlineEdit.alta = undefined;\n var idRowInline = DataTable.Api().inlineEdit.getRowSelected(dt, 'PUT').line;\n }\n\n break;\n\n case 'clone':\n ctx.oInit.buttons.myLastAction = 'clone'; // Abrimos el formulario\n\n if (ctx.oInit.formEdit !== undefined) {\n // Se busca el idRow con el último seleccionado. En caso de no existir, será el primero.\n $.when(DataTable.Api().editForm.getRowSelected(dt, 'CLONE')).then(function (rowInfo) {\n DataTable.Api().editForm.openSaveDialog('CLONE', dt, rowInfo.line, ctx.oInit.formEdit.customTitle);\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.alta = true;\n ctx.oInit.inlineEdit.currentPos = undefined;\n var idRowInline = DataTable.Api().inlineEdit.getRowSelected(dt, 'CLONE').line;\n }\n\n break;\n\n case 'delete':\n var customEliminar = ctx.oInit.validarEliminar;\n\n if (typeof customEliminar === \"function\" && customEliminar(ctx)) {\n return false;\n }\n\n ctx.oInit.buttons.myLastAction = 'delete'; // borramos todos los seleccionados.\n\n if (!ctx.oInit.noEdit && ctx.oInit.formEdit !== undefined) {\n DataTable.Api().editForm.deleteAllSelects(dt);\n } else if (!ctx.oInit.noEdit && ctx.oInit.inlineEdit !== undefined) {\n //edicion en linea\n DataTable.Api().inlineEdit.deleteAllSelects(dt);\n } else {\n //Delete sin formulario\n _deleteAllSelects(dt);\n }\n\n break;\n }\n }); // Detecta el numero de filas seleccionadas y en funcion de eso muestra u oculta los botones.\n\n DataTable.Api.register('buttons.displayRegex()', function (ctx) {\n if (ctx._buttons[0].inst.s.disableAllButtons === undefined) {\n var opts = ctx._buttons[0].inst.s.buttons;\n var collectionObject;\n $.each(opts, function (i) {\n collectionObject = null;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n\n if (ctx.oInit.masterDetail !== undefined && this.conf.id === ctx.sTableId + 'addButton_1') {\n //si es maestro detalle para el boton add ,solo se renderiza cuando hay selección en el padre.\n var table = $(ctx.oInit.masterDetail.master).DataTable();\n numOfSelectedRows = table.context[0].multiselection.numSelected; //Nums del padre\n\n this.conf.displayRegex = /^[1-9][0-9]*$/; //se cambia expresion regular\n }\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx); // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n collectionObject = this;\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx);\n }\n });\n }\n });\n DataTable.Api.register('buttons.disableAllButtons()', function (ctx, exception) {\n var s = ctx._buttons[0].inst.s;\n $.each(s.buttons, function () {\n if (ctx.oInit.noEdit && exception !== undefined && !exception.includes(this.node.id)) {\n // Deshabilita permanentemente el botón (tanto de la toolbar como del contextMenu).\n this.conf.displayRegex = undefined;\n } else if (exception === undefined || !exception.includes(this.node.id)) {\n // Deshabilita el botón de la toolbar.\n $(this.node).prop('disabled', true); // Deshabilita el botón del contextMenu.\n\n $('#' + this.node.id + '_contextMenuToolbar').addClass('disabledButtonsTable');\n }\n });\n s.disableAllButtons = true;\n });\n DataTable.Api.register('buttons.initButtons()', function (ctx, opts) {\n _initButtons(ctx, opts);\n });\n DataTable.Api.register('buttons.deleteNotForm()', function (dt) {\n _deleteAllSelects(dt);\n });\n /**\r\n * Get the file name for an exported file.\r\n *\r\n * @name _filename\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object}\tconfig Button configuration\r\n * @param {boolean} incExtension Include the file name extension\r\n *\r\n */\n\n var _filename = function _filename(config) {\n // Backwards compatibility\n var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined && config.title !== null && config.title !== '' ? config.title : config.filename;\n\n if (typeof filename === 'function') {\n filename = filename();\n }\n\n if (filename === undefined || filename === null) {\n return null;\n }\n\n if (filename.indexOf('*') !== -1) {\n filename = filename.replace('*', $('head > title').text()).trim();\n } // Strip characters which the OS will object to\n\n\n filename = filename.replace(/[^a-zA-Z0-9_\\u00A1-\\uFFFF\\.,\\-_ !\\(\\)]/g, '');\n\n var extension = _stringOrFunction(config.extension);\n\n if (!extension) {\n extension = '';\n }\n\n return filename + extension;\n };\n /**\r\n * Simply utility method to allow parameters to be given as a function\r\n *\r\n * @name _stringOrFunction\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {undefined|string|function} option Option\r\n *\r\n * @return {null|string} Resolved value\r\n *\r\n */\n\n\n var _stringOrFunction = function _stringOrFunction(option) {\n if (option === null || option === undefined) {\n return null;\n } else if (typeof option === 'function') {\n return option();\n }\n\n return option;\n };\n /**\r\n * Get the title for an exported file.\r\n *\r\n * @name _title\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config\tButton configuration\r\n *\r\n */\n\n\n var _title = function _title(config) {\n var title = _stringOrFunction(config.title);\n\n return title === null ? null : title.indexOf('*') !== -1 ? title.replace('*', $('head > title').text() || 'Exported data') : title;\n };\n\n var _message = function _message(dt, option, position) {\n var message = _stringOrFunction(option);\n\n if (message === null) {\n return null;\n }\n\n var caption = $('caption', dt.table().container()).eq(0);\n\n if (message === '*') {\n var side = caption.css('caption-side');\n\n if (side !== position) {\n return null;\n }\n\n return caption.length ? caption.text() : '';\n }\n\n return message;\n };\n\n var _exportTextarea = $('')[0];\n\n var _exportData = function _exportData(dt, inOpts) {\n var config = $.extend(true, {}, {\n rows: null,\n columns: '',\n modifier: {\n search: 'applied',\n order: 'applied'\n },\n orthogonal: 'display',\n stripHtml: true,\n stripNewlines: true,\n decodeEntities: true,\n trim: true,\n format: {\n header: function header(d) {\n return strip(d);\n },\n footer: function footer(d) {\n return strip(d);\n },\n body: function body(d) {\n return strip(d);\n }\n }\n }, inOpts);\n\n var strip = function strip(str) {\n if (typeof str !== 'string') {\n return str;\n } // Always remove script tags\n\n\n str = str.replace(/)<[^<]*)*<\\/script>/gi, '');\n\n if (config.stripHtml) {\n str = str.replace(/<[^>]*>/g, '');\n }\n\n if (config.trim) {\n str = str.replace(/^\\s+|\\s+$/g, '');\n }\n\n if (config.stripNewlines) {\n str = str.replace(/\\n/g, ' ');\n }\n\n if (config.decodeEntities) {\n _exportTextarea.innerHTML = str;\n str = _exportTextarea.value;\n }\n\n return str;\n };\n\n var header = dt.columns(config.columns).indexes().map(function (idx) {\n var el = dt.column(idx).header();\n return config.format.header(el.innerHTML, idx, el);\n }).toArray();\n var footer = dt.table().footer() ? dt.columns(config.columns).indexes().map(function (idx) {\n var el = dt.column(idx).footer();\n return config.format.footer(el ? el.innerHTML : '', idx, el);\n }).toArray() : null; // If Select is available on this table, and any rows are selected, limit the export\n // to the selected rows. If no rows are selected, all rows will be exported. Specify\n // a `selected` modifier to control directly.\n\n var modifier = $.extend({}, config.modifier);\n\n if (dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined) {\n if (dt.rows(config.rows, $.extend({\n selected: true\n }, modifier)).any()) {\n $.extend(modifier, {\n selected: true\n });\n }\n }\n\n var rowIndexes = dt.rows(config.rows, modifier).indexes().toArray();\n var selectedCells = dt.cells(rowIndexes, config.columns);\n var cells = selectedCells.render(config.orthogonal).toArray();\n var cellNodes = selectedCells.nodes().toArray();\n var columns = header.length;\n var rows = columns > 0 ? cells.length / columns : 0;\n var body = [rows];\n var cellCounter = 0;\n\n for (var i = 0, ien = rows; i < ien; i++) {\n var row = [columns];\n\n for (var j = 0; j < columns; j++) {\n row[j] = config.format.body(cells[cellCounter], i, j, cellNodes[cellCounter]);\n cellCounter++;\n }\n\n body[i] = row;\n }\n\n return {\n header: header,\n footer: footer,\n body: body\n };\n };\n /**\r\n * Activa la coleccion\r\n *\r\n * @name _enableCollection\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _enableCollection = function _enableCollection(id) {\n $('#' + id).prop('disabled', false);\n };\n /**\r\n * Desactiva la coleccion\r\n *\r\n * @name _disableCollection\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _disableCollection = function _disableCollection(id) {\n $('#' + id).prop('disabled', true);\n };\n /**\r\n * Activa el boton y su opcion dentro del context menu\r\n *\r\n * @name _enableButtonAndContextMenuOption\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _enableButtonAndContextMenuOption = function _enableButtonAndContextMenuOption(id) {\n $('#' + id).prop('disabled', false);\n $('#' + id + '_contextMenuToolbar').removeClass('disabledButtonsTable');\n };\n /**\r\n * Desactiva el boton y su opcion dentro del context menu\r\n *\r\n * @name _disableButtonAndContextMenuOption\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _disableButtonAndContextMenuOption = function _disableButtonAndContextMenuOption(id) {\n $('#' + id).prop('disabled', true);\n $('#' + id + '_contextMenuToolbar').addClass('disabledButtonsTable');\n };\n /**\r\n * Gestiona la propiedad de activado/desactivado de los botones y de sus opciones\r\n * dentro del context menu.\r\n *\r\n * @name _manageButtonsAndButtonsContextMenu\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} opts\tButtons properties\r\n * @param {int} numOfSelectedRows\tNumber of selected rows\r\n * @param {null|object} collectionObject\tCollection button properties\r\n *\r\n */\n\n\n var _manageButtonsAndButtonsContextMenu = function _manageButtonsAndButtonsContextMenu(opts, numOfSelectedRows, collectionObject, ctx) {\n if (opts.conf.custom === undefined || !opts.conf.custom) {\n // Si pertenece a un collection o es un collection\n if (opts.collection !== null && collectionObject) {\n var collectionId = collectionObject.conf.id;\n var collectionDisplayRegex = collectionObject.conf.displayRegex;\n var alreadyExecuted = false; // Recorre todos los botones dentro del collection\n\n $.each(collectionObject.buttons, function (key, value) {\n // Activa/desactiva en funcion de la propiedad 'displayRegex' del padre y los hijos\n if (collectionDisplayRegex !== undefined && value.conf.displayRegex !== undefined) {\n if (collectionDisplayRegex.test(numOfSelectedRows) && value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } else {\n _disableButtonAndContextMenuOption(value.conf.id);\n }\n } // Activa/desactiva en funcion de la propiedad 'displayRegex' de sus hijos\n else if (collectionDisplayRegex === undefined && value.conf.displayRegex !== undefined) {\n // Habilita la coleccion si cumple el regex (solo se ejecuta una vez como\n // maximo gracias al booleano 'alreadyExecuted')\n if (value.conf.displayRegex.test(numOfSelectedRows) && !alreadyExecuted) {\n _enableCollection(collectionId);\n\n alreadyExecuted = true;\n } // Habilita el boton si cumple el displayRegex\n\n\n if (value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } // Como este boton no cumple el 'displayRegex' para ser habilitado, se deshabilitan\n // tanto el boton como su opcion en el contextMenu\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n } // En caso de que ningun regex cumpliese, se fuerza la deshabilitacion\n\n\n if (!alreadyExecuted) {\n _disableCollection(collectionId);\n }\n } // Desactiva todo si ni el collection ni los hijos tienen la propiedad 'displayRegex'\n // o simplemente si los hijos no tienen la propiedad\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n\n if (!alreadyExecuted) {\n _disableCollection(collectionId);\n\n alreadyExecuted = true;\n }\n }\n }); // Genera un evento encargado de ocultar los botones dentro del collection.\n // Se comprueba mediante una clase si ya tiene o no el evento, mejorando asi\n // el rendimiento\n\n $('#' + collectionId + ':not(.listening)').addClass('listening').on('click', function (e) {\n // Se establece el valor de 'numOfSelectedRows' porque sino siempre tendria\n // el valor recibido cuando se creo el evento\n var numOfSelectedRows = ctx.multiselection.numSelected;\n $.each(collectionObject.buttons, function (key, value) {\n // Habilita el boton dentro del collection\n if (value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } // Deshabilita el boton dentro del collection\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n }\n });\n });\n } // Si el boton no tiene un regex definido, permanecera siempre desactivado\n else if (opts.conf.displayRegex === undefined) {\n // Deshabilita el boton y su opcion dentro del context menu\n _disableButtonAndContextMenuOption(opts.conf.id);\n } // Si tiene un regex definido, lo activa y desactiva en funcion de este\n else if (opts.conf.displayRegex !== undefined) {\n // Si el regex recibido de cada boton cumple la sentencia al probarlo contra\n // el numero de filas seleccionadas, se mostrara, en caso contrario, permanecera\n // oculto\n if (opts.conf.displayRegex.test(numOfSelectedRows)) {\n // Habilita el boton y su opcion dentro del context menu\n _enableButtonAndContextMenuOption(opts.conf.id);\n } else {\n // Deshabilita el boton y su opcion dentro del context menu\n _disableButtonAndContextMenuOption(opts.conf.id);\n }\n }\n }\n };\n /**\r\n * Establece el tipo de llamada necesario para obtener los datos según lo seleccionado\r\n * e inicia la gestión para finalmente obtenerlos\r\n *\r\n * @name _reports\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} that Objeto del boton\r\n * @param {object} config Configuracion del boton\r\n *\r\n */\n\n\n var _reports = function _reports(dt, that, config) {\n var ctx = dt.settings()[0];\n var info = dt.buttons.exportInfo(config);\n var type;\n var multiselection = ctx.multiselection;\n var selectedAll = multiselection.selectedAll;\n var deselectedIds = multiselection.deselectedIds;\n\n if (selectedAll) {\n if (deselectedIds.length > 0) {\n // Este caso es para cuando se selecciona todo y despues se\n // deseleccionan algunos registros\n type = 'all-deselected';\n } else {\n // Este caso es para cuando se seleccionan todos los registros\n type = 'all';\n }\n } else if (multiselection.selectedIds.length > 0) {\n // Este caso para cuando hay determinados registros seleccionados manualmente\n type = 'selected';\n } else {\n // Este caso para cuando no hay registros seleccionados\n type = 'all';\n selectedAll = true;\n }\n\n $.when(_reportsTypeOfCopy(dt, type, config.request, multiselection, selectedAll, deselectedIds)).then(function (exportData, ajaxOptions) {\n // Si exportData cumple la siguiente condicion significa que los datos se van a copiar al portapapeles\n if (exportData !== undefined) {\n var exportDataRows = exportData.length;\n var exportDataParsed = JSON.stringify(exportData);\n var hiddenDiv = $('
').css({\n height: 1,\n width: 1,\n overflow: 'hidden',\n position: 'fixed',\n top: 0,\n left: 0\n });\n\n if (typeof ajaxOptions.data == 'string') {\n ajaxOptions.data = JSON.parse(ajaxOptions.data);\n }\n\n exportDataParsed = _convertToTabulador(ajaxOptions.reportsExportAllColumns, ajaxOptions.data.columns, exportDataParsed, true);\n var textarea = $('').val(exportDataParsed).appendTo(hiddenDiv);\n\n _reportsOpenMessage(dt, ctx, that, exportDataRows, hiddenDiv, textarea);\n } else {\n // Descargara un fichero\n _reportsRequestFile(ctx, ajaxOptions);\n }\n });\n };\n /**\r\n * Se encarga de mapear los datos de json a datos separados por el tabulador.\r\n *\r\n * @name ConvertToTabulador\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} reportsExportAllColumns true en caso de querer mostrar todas las columnas (incluidas las ocultas)\r\n * @param {object} columns Objeto que contiene las columnas a mostrar\r\n * @param {object} objArray Objeto que contiene los datos a exportar\r\n * @param {boolean} true en caso de querer que se mueste la cabecera\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _convertToTabulador = function _convertToTabulador(reportsExportAllColumns, columns, objArray, showLabel) {\n var array = _typeof(objArray) !== 'object' ? JSON.parse(objArray) : objArray;\n var separator = \";\";\n var str = '';\n var checkColumns = false; // Separador de campos dependiendo del idioma\n\n if ($.rup.lang === 'en') {\n separator = \",\";\n }\n\n if (!reportsExportAllColumns && columns != undefined) {\n checkColumns = true;\n }\n\n if (showLabel) {\n // Comprueba si solo se quieren mostrar las columnas definidas/visibles o todas\n if (checkColumns) {\n str = '\\\"' + columns.toString().replace(/,/g, '\\\"' + separator + '\\\"') + '\\\"\\r\\n';\n } else {\n var row = ''; // Se asignan los nombres de las columnas\n\n $.each(array[0], function (key, value) {\n // Comprobar si es un objeto, en caso afirmativo lo recorremos y lo concatenamos\n if ($.isPlainObject(value)) {\n var objectName = key;\n $.each(this, function (key, value) {\n var keyToCamelKeys = key.substring(0, 1).toLocaleUpperCase() + key.substring(1);\n row += '\\\"' + objectName + keyToCamelKeys + '\\\"' + separator;\n });\n } else {\n row += '\\\"' + key + '\\\"' + separator;\n }\n });\n row = row.slice(0, -1);\n str += row + '\\r\\n';\n }\n } // Se asignan los valores\n\n\n $.each(array, function () {\n var line = '';\n $.each(this, function (key, value) {\n // Comprueba si solo se quieren mostrar los valores de las columnas definidas/visibles y evita la insercion de las no que no lo estan\n if (checkColumns && columns.indexOf(key) == -1) {\n return;\n } // Comprobar si es un objeto, en caso afirmativo lo recorremos y lo concatenamos\n\n\n if ($.isPlainObject(value)) {\n $.each(this, function (key, value) {\n line += '\\\"' + value + '\\\"' + separator;\n });\n } else {\n line += '\\\"' + value + '\\\"' + separator;\n }\n });\n line = line.slice(0, -1);\n str += line + '\\r\\n';\n });\n return str;\n };\n /**\r\n * Según el tipo de función de copia solicitada, realiza unas u otras comprobaciones\r\n * antes de solicitar los datos al servidor\r\n *\r\n * @name _reportsTypeOfCopy\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {string} type Tipo de funcion de copia a ejecutar\r\n * @param {object} request Contiene todos los parametros de la petición AJAX\r\n * @param {object} multiselection Propiedades de la multiseleccion\r\n * @param {boolean} selectedAll Cuando es true significa que todas las filas estan marcadas\r\n * @param {array} [deselectedIds] ID's de las filas deseleccionadas\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsTypeOfCopy = function _reportsTypeOfCopy(dt, type, request, multiselection, selectedAll, deselectedIds) {\n var ctx = dt.settings()[0];\n var deferred = $.Deferred();\n var exportData;\n var selectedIds = multiselection.selectedIds;\n var selectedRows = multiselection.selectedRowsPerPage;\n var ajaxOptions = {};\n\n if (type === 'selected') {\n var _exportData2 = [];\n\n if (request.dataType === 'json') {\n var localAccess = true; // Comprueba si todos los valores seleccionados estan en la misma pagina\n\n $.each(selectedRows, function (key, value) {\n if (ctx.json.page != value.page) {\n localAccess = false;\n return false;\n }\n });\n\n if (localAccess) {\n // Puede acceder a los valores seleccionados localmente\n $.each(selectedRows, function (key, value) {\n var idPadre = value.id;\n $.each(ctx.json.rows, function (key, value) {\n if (DataTable.Api().rupTable.getIdPk(value) === idPadre) {\n _exportData2.push(value);\n }\n });\n });\n ajaxOptions.data = {};\n ajaxOptions.data.columns = _loadDefinedColums(dt, ctx, request);\n\n if (ctx.oInit.buttons.report !== undefined) {\n ajaxOptions.data.columnsName = ctx.oInit.buttons.report.columnsName;\n }\n\n ajaxOptions.reportsExportAllColumns = request.reportsExportAllColumns;\n deferred.resolve(_exportData2, ajaxOptions);\n return deferred.promise();\n }\n }\n }\n\n if (request.dataType === 'json') {\n // Accede a los datos mediante el servidor ya que se ha hecho uso de la paginacion\n // Parametros necesarios para configurar la llamada AJAX\n ajaxOptions = _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds);\n $.when(_reportsRequestData(ajaxOptions, ctx)).then(function (data) {\n exportData = data;\n deferred.resolve(exportData, ajaxOptions);\n });\n } else {\n // Parametros necesarios para configurar la llamada AJAX\n ajaxOptions = _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds);\n deferred.resolve(undefined, ajaxOptions);\n }\n\n return deferred.promise();\n };\n /**\r\n * Se encarga de generar las opciones de configuración con las que se llamara a la API\r\n *\r\n * @name _reportsPrepareRequestData\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n * @param {object} request Contiene todos los parametros de la petición ajax\r\n * @param {object} ctx Contexto\r\n * @param {boolean} selectedAll Cuando es true significa que todas las filas estan marcadas\r\n * @param {array} [deselectedIds] ID's de las filas deseleccionadas\r\n * @param {array} [selectedIds] ID's de las filas seleccionadas\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsPrepareRequestData = function _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds) {\n var data = {};\n data.columns = _loadDefinedColums(dt, ctx, request);\n\n if (ctx.oInit.buttons.report !== undefined) {\n data.columnsName = ctx.oInit.buttons.report.columnsName;\n }\n\n data.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n }; // Solo se enviara el filtro si contiene algun valor. \n // Esto facilita la labor de exportacion al servidor ya que no tiene que iterar el filtro para comprobar si todos los campos son nulos.\n\n if (ctx.oInit.filter.$filterContainer != undefined && !jQuery.isEmptyObject(window.form2object(ctx.oInit.filter.$filterContainer[0]))) {\n data.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n }\n\n data.multiselection = {};\n data.multiselection.selectedAll = selectedAll;\n\n if (data.multiselection.selectedAll) {\n data.multiselection.selectedIds = deselectedIds;\n } else {\n data.multiselection.selectedIds = selectedIds;\n }\n\n data.reportsParams = []; // Se añaden los parametros definidos por el usuario (solo en caso de haber definido alguno)\n\n if (ctx.oInit.buttons.report !== undefined && ctx.oInit.buttons.report.reportsParams !== undefined && ctx.oInit.buttons.report.reportsParams.length > 0) {\n data.reportsParams = ctx.oInit.buttons.report.reportsParams;\n } // Completa el objeto 'ajaxOptions' con los parametros necesarios para la llamada que se realizara al servidor\n\n\n ajaxOptions.contentType = request.contentType;\n ajaxOptions.dataType = request.dataType;\n\n if (request.url !== undefined) {\n ajaxOptions.url = ctx.oInit.urlBase + request.url;\n } else {\n ajaxOptions.url = ctx.oInit.urlBase;\n }\n\n ajaxOptions.reportsExportAllColumns = request.reportsExportAllColumns;\n ajaxOptions.type = request.method;\n\n if (request.fileName !== undefined) {\n data.fileName = request.fileName;\n }\n\n if (request.sheetTitle !== undefined) {\n data.sheetTitle = request.sheetTitle;\n }\n\n ajaxOptions.data = $.toJSON(data);\n return ajaxOptions;\n };\n /**\r\n * Se encarga de devolver las columnas\r\n *\r\n * @name _loadDefinedColums\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ctx Contexto\r\n * @param {object} request Contiene todos los parametros de la petición AJAX\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _loadDefinedColums = function _loadDefinedColums(dt, ctx, request) {\n var columns = [];\n\n if (request.reportsExportAllColumns == undefined) {\n request.reportsExportAllColumns = ctx.ext.buttons.reportsButton.reportsExportAllColumns;\n }\n\n if (!request.reportsExportAllColumns) {\n // Se obtienen las columnas a mostrar definidas por el usuario\n if (ctx.oInit.buttons.report !== undefined && ctx.oInit.buttons.report.columns !== undefined) {\n columns = ctx.oInit.buttons.report.columns;\n } else {\n // En caso contrario se obtienen las columnas de la tabla\n $.each(ctx.oInit.columns, function (position, name) {\n // Se comprueba que el name.data no este vacio para evitar añadir\n // la columna del checkbox de multiseleccion. Tambien se comprueba\n // que la columna sea visible\n if (name.data !== \"\" && dt.column(position).visible()) {\n columns.push(name.data);\n }\n });\n }\n }\n\n return columns;\n };\n /**\r\n * Se encarga de llamar a la API y de devolver los datos recibidos\r\n *\r\n * @name _reportsRequestData\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n * @param {object} ctx Contexto\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsRequestData = function _reportsRequestData(ajaxOptions, ctx) {\n var deferred = $.Deferred();\n $.ajax(ajaxOptions).done(function (data) {\n deferred.resolve(data);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsSuccessReportsRequestData');\n }).complete(function () {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsCompleteReportsRequestData');\n }).error(function () {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsErrorReportsRequestData');\n });\n return deferred.promise();\n };\n /**\r\n * Se encarga de llamar a la API y de devolver el fichero recibido\r\n *\r\n * @name _reportsRequestFile\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx Contexto\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsRequestFile = function _reportsRequestFile(ctx, ajaxOptions) {\n // Dialogo de espera\n var $reportFileWait = $('#' + ctx.sTableId + 'reportFileWait');\n $reportFileWait.rup_dialog({\n type: $.rup.dialog.TEXT,\n autoOpen: false,\n modal: true,\n resizable: false\n }); // Titulo\n\n var title = $.rup.i18nParse($.rup.i18n.base, 'rup_report.waitTitle');\n var message = $.rup.i18nParse($.rup.i18n.base, 'rup_report.waitMsg');\n\n if (ctx.oInit.buttons.report !== undefined) {\n if (ctx.oInit.buttons.report.title !== undefined) {\n title = ctx.oInit.buttons.report.title;\n }\n\n if (ctx.oInit.buttons.report.message !== undefined) {\n message = ctx.oInit.buttons.report.message;\n }\n }\n\n $reportFileWait.rup_dialog('setOption', 'title', title); // Contenido\n\n var content = $reportFileWait.html().split($reportFileWait.text()),\n html = '';\n\n for (var i = 0; i < content.length; i++) {\n if (content[i] === '') {\n html += message;\n } else {\n html += content[i];\n }\n }\n\n $reportFileWait.html(html);\n $reportFileWait.rup_dialog('open');\n var url = ajaxOptions.url; // Lanzar peticion \n\n var request = new XMLHttpRequest();\n request.open(ajaxOptions.type, url, true);\n request.responseType = 'blob';\n request.send(ajaxOptions.data);\n\n request.onload = function (event) {\n if (this.status == 200) {\n var blob = request.response;\n var fileName = null;\n var contentType = request.getResponseHeader('content-type');\n var element; // Parece que IE y EDGE no devuelven la misma cabecera en la respuesta\n\n if (request.getResponseHeader('content-disposition')) {\n var contentDisposition = request.getResponseHeader('content-disposition');\n fileName = contentDisposition.substring(contentDisposition.indexOf('=') + 1);\n } else {\n fileName = 'report.' + contentType.substring(contentType.indexOf('/') + 1);\n }\n\n if (window.navigator.msSaveOrOpenBlob) {\n // IE y EDGE\n window.navigator.msSaveOrOpenBlob(blob, fileName);\n } else {\n // Para los demas navegadores\n if (!$('a#rupTableButtonsReportsExport').length) {\n $('#' + ctx.sTableId + 'rup_report_dialogsContainer').append(\"rupTableButtonsReportsExport\");\n }\n\n element = $('a#rupTableButtonsReportsExport')[0];\n element.href = window.URL.createObjectURL(blob);\n element.download = fileName;\n element.click(); // Eliminamos el ObjectURL y el elemento de DOM generado ya que han sido generados de manera temporal\n\n window.URL.revokeObjectURL(element.href);\n element.remove();\n }\n\n if ($('#' + $reportFileWait.attr('id')).length > 0) {\n $reportFileWait.rup_dialog('close');\n }\n } else {\n if ($('#' + $reportFileWait.attr('id')).length > 0) {\n $reportFileWait.rup_dialog('close');\n console.info('----------- ERROR -----------');\n }\n }\n };\n\n request.send();\n return false;\n };\n /**\r\n * Gestiona la apertura/cierre del mensaje de confirmación de copia\r\n *\r\n * @name _reportsOpenMessage\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ctx Contexto\r\n * @param {object} that Objeto del boton\r\n * @param {int} exportDataRows Numero de filas a ser exportadas\r\n * @param {object} hiddenDiv Elemento del DOM\r\n * @param {object} textarea Elemento del DOM\r\n *\r\n */\n\n\n var _reportsOpenMessage = function _reportsOpenMessage(dt, ctx, that, exportDataRows, hiddenDiv, textarea) {\n $.rup_messages('msgConfirm', {\n title: dt.i18n('rup_table.copyButton.changes', 'Copia de registros en clipboard'),\n message: dt.i18n('rup_table.copyButton.saveAndContinue', {\n _: '¿Desea copiar %d registros?',\n 1: '¿Desea copiar un registro?'\n }, exportDataRows),\n open: function open() {\n $('#' + dt.context[0].sTableId).trigger('rupTable_confirmMsgOpen');\n },\n OKFunction: function OKFunction() {\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.okCallBack = true;\n }\n\n _reportsToClipboard(dt, that, exportDataRows, hiddenDiv, textarea);\n\n if (ctx.oInit.formEdit !== undefined && !ctx.oInit.formEdit.detailForm.hasClass('d-none')) {\n //si esta oculto, no hace falta\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n }\n },\n beforeClose: function beforeClose() {\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.okCallBack = false;\n } // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n }\n });\n };\n /**\r\n * Copia los datos recibidos al portapapeles\r\n *\r\n * @name _reportsToClipboard\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} that Objeto del boton\r\n * @param {int} exportDataRows Numero de filas a ser exportadas\r\n * @param {object} hiddenDiv Elemento del DOM\r\n * @param {object} textarea Elemento del DOM\r\n *\r\n */\n\n\n var _reportsToClipboard = function _reportsToClipboard(dt, that, exportDataRows, hiddenDiv, textarea) {\n // Para los navegadores que soportan el comando de copia 'execCommand'\n if (document.queryCommandSupported('copy')) {\n hiddenDiv.appendTo(dt.table().container());\n textarea[0].focus();\n textarea[0].select();\n\n try {\n var successful = document.execCommand('copy');\n hiddenDiv.remove();\n\n if (successful) {\n dt.buttons.info(dt.i18n('rup_table.copyButton.changes', 'Copia de registros en portapapeles'), dt.i18n('rup_table.copyButton.saved', {\n _: 'Copiados %d registros al portapapeles',\n 1: 'Copiado un registro al portapapeles'\n }, exportDataRows), 2000); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n\n $('#' + dt.context[0].sTableId).trigger('rupTable_copied');\n return;\n }\n } catch (t) {}\n } // Si no soportan la copia mediante 'execCommand', se mostrara un text box\n // con las instrucciones de como copiar los elementos seleccionados\n\n\n var message = $('' + dt.i18n('rup_table.copyButton.copyKeys', 'Presiona ctrl o ⌘ + C para copiar los datos de la tabla al portapapeles.' + 'Para cancelar, haz click sobre este mensaje o pulsa el botón escape.') + '').append(hiddenDiv);\n dt.buttons.info(dt.i18n('rup_table.copyButton.copyTitle', 'Copiar al portapapeles'), message, 0); // Selecciona el texto para cuando el usuario accione la copia al portapapeles\n // se le pegue ese texto\n\n textarea[0].focus();\n textarea[0].select(); // Evento que oculta el mensaje cuando el usuario ha terminado con la copia\n\n var container = $(message).closest('.dt-button-info');\n\n var close = function close() {\n container.off('click.buttons-copy');\n $(document).off('.buttons-copy');\n dt.buttons.info(false); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n };\n\n container.on('click.buttons-copy', close);\n $(document).on('keydown.buttons-copy', function (e) {\n if (e.keyCode === 27) {\n // esc\n close();\n }\n }).on('copy.buttons-copy cut.buttons-copy', function () {\n close(); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n });\n };\n\n var _initContextMenu = function _initContextMenu(ctx, api) {\n // Creacion del Context Menu\n if (ctx.oInit.buttons !== undefined) {\n var botonesToolbar = ctx._buttons[0].inst.s.buttons;\n\n _updateContextMenu(botonesToolbar, api, ctx);\n }\n };\n /**\r\n * Metodo que elimina todos los registros seleccionados.\r\n *\r\n * @name _deleteAllSelects\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n var _deleteAllSelects = function _deleteAllSelects(dt) {\n var ctx = dt.settings()[0];\n var idRow = 0;\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.deleteAll'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.delete'),\n OKFunction: function OKFunction() {\n var row = {};\n row.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n\n if (ctx.multiselection.selectedIds.length > 1) {\n row.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n };\n row.multiselection = {};\n row.multiselection.selectedAll = ctx.multiselection.selectedAll;\n\n if (row.multiselection.selectedAll) {\n row.multiselection.selectedIds = ctx.multiselection.deselectedIds;\n } else {\n row.multiselection.selectedIds = ctx.multiselection.selectedIds;\n }\n\n _callDelete('POST', dt, ctx, row, '/deleteAll');\n } else {\n row = ctx.multiselection.selectedIds[0];\n row = row.replace(regex, '/');\n\n _callDelete('DELETE', dt, ctx, idRow, '/' + row);\n }\n }\n });\n };\n\n var _callDelete = function _callDelete(actionType, dt, ctx, row, url) {\n $('#' + ctx.sTableId).triggerHandler('tableBeforeCallDelete');\n\n var _callFeedbackDelete = function _callFeedbackDelete(ctx, msgFeedBack, type) {\n $('#' + ctx.sTableId).triggerHandler('tableFeedbackShowDelete');\n ctx.oInit.feedback.$feedbackContainer.rup_feedback('set', msgFeedBack, type);\n ctx.oInit.feedback.$feedbackContainer.rup_feedback('show');\n };\n\n if (ctx.oInit.masterDetail !== undefined) {\n //Asegurar que se recoge el idPadre\n var masterPkObject = DataTable.Api().masterDetail.getMasterTablePkObject(ctx);\n jQuery.extend(true, masterPkObject, row);\n row = masterPkObject;\n }\n\n var msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.deletedOK');\n var ajaxOptions = {\n url: ctx.oInit.urlBase + url,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: actionType,\n data: row,\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: true,\n success: function success() {\n // Eliminar\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt);\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tablefterDelete');\n ctx._buttons[0].inst.s.disableAllButtons = undefined;\n DataTable.Api().seeker.disabledButtons(ctx); // Recargar datos\n // Primer parametro para mandar una funcion a ejecutar, segundo parametro bloquear la pagina si pones false\n\n dt.ajax.reload(function () {\n _callFeedbackDelete(ctx, msgFeedBack, 'ok');\n }, false);\n $('#' + ctx.sTableId).triggerHandler('tableSuccessCallDelete');\n },\n complete: function complete() {\n $('#' + ctx.sTableId).triggerHandler('tableCompleteCallDelete');\n },\n error: function error(xhr) {\n _callFeedbackDelete(ctx, xhr.responseText, 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableErrorCallDelete');\n },\n feedback: function feedback() {\n _callFeedbackDelete(ctx, msgFeedBack, 'ok');\n }\n };\n ajaxOptions.data = JSON.stringify(ajaxOptions.data);\n $.rup_ajax(ajaxOptions);\n };\n\n var _updateContextMenu = function _updateContextMenu(botones, api, ctx) {\n var items = {};\n var tableId = ctx.sTableId;\n $.each(botones, function () {\n // Entra si tiene marcada la opcion para habilitarlo dentro del contextMenu\n if (this.conf.insideContextMenu) {\n // Poblamos el objeto 'items' con los botones habilitados\n items[this.conf.id] = {\n id: this.conf.id + '_contextMenuToolbar',\n name: this.conf.text(api),\n icon: this.conf.icon,\n inCollection: this.inCollection,\n idCollection: undefined\n };\n } // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n var idCollection = this.conf.id;\n $.each(this.buttons, function (i) {\n // Entra si tiene marcada la opcion para habilitarlo dentro del contextMenu\n if (this.conf.insideContextMenu) {\n // Poblamos el objeto 'items' con los botones habilitados\n items[this.conf.id] = {\n id: this.conf.id + '_contextMenuToolbar',\n name: this.conf.text(api),\n icon: this.conf.icon,\n inCollection: this.inCollection,\n idCollection: idCollection\n };\n }\n });\n }\n });\n var tableTrSelector = '#' + tableId + ' > tbody > tr';\n var tableTr = $(tableTrSelector);\n tableTr.selector = tableTrSelector;\n\n if (!jQuery.isEmptyObject(items)) {\n tableTr.rup_contextMenu('destroy');\n tableTr.rup_contextMenu({\n selector: tableTrSelector,\n callback: function callback(key, options) {\n var selector = items[key]; // Recogemos el id de la accion pulsada en el context menu\n\n var contextMenuActionId = selector.id; // Le quitamos la extension '_contextMenuToolbar' para tener asi\n // el id del boton que queremos accionar\n\n var buttonId = contextMenuActionId.replace('_contextMenuToolbar', ''); // Variable que nos dira si esta dentro de una coleccion\n\n var inCollection = selector.inCollection; // Variable que almacena el id de la coleccion (si no pertenece a una\n // siempre sera 'undefined')\n\n var idCollection = selector.idCollection; // Comprobamos si existe el elemento con este id\n\n if (inCollection && idCollection !== undefined) {\n // Obtenemos la info necesaria del boton y la guardamos en variables\n var buttonName;\n var dt = $('#' + ctx.sTableId).DataTable();\n var eventConfig;\n $.each(ctx.ext.buttons, function (key) {\n var buttonObject = ctx.ext.buttons[key];\n\n if (buttonObject.id === buttonId) {\n buttonName = key;\n eventConfig = buttonObject;\n }\n }); // Llamamos directamente al action para no hacer aparecer y desaparecer\n // el boton, empeorando la UX\n\n ctx.ext.buttons[buttonName].action(undefined, dt, undefined, eventConfig);\n } else {\n $('#' + buttonId).trigger('click');\n }\n },\n items: items\n });\n }\n };\n /**\r\n * Inicializa los botones\r\n *\r\n * @name _initButtons\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on\r\n * @param {List} opts Lista de botones\r\n *\r\n */\n\n\n var _initButtons = function _initButtons(ctx, opts) {\n $.each(opts, function (i) {\n // Activa/desactiva los botones en el inicio en funcion de la propiedad\n // 'displayRegex' que tengan asociada\n var collectionObject = null;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n\n if (ctx.oInit.masterDetail !== undefined && this.conf.id === ctx.sTableId + 'addButton_1') {\n //si es maestro detalle para el boton add ,solo se renderiza cuando hay selección en el padre.\n var table = $(ctx.oInit.masterDetail.master).DataTable();\n numOfSelectedRows = table.context[0].multiselection.numSelected; //Nums del padre\n\n this.conf.displayRegex = /^[1-9][0-9]*$/; //se cambia expresion regular\n }\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx); // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n collectionObject = this;\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx);\n } // Comprueba si tiene un icono asociado\n\n\n if (this.conf.icon !== undefined) {\n // Establece el icono de los botones\n if ($(this.node).find('i').length === 0) {\n $('#' + this.conf.id).prepend('');\n } // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0 && $('#' + this.conf.id).length > 0) {\n // Añadimos un evento para cuando se pulse sobre el boton padre, se le\n // asignen los iconos a los hijos\n $('#' + this.conf.id)[0].addEventListener('click', function eventHandler() {\n var that = this;\n $.each(opts[i].buttons, function (i) {\n var selectorCollection = $('#' + this.conf.id); // Establece el icono de los botones hijos\n\n if ($(this.node).find('i').length === 0) {\n selectorCollection.prepend('');\n }\n\n that.removeEventListener('click', eventHandler);\n });\n }, false);\n }\n }\n }); //Añadir dialogo por defecto\n\n var $defaultDialog_wait = $('
').attr('id', ctx.sTableId + 'reportFileWait').attr('title', 'Tittle Prueba').text('prueba').addClass('rup_report').hide() //progressbar\n .append($('
').addClass('ui-progressbar ui-progressbar-value ui-corner-left ui-corner-right')),\n $defaultDialog_error = $('
').attr('id', ctx.sTableId + 'reportFileError').attr('title', 'Error').text('error').addClass('rup_report').hide(),\n $defaultDialog = $('
').attr('id', ctx.sTableId + 'rup_report_dialogsContainer').append($defaultDialog_wait).append($defaultDialog_error);\n $('#' + ctx.sTableId).after($defaultDialog);\n };\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables interface\r\n */\n // Attach to DataTables objects for global access\n\n\n $.fn.dataTable.Buttons = Buttons;\n $.fn.DataTable.Buttons = Buttons;\n\n function inicio(ctx) {\n var api = new DataTable.Api(ctx);\n var defaultButtons = api.init().buttons || DataTable.defaults.buttons;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n var collectionObject;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeToolbarInit');\n\n if ($('#' + ctx.sTableId + '_filter_form').length > 0) {\n new Buttons(api, defaultButtons).container().insertBefore($('#' + ctx.sTableId + '_filter_form'));\n } else {\n new Buttons(api, defaultButtons).container().insertBefore($('#' + ctx.sTableId + '_wrapper'));\n }\n\n var opts = ctx._buttons[0].inst.s.buttons;\n DataTable.Api().buttons.initButtons(ctx, opts);\n\n _initContextMenu(ctx, api); // Detecta cuando se selecciona o se deselecciona una fila en el table\n\n\n $('#' + ctx.sTableId).DataTable().on('select deselect contextmenu', function (event) {\n DataTable.Api().buttons.displayRegex(ctx);\n }); // Si la edición está deshabilitada, se deshabilitan todos los botones menos el de informes.\n\n if (ctx.oInit.noEdit || ctx.oInit.formEdit === undefined && ctx.oInit.inlineEdit === undefined) {\n var exceptions; // Si existen botones personalizados, se excluyen.\n\n if (ctx.ext.buttons.custom.length > 0) {\n exceptions = ctx.ext.buttons.custom;\n exceptions.push(ctx.sTableId + 'informes_01');\n } else {\n exceptions = ctx.sTableId + 'informes_01';\n }\n\n DataTable.Api().buttons.disableAllButtons(ctx, exceptions);\n ctx._buttons[0].inst.s.disableAllButtons = undefined;\n DataTable.Api().buttons.displayRegex(ctx);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterToolbarInit');\n } // DataTables `dom` feature option\n\n\n DataTable.ext.feature.push({\n fnInit: function fnInit(settings) {\n var api = new DataTable.Api(settings);\n var opts = api.init().buttons || DataTable.defaults.buttons;\n return new Buttons(api, opts).container();\n },\n cFeature: 'B'\n }); //DataTables creation - check if the buttons have been defined for this table,\n //they will have been if the `B` option was used in `dom`, otherwise we should\n //create the buttons instance here so they can be inserted into the document\n //using the API. Listen for `init` for compatibility with pre 1.10.10, but to\n //be removed in future.\n\n $(document).on('plugin-init.dt', function (e, ctx) {\n if (e.namespace !== 'dt') {\n return;\n }\n\n if (ctx.oInit.buttons !== undefined && ctx.oInit.buttons.activate !== false) {\n inicio(ctx);\n }\n });\n return Buttons;\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup_table/rup.table.buttons.js?"); +eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/**\r\n * Genera los botones del table\r\n *\r\n * @summary \t\tExtensión del componente RUP Datatable\r\n * @module\t\t\t\"rup.table.buttons\"\r\n * @version 1.5.1\r\n * @license\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n * @copyright Copyright 2018 E.J.I.E., S.A.\r\n *\r\n */\n(function (factory) {\n if (true) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! datatables.net */ \"./node_modules/datatables.net/js/jquery.dataTables.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($) {\n return factory($, window, document);\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($, window, document, undefined) {\n 'use strict';\n\n var DataTable = $.fn.dataTable; // Used for namespacing events added to the document by each instance, so they\n // can be removed on destroy\n\n var _instCounter = 0; // Button namespacing counter for namespacing events on individual buttons\n\n var _buttonCounter = 0; // Default ID naming counter\n\n var _buttonIdCounter = 1;\n var _dtButtons = DataTable.ext.buttons;\n /**\r\n * Botones\r\n *\r\n * @name Buttons\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt\r\n * @param {object} config\r\n *\r\n */\n\n var Buttons = function Buttons(dt, config) {\n var idTable = dt.context[0].sTableId;\n var ctx = dt.context[0];\n ctx.ext = DataTable.ext;\n ctx.ext.buttons = {};\n ctx.ext.buttons.defaults = {\n buttons: ['addButton', 'editButton', 'cloneButton', 'deleteButton', 'reportsButton'],\n name: 'main',\n tabIndex: 0,\n dom: {\n container: {\n tag: 'div',\n className: 'dt-buttons row'\n },\n collection: {\n tag: 'div',\n className: 'dt-button-collection'\n },\n button: {\n tag: 'button',\n className: 'col-12 col-sm-auto btn-material',\n active: 'active',\n disabled: 'disabled'\n },\n buttonLiner: {\n tag: 'span',\n className: ''\n }\n }\n };\n ctx.ext.buttons.copyButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.copyButton');\n },\n id: idTable + 'copyButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'copyButton',\n request: {\n url: '/filter?clipboardReport=true',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'json',\n reportsExportAllColumns: false\n },\n init: function init(dt, node, config) {\n ctx.ext.buttons.copyButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCopyClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCopyClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.excelButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.excelButton');\n },\n id: idTable + 'excelButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'excelButton',\n request: {\n url: '/xlsxReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n reportsExportAllColumns: false,\n fileName: 'reportExcel',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeExcelClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterExcelClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.pdfButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.pdfButton');\n },\n id: idTable + 'pdfButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'pdfButton',\n request: {\n url: '/pdfReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/pdf',\n reportsExportAllColumns: false,\n fileName: 'reportPDF'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforePdfClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterPdfClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.odsButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.odsButton');\n },\n id: idTable + 'odsButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'odsButton',\n request: {\n url: '/odsReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'application/vnd.oasis.opendocument.spreadsheet',\n reportsExportAllColumns: false,\n fileName: 'reportODS',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeOdsClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterOdsClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.csvButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.csvButton');\n },\n id: idTable + 'csvButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-low-emphasis buttons-copyButton',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'csvButton',\n request: {\n url: '/csvReport',\n method: 'POST',\n contentType: 'application/json',\n dataType: 'text/csv',\n reportsExportAllColumns: false,\n fileName: 'reportCSV',\n sheetTitle: 'Usuario'\n },\n action: function action(e, dt, button, config) {\n // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n if (this.processing !== undefined) {\n this.processing(true);\n }\n\n var that = this;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCsvClick', [dt, button, config]);\n\n _reports(dt, that, config);\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCsvClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.addButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.add');\n },\n id: idTable + 'addButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnAdd order-1',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'add',\n init: function init(dt, button, config) {\n ctx.ext.buttons.addButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeAddClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterAddClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.editButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.edit');\n },\n id: idTable + 'editButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnEdit order-2',\n displayRegex: /^[1-9][0-9]*$/,\n // Se muestra siempre que sea un numero mayor a 0\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'edit',\n init: function init(dt, button, config) {\n ctx.ext.buttons.editButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeEditClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterEditClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.cloneButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.clone');\n },\n id: idTable + 'cloneButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnClone order-3',\n displayRegex: /^1$/,\n // Se muestra solo cuando sea igual a 1\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'clone',\n init: function init(dt, button, config) {\n ctx.ext.buttons.cloneButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeCloneClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterCloneClick', [dt, button, config]);\n }\n };\n ctx.ext.buttons.deleteButton = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.delete');\n },\n id: idTable + 'deleteButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnDelete order-4',\n displayRegex: /^[1-9][0-9]*$/,\n // Se muestra siempre que sea un numero mayor a 0\n insideContextMenu: ctx.oInit.buttons.contextMenu,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'delete',\n init: function init(dt, button, config) {\n ctx.ext.buttons.deleteButton.eventDT = dt;\n },\n action: function action(e, dt, button, config) {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeDeleteClick', [dt, button, config]);\n DataTable.Api().buttons.actions(dt, config);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterDeleteClick', [dt, button, config]);\n }\n };\n var listadoExports = ['copyButton', 'excelButton', 'pdfButton', 'odsButton', 'csvButton'];\n ctx.ext.buttons.reportsButton = {\n extend: 'collection',\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.toolbar.reports.main');\n },\n id: idTable + 'informes_01',\n className: 'btn-material-primary-medium-emphasis order-last ml-1 ml-lg-auto',\n displayRegex: /^\\d+$/,\n // Se muestra siempre que sea un numero positivo o neutro\n autoClose: true,\n type: 'reports',\n reportsExportAllColumns: false,\n buttons: listadoExports\n }; // Almacena los identificadores de los botones personalizados.\n\n ctx.ext.buttons.custom = []; // Ajusta el tamaño de los botones por defecto en caso de que haya sido especificado en las preferencias\n\n if (ctx.oInit.buttons.size !== undefined) {\n $.each(ctx.ext.buttons, function (name, item) {\n if (item.className !== undefined) {\n if (ctx.oInit.buttons.size === 'lg') {\n item.className += \" btn-material-lg\";\n } else if (ctx.oInit.buttons.size === 'sm') {\n item.className += \" btn-material-sm\";\n }\n }\n });\n }\n\n if (ctx.oInit.buttons.blackListButtons !== undefined) {\n if (ctx.oInit.buttons.blackListButtons === 'all') {\n //si no se quiere ninguno se elimina\n listadoExports = [];\n ctx.ext.buttons.defaults.buttons = [];\n } else if (ctx.oInit.buttons.blackListButtons && ctx.oInit.buttons.blackListButtons.length > 0) {\n $.each(ctx.oInit.buttons.blackListButtons, function () {\n var name = this;\n var pos = $.inArray(name, listadoExports);\n\n if (pos >= 0) {\n listadoExports.splice(pos, 1);\n } //Resto de botones\n\n\n var posBoton = $.inArray(name, ctx.ext.buttons.defaults.buttons);\n\n if (posBoton >= 0) {\n ctx.ext.buttons.defaults.buttons.splice(posBoton, 1);\n }\n });\n }\n } // Añadir los botones de la edición en línea.\n\n\n if (!ctx.oInit.noEdit && ctx.oInit.inlineEdit !== undefined) {\n $.extend(ctx.ext.buttons, ctx.oInit.inlineEdit.myButtons);\n\n for (var nameButton in ctx.oInit.inlineEdit.myButtons) {\n ctx.ext.buttons.defaults.buttons.push(nameButton);\n }\n } // Añadir los botones personalizados.\n\n\n if (ctx.oInit.buttons.myButtons !== undefined) {\n $.extend(ctx.ext.buttons, ctx.oInit.buttons.myButtons);\n\n for (var _nameButton in ctx.oInit.buttons.myButtons) {\n ctx.ext.buttons.defaults.buttons.push(_nameButton);\n ctx.ext.buttons.custom.push(ctx.oInit.buttons.myButtons[_nameButton].id);\n }\n } // If there is no config set it to an empty object\n\n\n if (typeof config === 'undefined') {\n config = {};\n } // Allow a boolean true for defaults\n\n\n if (config === true) {\n config = {};\n } // For easy configuration of buttons an array can be given\n\n\n if (Array.isArray(config)) {\n config = {\n buttons: config\n };\n }\n\n this.c = $.extend(true, {}, ctx.ext.buttons.defaults, config); // Don't want a deep copy for the buttons\n\n if (config.buttons) {\n this.c.buttons = config.buttons;\n }\n\n this.s = {\n dt: new DataTable.Api(dt),\n buttons: [],\n listenKeys: '',\n namespace: 'dtb' + _instCounter++\n };\n this.dom = {\n container: $('<' + this.c.dom.container.tag + '>').addClass(this.c.dom.container.className).attr('id', ctx.sTableId + '_containerToolbar')\n };\n\n this._constructor();\n };\n\n $.extend(Buttons.prototype, {\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Public methods\r\n */\n\n /**\r\n * Get the action of a button\r\n *\r\n * @name action\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string} Button index\r\n * @return {function}\r\n *\r\n */\n\n /**\r\n * Set the action of a button\r\n *\r\n * @name action\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button element\r\n * @param {function} action Function to set\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n action: function action(node, _action) {\n var button = this._nodeToButton(node);\n\n if (_action === undefined) {\n return button.conf.action;\n }\n\n button.conf.action = _action;\n return this;\n },\n\n /**\r\n * Add an active class to the button to make to look active or get current\r\n * active state.\r\n *\r\n * @name active\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button element\r\n * @param {boolean} [flag] Enable / disable flag\r\n * @return {Buttons} Self for chaining or boolean for getter\r\n *\r\n */\n active: function active(node, flag) {\n var button = this._nodeToButton(node);\n\n var klass = this.c.dom.button.active;\n var jqNode = $(button.node);\n\n if (flag === undefined) {\n return jqNode.hasClass(klass);\n }\n\n jqNode.toggleClass(klass, flag === undefined ? true : flag);\n return this;\n },\n\n /**\r\n * Add a new button\r\n *\r\n * @name add\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config Button configuration object, base string name or function\r\n * @param {int|string} [idx] Button index for where to insert the button\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n add: function add(config, idx) {\n var buttons = this.s.buttons;\n\n if (typeof idx === 'string') {\n var split = idx.split('-');\n var base = this.s;\n\n for (var i = 0, ien = split.length - 1; i < ien; i++) {\n base = base.buttons[split[i] * 1];\n }\n\n buttons = base.buttons;\n idx = split[split.length - 1] * 1;\n }\n\n this._expandButton(buttons, config, false, idx);\n\n this._draw();\n\n return this;\n },\n\n /**\r\n * Get the container node for the buttons\r\n *\r\n * @name container\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {jQuery} Buttons node\r\n *\r\n */\n container: function container() {\n return this.dom.container;\n },\n\n /**\r\n * Disable a button\r\n *\r\n * @name disable\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n disable: function disable(node, contextMenu) {\n var button = this._nodeToButton(node);\n\n $(button.node).addClass(this.c.dom.button.disabled);\n\n if (contextMenu) {\n $('#' + button.node.id + '_contextMenuToolbar').addClass(this.c.dom.button.disabled);\n }\n\n return this;\n },\n\n /**\r\n * Destroy the instance, cleaning up event handlers and removing DOM\r\n * elements\r\n *\r\n * @name destroy\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n destroy: function destroy() {\n // Key event listener\n $('body').off('keyup.' + this.s.namespace); // Individual button destroy (so they can remove their own events if\n // needed). Take a copy as the array is modified by `remove`\n\n var buttons = this.s.buttons.slice();\n var i, ien;\n\n for (i = 0, ien = buttons.length; i < ien; i++) {\n this.remove(buttons[i].node);\n } // Container\n\n\n this.dom.container.remove(); // Remove from the settings object collection\n\n var buttonInsts = this.s.dt.settings()[0];\n\n for (i = 0, ien = buttonInsts.length; i < ien; i++) {\n if (buttonInsts.inst === this) {\n buttonInsts.splice(i, 1);\n break;\n }\n }\n\n return this;\n },\n\n /**\r\n * Enable / disable a button\r\n *\r\n * @name enable\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {boolean} [flag=true] Enable / disable flag\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n enable: function enable(node, flag, contextMenu) {\n if (flag === false) {\n return this.disable(node);\n }\n\n var button = this._nodeToButton(node);\n\n $(button.node).removeClass(this.c.dom.button.disabled);\n\n if (contextMenu) {\n $('#' + button.node.id + '_contextMenuToolbar').removeClass(this.c.dom.button.disabled);\n }\n\n return this;\n },\n\n /**\r\n * Get the instance name for the button set selector\r\n *\r\n * @name name\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @return {string} Instance name\r\n *\r\n */\n name: function name() {\n return this.c.name;\n },\n\n /**\r\n * Get a button's node\r\n *\r\n * @name node\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {jQuery} Button element\r\n *\r\n */\n node: function node(_node) {\n var button = this._nodeToButton(_node);\n\n return $(button.node);\n },\n\n /**\r\n * Set / get a processing class on the selected button\r\n *\r\n * @name processing\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} flag true to add, false to remove, undefined to get\r\n * @return {boolean|Buttons} Getter value or this if a setter.\r\n *\r\n */\n processing: function processing(node, flag) {\n var button = this._nodeToButton(node);\n\n if (flag === undefined) {\n return $(button.node).hasClass('processing');\n }\n\n $(button.node).toggleClass('processing', flag);\n return this;\n },\n\n /**\r\n * Remove a button.\r\n *\r\n * @name remove\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n remove: function remove(node) {\n var button = this._nodeToButton(node);\n\n var host = this._nodeToHost(node);\n\n var dt = this.s.dt; // Remove any child buttons first\n\n if (button.buttons.length) {\n for (var i = button.buttons.length - 1; i >= 0; i--) {\n this.remove(button.buttons[i].node);\n }\n } // Allow the button to remove event handlers, etc\n\n\n if (button.conf.destroy) {\n button.conf.destroy.call(dt.button(node), dt, $(node), button.conf);\n }\n\n this._removeKey(button.conf);\n\n $(button.node).remove();\n var idx = $.inArray(button, host);\n host.splice(idx, 1);\n return this;\n },\n\n /**\r\n * Get the text for a button\r\n *\r\n * @name text\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string} node Button index\r\n * @return {string} Button text\r\n *\r\n */\n\n /**\r\n * Set the text for a button\r\n *\r\n * @name text\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {int|string|function} node Button index\r\n * @param {string} label Text\r\n * @return {Buttons} Self for chaining\r\n *\r\n */\n text: function text(node, label) {\n var button = this._nodeToButton(node);\n\n var buttonLiner = this.c.dom.collection.buttonLiner;\n var linerTag = button.inCollection && buttonLiner && buttonLiner.tag ? buttonLiner.tag : this.c.dom.buttonLiner.tag;\n var dt = this.s.dt;\n var jqNode = $(button.node);\n\n var text = function text(opt) {\n return typeof opt === 'function' ? opt(dt, jqNode, button.conf) : opt;\n };\n\n if (label === undefined) {\n return text(button.conf.text);\n }\n\n button.conf.text = label;\n\n if (linerTag) {\n jqNode.children(linerTag).html(text(label));\n } else {\n jqNode.html(text(label));\n }\n\n return this;\n },\n\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Constructor\r\n */\n\n /**\r\n * Buttons constructor\r\n *\r\n * @name _constructor\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n */\n _constructor: function _constructor() {\n var that = this;\n var dt = this.s.dt;\n var dtSettings = dt.settings()[0];\n var buttons = this.c.buttons;\n\n if (!dtSettings._buttons) {\n dtSettings._buttons = [];\n }\n\n dtSettings._buttons.push({\n inst: this,\n name: this.c.name\n });\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n this.add(buttons[i]);\n }\n\n dt.on('destroy', function () {\n that.destroy();\n }); // Global key event binding to listen for button keys\n\n $('body').on('keyup.' + this.s.namespace, function (e) {\n if (!document.activeElement || document.activeElement === document.body) {\n // SUse a string of characters for fast lookup of if we need to\n // handle this\n var character = String.fromCharCode(e.keyCode).toLowerCase();\n\n if (that.s.listenKeys.toLowerCase().indexOf(character) !== -1) {\n that._keypress(character, e);\n }\n }\n });\n },\n\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Private methods\r\n */\n\n /**\r\n * Add a new button to the key press listener\r\n *\r\n * @name _addKey\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} conf Resolved button configuration object\r\n *\r\n */\n _addKey: function _addKey(conf) {\n if (conf.key) {\n this.s.listenKeys += $.isPlainObject(conf.key) ? conf.key.key : conf.key;\n }\n },\n\n /**\r\n * Insert the buttons into the container. Call without parameters!\r\n *\r\n * @name _draw\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} [container] Recursive only - Insert point\r\n * @param {array} [buttons] Recursive only - Buttons array\r\n *\r\n */\n _draw: function _draw(container, buttons) {\n if (!container) {\n container = this.dom.container;\n buttons = this.s.buttons;\n }\n\n container.children().detach();\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n container.append(buttons[i].inserter);\n container.append(' ');\n\n if (buttons[i].buttons && buttons[i].buttons.length) {\n this._draw(buttons[i].collection, buttons[i].buttons);\n }\n }\n },\n\n /**\r\n * Create buttons from an array of buttons\r\n *\r\n * @name _expandButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {array} attachTo Buttons array to attach to\r\n * @param {object} button Button definition\r\n * @param {boolean} inCollection true if the button is in a collection\r\n *\r\n */\n _expandButton: function _expandButton(attachTo, button, inCollection, attachPoint) {\n var dt = this.s.dt;\n var buttonCounter = 0;\n var buttons = !Array.isArray(button) ? [button] : button;\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n var conf = this._resolveExtends(buttons[i]);\n\n if (!conf) {\n continue;\n } // If the configuration is an array, then expand the buttons at this\n // point\n\n\n if (Array.isArray(conf)) {\n this._expandButton(attachTo, conf, inCollection, attachPoint);\n\n continue;\n }\n\n var built = this._buildButton(conf, inCollection);\n\n if (!built) {\n continue;\n }\n\n if (attachPoint !== undefined) {\n attachTo.splice(attachPoint, 0, built);\n attachPoint++;\n } else {\n attachTo.push(built);\n }\n\n if (built.conf.buttons) {\n var collectionDom = this.c.dom.collection;\n built.collection = $('<' + collectionDom.tag + '>').addClass(collectionDom.className).attr('role', 'menu');\n built.conf._collection = built.collection;\n\n this._expandButton(built.buttons, built.conf.buttons, true, attachPoint);\n } // init call is made here, rather than buildButton as it needs to\n // be selectable, and for that it needs to be in the buttons array\n\n\n if (conf.init) {\n conf.init.call(dt.button(built.node), dt, $(built.node), conf);\n }\n\n buttonCounter++;\n }\n },\n\n /**\r\n * Create an individual button\r\n *\r\n * @name _buildButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config Resolved button configuration\r\n * @param {boolean} inCollection `true` if a collection button\r\n * @return {jQuery} Created button node (jQuery)\r\n *\r\n */\n _buildButton: function _buildButton(config, inCollection) {\n var buttonDom = this.c.dom.button;\n var linerDom = this.c.dom.buttonLiner;\n var collectionDom = this.c.dom.collection;\n var dt = this.s.dt;\n var ctx = dt.settings()[0];\n\n var text = function text(opt) {\n return typeof opt === 'function' ? opt(dt, button, config) : opt;\n };\n\n if (inCollection && collectionDom.button) {\n buttonDom = collectionDom.button;\n }\n\n if (inCollection && collectionDom.buttonLiner) {\n linerDom = collectionDom.buttonLiner;\n } // Make sure that the button is available based on whatever requirements\n // it has. For example, Flash buttons require Flash\n\n\n if (config.available && !config.available(dt, config)) {\n return false;\n }\n\n var action = function action(e, dt, button, config) {\n config.action.call(dt.button(button), e, dt, button, config);\n $(dt.table().node()).triggerHandler('buttons-action.dt', [dt.button(button), dt, button, config]);\n };\n\n var button = $('<' + buttonDom.tag + '>').addClass(buttonDom.className).attr('tabindex', this.s.dt.settings()[0].iTabIndex).attr('aria-controls', this.s.dt.table().node().id).on('click.dtb', function (e) {\n e.preventDefault();\n\n if (!button.hasClass(buttonDom.disabled) && config.action) {\n action(e, dt, button, config);\n }\n\n button.blur();\n }); // Make `a` tags act like a link\n\n if (buttonDom.tag.toLowerCase() === 'a') {\n button.attr('href', '#');\n }\n\n if (linerDom.tag) {\n var liner = $('<' + linerDom.tag + '>').html(text(config.text)).addClass(linerDom.className);\n\n if (linerDom.tag.toLowerCase() === 'a') {\n liner.attr('href', '#');\n }\n\n button.append(liner);\n } else {\n button.html(text(config.text));\n }\n\n if (config.id) {\n button.attr('id', config.id);\n } else {\n // Se desactiva el acceso desde el contextMenu por no tener un id establecido\n config.insideContextMenu = false; // Se asigna un id dinamico en funcion del nombre del table al que pertenece\n\n config.id = ctx.sTableId + '_button_' + _buttonIdCounter++;\n button.attr('id', config.id);\n }\n\n if (config.className) {\n button.addClass(config.className);\n }\n\n if (config.titleAttr) {\n button.attr('title', text(config.titleAttr));\n }\n\n if (config.attr) {\n button.attr(config.attr);\n }\n\n if (!config.namespace) {\n config.namespace = '.dt-button-' + _buttonCounter++;\n }\n\n if (!config.icon) {\n // Comprueba si es alguno de los botones con iconos definidos por defecto\n switch (config.type) {\n case 'add':\n config.icon = 'mdi-plus';\n break;\n\n case 'edit':\n config.icon = 'mdi-playlist-edit';\n break;\n\n case 'clone':\n config.icon = 'mdi-content-copy';\n break;\n\n case 'delete':\n config.icon = 'mdi-trash-can-outline';\n break;\n\n case 'reports':\n config.icon = 'mdi-file-export';\n break;\n\n case 'copyButton':\n config.icon = 'mdi-clipboard-text-outline';\n break;\n\n case 'excelButton':\n config.icon = 'mdi-file-excel';\n break;\n\n case 'pdfButton':\n config.icon = 'mdi-file-pdf';\n break;\n\n case 'odsButton':\n config.icon = 'mdi-file';\n break;\n\n case 'csvButton':\n config.icon = 'mdi-file';\n break;\n\n default:\n config.icon = 'mdi-settings';\n }\n }\n\n var buttonContainer = this.c.dom.buttonContainer;\n var inserter;\n\n if (buttonContainer && buttonContainer.tag) {\n inserter = $('<' + buttonContainer.tag + '>').addClass(buttonContainer.className).append(button);\n } else {\n inserter = button;\n }\n\n this._addKey(config);\n\n return {\n conf: config,\n node: button.get(0),\n inserter: inserter,\n buttons: [],\n inCollection: inCollection,\n collection: null\n };\n },\n\n /**\r\n * Get the button object from a node (recursive)\r\n *\r\n * @name _nodeToButton\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {array} [buttons] Button array, uses base if not defined\r\n * @return {object} Button object\r\n *\r\n */\n _nodeToButton: function _nodeToButton(node, buttons) {\n if (!buttons) {\n buttons = this.s.buttons;\n }\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].node === node) {\n return buttons[i];\n }\n\n if (buttons[i].buttons.length) {\n var ret = this._nodeToButton(node, buttons[i].buttons);\n\n if (ret) {\n return ret;\n }\n }\n }\n },\n\n /**\r\n * Get container array for a button from a button node (recursive)\r\n *\r\n * @name _nodeToHost\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {node} node Button node\r\n * @param {array} [buttons] Button array, uses base if not defined\r\n * @return {array} Button's host array\r\n *\r\n */\n _nodeToHost: function _nodeToHost(node, buttons) {\n if (!buttons) {\n buttons = this.s.buttons;\n }\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].node === node) {\n return buttons;\n }\n\n if (buttons[i].buttons.length) {\n var ret = this._nodeToHost(node, buttons[i].buttons);\n\n if (ret) {\n return ret;\n }\n }\n }\n },\n\n /**\r\n * Handle a key press - determine if any button's key configured matches\r\n * what was typed and trigger the action if so.\r\n *\r\n * @name _keypress\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} character The character pressed\r\n * @param {object} e Key event that triggered this call\r\n *\r\n */\n _keypress: function _keypress(character, e) {\n // Check if this button press already activated on another instance of Buttons\n if (e._buttonsHandled) {\n return;\n }\n\n var run = function run(conf, node) {\n if (!conf.key) {\n return;\n }\n\n if (conf.key === character) {\n e._buttonsHandled = true;\n $(node).click();\n } else if ($.isPlainObject(conf.key)) {\n if (conf.key.key !== character) {\n return;\n }\n\n if (conf.key.shiftKey && !e.shiftKey) {\n return;\n }\n\n if (conf.key.altKey && !e.altKey) {\n return;\n }\n\n if (conf.key.ctrlKey && !e.ctrlKey) {\n return;\n }\n\n if (conf.key.metaKey && !e.metaKey) {\n return;\n } // Made it this far - it is good\n\n\n e._buttonsHandled = true;\n $(node).click();\n }\n };\n\n var recurse = function recurse(a) {\n for (var i = 0, ien = a.length; i < ien; i++) {\n run(a[i].conf, a[i].node);\n\n if (a[i].buttons.length) {\n recurse(a[i].buttons);\n }\n }\n };\n\n recurse(this.s.buttons);\n },\n\n /**\r\n * Remove a key from the key listener for this instance (to be used when a\r\n * button is removed)\r\n *\r\n * @name _removeKey\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} conf Button configuration\r\n *\r\n */\n _removeKey: function _removeKey(conf) {\n if (conf.key) {\n var character = $.isPlainObject(conf.key) ? conf.key.key : conf.key; // Remove only one character, as multiple buttons could have the\n // same listening key\n\n var a = this.s.listenKeys.split('');\n var idx = $.inArray(character, a);\n a.splice(idx, 1);\n this.s.listenKeys = a.join('');\n }\n },\n\n /**\r\n * Resolve a button configuration\r\n *\r\n * @name _resolveExtends\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string|function|object} conf Button config to resolve\r\n * @return {object} Button configuration\r\n *\r\n */\n _resolveExtends: function _resolveExtends(conf) {\n var dt = this.s.dt;\n var i, ien;\n var ctx = dt.context[0];\n var _dtButtonsTable = ctx.ext.buttons;\n _dtButtonsTable.collection = _dtButtons.collection;\n\n var toConfObject = function toConfObject(base) {\n var loop = 0; // Loop until we have resolved to a button configuration, or an\n // array of button configurations (which will be iterated\n // separately)\n\n while (!$.isPlainObject(base) && !Array.isArray(base)) {\n if (base === undefined) {\n return;\n }\n\n if (typeof base === 'function') {\n base = base(dt, conf);\n\n if (!base) {\n return false;\n }\n } else if (typeof base === 'string') {\n if (!_dtButtonsTable[base]) {\n throw 'Unknown button type: ' + base;\n }\n\n base = _dtButtonsTable[base];\n }\n\n loop++;\n\n if (loop > 30) {\n // Protect against misconfiguration killing the browser\n throw 'Buttons: Too many iterations';\n }\n }\n\n return Array.isArray(base) ? base : $.extend({}, base);\n };\n\n conf = toConfObject(conf);\n\n while (conf && conf.extend) {\n // Use `toConfObject` in case the button definition being extended\n // is itself a string or a function\n if (!_dtButtonsTable[conf.extend]) {\n throw 'Cannot extend unknown button type: ' + conf.extend;\n }\n\n var objArray = toConfObject(_dtButtonsTable[conf.extend]);\n\n if (Array.isArray(objArray)) {\n return objArray;\n } else if (!objArray) {\n // This is a little brutal as it might be possible to have a\n // valid button without the extend, but if there is no extend\n // then the host button would be acting in an undefined state\n return false;\n } // Stash the current class name\n\n\n var originalClassName = objArray.className;\n conf = $.extend({}, objArray, conf); // The extend will have overwritten the original class name if the\n // `conf` object also assigned a class, but we want to concatenate\n // them so they are list that is combined from all extended buttons\n\n if (originalClassName && conf.className !== originalClassName) {\n conf.className = originalClassName + ' ' + conf.className;\n } // Buttons to be added to a collection -gives the ability to define\n // if buttons should be added to the start or end of a collection\n\n\n var postfixButtons = conf.postfixButtons;\n\n if (postfixButtons) {\n if (!conf.buttons) {\n conf.buttons = [];\n }\n\n for (i = 0, ien = postfixButtons.length; i < ien; i++) {\n conf.buttons.push(postfixButtons[i]);\n }\n\n conf.postfixButtons = null;\n }\n\n var prefixButtons = conf.prefixButtons;\n\n if (prefixButtons) {\n if (!conf.buttons) {\n conf.buttons = [];\n }\n\n for (i = 0, ien = prefixButtons.length; i < ien; i++) {\n conf.buttons.splice(i, 0, prefixButtons[i]);\n }\n\n conf.prefixButtons = null;\n } // Although we want the `conf` object to overwrite almost all of\n // the properties of the object being extended, the `extend`\n // property should come from the object being extended\n\n\n conf.extend = objArray.extend;\n }\n\n return conf;\n }\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Statics\r\n */\n\n /**\r\n * Show / hide a background layer behind a collection\r\n *\r\n * @name Buttons.background\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} Flag to indicate if the background should be shown or\r\n * hidden\r\n * @param {string} Class to assign to the background\r\n *\r\n * @static\r\n *\r\n */\n\n Buttons.background = function (show, className, fade) {\n if (fade === undefined) {\n fade = 400;\n }\n\n if (show) {\n $('
').addClass(className).css('display', 'none').appendTo('body').fadeIn(fade);\n } else {\n $('body > div.' + className).fadeOut(fade, function () {\n $(this).removeClass(className).remove();\n });\n }\n };\n /**\r\n * Instance selector - select Buttons instances based on an instance selector\r\n * value from the buttons assigned to a DataTable. This is only useful if\r\n * multiple instances are attached to a DataTable.\r\n *\r\n * @name Buttons.instanceSelector\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string|int|array} Instance selector - see `instance-selector`\r\n * documentation on the DataTables site\r\n * @param {array} Button instance array that was attached to the DataTables\r\n * settings object\r\n * @return {array} Buttons instances\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.instanceSelector = function (group, buttons) {\n if (!group) {\n return $.map(buttons, function (v) {\n return v.inst;\n });\n }\n\n var ret = [];\n var names = $.map(buttons, function (v) {\n return v.name;\n }); // Flatten the group selector into an array of single options\n\n var process = function process(input) {\n if (Array.isArray(input)) {\n for (var i = 0, ien = input.length; i < ien; i++) {\n process(input[i]);\n }\n\n return;\n }\n\n if (typeof input === 'string') {\n if (input.indexOf(',') !== -1) {\n // String selector, list of names\n process(input.split(','));\n } else {\n // String selector individual name\n var idx = $.inArray(input.trim(), names);\n\n if (idx !== -1) {\n ret.push(buttons[idx].inst);\n }\n }\n } else if (typeof input === 'number') {\n // Index selector\n ret.push(buttons[input].inst);\n }\n };\n\n process(group);\n return ret;\n };\n /**\r\n * Button selector - select one or more buttons from a selector input so some\r\n * operation can be performed on them.\r\n *\r\n * @name Buttons.buttonSelector\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {array} Button instances array that the selector should operate on\r\n * @param {string|int|node|jQuery|array} Button selector - see\r\n * `button-selector` documentation on the DataTables site\r\n * @return {array} Array of objects containing `inst` and `idx` properties of\r\n * the selected buttons so you know which instance each button belongs to.\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.buttonSelector = function (insts, selector) {\n var ret = [];\n\n var nodeBuilder = function nodeBuilder(a, buttons, baseIdx) {\n var button;\n var idx;\n\n for (var i = 0, ien = buttons.length; i < ien; i++) {\n button = buttons[i];\n\n if (button) {\n idx = baseIdx !== undefined ? baseIdx + i : i + '';\n a.push({\n node: button.node,\n name: button.conf.name,\n idx: idx\n });\n\n if (button.buttons) {\n nodeBuilder(a, button.buttons, idx + '-');\n }\n }\n }\n };\n\n var run = function run(selector, inst) {\n var i, ien;\n var buttons = [];\n nodeBuilder(buttons, inst.s.buttons);\n var nodes = $.map(buttons, function (v) {\n return v.node;\n });\n\n if (Array.isArray(selector) || selector instanceof $) {\n for (i = 0, ien = selector.length; i < ien; i++) {\n run(selector[i], inst);\n }\n\n return;\n }\n\n if (selector === null || selector === undefined || selector === '*') {\n // Select all\n for (i = 0, ien = buttons.length; i < ien; i++) {\n ret.push({\n inst: inst,\n node: buttons[i].node\n });\n }\n } else if (typeof selector === 'number') {\n // Main button index selector\n ret.push({\n inst: inst,\n node: inst.s.buttons[selector].node\n });\n } else if (typeof selector === 'string') {\n if (selector.indexOf(',') !== -1) {\n // Split\n var a = selector.split(',');\n\n for (i = 0, ien = a.length; i < ien; i++) {\n run(a[i].trim(), inst);\n }\n } else if (selector.match(/^\\d+(\\-\\d+)*$/)) {\n // Sub-button index selector\n var indexes = $.map(buttons, function (v) {\n return v.idx;\n });\n ret.push({\n inst: inst,\n node: buttons[$.inArray(selector, indexes)].node\n });\n } else if (selector.indexOf(':name') !== -1) {\n // Button name selector\n var name = selector.replace(':name', '');\n\n for (i = 0, ien = buttons.length; i < ien; i++) {\n if (buttons[i].name === name) {\n ret.push({\n inst: inst,\n node: buttons[i].node\n });\n }\n }\n } else {\n // jQuery selector on the nodes\n $(nodes).filter(selector).each(function () {\n ret.push({\n inst: inst,\n node: this\n });\n });\n }\n } else if (_typeof(selector) === 'object' && selector.nodeName) {\n // Node selector\n var idx = $.inArray(selector, nodes);\n\n if (idx !== -1) {\n ret.push({\n inst: inst,\n node: nodes[idx]\n });\n }\n }\n };\n\n for (var i = 0, ien = insts.length; i < ien; i++) {\n var inst = insts[i];\n run(selector, inst);\n }\n\n return ret;\n };\n /**\r\n * Version information\r\n *\r\n * @name Buttons.version\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @type {string}\r\n *\r\n * @static\r\n *\r\n */\n\n\n Buttons.version = '1.5.1';\n $.extend(_dtButtons, {\n collection: {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.collection');\n },\n className: 'buttons-collection',\n action: function action(e, dt, button, config) {\n var host = button;\n var collectionParent = $(button).parents('div.dt-button-collection');\n var hostPosition = {\n top: host.position().top + parseInt(host.css('marginTop'), 10),\n left: host.position().left + parseInt(host.css('marginLeft'), 10)\n };\n var tableContainer = $(dt.table().container());\n var multiLevel = false;\n var insertPoint = host; // Remove any old collection\n\n if (collectionParent.length) {\n multiLevel = $('.dt-button-collection').position();\n insertPoint = collectionParent;\n $('body').trigger('click.dtb-collection');\n }\n\n config._collection.addClass(config.collectionLayout).css('display', 'none').insertAfter(insertPoint).fadeIn(config.fade);\n\n var position = config._collection.css('position');\n\n if (multiLevel && position === 'absolute') {\n config._collection.css({\n top: multiLevel.top,\n left: multiLevel.left\n });\n } else if (position === 'absolute') {\n config._collection.css({\n top: hostPosition.top + host.outerHeight(),\n left: hostPosition.left\n }); // calculate overflow when positioned beneath\n\n\n var tableBottom = tableContainer.offset().top + tableContainer.height();\n\n var listBottom = hostPosition.top + host.outerHeight() + config._collection.outerHeight();\n\n var bottomOverflow = listBottom - tableBottom; // calculate overflow when positioned above\n\n var listTop = hostPosition.top - config._collection.outerHeight();\n\n var tableTop = tableContainer.offset().top;\n var topOverflow = tableTop - listTop; // if bottom overflow is larger, move to the top because it fits better\n\n if (bottomOverflow > topOverflow) {\n config._collection.css('top', hostPosition.top - config._collection.outerHeight() - 5);\n }\n\n var listRight = hostPosition.left + config._collection.outerWidth();\n\n var tableRight = tableContainer.offset().left + tableContainer.width();\n\n if (listRight > tableRight) {\n config._collection.css('left', hostPosition.left - (listRight - tableRight));\n }\n } else {\n // Fix position - centre on screen\n var top = config._collection.height() / 2;\n\n if (top > $(window).height() / 2) {\n top = $(window).height() / 2;\n }\n\n config._collection.css('marginTop', top * -1);\n }\n\n if (config.background) {\n // Si la tabla se encuentra en un dialogo insertamos el background dentro del dialogo\n if ($('div.rup-dialog').has('#' + dt.context[0].sTableId + '_wrapper').length ? true : false) {\n $('div.rup-dialog #' + dt.context[0].sTableId + '_wrapper').append('
');\n } // Si no usamos el funcionamiento por defecto\n else {\n Buttons.background(true, config.backgroundClassName, config.fade);\n }\n } // Need to break the 'thread' for the collection button being\n // activated by a click - it would also trigger this event\n\n\n setTimeout(function () {\n // This is bonkers, but if we don't have a click listener on the\n // background element, iOS Safari will ignore the body click\n // listener below. An empty function here is all that is\n // required to make it work...\n $('div.dt-button-background').on('click.dtb-collection', function () {});\n $('body').on('click.dtb-collection', function (e) {\n // andSelf is deprecated in jQ1.8, but we want 1.7 compat\n var back = $.fn.addBack ? 'addBack' : 'andSelf';\n\n if (!$(e.target).parents()[back]().filter(config._collection).length) {\n config._collection.fadeOut(config.fade, function () {\n config._collection.detach();\n });\n\n $('div.dt-button-background').off('click.dtb-collection'); // Si la tabla se encuentra en un dialogo eliminamos el background de dentro del dialogo\n\n if ($('div.rup-dialog').has('#' + dt.context[0].sTableId + '_wrapper').length ? true : false) {\n $('div.dt-button-background').remove();\n } // Si no usamos el funcionamiento por defecto\n else {\n Buttons.background(false, config.backgroundClassName, config.fade);\n }\n\n $('body').off('click.dtb-collection');\n dt.off('buttons-action.b-internal');\n }\n });\n }, 10); // Como el boton se posiciona de manera absoluta hay que establecerle la posicion\n // cada vez que se cambia el tamaño de la pantalla.\n\n $(window).on('resize.ajustarCollection', function () {\n if (!$('div.dt-button-collection').is(':visible')) {\n $(window).off('resize.ajustarCollection');\n } else {\n hostPosition = {\n top: host.position().top + parseInt(host.css('marginTop'), 10),\n left: host.position().left + parseInt(host.css('marginLeft'), 10)\n };\n\n config._collection.css({\n top: hostPosition.top + host.outerHeight(),\n left: hostPosition.left\n });\n }\n });\n\n if (config.autoClose) {\n dt.on('buttons-action.b-internal', function () {\n $('div.dt-button-background').click();\n });\n }\n },\n background: true,\n collectionLayout: '',\n backgroundClassName: 'dt-button-background',\n autoClose: false,\n fade: 400,\n attr: {\n 'aria-haspopup': true\n }\n },\n addButton: function addButton(dt, conf) {\n var ctx = dt.context[0];\n var collection = _dtButtons['collection'];\n _dtButtons = ctx.ext.buttons;\n _dtButtons.collection = collection;\n\n if (_dtButtons.addButton) {\n return 'addButton';\n }\n },\n editButton: function editButton(dt, conf) {\n if (_dtButtons.editButton) {\n return 'editButton';\n }\n },\n cloneButton: function cloneButton(dt, conf) {\n if (_dtButtons.cloneButton) {\n return 'cloneButton';\n }\n },\n deleteButton: function deleteButton(dt, conf) {\n if (_dtButtons.deleteButton) {\n return 'deleteButton';\n }\n },\n reportsButton: function reportsButton(dt, conf) {\n if (_dtButtons.reportsButton) {\n return 'reportsButton';\n }\n },\n pageLength: function pageLength(dt) {\n var lengthMenu = dt.settings()[0].aLengthMenu;\n var vals = Array.isArray(lengthMenu[0]) ? lengthMenu[0] : lengthMenu;\n var lang = Array.isArray(lengthMenu[0]) ? lengthMenu[1] : lengthMenu;\n\n var text = function text(dt) {\n return dt.i18n('rup_table.pageLength', {\n '-1': 'Show all rows',\n _: 'Show %d rows'\n }, dt.page.len());\n };\n\n return {\n extend: 'collection',\n text: text,\n className: 'buttons-page-length',\n autoClose: true,\n buttons: $.map(vals, function (val, i) {\n return {\n text: lang[i],\n className: 'button-page-length',\n action: function action(e, dt) {\n dt.page.len(val).draw();\n },\n init: function init(dt, node, conf) {\n var that = this;\n\n var fn = function fn() {\n that.active(dt.page.len() === val);\n };\n\n dt.on('length.dt' + conf.namespace, fn);\n fn();\n },\n destroy: function destroy(dt, node, conf) {\n dt.off('length.dt' + conf.namespace);\n }\n };\n }),\n init: function init(dt, node, conf) {\n var that = this;\n dt.on('length.dt' + conf.namespace, function () {\n that.text(text(dt));\n });\n },\n destroy: function destroy(dt, node, conf) {\n dt.off('length.dt' + conf.namespace);\n }\n };\n }\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables API\r\n *\r\n * For complete documentation, please refer to the docs/api directory or the\r\n * DataTables site\r\n */\n // Buttons group and individual button selector\n\n DataTable.Api.register('buttons()', function (group, selector) {\n // Argument shifting\n if (selector === undefined) {\n selector = group;\n group = undefined;\n }\n\n this.selector.buttonGroup = group;\n var res = this.iterator(true, 'table', function (ctx) {\n if (ctx._buttons) {\n return Buttons.buttonSelector(Buttons.instanceSelector(group, ctx._buttons), selector);\n }\n }, true);\n res._groupSelector = group;\n return res;\n }); // Individual button selector\n\n DataTable.Api.register('button()', function (group, selector) {\n // just run buttons() and truncate\n var buttons = this.buttons(group, selector);\n\n if (buttons.length > 1) {\n buttons.splice(1, buttons.length);\n }\n\n return buttons;\n }); // Active buttons\n\n DataTable.Api.registerPlural('buttons().active()', 'button().active()', function (flag) {\n if (flag === undefined) {\n return this.map(function (set) {\n return set.inst.active(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.active(set.node, flag);\n });\n }); // Get / set button action\n\n DataTable.Api.registerPlural('buttons().action()', 'button().action()', function (action) {\n if (action === undefined) {\n return this.map(function (set) {\n return set.inst.action(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.action(set.node, action);\n });\n }); // Enable / disable buttons\n\n DataTable.Api.register(['buttons().enable()', 'button().enable()'], function (flag, contextMenu) {\n return this.each(function (set) {\n set.inst.enable(set.node, flag, contextMenu);\n });\n }); // Disable buttons\n\n DataTable.Api.register(['buttons().disable()', 'button().disable()'], function (contextMenu) {\n return this.each(function (set) {\n set.inst.disable(set.node, contextMenu);\n });\n }); // Get button nodes\n\n DataTable.Api.registerPlural('buttons().nodes()', 'button().node()', function () {\n var jq = $(); // jQuery will automatically reduce duplicates to a single entry\n\n $(this.each(function (set) {\n jq = jq.add(set.inst.node(set.node));\n }));\n return jq;\n }); // Get / set button processing state\n\n DataTable.Api.registerPlural('buttons().processing()', 'button().processing()', function (flag) {\n if (flag === undefined) {\n return this.map(function (set) {\n return set.inst.processing(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.processing(set.node, flag);\n });\n }); // Get / set button text (i.e. the button labels)\n\n DataTable.Api.registerPlural('buttons().text()', 'button().text()', function (label) {\n if (label === undefined) {\n return this.map(function (set) {\n return set.inst.text(set.node);\n });\n }\n\n return this.each(function (set) {\n set.inst.text(set.node, label);\n });\n }); // Trigger a button's action\n\n DataTable.Api.registerPlural('buttons().trigger()', 'button().trigger()', function () {\n return this.each(function (set) {\n set.inst.node(set.node).trigger('click');\n });\n }); // Get the container elements\n\n DataTable.Api.registerPlural('buttons().containers()', 'buttons().container()', function () {\n var jq = $();\n var groupSelector = this._groupSelector; // We need to use the group selector directly, since if there are no buttons\n // the result set will be empty\n\n this.iterator(true, 'table', function (ctx) {\n if (ctx._buttons) {\n var insts = Buttons.instanceSelector(groupSelector, ctx._buttons);\n\n for (var i = 0, ien = insts.length; i < ien; i++) {\n jq = jq.add(insts[i].container());\n }\n }\n });\n return jq;\n }); // Add a new button\n\n DataTable.Api.register('button().add()', function (idx, conf) {\n var ctx = this.context;\n var api = new DataTable.Api(ctx); // Don't use `this` as it could be empty - select the instances directly\n\n if (ctx.length) {\n var inst = Buttons.instanceSelector(this._groupSelector, ctx[0]._buttons);\n\n if (inst.length) {\n inst[0].add(conf, idx); // Nuevo botón al contextMenu\n\n _updateContextMenu(this[0].inst.s.buttons, api, ctx[0]);\n }\n }\n\n return this.button(this._groupSelector, idx);\n }); // Destroy the button sets selected\n\n DataTable.Api.register('buttons().destroy()', function () {\n this.pluck('inst').each(function (inst) {\n inst.destroy();\n });\n return this;\n }); // Remove a button\n\n DataTable.Api.registerPlural('buttons().remove()', 'buttons().remove()', function () {\n this.each(function (set) {\n set.inst.remove(set.node);\n });\n return this;\n }); // Information box that can be used by buttons\n\n var _infoTimer;\n\n DataTable.Api.register('buttons.info()', function (title, message, time) {\n var that = this;\n\n if (title === false) {\n $('#table_buttons_info').fadeOut(function () {\n $(this).remove();\n });\n clearTimeout(_infoTimer);\n _infoTimer = null;\n return this;\n }\n\n if (_infoTimer) {\n clearTimeout(_infoTimer);\n }\n\n if ($('#table_buttons_info').length) {\n $('#table_buttons_info').remove();\n }\n\n title = title ? '

' + title + '

' : '';\n $('
').html(title).append($('
')[typeof message === 'string' ? 'html' : 'append'](message)).css('display', 'none').appendTo('body').fadeIn();\n\n if (time !== undefined && time !== 0) {\n _infoTimer = setTimeout(function () {\n that.buttons.info(false);\n }, time);\n }\n\n return this;\n }); // Get data from the table for export - this is common to a number of plug-in\n // buttons so it is included in the Buttons core library\n\n DataTable.Api.register('buttons.exportData()', function (options) {\n if (this.context.length) {\n return _exportData(new DataTable.Api(this.context[0]), options);\n }\n }); // Get information about the export that is common to many of the export data\n // types (DRY)\n\n DataTable.Api.register('buttons.exportInfo()', function (conf) {\n if (!conf) {\n conf = {};\n }\n\n return {\n filename: _filename(conf),\n title: _title(conf),\n messageTop: _message(this, conf.message || conf.messageTop, 'top'),\n messageBottom: _message(this, conf.messageBottom, 'bottom')\n };\n }); // Gestiona las acciones de los botones\n\n DataTable.Api.register('buttons.actions()', function (dt, config) {\n var ctx = dt.settings()[0]; // Añade aquí las funciones de tus botones\n\n switch (config.type) {\n case 'add':\n ctx.oInit.buttons.myLastAction = 'add';\n\n if (ctx.oInit.formEdit !== undefined) {\n $.when(DataTable.Api().editForm.loadSaveDialogForm(ctx, 'POST')).then(function () {\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Limpiamos el formulario\n\n if ($(idTableDetail).find('form')[0] !== undefined) {\n $(idTableDetail).find('form')[0].reset();\n jQuery.each($('select.rup_combo', $(idTableDetail)), function (index, elem) {\n jQuery(elem).rup_combo('refresh');\n });\n\n if (ctx.multiselection.numSelected > 0) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.checkSelectedElems'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n // Abrimos el formulario\n if (ctx.oInit.seeker !== undefined && ctx.oInit.seeker.activate) {\n DataTable.Api().seeker.limpiarSeeker(dt, ctx); // Y deselecionamos los checks y seekers\n } else {\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt); // Y deselecionamos los checks y seekers\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx); // Y deselecionamos los checks y seekers\n }\n }\n\n DataTable.Api().editForm.openSaveDialog('POST', dt, null, ctx.oInit.formEdit.customTitle);\n }\n });\n } else {\n DataTable.Api().editForm.openSaveDialog('POST', dt, null, ctx.oInit.formEdit.customTitle);\n }\n } else {\n $.rup_messages('msgError', {\n title: 'Error grave',\n message: '

Falta definir \"detailForm\" en la inicialización de la tabla.

'\n });\n }\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.currentPos = undefined;\n DataTable.Api().inlineEdit.add(dt, ctx);\n }\n\n break;\n\n case 'edit':\n // Abrimos el formulario\n ctx.oInit.buttons.myLastAction = 'edit';\n\n if (ctx.oInit.formEdit !== undefined) {\n // Se busca el idRow con el último seleccionado. En caso de no existir, será el primero.\n $.when(DataTable.Api().editForm.getRowSelected(dt, 'PUT')).then(function (rowInfo) {\n if (ctx.oInit.formEdit.$navigationBar === undefined || ctx.oInit.formEdit.$navigationBar.funcionParams === undefined || ctx.oInit.formEdit.$navigationBar.funcionParams[4] === undefined || dt.page() + 1 === Number(ctx.oInit.formEdit.$navigationBar.funcionParams[4])) {\n DataTable.Api().editForm.openSaveDialog('PUT', dt, rowInfo.line, ctx.oInit.formEdit.customTitle);\n }\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.currentPos = undefined;\n ctx.oInit.inlineEdit.alta = undefined;\n var idRowInline = DataTable.Api().inlineEdit.getRowSelected(dt, 'PUT').line;\n }\n\n break;\n\n case 'clone':\n ctx.oInit.buttons.myLastAction = 'clone'; // Abrimos el formulario\n\n if (ctx.oInit.formEdit !== undefined) {\n // Se busca el idRow con el último seleccionado. En caso de no existir, será el primero.\n $.when(DataTable.Api().editForm.getRowSelected(dt, 'CLONE')).then(function (rowInfo) {\n DataTable.Api().editForm.openSaveDialog('CLONE', dt, rowInfo.line, ctx.oInit.formEdit.customTitle);\n });\n } else {\n //edicion en linea\n ctx.oInit.inlineEdit.alta = true;\n ctx.oInit.inlineEdit.currentPos = undefined;\n var idRowInline = DataTable.Api().inlineEdit.getRowSelected(dt, 'CLONE').line;\n }\n\n break;\n\n case 'delete':\n var customEliminar = ctx.oInit.validarEliminar;\n\n if (typeof customEliminar === \"function\" && customEliminar(ctx)) {\n return false;\n }\n\n ctx.oInit.buttons.myLastAction = 'delete'; // borramos todos los seleccionados.\n\n if (!ctx.oInit.noEdit && ctx.oInit.formEdit !== undefined) {\n DataTable.Api().editForm.deleteAllSelects(dt);\n } else if (!ctx.oInit.noEdit && ctx.oInit.inlineEdit !== undefined) {\n //edicion en linea\n DataTable.Api().inlineEdit.deleteAllSelects(dt);\n } else {\n //Delete sin formulario\n _deleteAllSelects(dt);\n }\n\n break;\n }\n }); // Detecta el numero de filas seleccionadas y en funcion de eso muestra u oculta los botones.\n\n DataTable.Api.register('buttons.displayRegex()', function (ctx) {\n if (ctx._buttons[0].inst.s.disableAllButtons === undefined) {\n var opts = ctx._buttons[0].inst.s.buttons;\n var collectionObject;\n $.each(opts, function (i) {\n collectionObject = null;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n\n if (ctx.oInit.masterDetail !== undefined && this.conf.id === ctx.sTableId + 'addButton_1') {\n //si es maestro detalle para el boton add ,solo se renderiza cuando hay selección en el padre.\n var table = $(ctx.oInit.masterDetail.master).DataTable();\n numOfSelectedRows = table.context[0].multiselection.numSelected; //Nums del padre\n\n this.conf.displayRegex = /^[1-9][0-9]*$/; //se cambia expresion regular\n }\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx); // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n collectionObject = this;\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx);\n }\n });\n }\n });\n DataTable.Api.register('buttons.disableAllButtons()', function (ctx, exception) {\n var s = ctx._buttons[0].inst.s;\n $.each(s.buttons, function () {\n if (ctx.oInit.noEdit && exception !== undefined && !exception.includes(this.node.id)) {\n // Deshabilita permanentemente el botón (tanto de la toolbar como del contextMenu).\n this.conf.displayRegex = undefined;\n } else if (exception === undefined || !exception.includes(this.node.id)) {\n // Deshabilita el botón de la toolbar.\n $(this.node).prop('disabled', true); // Deshabilita el botón del contextMenu.\n\n $('#' + this.node.id + '_contextMenuToolbar').addClass('disabledButtonsTable');\n }\n });\n s.disableAllButtons = true;\n });\n DataTable.Api.register('buttons.initButtons()', function (ctx, opts) {\n _initButtons(ctx, opts);\n });\n DataTable.Api.register('buttons.deleteNotForm()', function (dt) {\n _deleteAllSelects(dt);\n });\n /**\r\n * Get the file name for an exported file.\r\n *\r\n * @name _filename\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object}\tconfig Button configuration\r\n * @param {boolean} incExtension Include the file name extension\r\n *\r\n */\n\n var _filename = function _filename(config) {\n // Backwards compatibility\n var filename = config.filename === '*' && config.title !== '*' && config.title !== undefined && config.title !== null && config.title !== '' ? config.title : config.filename;\n\n if (typeof filename === 'function') {\n filename = filename();\n }\n\n if (filename === undefined || filename === null) {\n return null;\n }\n\n if (filename.indexOf('*') !== -1) {\n filename = filename.replace('*', $('head > title').text()).trim();\n } // Strip characters which the OS will object to\n\n\n filename = filename.replace(/[^a-zA-Z0-9_\\u00A1-\\uFFFF\\.,\\-_ !\\(\\)]/g, '');\n\n var extension = _stringOrFunction(config.extension);\n\n if (!extension) {\n extension = '';\n }\n\n return filename + extension;\n };\n /**\r\n * Simply utility method to allow parameters to be given as a function\r\n *\r\n * @name _stringOrFunction\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {undefined|string|function} option Option\r\n *\r\n * @return {null|string} Resolved value\r\n *\r\n */\n\n\n var _stringOrFunction = function _stringOrFunction(option) {\n if (option === null || option === undefined) {\n return null;\n } else if (typeof option === 'function') {\n return option();\n }\n\n return option;\n };\n /**\r\n * Get the title for an exported file.\r\n *\r\n * @name _title\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} config\tButton configuration\r\n *\r\n */\n\n\n var _title = function _title(config) {\n var title = _stringOrFunction(config.title);\n\n return title === null ? null : title.indexOf('*') !== -1 ? title.replace('*', $('head > title').text() || 'Exported data') : title;\n };\n\n var _message = function _message(dt, option, position) {\n var message = _stringOrFunction(option);\n\n if (message === null) {\n return null;\n }\n\n var caption = $('caption', dt.table().container()).eq(0);\n\n if (message === '*') {\n var side = caption.css('caption-side');\n\n if (side !== position) {\n return null;\n }\n\n return caption.length ? caption.text() : '';\n }\n\n return message;\n };\n\n var _exportTextarea = $('')[0];\n\n var _exportData = function _exportData(dt, inOpts) {\n var config = $.extend(true, {}, {\n rows: null,\n columns: '',\n modifier: {\n search: 'applied',\n order: 'applied'\n },\n orthogonal: 'display',\n stripHtml: true,\n stripNewlines: true,\n decodeEntities: true,\n trim: true,\n format: {\n header: function header(d) {\n return strip(d);\n },\n footer: function footer(d) {\n return strip(d);\n },\n body: function body(d) {\n return strip(d);\n }\n }\n }, inOpts);\n\n var strip = function strip(str) {\n if (typeof str !== 'string') {\n return str;\n } // Always remove script tags\n\n\n str = str.replace(/)<[^<]*)*<\\/script>/gi, '');\n\n if (config.stripHtml) {\n str = str.replace(/<[^>]*>/g, '');\n }\n\n if (config.trim) {\n str = str.replace(/^\\s+|\\s+$/g, '');\n }\n\n if (config.stripNewlines) {\n str = str.replace(/\\n/g, ' ');\n }\n\n if (config.decodeEntities) {\n _exportTextarea.innerHTML = str;\n str = _exportTextarea.value;\n }\n\n return str;\n };\n\n var header = dt.columns(config.columns).indexes().map(function (idx) {\n var el = dt.column(idx).header();\n return config.format.header(el.innerHTML, idx, el);\n }).toArray();\n var footer = dt.table().footer() ? dt.columns(config.columns).indexes().map(function (idx) {\n var el = dt.column(idx).footer();\n return config.format.footer(el ? el.innerHTML : '', idx, el);\n }).toArray() : null; // If Select is available on this table, and any rows are selected, limit the export\n // to the selected rows. If no rows are selected, all rows will be exported. Specify\n // a `selected` modifier to control directly.\n\n var modifier = $.extend({}, config.modifier);\n\n if (dt.select && typeof dt.select.info === 'function' && modifier.selected === undefined) {\n if (dt.rows(config.rows, $.extend({\n selected: true\n }, modifier)).any()) {\n $.extend(modifier, {\n selected: true\n });\n }\n }\n\n var rowIndexes = dt.rows(config.rows, modifier).indexes().toArray();\n var selectedCells = dt.cells(rowIndexes, config.columns);\n var cells = selectedCells.render(config.orthogonal).toArray();\n var cellNodes = selectedCells.nodes().toArray();\n var columns = header.length;\n var rows = columns > 0 ? cells.length / columns : 0;\n var body = [rows];\n var cellCounter = 0;\n\n for (var i = 0, ien = rows; i < ien; i++) {\n var row = [columns];\n\n for (var j = 0; j < columns; j++) {\n row[j] = config.format.body(cells[cellCounter], i, j, cellNodes[cellCounter]);\n cellCounter++;\n }\n\n body[i] = row;\n }\n\n return {\n header: header,\n footer: footer,\n body: body\n };\n };\n /**\r\n * Activa la coleccion\r\n *\r\n * @name _enableCollection\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _enableCollection = function _enableCollection(id) {\n $('#' + id).prop('disabled', false);\n };\n /**\r\n * Desactiva la coleccion\r\n *\r\n * @name _disableCollection\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _disableCollection = function _disableCollection(id) {\n $('#' + id).prop('disabled', true);\n };\n /**\r\n * Activa el boton y su opcion dentro del context menu\r\n *\r\n * @name _enableButtonAndContextMenuOption\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _enableButtonAndContextMenuOption = function _enableButtonAndContextMenuOption(id) {\n $('#' + id).prop('disabled', false);\n $('#' + id + '_contextMenuToolbar').removeClass('disabledButtonsTable');\n };\n /**\r\n * Desactiva el boton y su opcion dentro del context menu\r\n *\r\n * @name _disableButtonAndContextMenuOption\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} id\tId of the button\r\n *\r\n */\n\n\n var _disableButtonAndContextMenuOption = function _disableButtonAndContextMenuOption(id) {\n $('#' + id).prop('disabled', true);\n $('#' + id + '_contextMenuToolbar').addClass('disabledButtonsTable');\n };\n /**\r\n * Gestiona la propiedad de activado/desactivado de los botones y de sus opciones\r\n * dentro del context menu.\r\n *\r\n * @name _manageButtonsAndButtonsContextMenu\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} opts\tButtons properties\r\n * @param {int} numOfSelectedRows\tNumber of selected rows\r\n * @param {null|object} collectionObject\tCollection button properties\r\n *\r\n */\n\n\n var _manageButtonsAndButtonsContextMenu = function _manageButtonsAndButtonsContextMenu(opts, numOfSelectedRows, collectionObject, ctx) {\n if (opts.conf.custom === undefined || !opts.conf.custom) {\n // Si pertenece a un collection o es un collection\n if (opts.collection !== null && collectionObject) {\n var collectionId = collectionObject.conf.id;\n var collectionDisplayRegex = collectionObject.conf.displayRegex;\n var alreadyExecuted = false; // Recorre todos los botones dentro del collection\n\n $.each(collectionObject.buttons, function (key, value) {\n // Activa/desactiva en funcion de la propiedad 'displayRegex' del padre y los hijos\n if (collectionDisplayRegex !== undefined && value.conf.displayRegex !== undefined) {\n if (collectionDisplayRegex.test(numOfSelectedRows) && value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } else {\n _disableButtonAndContextMenuOption(value.conf.id);\n }\n } // Activa/desactiva en funcion de la propiedad 'displayRegex' de sus hijos\n else if (collectionDisplayRegex === undefined && value.conf.displayRegex !== undefined) {\n // Habilita la coleccion si cumple el regex (solo se ejecuta una vez como\n // maximo gracias al booleano 'alreadyExecuted')\n if (value.conf.displayRegex.test(numOfSelectedRows) && !alreadyExecuted) {\n _enableCollection(collectionId);\n\n alreadyExecuted = true;\n } // Habilita el boton si cumple el displayRegex\n\n\n if (value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } // Como este boton no cumple el 'displayRegex' para ser habilitado, se deshabilitan\n // tanto el boton como su opcion en el contextMenu\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n } // En caso de que ningun regex cumpliese, se fuerza la deshabilitacion\n\n\n if (!alreadyExecuted) {\n _disableCollection(collectionId);\n }\n } // Desactiva todo si ni el collection ni los hijos tienen la propiedad 'displayRegex'\n // o simplemente si los hijos no tienen la propiedad\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n\n if (!alreadyExecuted) {\n _disableCollection(collectionId);\n\n alreadyExecuted = true;\n }\n }\n }); // Genera un evento encargado de ocultar los botones dentro del collection.\n // Se comprueba mediante una clase si ya tiene o no el evento, mejorando asi\n // el rendimiento\n\n $('#' + collectionId + ':not(.listening)').addClass('listening').on('click', function (e) {\n // Se establece el valor de 'numOfSelectedRows' porque sino siempre tendria\n // el valor recibido cuando se creo el evento\n var numOfSelectedRows = ctx.multiselection.numSelected;\n $.each(collectionObject.buttons, function (key, value) {\n // Habilita el boton dentro del collection\n if (value.conf.displayRegex.test(numOfSelectedRows)) {\n _enableButtonAndContextMenuOption(value.conf.id);\n } // Deshabilita el boton dentro del collection\n else {\n _disableButtonAndContextMenuOption(value.conf.id);\n }\n });\n });\n } // Si el boton no tiene un regex definido, permanecera siempre desactivado\n else if (opts.conf.displayRegex === undefined) {\n // Deshabilita el boton y su opcion dentro del context menu\n _disableButtonAndContextMenuOption(opts.conf.id);\n } // Si tiene un regex definido, lo activa y desactiva en funcion de este\n else if (opts.conf.displayRegex !== undefined) {\n // Si el regex recibido de cada boton cumple la sentencia al probarlo contra\n // el numero de filas seleccionadas, se mostrara, en caso contrario, permanecera\n // oculto\n if (opts.conf.displayRegex.test(numOfSelectedRows)) {\n // Habilita el boton y su opcion dentro del context menu\n _enableButtonAndContextMenuOption(opts.conf.id);\n } else {\n // Deshabilita el boton y su opcion dentro del context menu\n _disableButtonAndContextMenuOption(opts.conf.id);\n }\n }\n }\n };\n /**\r\n * Establece el tipo de llamada necesario para obtener los datos según lo seleccionado\r\n * e inicia la gestión para finalmente obtenerlos\r\n *\r\n * @name _reports\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} that Objeto del boton\r\n * @param {object} config Configuracion del boton\r\n *\r\n */\n\n\n var _reports = function _reports(dt, that, config) {\n var ctx = dt.settings()[0];\n var info = dt.buttons.exportInfo(config);\n var type;\n var multiselection = ctx.multiselection;\n var selectedAll = multiselection.selectedAll;\n var deselectedIds = multiselection.deselectedIds;\n\n if (selectedAll) {\n if (deselectedIds.length > 0) {\n // Este caso es para cuando se selecciona todo y despues se\n // deseleccionan algunos registros\n type = 'all-deselected';\n } else {\n // Este caso es para cuando se seleccionan todos los registros\n type = 'all';\n }\n } else if (multiselection.selectedIds.length > 0) {\n // Este caso para cuando hay determinados registros seleccionados manualmente\n type = 'selected';\n } else {\n // Este caso para cuando no hay registros seleccionados\n type = 'all';\n selectedAll = true;\n }\n\n $.when(_reportsTypeOfCopy(dt, type, config.request, multiselection, selectedAll, deselectedIds)).then(function (exportData, ajaxOptions) {\n // Si exportData cumple la siguiente condicion significa que los datos se van a copiar al portapapeles\n if (exportData !== undefined) {\n var exportDataRows = exportData.length;\n var exportDataParsed = JSON.stringify(exportData);\n var hiddenDiv = $('
').css({\n height: 1,\n width: 1,\n overflow: 'hidden',\n position: 'fixed',\n top: 0,\n left: 0\n });\n\n if (typeof ajaxOptions.data == 'string') {\n ajaxOptions.data = JSON.parse(ajaxOptions.data);\n }\n\n exportDataParsed = _convertToTabulador(ajaxOptions.reportsExportAllColumns, ajaxOptions.data.columns, exportDataParsed, true);\n var textarea = $('').val(exportDataParsed).appendTo(hiddenDiv);\n\n _reportsOpenMessage(dt, ctx, that, exportDataRows, hiddenDiv, textarea);\n } else {\n // Descargara un fichero\n _reportsRequestFile(ctx, ajaxOptions);\n }\n });\n };\n /**\r\n * Se encarga de mapear los datos de json a datos separados por el tabulador.\r\n *\r\n * @name ConvertToTabulador\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {boolean} reportsExportAllColumns true en caso de querer mostrar todas las columnas (incluidas las ocultas)\r\n * @param {object} columns Objeto que contiene las columnas a mostrar\r\n * @param {object} objArray Objeto que contiene los datos a exportar\r\n * @param {boolean} true en caso de querer que se mueste la cabecera\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _convertToTabulador = function _convertToTabulador(reportsExportAllColumns, columns, objArray, showLabel) {\n var array = _typeof(objArray) !== 'object' ? JSON.parse(objArray) : objArray;\n var separator = \";\";\n var str = '';\n var checkColumns = false; // Separador de campos dependiendo del idioma\n\n if ($.rup.lang === 'en') {\n separator = \",\";\n }\n\n if (!reportsExportAllColumns && columns != undefined) {\n checkColumns = true;\n }\n\n if (showLabel) {\n // Comprueba si solo se quieren mostrar las columnas definidas/visibles o todas\n if (checkColumns) {\n str = '\\\"' + columns.toString().replace(/,/g, '\\\"' + separator + '\\\"') + '\\\"\\r\\n';\n } else {\n var row = ''; // Se asignan los nombres de las columnas\n\n $.each(array[0], function (key, value) {\n // Comprobar si es un objeto, en caso afirmativo lo recorremos y lo concatenamos\n if ($.isPlainObject(value)) {\n var objectName = key;\n $.each(this, function (key, value) {\n var keyToCamelKeys = key.substring(0, 1).toLocaleUpperCase() + key.substring(1);\n row += '\\\"' + objectName + keyToCamelKeys + '\\\"' + separator;\n });\n } else {\n row += '\\\"' + key + '\\\"' + separator;\n }\n });\n row = row.slice(0, -1);\n str += row + '\\r\\n';\n }\n } // Se asignan los valores\n\n\n $.each(array, function () {\n var line = '';\n $.each(this, function (key, value) {\n // Comprueba si solo se quieren mostrar los valores de las columnas definidas/visibles y evita la insercion de las no que no lo estan\n if (checkColumns && columns.indexOf(key) == -1) {\n return;\n } // Comprobar si es un objeto, en caso afirmativo lo recorremos y lo concatenamos\n\n\n if ($.isPlainObject(value)) {\n $.each(this, function (key, value) {\n line += '\\\"' + value + '\\\"' + separator;\n });\n } else {\n line += '\\\"' + value + '\\\"' + separator;\n }\n });\n line = line.slice(0, -1);\n str += line + '\\r\\n';\n });\n return str;\n };\n /**\r\n * Según el tipo de función de copia solicitada, realiza unas u otras comprobaciones\r\n * antes de solicitar los datos al servidor\r\n *\r\n * @name _reportsTypeOfCopy\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {string} type Tipo de funcion de copia a ejecutar\r\n * @param {object} request Contiene todos los parametros de la petición AJAX\r\n * @param {object} multiselection Propiedades de la multiseleccion\r\n * @param {boolean} selectedAll Cuando es true significa que todas las filas estan marcadas\r\n * @param {array} [deselectedIds] ID's de las filas deseleccionadas\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsTypeOfCopy = function _reportsTypeOfCopy(dt, type, request, multiselection, selectedAll, deselectedIds) {\n var ctx = dt.settings()[0];\n var deferred = $.Deferred();\n var exportData;\n var selectedIds = multiselection.selectedIds;\n var selectedRows = multiselection.selectedRowsPerPage;\n var ajaxOptions = {};\n\n if (type === 'selected') {\n var _exportData2 = [];\n\n if (request.dataType === 'json') {\n var localAccess = true; // Comprueba si todos los valores seleccionados estan en la misma pagina\n\n $.each(selectedRows, function (key, value) {\n if (ctx.json.page != value.page) {\n localAccess = false;\n return false;\n }\n });\n\n if (localAccess) {\n // Puede acceder a los valores seleccionados localmente\n $.each(selectedRows, function (key, value) {\n var idPadre = value.id;\n $.each(ctx.json.rows, function (key, value) {\n if (DataTable.Api().rupTable.getIdPk(value) === idPadre) {\n _exportData2.push(value);\n }\n });\n });\n ajaxOptions.data = {};\n ajaxOptions.data.columns = _loadDefinedColums(dt, ctx, request);\n\n if (ctx.oInit.buttons.report !== undefined) {\n ajaxOptions.data.columnsName = ctx.oInit.buttons.report.columnsName;\n }\n\n ajaxOptions.reportsExportAllColumns = request.reportsExportAllColumns;\n deferred.resolve(_exportData2, ajaxOptions);\n return deferred.promise();\n }\n }\n }\n\n if (request.dataType === 'json') {\n // Accede a los datos mediante el servidor ya que se ha hecho uso de la paginacion\n // Parametros necesarios para configurar la llamada AJAX\n ajaxOptions = _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds);\n $.when(_reportsRequestData(ajaxOptions, ctx)).then(function (data) {\n exportData = data;\n deferred.resolve(exportData, ajaxOptions);\n });\n } else {\n // Parametros necesarios para configurar la llamada AJAX\n ajaxOptions = _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds);\n deferred.resolve(undefined, ajaxOptions);\n }\n\n return deferred.promise();\n };\n /**\r\n * Se encarga de generar las opciones de configuración con las que se llamara a la API\r\n *\r\n * @name _reportsPrepareRequestData\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n * @param {object} request Contiene todos los parametros de la petición ajax\r\n * @param {object} ctx Contexto\r\n * @param {boolean} selectedAll Cuando es true significa que todas las filas estan marcadas\r\n * @param {array} [deselectedIds] ID's de las filas deseleccionadas\r\n * @param {array} [selectedIds] ID's de las filas seleccionadas\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsPrepareRequestData = function _reportsPrepareRequestData(dt, ajaxOptions, request, ctx, selectedAll, deselectedIds, selectedIds) {\n var data = {};\n data.columns = _loadDefinedColums(dt, ctx, request);\n\n if (ctx.oInit.buttons.report !== undefined) {\n data.columnsName = ctx.oInit.buttons.report.columnsName;\n }\n\n data.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n }; // Solo se enviara el filtro si contiene algun valor. \n // Esto facilita la labor de exportacion al servidor ya que no tiene que iterar el filtro para comprobar si todos los campos son nulos.\n\n if (ctx.oInit.filter.$filterContainer != undefined && !jQuery.isEmptyObject(window.form2object(ctx.oInit.filter.$filterContainer[0]))) {\n data.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n }\n\n data.multiselection = {};\n data.multiselection.selectedAll = selectedAll;\n\n if (data.multiselection.selectedAll) {\n data.multiselection.selectedIds = deselectedIds;\n } else {\n data.multiselection.selectedIds = selectedIds;\n }\n\n data.reportsParams = []; // Se añaden los parametros definidos por el usuario (solo en caso de haber definido alguno)\n\n if (ctx.oInit.buttons.report !== undefined && ctx.oInit.buttons.report.reportsParams !== undefined && ctx.oInit.buttons.report.reportsParams.length > 0) {\n data.reportsParams = ctx.oInit.buttons.report.reportsParams;\n } // Completa el objeto 'ajaxOptions' con los parametros necesarios para la llamada que se realizara al servidor\n\n\n ajaxOptions.contentType = request.contentType;\n ajaxOptions.dataType = request.dataType;\n\n if (request.url !== undefined) {\n ajaxOptions.url = ctx.oInit.urlBase + request.url;\n } else {\n ajaxOptions.url = ctx.oInit.urlBase;\n }\n\n ajaxOptions.reportsExportAllColumns = request.reportsExportAllColumns;\n ajaxOptions.type = request.method;\n\n if (request.fileName !== undefined) {\n data.fileName = request.fileName;\n }\n\n if (request.sheetTitle !== undefined) {\n data.sheetTitle = request.sheetTitle;\n }\n\n ajaxOptions.data = $.toJSON(data);\n return ajaxOptions;\n };\n /**\r\n * Se encarga de devolver las columnas\r\n *\r\n * @name _loadDefinedColums\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ctx Contexto\r\n * @param {object} request Contiene todos los parametros de la petición AJAX\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _loadDefinedColums = function _loadDefinedColums(dt, ctx, request) {\n var columns = [];\n\n if (request.reportsExportAllColumns == undefined) {\n request.reportsExportAllColumns = ctx.ext.buttons.reportsButton.reportsExportAllColumns;\n }\n\n if (!request.reportsExportAllColumns) {\n // Se obtienen las columnas a mostrar definidas por el usuario\n if (ctx.oInit.buttons.report !== undefined && ctx.oInit.buttons.report.columns !== undefined) {\n columns = ctx.oInit.buttons.report.columns;\n } else {\n // En caso contrario se obtienen las columnas de la tabla\n $.each(ctx.oInit.columns, function (position, name) {\n // Se comprueba que el name.data no este vacio para evitar añadir\n // la columna del checkbox de multiseleccion. Tambien se comprueba\n // que la columna sea visible\n if (name.data !== \"\" && dt.column(position).visible()) {\n columns.push(name.data);\n }\n });\n }\n }\n\n return columns;\n };\n /**\r\n * Se encarga de llamar a la API y de devolver los datos recibidos\r\n *\r\n * @name _reportsRequestData\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n * @param {object} ctx Contexto\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsRequestData = function _reportsRequestData(ajaxOptions, ctx) {\n var deferred = $.Deferred();\n $.ajax(ajaxOptions).done(function (data) {\n deferred.resolve(data);\n $('#' + ctx.sTableId).triggerHandler('tableButtonsSuccessReportsRequestData');\n }).complete(function () {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsCompleteReportsRequestData');\n }).error(function () {\n $('#' + ctx.sTableId).triggerHandler('tableButtonsErrorReportsRequestData');\n });\n return deferred.promise();\n };\n /**\r\n * Se encarga de llamar a la API y de devolver el fichero recibido\r\n *\r\n * @name _reportsRequestFile\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx Contexto\r\n * @param {object} ajaxOptions Parametros de la llamada AJAX\r\n *\r\n * @return {object}\r\n *\r\n */\n\n\n var _reportsRequestFile = function _reportsRequestFile(ctx, ajaxOptions) {\n // Dialogo de espera\n var $reportFileWait = $('#' + ctx.sTableId + 'reportFileWait');\n $reportFileWait.rup_dialog({\n type: $.rup.dialog.TEXT,\n autoOpen: false,\n modal: true,\n resizable: false\n }); // Titulo\n\n var title = $.rup.i18nParse($.rup.i18n.base, 'rup_report.waitTitle');\n var message = $.rup.i18nParse($.rup.i18n.base, 'rup_report.waitMsg');\n\n if (ctx.oInit.buttons.report !== undefined) {\n if (ctx.oInit.buttons.report.title !== undefined) {\n title = ctx.oInit.buttons.report.title;\n }\n\n if (ctx.oInit.buttons.report.message !== undefined) {\n message = ctx.oInit.buttons.report.message;\n }\n }\n\n $reportFileWait.rup_dialog('setOption', 'title', title); // Contenido\n\n var content = $reportFileWait.html().split($reportFileWait.text()),\n html = '';\n\n for (var i = 0; i < content.length; i++) {\n if (content[i] === '') {\n html += message;\n } else {\n html += content[i];\n }\n }\n\n $reportFileWait.html(html);\n $reportFileWait.rup_dialog('open');\n var url = ajaxOptions.url; // Lanzar peticion \n\n var request = new XMLHttpRequest();\n request.open(ajaxOptions.type, url, true);\n request.responseType = 'blob';\n request.send(ajaxOptions.data);\n\n request.onload = function (event) {\n if (this.status == 200) {\n var blob = request.response;\n var fileName = null;\n var contentType = request.getResponseHeader('content-type');\n var element; // Parece que IE y EDGE no devuelven la misma cabecera en la respuesta\n\n if (request.getResponseHeader('content-disposition')) {\n var contentDisposition = request.getResponseHeader('content-disposition');\n fileName = contentDisposition.substring(contentDisposition.indexOf('=') + 1);\n } else {\n fileName = 'report.' + contentType.substring(contentType.indexOf('/') + 1);\n }\n\n if (window.navigator.msSaveOrOpenBlob) {\n // IE y EDGE\n window.navigator.msSaveOrOpenBlob(blob, fileName);\n } else {\n // Para los demas navegadores\n if (!$('a#rupTableButtonsReportsExport').length) {\n $('#' + ctx.sTableId + 'rup_report_dialogsContainer').append(\"rupTableButtonsReportsExport\");\n }\n\n element = $('a#rupTableButtonsReportsExport')[0];\n element.href = window.URL.createObjectURL(blob);\n element.download = fileName;\n element.click(); // Eliminamos el ObjectURL y el elemento de DOM generado ya que han sido generados de manera temporal\n\n window.URL.revokeObjectURL(element.href);\n element.remove();\n }\n\n if ($('#' + $reportFileWait.attr('id')).length > 0) {\n $reportFileWait.rup_dialog('close');\n }\n } else {\n if ($('#' + $reportFileWait.attr('id')).length > 0) {\n $reportFileWait.rup_dialog('close');\n console.info('----------- ERROR -----------');\n }\n }\n };\n\n request.send();\n return false;\n };\n /**\r\n * Gestiona la apertura/cierre del mensaje de confirmación de copia\r\n *\r\n * @name _reportsOpenMessage\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} ctx Contexto\r\n * @param {object} that Objeto del boton\r\n * @param {int} exportDataRows Numero de filas a ser exportadas\r\n * @param {object} hiddenDiv Elemento del DOM\r\n * @param {object} textarea Elemento del DOM\r\n *\r\n */\n\n\n var _reportsOpenMessage = function _reportsOpenMessage(dt, ctx, that, exportDataRows, hiddenDiv, textarea) {\n $.rup_messages('msgConfirm', {\n title: dt.i18n('rup_table.copyButton.changes', 'Copia de registros en clipboard'),\n message: dt.i18n('rup_table.copyButton.saveAndContinue', {\n _: '¿Desea copiar %d registros?',\n 1: '¿Desea copiar un registro?'\n }, exportDataRows),\n open: function open() {\n $('#' + dt.context[0].sTableId).trigger('rupTable_confirmMsgOpen');\n },\n OKFunction: function OKFunction() {\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.okCallBack = true;\n }\n\n _reportsToClipboard(dt, that, exportDataRows, hiddenDiv, textarea);\n\n if (ctx.oInit.formEdit !== undefined && !ctx.oInit.formEdit.detailForm.hasClass('d-none')) {\n //si esta oculto, no hace falta\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n }\n },\n beforeClose: function beforeClose() {\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.okCallBack = false;\n } // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n }\n });\n };\n /**\r\n * Copia los datos recibidos al portapapeles\r\n *\r\n * @name _reportsToClipboard\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt Instancia del table\r\n * @param {object} that Objeto del boton\r\n * @param {int} exportDataRows Numero de filas a ser exportadas\r\n * @param {object} hiddenDiv Elemento del DOM\r\n * @param {object} textarea Elemento del DOM\r\n *\r\n */\n\n\n var _reportsToClipboard = function _reportsToClipboard(dt, that, exportDataRows, hiddenDiv, textarea) {\n // Para los navegadores que soportan el comando de copia 'execCommand'\n if (document.queryCommandSupported('copy')) {\n hiddenDiv.appendTo(dt.table().container());\n textarea[0].focus();\n textarea[0].select();\n\n try {\n var successful = document.execCommand('copy');\n hiddenDiv.remove();\n\n if (successful) {\n dt.buttons.info(dt.i18n('rup_table.copyButton.changes', 'Copia de registros en portapapeles'), dt.i18n('rup_table.copyButton.saved', {\n _: 'Copiados %d registros al portapapeles',\n 1: 'Copiado un registro al portapapeles'\n }, exportDataRows), 2000); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n\n $('#' + dt.context[0].sTableId).trigger('rupTable_copied');\n return;\n }\n } catch (t) {}\n } // Si no soportan la copia mediante 'execCommand', se mostrara un text box\n // con las instrucciones de como copiar los elementos seleccionados\n\n\n var message = $('' + dt.i18n('rup_table.copyButton.copyKeys', 'Presiona ctrl o ⌘ + C para copiar los datos de la tabla al portapapeles.' + 'Para cancelar, haz click sobre este mensaje o pulsa el botón escape.') + '').append(hiddenDiv);\n dt.buttons.info(dt.i18n('rup_table.copyButton.copyTitle', 'Copiar al portapapeles'), message, 0); // Selecciona el texto para cuando el usuario accione la copia al portapapeles\n // se le pegue ese texto\n\n textarea[0].focus();\n textarea[0].select(); // Evento que oculta el mensaje cuando el usuario ha terminado con la copia\n\n var container = $(message).closest('.dt-button-info');\n\n var close = function close() {\n container.off('click.buttons-copy');\n $(document).off('.buttons-copy');\n dt.buttons.info(false); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n };\n\n container.on('click.buttons-copy', close);\n $(document).on('keydown.buttons-copy', function (e) {\n if (e.keyCode === 27) {\n // esc\n close();\n }\n }).on('copy.buttons-copy cut.buttons-copy', function () {\n close(); // Si es llamado desde el contextMenu este paso es innecesario y la condicion\n // del if evita un error\n\n if (that.processing !== undefined) {\n that.processing(false);\n }\n });\n };\n\n var _initContextMenu = function _initContextMenu(ctx, api) {\n // Creacion del Context Menu\n if (ctx.oInit.buttons !== undefined) {\n var botonesToolbar = ctx._buttons[0].inst.s.buttons;\n\n _updateContextMenu(botonesToolbar, api, ctx);\n }\n };\n /**\r\n * Metodo que elimina todos los registros seleccionados.\r\n *\r\n * @name _deleteAllSelects\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n var _deleteAllSelects = function _deleteAllSelects(dt) {\n var ctx = dt.settings()[0];\n var idRow = 0;\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.deleteAll'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.delete'),\n OKFunction: function OKFunction() {\n var row = {};\n row.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n\n if (ctx.multiselection.selectedIds.length > 1) {\n row.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n };\n row.multiselection = {};\n row.multiselection.selectedAll = ctx.multiselection.selectedAll;\n\n if (row.multiselection.selectedAll) {\n row.multiselection.selectedIds = ctx.multiselection.deselectedIds;\n } else {\n row.multiselection.selectedIds = ctx.multiselection.selectedIds;\n }\n\n _callDelete('POST', dt, ctx, row, '/filter?deleteAll=true');\n } else {\n row = ctx.multiselection.selectedIds[0];\n row = row.replace(regex, '/');\n\n _callDelete('DELETE', dt, ctx, idRow, '/' + row);\n }\n }\n });\n };\n\n var _callDelete = function _callDelete(actionType, dt, ctx, row, url) {\n $('#' + ctx.sTableId).triggerHandler('tableBeforeCallDelete');\n\n var _callFeedbackDelete = function _callFeedbackDelete(ctx, msgFeedBack, type) {\n $('#' + ctx.sTableId).triggerHandler('tableFeedbackShowDelete');\n ctx.oInit.feedback.$feedbackContainer.rup_feedback('set', msgFeedBack, type);\n ctx.oInit.feedback.$feedbackContainer.rup_feedback('show');\n };\n\n if (ctx.oInit.masterDetail !== undefined) {\n //Asegurar que se recoge el idPadre\n var masterPkObject = DataTable.Api().masterDetail.getMasterTablePkObject(ctx);\n jQuery.extend(true, masterPkObject, row);\n row = masterPkObject;\n }\n\n var msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.deletedOK');\n var ajaxOptions = {\n url: ctx.oInit.urlBase + url,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: actionType,\n data: row,\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: true,\n success: function success() {\n // Eliminar\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt);\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tablefterDelete');\n ctx._buttons[0].inst.s.disableAllButtons = undefined;\n DataTable.Api().seeker.disabledButtons(ctx); // Recargar datos\n // Primer parametro para mandar una funcion a ejecutar, segundo parametro bloquear la pagina si pones false\n\n dt.ajax.reload(function () {\n _callFeedbackDelete(ctx, msgFeedBack, 'ok');\n }, false);\n $('#' + ctx.sTableId).triggerHandler('tableSuccessCallDelete');\n },\n complete: function complete() {\n $('#' + ctx.sTableId).triggerHandler('tableCompleteCallDelete');\n },\n error: function error(xhr) {\n _callFeedbackDelete(ctx, xhr.responseText, 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableErrorCallDelete');\n },\n feedback: function feedback() {\n _callFeedbackDelete(ctx, msgFeedBack, 'ok');\n }\n };\n ajaxOptions.data = JSON.stringify(ajaxOptions.data);\n $.rup_ajax(ajaxOptions);\n };\n\n var _updateContextMenu = function _updateContextMenu(botones, api, ctx) {\n var items = {};\n var tableId = ctx.sTableId;\n $.each(botones, function () {\n // Entra si tiene marcada la opcion para habilitarlo dentro del contextMenu\n if (this.conf.insideContextMenu) {\n // Poblamos el objeto 'items' con los botones habilitados\n items[this.conf.id] = {\n id: this.conf.id + '_contextMenuToolbar',\n name: this.conf.text(api),\n icon: this.conf.icon,\n inCollection: this.inCollection,\n idCollection: undefined\n };\n } // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n var idCollection = this.conf.id;\n $.each(this.buttons, function (i) {\n // Entra si tiene marcada la opcion para habilitarlo dentro del contextMenu\n if (this.conf.insideContextMenu) {\n // Poblamos el objeto 'items' con los botones habilitados\n items[this.conf.id] = {\n id: this.conf.id + '_contextMenuToolbar',\n name: this.conf.text(api),\n icon: this.conf.icon,\n inCollection: this.inCollection,\n idCollection: idCollection\n };\n }\n });\n }\n });\n var tableTrSelector = '#' + tableId + ' > tbody > tr';\n var tableTr = $(tableTrSelector);\n tableTr.selector = tableTrSelector;\n\n if (!jQuery.isEmptyObject(items)) {\n tableTr.rup_contextMenu('destroy');\n tableTr.rup_contextMenu({\n selector: tableTrSelector,\n callback: function callback(key, options) {\n var selector = items[key]; // Recogemos el id de la accion pulsada en el context menu\n\n var contextMenuActionId = selector.id; // Le quitamos la extension '_contextMenuToolbar' para tener asi\n // el id del boton que queremos accionar\n\n var buttonId = contextMenuActionId.replace('_contextMenuToolbar', ''); // Variable que nos dira si esta dentro de una coleccion\n\n var inCollection = selector.inCollection; // Variable que almacena el id de la coleccion (si no pertenece a una\n // siempre sera 'undefined')\n\n var idCollection = selector.idCollection; // Comprobamos si existe el elemento con este id\n\n if (inCollection && idCollection !== undefined) {\n // Obtenemos la info necesaria del boton y la guardamos en variables\n var buttonName;\n var dt = $('#' + ctx.sTableId).DataTable();\n var eventConfig;\n $.each(ctx.ext.buttons, function (key) {\n var buttonObject = ctx.ext.buttons[key];\n\n if (buttonObject.id === buttonId) {\n buttonName = key;\n eventConfig = buttonObject;\n }\n }); // Llamamos directamente al action para no hacer aparecer y desaparecer\n // el boton, empeorando la UX\n\n ctx.ext.buttons[buttonName].action(undefined, dt, undefined, eventConfig);\n } else {\n $('#' + buttonId).trigger('click');\n }\n },\n items: items\n });\n }\n };\n /**\r\n * Inicializa los botones\r\n *\r\n * @name _initButtons\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on\r\n * @param {List} opts Lista de botones\r\n *\r\n */\n\n\n var _initButtons = function _initButtons(ctx, opts) {\n $.each(opts, function (i) {\n // Activa/desactiva los botones en el inicio en funcion de la propiedad\n // 'displayRegex' que tengan asociada\n var collectionObject = null;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n\n if (ctx.oInit.masterDetail !== undefined && this.conf.id === ctx.sTableId + 'addButton_1') {\n //si es maestro detalle para el boton add ,solo se renderiza cuando hay selección en el padre.\n var table = $(ctx.oInit.masterDetail.master).DataTable();\n numOfSelectedRows = table.context[0].multiselection.numSelected; //Nums del padre\n\n this.conf.displayRegex = /^[1-9][0-9]*$/; //se cambia expresion regular\n }\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx); // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0) {\n collectionObject = this;\n\n _manageButtonsAndButtonsContextMenu(opts[i], numOfSelectedRows, collectionObject, ctx);\n } // Comprueba si tiene un icono asociado\n\n\n if (this.conf.icon !== undefined) {\n // Establece el icono de los botones\n if ($(this.node).find('i').length === 0) {\n $('#' + this.conf.id).prepend('');\n } // Comprueba si tiene botones hijos\n\n\n if (this.buttons.length > 0 && $('#' + this.conf.id).length > 0) {\n // Añadimos un evento para cuando se pulse sobre el boton padre, se le\n // asignen los iconos a los hijos\n $('#' + this.conf.id)[0].addEventListener('click', function eventHandler() {\n var that = this;\n $.each(opts[i].buttons, function (i) {\n var selectorCollection = $('#' + this.conf.id); // Establece el icono de los botones hijos\n\n if ($(this.node).find('i').length === 0) {\n selectorCollection.prepend('');\n }\n\n that.removeEventListener('click', eventHandler);\n });\n }, false);\n }\n }\n }); //Añadir dialogo por defecto\n\n var $defaultDialog_wait = $('
').attr('id', ctx.sTableId + 'reportFileWait').attr('title', 'Tittle Prueba').text('prueba').addClass('rup_report').hide() //progressbar\n .append($('
').addClass('ui-progressbar ui-progressbar-value ui-corner-left ui-corner-right')),\n $defaultDialog_error = $('
').attr('id', ctx.sTableId + 'reportFileError').attr('title', 'Error').text('error').addClass('rup_report').hide(),\n $defaultDialog = $('
').attr('id', ctx.sTableId + 'rup_report_dialogsContainer').append($defaultDialog_wait).append($defaultDialog_error);\n $('#' + ctx.sTableId).after($defaultDialog);\n };\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables interface\r\n */\n // Attach to DataTables objects for global access\n\n\n $.fn.dataTable.Buttons = Buttons;\n $.fn.DataTable.Buttons = Buttons;\n\n function inicio(ctx) {\n var api = new DataTable.Api(ctx);\n var defaultButtons = api.init().buttons || DataTable.defaults.buttons;\n var numOfSelectedRows = ctx.multiselection.numSelected;\n var collectionObject;\n $('#' + ctx.sTableId).triggerHandler('tableButtonsBeforeToolbarInit');\n\n if ($('#' + ctx.sTableId + '_filter_form').length > 0) {\n new Buttons(api, defaultButtons).container().insertBefore($('#' + ctx.sTableId + '_filter_form'));\n } else {\n new Buttons(api, defaultButtons).container().insertBefore($('#' + ctx.sTableId + '_wrapper'));\n }\n\n var opts = ctx._buttons[0].inst.s.buttons;\n DataTable.Api().buttons.initButtons(ctx, opts);\n\n _initContextMenu(ctx, api); // Detecta cuando se selecciona o se deselecciona una fila en el table\n\n\n $('#' + ctx.sTableId).DataTable().on('select deselect contextmenu', function (event) {\n DataTable.Api().buttons.displayRegex(ctx);\n }); // Si la edición está deshabilitada, se deshabilitan todos los botones menos el de informes.\n\n if (ctx.oInit.noEdit || ctx.oInit.formEdit === undefined && ctx.oInit.inlineEdit === undefined) {\n var exceptions; // Si existen botones personalizados, se excluyen.\n\n if (ctx.ext.buttons.custom.length > 0) {\n exceptions = ctx.ext.buttons.custom;\n exceptions.push(ctx.sTableId + 'informes_01');\n } else {\n exceptions = ctx.sTableId + 'informes_01';\n }\n\n DataTable.Api().buttons.disableAllButtons(ctx, exceptions);\n ctx._buttons[0].inst.s.disableAllButtons = undefined;\n DataTable.Api().buttons.displayRegex(ctx);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonsAfterToolbarInit');\n } // DataTables `dom` feature option\n\n\n DataTable.ext.feature.push({\n fnInit: function fnInit(settings) {\n var api = new DataTable.Api(settings);\n var opts = api.init().buttons || DataTable.defaults.buttons;\n return new Buttons(api, opts).container();\n },\n cFeature: 'B'\n }); //DataTables creation - check if the buttons have been defined for this table,\n //they will have been if the `B` option was used in `dom`, otherwise we should\n //create the buttons instance here so they can be inserted into the document\n //using the API. Listen for `init` for compatibility with pre 1.10.10, but to\n //be removed in future.\n\n $(document).on('plugin-init.dt', function (e, ctx) {\n if (e.namespace !== 'dt') {\n return;\n }\n\n if (ctx.oInit.buttons !== undefined && ctx.oInit.buttons.activate !== false) {\n inicio(ctx);\n }\n });\n return Buttons;\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup_table/rup.table.buttons.js?"); /***/ }), @@ -8711,7 +8711,7 @@ eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/* eslint-env jquery,amd */\n\n/**\r\n * Módulo que habilita la edicción mediante un formulario.\r\n *\r\n * @summary \t\tExtensión del componente RUP Datatable\r\n * @module\t\t\t\"rup.table.editForm\"\r\n * @version 1.0.0\r\n * @license\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n * @copyright Copyright 2018 E.J.I.E., S.A.\r\n *\r\n */\n(function (factory) {\n if (true) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ../core/utils/jquery.form */ \"./src/core/utils/jquery.form.js\"), __webpack_require__(/*! ../rup.form */ \"./src/rup.form.js\"), __webpack_require__(/*! ../rup.combo */ \"./src/rup.combo.js\"), __webpack_require__(/*! datatables.net */ \"./node_modules/datatables.net/js/jquery.dataTables.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($) {\n return factory($, window, document);\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($, window, document, undefined) {\n 'use strict';\n\n var DataTable = $.fn.dataTable; // Version information for debugger\n\n DataTable.editForm = {};\n DataTable.editForm.version = '1.2.4';\n /**\r\n * Configura el componente editForm para su inicialización\r\n *\r\n * @name preConfigure\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n DataTable.editForm.preConfigure = function (dt) {\n var ctx = dt.settings()[0];\n var init = ctx.oInit.multiSelect;\n var defaults = DataTable.defaults.multiSelect;\n\n if (init === undefined) {\n init = defaults;\n } // DetailForm se convierte en función y se inicializan los botones\n\n\n ctx.oInit.formEdit.detailForm = $(ctx.oInit.formEdit.detailForm);\n ctx.oInit.formEdit.idForm = ctx.oInit.formEdit.detailForm.find('form').first();\n ctx.oInit.formEdit.id = ctx.oInit.formEdit.detailForm[0].id.replace('_detail_div', '');\n\n if (ctx.oInit.formEdit.detailForm !== undefined && $('body').find('[aria-describedby=\\'' + ctx.oInit.formEdit.detailForm[0].id + '\\']').length > 0) {\n $('body').find('[aria-describedby=\\'' + ctx.oInit.formEdit.detailForm[0].id + '\\']').remove();\n } // Obtiene el adapter y crea la barra de navegación en función de si la multiselección está o no activada\n\n\n if (ctx.oInit.multiSelect === undefined) {\n _callNavigationSelectBar(dt);\n } else {\n _callNavigationBar(dt);\n } // Inicializa el paginador del formulario de edición\n\n\n _updateDetailPagination(ctx, 1, 1); // Añade el botón de cancelar\n\n\n ctx.oInit.formEdit.buttoCancel = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_cancel');\n ctx.oInit.formEdit.buttoCancel.on('click', function () {\n _cancelPopup(ctx); // Cierra el dialog\n\n\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n });\n var idRow;\n var rowsBody = $(ctx.nTBody); // Gestiona la creación del evento de doble click para editar una fila\n\n if (ctx.oInit.multiSelect !== undefined || ctx.oInit.select !== undefined) {\n var sel = ctx.oInit.multiSelect;\n\n if (sel === undefined) {\n sel = ctx.oInit.select;\n } // Propiedad que no genera el evento de doble click en caso de existir y tener un valor true\n\n\n if (!sel.deleteDoubleClick) {\n rowsBody.on('dblclick.DT keypress', 'tr:not(.group)', function (e) {\n // Sólo selecciona si se pulsa sobre el enter o se hace click izquierdo con el ratón\n if (e.type == 'keypress' && e.which == 13 || e.type === 'dblclick') {\n idRow = this._DT_RowIndex; // Añadir la selección del mismo\n\n if (ctx.oInit.multiSelect !== undefined) {\n dt['row'](idRow).multiSelect();\n } else {\n $('tr', rowsBody).removeClass('selected tr-highlight');\n DataTable.Api().select.selectRowIndex(dt, idRow, true);\n }\n\n _getRowSelected(dt, 'PUT');\n\n DataTable.editForm.fnOpenSaveDialog('PUT', dt, idRow, ctx.oInit.formEdit.customTitle);\n $('#' + ctx.sTableId).triggerHandler('tableEditFormClickRow', ctx);\n }\n });\n }\n } // Establece el valor de las propiedades del formulario de edición.\n\n\n ctx.oInit.formEdit.loadSpinner = typeof ctx.oInit.formEdit.loadSpinner === 'boolean' ? ctx.oInit.formEdit.loadSpinner : true;\n ctx.oInit.formEdit.detailForm.settings = {\n type: ctx.oInit.formEdit.type !== undefined ? ctx.oInit.formEdit.type : $.rup.dialog.DIV,\n width: ctx.oInit.formEdit.width !== undefined ? ctx.oInit.formEdit.width : 569,\n saveDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.saveDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.saveDialog : true,\n cancelDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.cancelDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.cancelDialog : true,\n deleteDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.deleteDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.deleteDialog : true\n }; // Calcula el responsive\n\n $(window).on('resize.dtr', DataTable.util.throttle(function () {\n _addChildIcons(ctx);\n }));\n };\n /**\r\n * Inicializa el componente editForm\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n DataTable.editForm.init = function (ctx) {\n // Capturar evento de cierre\n ctx.oInit.formEdit.detailForm.on('dialogbeforeclose', function (event) {\n if (event.originalEvent !== undefined) {\n //el evento es cerrado por el aspa\n ctx.oInit.formEdit.okCallBack = false;\n } // Si es igual no se debe hacer nada\n\n\n var formSerializado = _editFormSerialize(ctx.oInit.formEdit.idForm, ctx.oInit.formEdit.serializerSplitter);\n\n if (ctx.oInit.formEdit.dataOrigin === formSerializado || !ctx.oInit.formEdit.detailForm.settings.cancelDialog) {\n _cancelPopup(ctx);\n\n return true;\n }\n\n if (ctx.oInit.formEdit.dataOrigin !== formSerializado && !ctx.oInit.formEdit.okCallBack) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.saveAndContinue'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n _cancelPopup(ctx);\n\n ctx.oInit.formEdit.okCallBack = true;\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: function CANCELFunction() {\n ctx.oInit.formEdit.okCallBack = false;\n $('#' + ctx.sTableId).triggerHandler('tableMessageCancel', ctx);\n },\n CLOSEFunction: function CLOSEFunction() {\n ctx.oInit.formEdit.okCallBack = false;\n $('#' + ctx.sTableId).triggerHandler('tableMessageClose', ctx);\n }\n });\n } // En caso de aceptar, se cierra y se limpia\n\n\n if (!ctx.oInit.formEdit.okCallBack || ctx.oInit.formEdit.okCallBack === undefined) {\n return false;\n }\n });\n };\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Local functions\r\n */\n\n /**\r\n * Initialisation of a new table. Attach event handlers and callbacks to allow\r\n * Select to operate correctly.\r\n *\r\n * This will occur _after_ the initial DataTables initialisation, although\r\n * before Ajax data is rendered, if there is ajax data\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {DataTable.settings} ctx Settings object to operate on\r\n *\r\n */\n\n\n function init(ctx) {\n var api = new DataTable.Api(ctx); // Row callback so that classes can be added to rows and cells if the item\n // was selected before the element was created. This will happen with the\n // `deferRender` option enabled.\n //\n // This method of attaching to `aoRowCreatedCallback` is a hack until\n // DataTables has proper events for row manipulation If you are reviewing\n // this code to create your own plug-ins, please do not do this!\n\n ctx.aoRowCreatedCallback.push({\n fn: function fn(row, data, index) {\n var i, ien;\n var d = ctx.aoData[index]; // Row\n\n if (d._multiSelect_selected) {\n $(row).addClass(ctx._multiSelect.className);\n } // Cells and columns - if separated out, we would need to do two\n // loops, so it makes sense to combine them into a single one\n\n\n for (i = 0, ien = ctx.aoColumns.length; i < ien; i++) {\n if (ctx.aoColumns[i]._multiSelect_selected || d._selected_cells && d._selected_cells[i]) {\n $(d.anCells[i]).addClass(ctx._multiSelect.className);\n }\n }\n },\n sName: 'select-deferRender'\n }); // On Ajax reload we want to reselect all rows which are currently selected,\n // if there is an rowId (i.e. a unique value to identify each row with)\n\n api.on('preXhr.dt.dtSelect', function () {\n // note that column selection doesn't need to be cached and then\n // reselected, as they are already selected\n var rows = api.rows({\n selected: true\n }).ids(true).filter(function (d) {\n return d !== undefined;\n });\n var cells = api.cells({\n selected: true\n }).eq(0).map(function (cellIdx) {\n var id = api.row(cellIdx.row).id(true);\n return id ? {\n row: id,\n column: cellIdx.column\n } : undefined;\n }).filter(function (d) {\n return d !== undefined;\n }); // On the next draw, reselect the currently selected items\n\n api.one('draw.dt.dtSelect', function () {\n api.rows(rows).multiSelect(); // `cells` is not a cell index selector, so it needs a loop\n\n if (cells.any()) {\n cells.each(function (id) {\n api.cells(id.row, id.column).multiSelect();\n });\n }\n });\n }); // Clean up and release\n\n api.on('destroy.dtSelect', function () {\n disableMouseSelection(api);\n api.off('.dtSelect');\n });\n }\n\n function eventTrigger(api, type, args, any) {\n if (any && !api.flatten().length) {\n return;\n }\n\n if (typeof type === 'string') {\n type = type + '.dt';\n }\n\n args.unshift(api);\n $(api.table().node()).trigger(type, args);\n }\n\n function _cancelPopup(ctx) {\n ctx.oInit.formEdit.okCallBack = false;\n var feedback = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_feedback'); //Despues de cerrar\n //Se limpia los elementos.\n\n if (ctx.oInit.formEdit.idForm.find('.error').length > 0) {\n ctx.oInit.formEdit.idForm.rup_validate('resetElements'); //nos aseguramos de borrar todo\n\n ctx.oInit.formEdit.idForm.find('.error').not('input').remove();\n ctx.oInit.formEdit.idForm.find('.rup-validate-field-error').removeClass('rup-validate-field-error');\n } //Se cierran los mensajes del feedback\n\n\n if (feedback[0].className !== '') {\n feedback.rup_feedback('hide', 0);\n }\n }\n /**\r\n * Función que añade las validaciones a un formulario.\r\n *\r\n * @name addValidation\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _addValidation(ctx) {\n var idTableDetail = ctx.oInit.formEdit.detailForm;\n var feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n var validaciones;\n\n if (ctx.oInit.formEdit.validate !== undefined) {\n validaciones = ctx.oInit.formEdit.validate.rules;\n }\n\n if (feed.length === 0) {\n feed = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n }\n\n feed.rup_feedback(ctx.oInit.feedback);\n var propertiesDefault = {\n liveCheckingErrors: false,\n showFieldErrorAsDefault: true,\n showErrorsInFeedback: true,\n showFieldErrorsInFeedback: true\n };\n var propertiesValidate = $.extend(true, {}, propertiesDefault, ctx.oInit.formEdit.propertiesValidate);\n propertiesValidate.feedback = feed;\n propertiesValidate.rules = validaciones;\n ctx.oInit.formEdit.idForm.rup_validate(propertiesValidate);\n }\n /**\r\n * Función que gestiona la carga del diálogo de añadir o editar.\r\n *\r\n * @name loadSaveDialogForm\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {string} actionType - Acción a ajecutar en el formulario para ir al controller, basado en REST.\r\n * @param {object} row - Datos para alimentar los campos del formulario.\r\n *\r\n * @return {object}\r\n */\n\n\n function _loadSaveDialogForm(ctx, actionType, row) {\n var idForm = ctx.oInit.formEdit !== undefined ? ctx.oInit.formEdit.idForm : undefined; // Servirá para saber si la última llamada a editForm fue para añadir, editar o si aún no ha sido inicializado\n\n var lastAction = ctx.oInit.formEdit.actionType; // Botón de guardar y continuar\n\n var buttonContinue = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save_repeat'); // En caso de ser clonado el method ha de ser POST\n\n if (actionType === 'CLONE') {\n actionType = 'POST';\n buttonContinue.hide();\n } else {\n buttonContinue.show();\n } // Si el usuario ha activado los formularios dinámicos, la última acción no es la misma que la actual o el valor del identificador ha cambiado,\n // es necesario volver a obtener el formulario.\n\n\n if (_validarFormulario(ctx, lastAction, actionType, row)) {\n // Preparar la información a enviar al servidor. Como mínimo se enviará el actionType, un booleano que indique si el formulario es multipart y \n // el valor de la clave primaria siempre y cuando no contenga un string vacío.\n var defaultData = _objectSpread({\n 'actionType': actionType,\n 'isMultipart': ctx.oInit.formEdit.multipart === true ? true : false\n }, DataTable.Api().rupTable.getIdPk(row, ctx.oInit) != \"\" && {\n 'pkValue': DataTable.Api().rupTable.getIdPk(row, ctx.oInit)\n });\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterData', ctx);\n var data = ctx.oInit.formEdit.data !== undefined ? $.extend({}, defaultData, ctx.oInit.formEdit.data) : defaultData;\n $('#' + ctx.sTableId).triggerHandler('tableEditFormBeforeLoad', ctx);\n return $.post(ctx.oInit.formEdit.url !== undefined ? ctx.oInit.formEdit.url : ctx.oInit.urlBase + '/editForm', data, function (form) {\n // Guardar anterior formulario para poder comprobarlo con el recién recibido\n var tempForm = idForm !== undefined ? idForm : undefined; // Guardar referencia del formulario recibido\n\n var receivedForm = $(form).find(\"form\").addBack('form'); // Si existe un formulario previo con el mismo identificador que el recibido, se elimina\n\n if (tempForm !== undefined && tempForm.length === 1 && tempForm.attr(\"id\") === receivedForm.attr(\"id\")) {\n tempForm.remove();\n } // Insertar formulario recibido dentro del contenedor especificado\n\n\n var formContainerID = '#' + ctx.sTableId + '_detail_form_container';\n $(formContainerID).prepend(receivedForm);\n ctx.oInit.formEdit.actionType = actionType;\n ctx.oInit.formEdit.idForm = $(ctx.oInit.formEdit.detailForm).find('form').first(); // Si el diálogo no ha sido inicializado, se inicializa\n\n if (lastAction === undefined) {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormInitialize', ctx);\n } // Detectar componentes RUP e inicializarlos\n\n\n _formInitializeRUP(ctx, row, $(formContainerID + ' #' + receivedForm.attr(\"id\"))); // Añadir validaciones\n\n\n _addValidation(ctx);\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterLoad', ctx);\n }, 'html');\n } else if (!ctx.oInit.enableDynamicForms && lastAction === undefined) {\n // Entrará por aquí cuando los formularios dinámicos hayan sido desactivados (comportamiento por defecto) y se necesite inicializar el formulario por ser la primera llamada\n ctx.oInit.formEdit.actionType = actionType;\n $.when($('#' + ctx.sTableId).triggerHandler('tableEditFormInitialize', ctx)).then(function () {\n var deferred = $.Deferred(); // Detectar componentes RUP e inicializarlos\n\n _formInitializeRUP(ctx, row, idForm); // Añadir validaciones\n\n\n _addValidation(ctx);\n\n deferred.resolve();\n return deferred.promise();\n });\n } else {\n // Para cuando el formulario actual sigue siendo válido (ya sea dinámico o no)\n var deferred = $.Deferred();\n ctx.oInit.formEdit.actionType = actionType;\n deferred.resolve();\n return deferred.promise();\n }\n }\n /**\r\n * Valida los formularios para no, buscarlos.\r\n *\r\n * @name formInitializeRUP\r\n * @function\r\n * @since UDA 5.0.2 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {object} lastAction - última accion realizado.\r\n * @param {object} actionType - Tipo de acción.\r\n */\n\n\n function _validarFormulario(ctx, lastAction, actionType, row) {\n if (ctx.oInit.enableDynamicForms) {\n var lastSelectedIdUsed = ctx.oInit.formEdit.lastSelectedIdUsed;\n var lastSelected = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.oInit.formEdit.lastSelectedIdUsed = lastSelected;\n\n if (lastAction !== actionType || lastSelectedIdUsed === undefined || lastSelected !== lastSelectedIdUsed) {\n return true;\n }\n }\n\n return false;\n }\n /**\r\n * Detecta los componentes RUP del formulario y los inicializa.\r\n *\r\n * @name formInitializeRUP\r\n * @function\r\n * @since UDA 5.0.2 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {object} row - Datos para alimentar los campos del formulario.\r\n * @param {object} form - Formulario en el que hay que inicializar los componentes.\r\n */\n\n\n function _formInitializeRUP(ctx, row, form) {\n if (ctx.oInit.colModel !== undefined && (ctx.oInit.multiSelect !== undefined || ctx.oInit.select !== undefined)) {\n $.each(ctx.oInit.colModel, function (key, column) {\n var element = form.find('[name=\"' + column.name + '\"]'); // Comprobar que es un componente RUP y editable. En caso de no ser editable, se añade la propiedad readonly.\n\n if (column.rupType && column.editable) {\n if (column.editoptions !== undefined) {\n if (column.rupType === 'combo') {\n // Si se recibe una fila con valores, se establece el valor del campo correspondiente como el registro seleccionado en el combo.\n if (row !== undefined) {\n column.editoptions.selected = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n } // Cuando no se haya definido un elemento al que hacer el append del menú del combo, se hace al \"body\" para evitar problemas de CSS.\n\n\n if (column.editoptions.appendTo === undefined) {\n column.editoptions.appendTo = 'body';\n }\n } else if (column.rupType == 'autocomplete') {\n // Establece el valor por defecto.\n if (row !== undefined) {\n column.editoptions.defaultValue = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n }\n\n if (column.editoptions.menuAppendTo === undefined) {\n // Cuando no se haya definido un elemento al que hacer el append del menú del autocomplete, se hace al \"body\" para evitar problemas de CSS.\n column.editoptions.menuAppendTo = 'body';\n }\n } else if (column.rupType === 'select') {\n // Si se recibe una fila con valores, se establece el valor del campo correspondiente como el registro seleccionado en el select.\n if (row !== undefined) {\n column.editoptions.selected = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n }\n } // Inicializar componente.\n\n\n element['rup_' + column.rupType](column.editoptions);\n } else if (column.searchoptions === undefined) {\n console.error($.rup_utils.format(jQuery.rup.i18nParse(jQuery.rup.i18n.base, 'rup_table.errors.wrongColModel'), column.name));\n }\n } else if (!column.editable) {\n element.prop('readonly', true);\n }\n });\n }\n }\n /**\r\n * Función que gestiona el comportamiento de abrir el dialog para añadir o editar un registro.\r\n *\r\n * @name openSaveDialog\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} actionType - Es la acción que se va a ajecutar en el formulario para ir al controller, basado en rest.\r\n * @param {object} dt - Es el objeto table.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n * @param {string} customTitle - Título personalizado.\r\n *\r\n */\n\n\n DataTable.editForm.fnOpenSaveDialog = function _openSaveDialog(actionType, dt, idRow, customTitle) {\n var ctx = dt.settings()[0]; // Mostrar spinner de carga hasta que el formulario sea visible (sólo si fue activado). La segunda comprobación, evita que aparezca el spinner cuando se pagina dentro de editForm entre registros porque para ese caso, ya existe otro spinner\n\n if (ctx.oInit.formEdit.loadSpinner && $('#' + ctx.sTableId + '_detail_div_loading').length == 0) {\n $('body').append('
' + '
' + '' + '
');\n }\n\n if (idRow == null || idRow == undefined || idRow < 0) {\n idRow = 1;\n }\n\n var row;\n\n if (ctx.json !== undefined && actionType !== 'POST') {\n //si acción es add, no hace falta coger el row.\n row = ctx.json.rows[idRow];\n } // Comprobar si existe un formulario, en caso de no existir o de no contener el action requerido, lo crea\n\n\n $.when(_loadSaveDialogForm(ctx, actionType, row)).then(function () {\n var loadPromise = $.Deferred();\n var idForm = ctx.oInit.formEdit.idForm; // Limpiar los errores en caso de haberlos\n\n var feed = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_feedback');\n var divErrorFeedback = ctx.oInit.formEdit.detailForm.find('#' + feed[0].id);\n\n if (divErrorFeedback.length > 0) {\n divErrorFeedback.hide();\n } // Limpiar los elementos\n\n\n if (idForm.find('.error').length > 0) {\n idForm.rup_validate('resetElements');\n } // Botón de guardar\n\n\n var button = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save'); // Botón de guardar y continuar\n\n var buttonContinue = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save_repeat');\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditBeforeInitData', ctx);\n var rowArray = $.rup_utils.jsontoarray(row);\n var title = customTitle != (undefined && null) ? customTitle : \"\"; // Actualizar el valor de la variable por si ha sufrido cambios en la función _loadSaveDialogForm() ya que en caso de ser un CLONE, habrá sido convertido a POST\n\n actionType = ctx.oInit.formEdit.actionType;\n\n if (actionType === 'PUT') {\n // Si la opción 'direct' es verdadera, no se solicita el registro a BBDD, en su lugar, se obtiene de la tabla directamente.\n if (!ctx.oInit.formEdit.direct) {\n //se obtiene el row entero de bbdd, meter parametro opcional.\n var pk = DataTable.Api().rupTable.getIdPk(row, ctx.oInit); //se evita slash en la url GET como parámetros.Formateo de fecha.\n\n var regexSlash = new RegExp('/', 'g');\n pk = pk.replace(regexSlash, '-');\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n pk = pk.replace(regex, '/');\n var ajaxOptions = {\n url: ctx.oInit.urlBase + '/' + pk,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: 'GET',\n data: [],\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: false,\n success: function success(data) {\n row = data;\n\n if (ctx.oInit.primaryKey !== undefined && ctx.oInit.primaryKey.length === 1) {\n //si hdiv esta activo.\n // Actualizar el nuevo id que viene de HDIV.\n var idHdiv = \"\" + data[ctx.oInit.primaryKey];\n\n if (pk == ctx.multiselection.lastSelectedId) {\n ctx.multiselection.lastSelectedId = idHdiv;\n }\n\n var pos = jQuery.inArray(pk, ctx.multiselection.selectedIds);\n\n if (pos >= 0) {\n ctx.multiselection.selectedIds[pos] = idHdiv;\n }\n\n var result = $.grep(ctx.multiselection.selectedRowsPerPage, function (v) {\n return v.id == pk;\n });\n\n if (result !== undefined && result.length > 0) {\n result[0].id = idHdiv;\n }\n }\n },\n error: function error(xhr) {\n var divErrorFeedback = feed; //idTableDetail.find('#'+feed[0].id + '_ok');\n\n if (divErrorFeedback.length === 0) {\n divErrorFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxGet', ctx);\n },\n complete: function complete() {\n if (ctx.oInit.formEdit.$navigationBar.funcionParams && ctx.oInit.formEdit.$navigationBar.funcionParams.length >= 4) {\n _showOnNav(dt, ctx.oInit.formEdit.$navigationBar.funcionParams[3]);\n } // Reiniciarlo para las próximas acciones.\n\n\n ctx.oInit.formEdit.$navigationBar.funcionParams = {};\n }\n };\n loadPromise = $.rup_ajax(ajaxOptions); //Se carga desde bbdd y se actualiza la fila\n\n dt.row(idRow).data(row);\n ctx.json.rows[idRow] = row; // Recrear iconos del responsive en caso de ser necesario.\n\n _addChildIcons(ctx); //Se mantiene el checked sin quitar.\n\n\n $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(idRow).find('td.select-checkbox input[type=\"checkbox\"]').prop('checked', true);\n rowArray = $.rup_utils.jsontoarray(row);\n }\n\n $.rup_utils.populateForm(rowArray, idForm);\n var multiselection = ctx.multiselection;\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), multiselection.selectedIds);\n\n if (ctx.multiselection.selectedAll) {\n //Si es selecAll recalcular el numero de los selects. Solo la primera vez es necesario.\n indexInArray = ctx.oInit.formEdit.$navigationBar.numPosition;\n }\n\n if (indexInArray === undefined) {\n indexInArray = 0;\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n }\n\n var numTotal = multiselection.numSelected;\n\n if (ctx.oInit.multiSelect === undefined) {\n numTotal = ctx.json.recordsTotal;\n indexInArray = (Number(ctx.json.page) - 1) * ctx.aBaseJson.length;\n indexInArray = indexInArray + idRow;\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterFillData', ctx);\n\n if (ctx.oInit.formEdit.$navigationBar.funcionParams == undefined || ctx.oInit.formEdit.$navigationBar.funcionParams.length == undefined) {\n _updateDetailPagination(ctx, indexInArray + 1, numTotal);\n }\n\n DataTable.Api().rupTable.selectPencil(ctx, idRow); // Se guarda el ultimo id editado.\n\n ctx.multiselection.lastSelectedId = DataTable.Api().rupTable.getIdPk(row, ctx.oInit); // Se muestra el dialog.\n\n ctx.oInit.formEdit.$navigationBar.show(); // Si no se ha definido un 'customTitle' asignamos un valor a la variable del título del formulario\n\n if (customTitle == (undefined || null)) {\n title = $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.editCaption');\n } // Comprobamos si se desea bloquear la edicion de las claves primarias\n\n\n DataTable.Api().rupTable.blockPKEdit(ctx, actionType);\n } else if (actionType === 'POST') {\n //al ser add, s elimpian los combos\n jQuery.each($('select.rup_combo', idForm), function (index, elem) {\n jQuery(elem).rup_combo('setRupValue', '');\n });\n $.rup_utils.populateForm(rowArray, idForm);\n ctx.oInit.formEdit.$navigationBar.hide(); // Si no se ha definido un 'customTitle' asignamos un valor a la variable del título del formulario\n\n if (customTitle == (undefined || null)) {\n title = $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.addCaption');\n } // Comprobamos si hay claves primarias bloqueadas y las desbloqueamos\n\n\n DataTable.Api().rupTable.blockPKEdit(ctx, actionType);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditBeforeShowForm', ctx); // Establecemos el título del formulario\n\n ctx.oInit.formEdit.detailForm.rup_dialog(ctx.oInit.formEdit.detailForm.settings);\n ctx.oInit.formEdit.detailForm.rup_dialog('setOption', 'title', title);\n ctx.oInit.formEdit.detailForm.rup_dialog('open'); // Quitar spinner de carga porque el formulario ya es visible (si fue activado)\n\n if ($('#' + ctx.sTableId + '_formEdit_dialog_loading').length > 0) {\n $('#' + ctx.sTableId + '_formEdit_dialog_loading').remove();\n } // Establecemos el foco al primer elemento input o select que se\n // encuentre habilitado en el formulario\n\n\n $(idForm[0]).find('input,select').filter(':not([readonly])').first().focus(); // Se guardan los datos originales\n\n ctx.oInit.formEdit.dataOrigin = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter);\n ctx.oInit.formEdit.okCallBack = false;\n button.off('click');\n button.on('click', function () {\n //Funcion de validacion\n if (actionType === 'PUT') {\n var customModificar = ctx.oInit.validarModificar;\n\n if (typeof customModificar === \"function\" && customModificar(ctx)) {\n return false;\n }\n } else if (actionType === 'POST') {\n var customAlta = ctx.oInit.validarAlta;\n\n if (typeof customAlta === \"function\" && customAlta(ctx)) {\n return false;\n }\n } // Comprobar si row ha sido modificada\n // Se serializa el formulario con los cambios\n\n\n row = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter); // Se transforma\n\n row = $.rup_utils.queryStringToJson(row, ctx.oInit.formEdit.serializerSplitter, ctx.oInit.formEdit.allowAllCharacters); //listas checkbox\n\n row = _addListType(idForm, row);\n\n if (actionType === 'PUT') {\n //Solo al modificar\n $.each(ctx.oInit.primaryKey, function (index, key) {\n row[key] = ctx.json.rows[idRow][key];\n });\n }\n\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Muestra un feedback de error por caracter ilegal\n\n if (!row) {\n ctx.oInit.formEdit.okCallBack = false;\n\n var _feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n\n var _divErrorFeedback = _feed;\n\n if (_divErrorFeedback.length === 0) {\n _divErrorFeedback = $('
').attr('id', _feed[0].id + '_ok').insertBefore(_feed);\n\n _divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, _divErrorFeedback, $.rup.i18nParse($.rup.i18n.base, 'rup_global.charError'), 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxNotRow', ctx);\n } else {\n var url = actionType == 'POST' ? '/add' : '/edit'; // Comprobar si se ha definido otra URL en las propiedades, en caso afirmativo, se aplica.\n\n var property = url.substring(1) + 'Url';\n\n if (ctx.oInit.formEdit[property]) {\n url = ctx.oInit.formEdit[property];\n }\n\n _callSaveAjax(actionType, dt, row, idRow, false, idTableDetail, url, false);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonSave', ctx);\n });\n ctx.oInit.formEdit.detailForm.buttonSaveContinue = buttonContinue;\n ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType = actionType;\n buttonContinue.off('click');\n buttonContinue.on('click', function () {\n //Funcion de validacion\n if (actionType === 'PUT') {\n var customModificar = ctx.oInit.validarModificarContinuar;\n\n if (typeof customModificar === \"function\" && customModificar(ctx)) {\n return false;\n }\n } else if (actionType === 'POST') {\n var customAlta = ctx.oInit.validarAltaContinuar;\n\n if (typeof customAlta === \"function\" && customAlta(ctx)) {\n return false;\n }\n }\n\n var actionSaveContinue = ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType; // Comprobar si row ha sido modificada\n // Se serializa el formulario con los cambios\n\n row = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter); // Se transforma\n\n row = $.rup_utils.queryStringToJson(row, ctx.oInit.formEdit.serializerSplitter, ctx.oInit.formEdit.allowAllCharacters); //listas checkbox\n\n row = _addListType(idForm, row);\n\n if (actionType === 'PUT') {\n //Solo al modificar\n $.each(ctx.oInit.primaryKey, function (index, key) {\n row[key] = ctx.json.rows[idRow][key];\n });\n }\n\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Muestra un feedback de error por caracter ilegal\n\n if (!row) {\n ctx.oInit.formEdit.okCallBack = false;\n\n var _feed2 = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n\n var _divErrorFeedback2 = _feed2;\n\n if (_divErrorFeedback2.length === 0) {\n _divErrorFeedback2 = $('
').attr('id', _feed2[0].id + '_ok').insertBefore(_feed2);\n\n _divErrorFeedback2.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, _divErrorFeedback2, $.rup.i18nParse($.rup.i18n.base, 'rup_global.charError'), 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxNotRow', ctx);\n } else {\n var url = actionType == 'POST' ? '/add' : '/edit'; // Comprobar si se ha definido otra URL en las propiedades, en caso afirmativo, se aplica.\n\n var property = url.substring(1) + 'Url';\n\n if (ctx.oInit.formEdit[property]) {\n url = ctx.oInit.formEdit[property];\n }\n\n _callSaveAjax(actionSaveContinue, dt, row, idRow, true, idTableDetail, url, false);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonSaveContinue', ctx);\n });\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditAfterShowForm', ctx);\n return loadPromise;\n });\n };\n /**\r\n * Llamada al servidor con los datos de edición.\r\n *\r\n * @name _callSaveAjax\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} actionType - Es la acción que se va a ajecutar en el formulario para ir al controller, basado en rest.\r\n * @param {object} dt - Es el objeto table.\r\n * @param {object} row - Son los datos que se cargan.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n * @param {boolean} continuar - Si es true guarda la pagina y se queda en el dialog , si es false guarda y cierra el dialog.\r\n * @param {string} idTableDetail - Identificdor del detail de la table.\r\n * @param {string} url - Url que se añade para llamar al controller.\r\n * @param {boolean} isDeleting - Evita mostrar el diálogo de confirmación porque la función _deleteAllSelects() tiene el suyo propio.\r\n *\r\n */\n\n\n function _callSaveAjax(actionType, dt, row, idRow, continuar, idTableDetail, url, isDeleting) {\n var ctx = dt.settings()[0];\n\n var _makeAjaxCall = function _makeAjaxCall() {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormBeforeCallAjax', [ctx, actionType, url]); // Añadir filtro\n\n var feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n var msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.modifyOK');\n var validaciones = ctx.oInit.formEdit.validate;\n\n if (url === '/deleteAll' || actionType === 'DELETE') {\n msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.deletedOK');\n\n if (validaciones !== undefined) {\n validaciones.rules = {};\n }\n }\n\n if (ctx.oInit.masterDetail !== undefined) {\n //Asegurar que se recoge el idPadre\n var masterPkObject = DataTable.Api().masterDetail.getMasterTablePkObject(ctx);\n $('#' + ctx.sTableId + '_detail_masterPK').val($('#' + ctx.sTableId + '_filter_masterPK').val());\n row = jQuery.extend(true, row, masterPkObject);\n }\n\n var ajaxOptions = {\n url: ctx.oInit.urlBase + url,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: actionType,\n data: row,\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: true,\n success: function success(valor) {\n ctx.oInit.formEdit.okCallBack = true;\n ctx.oInit.formEdit.lastValue = valor;\n\n if (url !== '/deleteAll' && actionType !== 'DELETE') {\n if (continuar) {\n //Se crea un feedback_ok, para que no se pise con el de los errores\n var divOkFeedback = idTableDetail.find('#' + feed[0].id + '_ok');\n\n if (divOkFeedback.length === 0) {\n divOkFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divOkFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, divOkFeedback, msgFeedBack, 'ok'); //Se informa, feedback del formulario\n\n } else {\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n\n _callFeedbackOk(ctx, ctx.oInit.feedback.$feedbackContainer, msgFeedBack, 'ok'); //Se informa feedback de la tabla\n\n } // Sobrescribir valores anteriores con los recibidos desde el servidor\n\n\n row = $.extend({}, row, valor);\n\n if (actionType === 'PUT') {\n //Modificar\n dt.row(idRow).data(row); // se actualiza al editar\n\n ctx.json.rows[idRow] = row; // Actualizamos el ultimo id seleccionado (por si ha sido editado)\n\n var posicion = 0;\n $.each(ctx.multiselection.selectedRowsPerPage, function (index, p) {\n if (p.id == ctx.multiselection.lastSelectedId) {\n posicion = index;\n return;\n }\n });\n\n if (ctx.seeker !== undefined && ctx.seeker.ajaxOption.data !== undefined && ctx.seeker.ajaxOption.data.search !== undefined && ctx.seeker.search.funcionParams !== undefined && ctx.seeker.search.funcionParams.length > 0) {\n _comprobarSeeker(row, ctx, idRow);\n }\n\n ctx.multiselection.lastSelectedId = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.multiselection.selectedRowsPerPage[posicion].id = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.oInit.feedback.type = undefined; //se recarga el type no esta definido.\n } else {\n // Asegura a cargar los nuevos IDS.\n $.each(ctx.oInit.primaryKey, function (index, key) {\n var posibleId = row[key]; // Comprueba si la primaryKey es un subcampo\n\n if (key.indexOf('.') !== -1) {\n row[key] = DataTable.Api().rupTable.getDescendantProperty(valor, key);\n } else {\n row[key] = valor[key];\n }\n\n if (row[key] === undefined) {\n row[key] = posibleId;\n }\n }); // Se actualiza la tabla temporalmente. y deja de ser post para pasar a put(edicion)\n\n if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx);\n }\n\n var rowAux = row;\n\n if (ctx.json !== undefined) {\n $.each(ctx.json.rows, function (index, r) {\n var rowNext = r;\n dt.row(index).data(rowAux);\n rowAux = rowNext;\n });\n ctx.json.rows.pop();\n ctx.json.rows.splice(0, 0, row);\n } else {\n //es el primer registro\n dt.row.add(rowAux).draw(false);\n ctx.json = {};\n ctx.json.rows = [];\n ctx.json.rows.push(rowAux);\n } // Se guardan los datos para pasar de nuevo a editable.\n\n\n if (ctx.oInit.formEdit.saveContinueEdit) {\n ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType = 'PUT';\n DataTable.Api().rupTable.blockPKEdit(ctx, 'PUT');\n } else {\n //mantener y borrar\n ctx.oInit.formEdit.idForm.resetForm();\n }\n\n ctx.oInit.formEdit.dataOrigin = _editFormSerialize(ctx.oInit.formEdit.idForm, ctx.oInit.formEdit.serializerSplitter);\n\n if (ctx.oInit.multiSelect !== undefined) {\n ctx.oInit.feedback.type = 'noBorrar';\n dt.row().multiSelect();\n } // Se actualiza la linea\n\n\n if (ctx.json.reorderedSelection !== null && ctx.json.reorderedSelection !== undefined) {\n try {\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.json.reorderedSelection[0].pageLine;\n } catch (err) {\n console.log(err.message);\n }\n }\n /* \r\n * Filtrar para colocar cada registro en su lugar correspondiente. \r\n * Si no se filtra, aparece un error visual en la selección de registros y otro en el paginador del formulario de edición.\r\n */\n\n\n dt.ajax.reload();\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterInsertRow', actionType, ctx);\n }\n\n if (actionType === 'PUT') {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n }, false);\n } else {\n if (ctx.oInit.multiSelect === undefined) {\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: Number(ctx.json.page),\n line: 0\n };\n ctx.multiselection.selectedRowsPerPage[0] = arra;\n DataTable.Api().select.drawSelectId(ctx);\n }\n\n $('#' + ctx.sTableId).trigger('tableAddFormSuccessCallSaveAjax', actionType, ctx);\n }\n } else {\n // Eliminar\n ctx.oInit.feedback.type = 'eliminar';\n ctx.oInit.feedback.msgFeedBack = msgFeedBack;\n\n if (ctx.oInit.multiSelect !== undefined) {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n DataTable.Api().multiSelect.deselectAll(dt);\n }, false);\n } else if (ctx.oInit.select !== undefined) {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n DataTable.Api().select.deselect(ctx);\n }, false);\n }\n\n _callFeedbackOk(ctx, ctx.oInit.feedback.$feedbackContainer, msgFeedBack, 'ok'); //Se informa feedback de la tabla\n\n }\n },\n complete: function complete() {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormCompleteCallSaveAjax', actionType, ctx);\n },\n error: function error(xhr) {\n var divErrorFeedback; // Si es una petición de tipo DELETE o no existe la referencia al feedback de editForm, el feedback utilizado será el de la tabla, en los demás casos, se usará el del editForm.\n\n if (actionType === 'DELETE' || feed[0] == undefined) {\n divErrorFeedback = ctx.oInit.feedback.$feedbackContainer;\n } else {\n divErrorFeedback = idTableDetail.find('#' + feed[0].id + '_ok');\n }\n\n if (divErrorFeedback.length === 0) {\n divErrorFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n if (xhr.status === 406 && xhr.responseText !== '') {\n try {\n var responseJSON = JSON.parse(xhr.responseText);\n\n if (responseJSON.rupErrorFields) {\n if (responseJSON.rupErrorFields !== undefined || responseJSON.rupFeedback !== undefined) {\n var $form = ctx.oInit.formEdit.idForm;\n $form.validate().submitted = $.extend(true, $form.validate().submitted, responseJSON.rupErrorFields);\n $form.validate().invalid = responseJSON.rupErrorFields;\n $form.validate().showErrors(responseJSON.rupErrorFields);\n } else if (errors.rupFeedback !== undefined) {\n var mensajeJSON = $.rup_utils.printMsg(responseJSON.rupFeedback.message);\n\n _callFeedbackOk(ctx, divErrorFeedback, mensajeJSON, 'error');\n }\n }\n } catch (e) {\n // El mensaje NO es JSON\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n }\n } else {\n //cualquier error se devuelve el texto\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjax', actionType, ctx);\n },\n validate: validaciones,\n feedback: feed.rup_feedback({\n type: 'error',\n block: false\n })\n }; // Se cambia el data\n\n if (ajaxOptions.data == '') {\n delete ajaxOptions.data;\n $.rup_ajax(ajaxOptions);\n } else if (isDeleting || ctx.oInit.formEdit.idForm.valid()) {\n // Obtener el valor del parámetro HDIV_STATE (en caso de no estar disponible se devolverá vacío) siempre y cuando no se trate de un deleteAll porque en ese caso ya lo contiene el filtro\n if (url.indexOf('deleteAll') === -1) {\n // Elimina los campos _label generados por los autocompletes que no forman parte de la entidad\n $.fn.deleteAutocompleteLabelFromObject(ajaxOptions.data); // Elimina los campos autogenerados por los multicombos que no forman parte de la entidad\n\n $.fn.deleteMulticomboLabelFromObject(ajaxOptions.data, ctx.oInit.formEdit.detailForm);\n var hdivStateParamValue = $.fn.getHDIV_STATE(undefined, ctx.oInit.formEdit.idForm);\n\n if (hdivStateParamValue !== '') {\n ajaxOptions.data._HDIV_STATE_ = hdivStateParamValue;\n } // Comprueba si debe enviarse como multipart.\n\n\n if (ctx.oInit.formEdit.multipart === true) {\n ajaxOptions.enctype = 'multipart/form-data';\n ajaxOptions.processData = false;\n ajaxOptions.contentType = false;\n var formData = new FormData();\n $.each(ajaxOptions.data, function (key, value) {\n var field = ctx.oInit.formEdit.idForm.find('input[type=\"file\"][name=\"' + key + '\"]'); // Gestiona el guardado de ficheros.\n\n if (field.length != 0 && field.prop('files').length > 0) {\n $.each(field.prop('files'), function (fileIndex, fileValue) {\n formData.append(key, fileValue);\n });\n } else {\n formData.append(key, value);\n }\n });\n ajaxOptions.data = formData;\n }\n }\n\n if (ajaxOptions.enctype != 'multipart/form-data') {\n ajaxOptions.data = JSON.stringify(ajaxOptions.data);\n }\n\n $.rup_ajax(ajaxOptions);\n }\n };\n\n if (ctx.oInit.formEdit.detailForm.settings.saveDialog && !isDeleting) {\n $.rup_messages('msgConfirm', {\n title: actionType == 'POST' ? $.rup.i18nParse($.rup.i18n.base, 'rup_table.add.save') : $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.save'),\n message: actionType == 'POST' ? $.rup.i18nParse($.rup.i18n.base, 'rup_table.add.saveData') : $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.saveData'),\n OKFunction: function OKFunction() {\n _makeAjaxCall();\n\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: function CANCELFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageCancel', ctx);\n },\n CLOSEFunction: function CLOSEFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageClose', ctx);\n }\n });\n } else {\n _makeAjaxCall();\n }\n }\n /**\r\n * Llamada para crear el feedback dentro del dialog.\r\n *\r\n * @name callFeedbackOk\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {object} feedback - Div donde se va ejecutar el feedback.\r\n * @param {string} msgFeedBack - Mensaje para el feedback.\r\n * @param {string} type - Tipos del feedback, mirar en el rup.feedback..\r\n *\r\n */\n\n\n function _callFeedbackOk(ctx, feedback, msgFeedBack, type) {\n if (ctx.oInit.formEdit.disabledFeedback) {\n //no muestra el feedback\n return false;\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormFeedbackShow', ctx);\n feedback.rup_feedback('set', msgFeedBack, type);\n feedback.rup_feedback('show');\n }\n /**\r\n * Se añade el tipo de la lista.\r\n *\r\n * @name addListType\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} idForm - Identificador del formulario.\r\n * @param {string} row - Values ya añadidos al formulario.\r\n *\r\n */\n\n\n function _addListType(idForm, row) {\n //Listas de checkbox\n $.each(idForm.find('[data-lista]'), function () {\n var name = this.dataset.lista;\n var prop = '';\n var propSplit = this.name.split(\".\");\n\n if (propSplit !== undefined && propSplit.length === 2) {\n prop = propSplit[1];\n }\n\n if (row[name] === undefined || !Array.isArray(row[name])) {\n //si no existe se crea o // si no es de tipo array\n row[name] = [];\n }\n\n var array = {};\n\n if (prop !== undefined) {\n var clave = this.dataset.clave;\n\n if (clave !== undefined) {\n //si tiene clave es porque es objeto\n var label = this.dataset.valor; //se manda el valor id.\n\n array[clave] = label;\n array[prop] = $(this).is(':checked');\n } else {\n //si no tiene clave es porque es string\n array = $(this).is(':checked');\n }\n\n row[name].push(array);\n }\n }); //Se buscan los array para que sean listas.combos con multiselect\n\n $.each(row, function (name) {\n if (this !== undefined && this.toString() === '[object Object]') {\n if ($.rup_utils.isNumeric(Object.keys(this)[0])) {\n //se asegura, que no es una lista de objetos.\n row[name] = Object.values(this);\n }\n }\n });\n return row;\n }\n /**\r\n * Actualiza la navegación del dialogo.\r\n *\r\n * @name updateDetailPagination\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} currentRowNum - Número de la posición actual del registro selecionado.\r\n * @param {integer} totalRowNum - Número total de registros seleccionados.\r\n *\r\n */\n\n\n function _updateDetailPagination(ctx, currentRowNum, totalRowNum) {\n var tableId = ctx.oInit.formEdit.$navigationBar[0].id;\n\n if (currentRowNum === 1 || currentRowNum === totalRowNum) {\n var focusedElement = document.activeElement; // Eliminar foco del elemento porque va a ser deshabilitado a continuación\n\n if ($(ctx.oInit.formEdit.detailForm).find(focusedElement).length > 0) {\n focusedElement.blur();\n }\n }\n\n if (currentRowNum === 1) {\n $('#first_' + tableId + ', #back_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', true);\n } else {\n $('#first_' + tableId + ', #back_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', false);\n }\n\n if (currentRowNum === totalRowNum) {\n $('#forward_' + tableId + ', #last_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', true);\n } else {\n $('#forward_' + tableId + ', #last_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', false);\n }\n\n $('#rup_table_selectedElements_' + tableId).text($.rup_utils.format(jQuery.rup.i18nParse(jQuery.rup.i18n.base, 'rup_table.defaults.detailForm_pager'), currentRowNum, totalRowNum));\n }\n /**\r\n * Constructor de la barra de navegación.\r\n *\r\n * @name callNavigatorBar\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _callNavigationBar(dt) {\n var ctx = dt.settings()[0];\n ctx.oInit._ADAPTER = $.rup.adapter[jQuery.fn.rup_table.defaults.adapter];\n ctx.oInit.formEdit.$navigationBar = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_navigation');\n var settings = {}; // Funcion para obtener los parametros de navegacion.\n\n settings.fncGetNavigationParams = function getNavigationParams_multiselection(linkType) {\n var execute = false,\n changePage = false,\n index = 0,\n newPageIndex = 0,\n npos = ctx.oInit.formEdit.$navigationBar.currentPos,\n page = dt.page() + 1,\n newPage = page,\n lastPage = ctx.json.total;\n var multiselection = ctx.multiselection;\n var rowSelected;\n\n switch (linkType) {\n case 'first':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n rowSelected = multiselection.selectedRowsPerPage[0];\n rowSelected.indexSelected = 0;\n } else {\n // En el caso de que se hayan seleccionado todos los elementos de la tabla\n // Recorremos las páginas buscando la primera en la que existan elementos seleccionados\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getNextPageSelected(ctx, 1, 'next');\n\n if (Number(rowSelected.page) === page) {\n //Si es la misma pagina.buscar la linea\n rowSelected.line = _getLineByPageSelected(ctx, -1);\n } else {\n rowSelected.line = 0; // luego hay que buscar la linea\n }\n }\n\n break;\n\n case 'prev':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexPrev = ctx.oInit.formEdit.$navigationBar.currentPos.indexSelected - 1;\n rowSelected = multiselection.selectedRowsPerPage[indexPrev];\n rowSelected.indexSelected = indexPrev;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition--;\n\n var linea = _getLineByPageSelectedReverse(ctx, ctx.oInit.formEdit.$navigationBar.currentPos.line);\n\n if (linea === -1) {\n //Es que hay que cambiar de pagina.\n //buscarPAgina.\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getPrevPageSelected(ctx, page - 1);\n } else {\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n }\n }\n\n break;\n\n case 'next':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexNext = ctx.oInit.formEdit.$navigationBar.currentPos.indexSelected + 1;\n rowSelected = multiselection.selectedRowsPerPage[indexNext];\n rowSelected.indexSelected = indexNext;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition++; //2 casos: Si hay que navegar o no.\n\n var lineaNext = _getLineByPageSelected(ctx, ctx.oInit.formEdit.$navigationBar.currentPos.line);\n\n if (lineaNext === -1) {\n //Es que hay que cambiar de pagina.\n //buscarPAgina.\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getNextPageSelected(ctx, page + 1, 'next');\n rowSelected.line = 0; // luego hay que buscar la linea\n } else {\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n }\n }\n\n break;\n\n case 'last':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexLast = multiselection.selectedRowsPerPage.length - 1;\n rowSelected = multiselection.selectedRowsPerPage[indexLast];\n rowSelected.indexSelected = indexLast;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition = ctx.multiselection.numSelected - 1;\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getPrevPageSelected(ctx, lastPage);\n\n if (Number(rowSelected.page) === page) {\n //Si es la misma pagina.buscar la linea\n rowSelected.line = _getLineByPageSelectedReverse(ctx, ctx.aBaseJson.length);\n }\n }\n\n }\n\n _hideOnNav(dt, linkType, function () {\n var tableId = ctx.sTableId;\n\n if (Number(rowSelected.page) !== page) {\n var table = $('#' + tableId).DataTable();\n table.page(rowSelected.page - 1).draw('page'); // Se añaden los parámetros para luego ejecutar la función del dialog\n\n ctx.oInit.formEdit.$navigationBar.funcionParams = ['PUT', dt, rowSelected.line, linkType];\n } else {\n // Llamar directamente a la función\n $.when(DataTable.editForm.fnOpenSaveDialog('PUT', dt, rowSelected.line, ctx.oInit.formEdit.customTitle)).then(function () {\n _showOnNav(dt, linkType);\n }); // Solventar problemas de los componentes combo y autocomplete en los formularios de edición.\n\n _fixComboAutocompleteOnEditForm(ctx);\n }\n\n $('#first_' + tableId + '_detail_navigation' + ', #back_' + tableId + '_detail_navigation' + ', #forward_' + tableId + '_detail_navigation' + ', #last_' + tableId + '_detail_navigation', ctx.oInit.formEdit.detailForm).prop('disabled', true);\n }); // Actualizar la última posición movida\n\n\n ctx.oInit.formEdit.$navigationBar.currentPos = rowSelected;\n return [linkType, execute, changePage, index - 1, npos, newPage, newPageIndex - 1];\n };\n\n ctx.oInit.formEdit.$navigationBar.data('settings', settings);\n\n var barraNavegacion = ctx.oInit._ADAPTER.createDetailNavigation.bind(ctx.oInit.formEdit.$navigationBar);\n\n ctx.oInit.formEdit.$navigationBar.append(barraNavegacion);\n }\n\n function _fixComboAutocompleteOnEditForm(ctx) {\n // Solventar problemas de los componentes combo y autocomplete en los formularios de edición.\n if (ctx.oInit.colModel !== undefined) {\n $.each(ctx.oInit.colModel, function (key, column) {\n if (column.editable) {\n if (column.rupType === 'combo') {\n // Realizar una limpieza total para asegurar un buen funcionamiento.\n ctx.oInit.formEdit.idForm.find('[name=\"' + column.name + '\"]')['rup_combo']('hardReset');\n } else if (column.rupType === 'autocomplete') {\n // Establecer el valor por defecto del componente.\n var newDefaultValue = ctx.json.rows.find(function (row) {\n return row.id === ctx.oInit.formEdit.$navigationBar.currentPos.id;\n })[column.name];\n column.editoptions.defaultValue = newDefaultValue;\n ctx.oInit.formEdit.idForm.find('[name=\"' + column.name + '\"]').data('rup.autocomplete').$labelField.data('settings').defaultValue = newDefaultValue;\n }\n }\n });\n }\n }\n\n function _hideOnNav(dt, linkType, callback) {\n var ctx = dt.settings()[0];\n var direction = linkType === 'prev' || linkType === 'first' ? 'right' : 'left';\n var $dialogContent = $('#' + ctx.sTableId + '_detail_div .dialog-content-material');\n $dialogContent.parent().css('overflow-x', 'hidden');\n $dialogContent.hide('slide', {\n direction: direction\n }, 100, function () {\n $dialogContent.after('');\n callback();\n });\n }\n\n function _showOnNav(dt, linkType) {\n var ctx = dt.settings()[0];\n var direction = linkType === 'prev' || linkType === 'first' ? 'left' : 'right';\n var $dialogContent = $('#' + ctx.sTableId + '_detail_div .dialog-content-material');\n $('#' + ctx.sTableId + '_detail_div_loading').remove();\n $dialogContent.show('slide', {\n direction: direction\n }, 100, function () {\n $dialogContent.parent().css('overflow-x', 'auto');\n });\n }\n /**\r\n * Constructor de la barra de navegación.\r\n *\r\n * @name callNavigatorSelectBar\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _callNavigationSelectBar(dt) {\n var ctx = dt.settings()[0];\n ctx.oInit._ADAPTER = $.rup.adapter[jQuery.fn.rup_table.defaults.adapter];\n ctx.oInit.formEdit.$navigationBar = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_navigation');\n var settings = {}; // Funcion para obtener los parametros de navegacion.\n\n settings.fncGetNavigationParams = function getNavigationParams_multiselection(linkType) {\n var execute = false,\n changePage = false,\n index = 0,\n newPageIndex = 0,\n npos = ctx.oInit.formEdit.$navigationBar.currentPos,\n page = dt.page() + 1,\n newPage = page,\n lastPage = ctx.json.total;\n var futurePage = page;\n\n switch (linkType) {\n case 'first':\n futurePage = 1;\n ctx.multiselection.selectedRowsPerPage[0].line = 0;\n break;\n\n case 'prev':\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.multiselection.selectedRowsPerPage[0].line - 1;\n\n if (ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line] === undefined) {\n futurePage = futurePage - 1;\n }\n\n break;\n\n case 'next':\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.multiselection.selectedRowsPerPage[0].line + 1;\n\n if (ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line] === undefined) {\n futurePage = futurePage + 1;\n }\n\n break;\n\n case 'last':\n futurePage = lastPage;\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.json.rows.length - 1;\n } // Cambio de pagina\n\n\n if (Number(futurePage) !== page) {\n var table = $('#' + ctx.sTableId).DataTable();\n ctx.select.selectedRowsPerPage = {};\n ctx.select.selectedRowsPerPage.cambio = linkType;\n ctx.select.selectedRowsPerPage.page = futurePage;\n table.page(futurePage - 1).draw('page');\n } else {\n //Si no se pagina se abre directamente la funcion.\n DataTable.editForm.fnOpenSaveDialog('PUT', dt, ctx.multiselection.selectedRowsPerPage[0].line, ctx.oInit.formEdit.customTitle);\n var rowSelectAux = ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line];\n ctx.multiselection.selectedRowsPerPage[0].id = DataTable.Api().rupTable.getIdPk(rowSelectAux, ctx.oInit);\n DataTable.Api().select.deselect(ctx);\n DataTable.Api().select.drawSelectId(ctx);\n } //Se actualiza la ultima posicion movida.\n //ctx.oInit.formEdit.$navigationBar.currentPos = rowSelected;\n\n\n var tableId = ctx.sTableId;\n $('#first_' + tableId + '_detail_navigation' + ', #back_' + tableId + '_detail_navigation' + ', #forward_' + tableId + '_detail_navigation' + ', #last_' + tableId + '_detail_navigation', ctx.oInit.formEdit.detailForm).prop('disabled', true);\n return [linkType, execute, changePage, index - 1, npos, newPage, newPageIndex - 1];\n };\n\n ctx.oInit.formEdit.$navigationBar.data('settings', settings);\n\n var barraNavegacion = ctx.oInit._ADAPTER.createDetailNavigation.bind(ctx.oInit.formEdit.$navigationBar);\n\n ctx.oInit.formEdit.$navigationBar.append(barraNavegacion);\n }\n /**\r\n * Método que obtiene la fila siguiente seleccionada.\r\n *\r\n * @name getRowSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Instancia de la tabla.\r\n * @param {string} actionType - Acción a ajecutar en el formulario para ir al controller, basado en REST.\r\n *\r\n * @return {object} Contiene el identificador, la página y la línea de la fila seleccionada.\r\n *\r\n */\n\n\n function _getRowSelected(dt, actionType) {\n var ctx = dt.settings()[0];\n var rowDefault = {\n id: 0,\n page: 1,\n line: 0\n };\n var lastSelectedId = ctx.multiselection.lastSelectedId;\n\n if (!ctx.multiselection.selectedAll) {\n $.each(ctx.multiselection.selectedRowsPerPage, function (index, p) {\n if (p.id == ctx.multiselection.lastSelectedId) {\n rowDefault.id = p.id;\n rowDefault.page = p.page;\n rowDefault.line = p.line;\n rowDefault.indexSelected = index;\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = rowDefault;\n }\n\n return false;\n }\n });\n } else {\n if (ctx.oInit.formEdit !== undefined) {\n // Indica los mostrados cuando es selectAll y no se puede calcular. El inicio es 0.\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n }\n\n if (lastSelectedId === undefined || lastSelectedId === '') {\n // Como arranca de primeras, la página es la 1\n rowDefault.page = _getNextPageSelected(ctx, 1, 'next');\n rowDefault.line = _getLineByPageSelected(ctx, -1);\n } else {\n // Buscar la posición y la página\n var result = $.grep(ctx.multiselection.selectedRowsPerPage, function (v) {\n return v.id == ctx.multiselection.lastSelectedId;\n });\n rowDefault.page = result[0].page;\n rowDefault.line = result[0].line;\n var index = ctx._iDisplayLength * (Number(rowDefault.page) - 1);\n index = index + 1 + rowDefault.line; // Restar los deselecionados\n\n result = $.grep(ctx.multiselection.deselectedRowsPerPage, function (v) {\n return Number(v.page) < Number(rowDefault.page) || Number(rowDefault.page) === Number(v.page) && Number(v.line) < Number(rowDefault.line);\n }); // Buscar índice\n\n rowDefault.indexSelected = index - result.length;\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.numPosition = rowDefault.indexSelected - 1;\n }\n }\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = rowDefault;\n }\n } // En caso de estar en una página distinta, navegamos a ella\n\n\n if (dt.page() + 1 !== Number(rowDefault.page)) {\n var pageActual = dt.page() + 1;\n var table = $('#' + ctx.sTableId).DataTable();\n table.page(rowDefault.page - 1).draw('page');\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.funcionParams = [actionType, dt, rowDefault.line, undefined, pageActual];\n }\n }\n\n return rowDefault;\n }\n /**\r\n * Metodo que obtiene la página siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getNextPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} pageInit - Página a partir de la cual hay que mirar, en general serà la 1.\r\n * @param {string} orden - Pueder ser pre o next, en función de si necesitar ir hacia adelante o hacia atrás.\r\n *\r\n * @return integer - devuelve la página\r\n *\r\n */\n\n\n function _getNextPageSelected(ctx, pageInit, orden) {\n var pagina = pageInit;\n var pageTotals = ctx.json.total;\n\n if (orden === 'prev') {\n //Si es previo se resta.\n pageTotals = 1;\n }\n\n if (ctx.multiselection.deselectedRowsPerPage.length > 0) {\n var maxPagina = ctx.json.rows.length;\n var count = 0; //Buscar la pagina donde va estar el seleccionado.\n\n for (var page = pageInit; page < pageTotals;) {\n $.each(ctx.multiselection.deselectedRowsPerPage, function (index, p) {\n if (page === Number(p.page)) {\n count++;\n }\n\n if (count === maxPagina) {\n return false;\n }\n });\n\n if (count < maxPagina) {\n pagina = page;\n page = ctx.json.total; //Se pone el total para salir del bucle.\n }\n\n count = 0;\n\n if (orden === 'next') {\n page++;\n } else if (orden === 'prev') {\n page--;\n }\n }\n }\n\n return pagina;\n }\n /**\r\n * Metodo que obtiene la página siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getPrevPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} pageInit - Página a partir de la cual hay que mirar, en general serà la 1.\r\n *\r\n * @return integer - devuele la página\r\n *\r\n */\n\n\n function _getPrevPageSelected(ctx, pageInit) {\n var pagina = pageInit;\n var pageTotals = 1;\n\n if (ctx.multiselection.deselectedRowsPerPage.length > 0) {\n var maxPagina = ctx.json.rows.length;\n\n if (ctx.json.total === pagina) {\n //Es ultima pagina, calcular los registros{\n maxPagina = ctx.json.records % ctx._iDisplayLength;\n }\n\n var count = 0; //Buscar la pagina donde va estar el seleccionado.\n\n for (var page = pageInit; pageTotals <= page;) {\n $.each(ctx.multiselection.deselectedRowsPerPage, function (index, p) {\n if (Number(page) === Number(p.page)) {\n count++;\n }\n\n if (count === maxPagina) {\n return false;\n }\n });\n\n if (count < maxPagina) {\n pagina = page;\n pageTotals = ctx.json.total; //Se pone el total para salir del bucle.\n }\n\n count = 0;\n page--;\n }\n }\n\n return pagina;\n }\n /**\r\n * Metodo que obtiene la linea siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getLineByPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} lineInit - Linea a partir de la cual hay que mirar, en general será la 1.\r\n *\r\n * @return integer - devuele la linea\r\n *\r\n */\n\n\n function _getLineByPageSelected(ctx, lineInit) {\n var line = -1;\n var rows = ctx.json.rows;\n $.each(rows, function (index, row) {\n if (index > lineInit) {\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), ctx.multiselection.deselectedIds);\n\n if (indexInArray === -1) {\n line = index;\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: ctx.json.page,\n line: index\n };\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = arra;\n }\n\n return false;\n }\n }\n });\n return line;\n }\n /**\r\n * Metodo que obtiene la última linea siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getLineByPageSelectedReverse\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} lineInit - Linea a partir de la cual hay que mirar.\r\n *\r\n * @return integer - devuele la linea\r\n *\r\n */\n\n\n function _getLineByPageSelectedReverse(ctx, lineInit) {\n var line = -1;\n var rows = ctx.json.rows;\n\n for (var index = rows.length - 1; index >= 0; index--) {\n var row = rows[index];\n\n if (index < lineInit) {\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), ctx.multiselection.deselectedIds);\n\n if (indexInArray === -1) {\n line = index;\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: ctx.json.page,\n line: index\n };\n ctx.oInit.formEdit.$navigationBar.currentPos = arra;\n index = -1;\n }\n }\n }\n\n return line;\n }\n /**\r\n * Metodo que elimina todos los registros seleccionados.\r\n *\r\n * @name _deleteAllSelects\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _deleteAllSelects(dt) {\n var ctx = dt.settings()[0];\n var idRow = 0;\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n var actionType = ctx.multiselection.selectedIds.length > 1 ? 'POST' : 'DELETE';\n\n var _doDelete = function _doDelete() {\n var row = {};\n row.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n\n if (ctx.multiselection.selectedIds.length > 1) {\n row.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n };\n row.multiselection = {};\n row.multiselection.selectedAll = ctx.multiselection.selectedAll;\n\n if (row.multiselection.selectedAll) {\n row.multiselection.selectedIds = ctx.multiselection.deselectedIds;\n } else {\n row.multiselection.selectedIds = ctx.multiselection.selectedIds;\n }\n\n _callSaveAjax(actionType, dt, row, idRow, false, ctx.oInit.formEdit.detailForm, '/deleteAll', true);\n } else {\n row = ctx.multiselection.selectedIds[0];\n row = row.replace(regex, '/');\n\n _callSaveAjax(actionType, dt, '', idRow, false, ctx.oInit.formEdit.detailForm, '/' + row, true);\n }\n };\n\n if (ctx.oInit.formEdit.detailForm.settings.deleteDialog) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.deleteAll'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.delete'),\n OKFunction: function OKFunction() {\n _doDelete();\n\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: ctx.oInit.formEdit.cancelDeleteFunction\n });\n } else {\n _doDelete();\n }\n }\n /**\r\n * Método que serializa los datos del formulario.\r\n *\r\n * @name _editFormSerialize\r\n * @function\r\n * @since UDA 3.6.0 // Table 1.2.0\r\n *\r\n * @param {object} idForm - Formulario que alberga los datos.\r\n * @param {string} [serializerSplitter=&] - Cadena a usar para separar los campos.\r\n *\r\n * @return {string} - Devuelve los datos del formulario serializados\r\n *\r\n */\n\n\n function _editFormSerialize(idForm) {\n var serializerSplitter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '&';\n var serializedForm = '';\n var idFormArray = idForm.formToArray();\n var ultimo = '';\n var count = 0;\n $.each(idFormArray, function (key, obj) {\n if (ultimo != obj.name) {\n count = 0;\n }\n\n var valor = '';\n\n if ($(idForm).find('[name=\"' + obj.name + '\"]').prop('multiple')) {\n valor = '[' + count++ + ']';\n } else if (ultimo === obj.name) {\n //Se mete como lista\n //se hace replace del primer valor\n serializedForm = serializedForm.replace(ultimo + '=', ultimo + '[' + count++ + ']=');\n valor = '[' + count++ + ']'; //y se mete el array\n }\n\n serializedForm += obj.name + valor + '=' + obj.value;\n serializedForm += serializerSplitter;\n ultimo = obj.name;\n }); // Evitar que el último carácter sea \"&\" o el separador definido por el usuario.\n\n serializedForm = serializedForm.substring(0, serializedForm.length - serializerSplitter.length);\n return serializedForm;\n }\n /**\r\n * Metodo que comprueba el seeker.\r\n *\r\n * @name _comprobarSeeker\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} row - Son los datos que se cargan.\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {number} idRow - Identificador de la fila.\r\n *\r\n */\n\n\n function _comprobarSeeker(row, ctx, idRow) {\n var cumple = true;\n $.each(ctx.seeker.ajaxOption.data.search, function (key, obj) {\n if (row[key].indexOf(obj) === -1) {\n cumple = false;\n return false;\n }\n });\n\n if (!cumple) {\n // eliminar del seeker, por pagina y linea\t\t\n ctx.seeker.search.funcionParams = jQuery.grep(ctx.seeker.search.funcionParams, function (search) {\n return search.page !== Number(ctx.json.page) || search.pageLine !== idRow + 1;\n }); // se borra el icono\n\n $('#' + ctx.sTableId + ' tbody tr').eq(idRow).find('td.select-checkbox i.filtered-row').remove();\n $('#' + ctx.sTableId + ' tbody tr').eq(idRow).find('td i.filtered-row').remove();\n DataTable.Api().seeker.updateDetailSeekPagination(1, ctx.seeker.search.funcionParams.length, ctx);\n }\n }\n /**\r\n * Método que gestiona el bloqueo de la edición de las claves primarias.\r\n *\r\n * @name _blockPKeditForm\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {string} actionType - Método de operación CRUD.\r\n *\r\n */\n\n\n function _blockPKeditForm(ctx, actionType) {\n var blockPK = ctx.oInit.blockPKeditForm;\n var idForm = ctx.oInit.formEdit.idForm;\n\n if (blockPK) {\n // En caso de ser edición bloqueamos la modificación\n if (actionType === 'PUT') {\n $.each(ctx.oInit.primaryKey, function (key, id) {\n var input = $(idForm[0]).find(':input[name=\\'' + id + '\\']'); // Comprobamos si es un componente rup o no. En caso de serlo usamos el metodo disable.\n\n if (input.attr('ruptype') === 'date' && !input.rup_date('isDisabled')) {\n input.rup_date('disable');\n } else if (input.attr('ruptype') === 'combo' && !input.rup_combo('isDisabled')) {\n input.rup_combo('disable');\n } else if (input.attr('ruptype') === 'select' && !input.rup_select('isDisabled')) {\n input.rup_select('disable');\n } else if (input.attr('ruptype') === 'time' && !input.rup_time('isDisabled')) {\n input.rup_time('disable');\n } else if (input.attr('type') === 'checkbox') {\n if (!input.hasClass('checkboxPKBloqueado')) {\n input.addClass('checkboxPKBloqueado');\n }\n\n var valorCheck = input.is(':checked') ? 1 : 0;\n var selectorInputSustituto = $('#' + id + '_bloqueado'); // Comprobamos si es necesario cambiar el check\n\n if (selectorInputSustituto.attr('valor') !== valorCheck) {\n if (selectorInputSustituto.attr('valor') !== undefined) {\n selectorInputSustituto.remove();\n }\n\n if (valorCheck === 1) {\n input.after('');\n } else {\n input.after('');\n }\n }\n } else {\n input.prop('readOnly', true);\n } // Quitamos el foco del elemento\n\n\n input.on('mousedown', function (event) {\n event.preventDefault();\n });\n });\n } // En caso de ser clonación permitimos la edición\n else if (actionType === 'POST') {\n $.each(ctx.oInit.primaryKey, function (key, id) {\n var input = $(idForm[0]).find(':input[name=\\'' + id + '\\']'); // Comprobamos si es un componente rup o no. En caso de serlo usamos el metodo enable.\n\n if (input.attr('ruptype') === 'date' && input.rup_date('isDisabled')) {\n input.rup_date('enable');\n } else if (input.attr('ruptype') === 'combo' && input.rup_combo('isDisabled')) {\n input.rup_combo('enable');\n } else if (input.attr('ruptype') === 'select' && input.rup_select('isDisabled')) {\n input.rup_select('enable');\n } else if (input.attr('ruptype') === 'time' && input.rup_time('isDisabled')) {\n input.rup_time('enable');\n } else if (input.attr('type') === 'checkbox') {\n input.removeClass('checkboxPKBloqueado');\n $('#' + id + '_bloqueado').remove();\n } else {\n input.prop('readOnly', false);\n } // Devolvemos el foco al elemento\n\n\n input.on('mousedown', function (event) {\n $(this).off(event.preventDefault());\n input.focus();\n });\n });\n }\n }\n }\n /**\r\n * Se añaden los iconos al responsive.\r\n *\r\n * @name _addChildIcons\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _addChildIcons(ctx) {\n try {\n var hasHidden = false;\n\n var columnsVisiblity = ctx.responsive._columnsVisiblity();\n\n for (var i = 0; i < columnsVisiblity.length; i++) {\n if (!columnsVisiblity[i]) {\n if (!ctx.aoColumns[i].className || ctx.aoColumns[i].className.indexOf('never') < 0) {\n hasHidden = true;\n }\n }\n }\n\n if (ctx.responsive.c.details.target === 'td span.openResponsive') {\n //por defecto\n $('#' + ctx.sTableId).find('tbody td:first-child span.openResponsive').remove();\n\n if (hasHidden) {\n //añadir span ala primera fila\n $.each($('#' + ctx.sTableId).find('tbody td:first-child:not(.child):not(.dataTables_empty)'), function () {\n var $span = $('');\n\n if ($(this).find('span.openResponsive').length === 0) {\n $(this).prepend($span.addClass('openResponsive'));\n } else {\n //si ya existe se asigna el valor.\n $span = $(this).find('span.openResponsive');\n }\n\n if ($(this).parent().next().hasClass('child')) {\n $span.addClass('closeResponsive');\n }\n\n var $fila = $(this).parent();\n $span.click(function (event) {\n if ($fila.hasClass('editable') && $fila.find('.closeResponsive').length) {\n //no se hace nada. si esta editando\n event.stopPropagation();\n } else {\n if ($span.hasClass('closeResponsive')) {\n $span.removeClass('closeResponsive');\n } else {\n $span.addClass('closeResponsive');\n }\n }\n });\n });\n }\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddChildIcons', ctx);\n } catch (error) {}\n }\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables API\r\n *\r\n * For complete documentation, please refer to the docs/api directory or the\r\n * DataTables site\r\n */\n // Local variables to improve compression\n\n\n var apiRegister = DataTable.Api.register; // Se declara la variable de editForm para que pueda ser invocada desde cualquier sitio\n\n apiRegister('editForm.openSaveDialog()', function (actionType, dt, idRow, customTitle) {\n DataTable.editForm.fnOpenSaveDialog(actionType, dt, idRow, customTitle);\n });\n apiRegister('editForm.updateDetailPagination()', function (ctx, currentRowNum, totalRowNum) {\n _updateDetailPagination(ctx, currentRowNum, totalRowNum);\n });\n apiRegister('editForm.loadSaveDialogForm()', function (ctx, actionType, row) {\n return _loadSaveDialogForm(ctx, actionType, row);\n });\n apiRegister('editForm.getRowSelected()', function (dt, actionType) {\n return _getRowSelected(dt, actionType);\n });\n apiRegister('editForm.deleteAllSelects()', function (dt) {\n return _deleteAllSelects(dt);\n });\n apiRegister('editForm.getLineByPageSelected()', function (ctx, linea) {\n return _getLineByPageSelected(ctx, linea);\n });\n apiRegister('editForm.getLineByPageSelectedReverse()', function (ctx, linea) {\n return _getLineByPageSelectedReverse(ctx, linea);\n });\n apiRegister('editForm.addchildIcons()', function (ctx) {\n _addChildIcons(ctx);\n });\n apiRegister('editForm.fixComboAutocompleteOnEditForm()', function (ctx) {\n _fixComboAutocompleteOnEditForm(ctx);\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Initialisation\r\n */\n // DataTables creation - check if select has been defined in the options. Note\n // this required that the table be in the document! If it isn't then something\n // needs to trigger this method unfortunately. The next major release of\n // DataTables will rework the events and address this.\n\n $(document).on('plugin-init.dt', function (e, ctx) {\n if (e.namespace !== 'dt') {\n return;\n }\n\n if (!ctx.oInit.noEdit && ctx.oInit.formEdit !== undefined && ctx.oInit.formEdit.activate !== false) {\n DataTable.editForm.preConfigure(new DataTable.Api(ctx));\n $('#' + ctx.sTableId).on('tableEditFormInitialize', function (event, ctx) {\n var deferred = $.Deferred();\n DataTable.editForm.init(ctx);\n $(ctx.oInit.formEdit.detailForm).rup_dialog($.extend({}, {\n type: $.rup.dialog.DIV,\n autoOpen: false,\n modal: true,\n resizable: '',\n width: ctx.oInit.formEdit.detailForm.settings.width,\n create: function create() {\n /* Se encarga de eliminar la clase que oculta los campos del formEdit. Esta clase esta presente\r\n * en el formEdit para evitar un bug visual en el que hacia que sus campos apareciesen \r\n * bajo la tabla y fueran visibles previa a la inicializacion del componente rup.dialog.\r\n */\n $('#' + ctx.sTableId + '_detail_div.rup-table-formEdit-detail').removeClass('d-none');\n }\n }, {}));\n\n if (ctx.oInit.formEdit.cancelDeleteFunction === undefined) {\n ctx.oInit.formEdit.cancelDeleteFunction = function cancelClicked() {};\n }\n\n deferred.resolve();\n return deferred.promise();\n });\n }\n });\n return DataTable.editForm;\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup_table/rup.table.editForm.js?"); +eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/* eslint-env jquery,amd */\n\n/**\r\n * Módulo que habilita la edicción mediante un formulario.\r\n *\r\n * @summary \t\tExtensión del componente RUP Datatable\r\n * @module\t\t\t\"rup.table.editForm\"\r\n * @version 1.0.0\r\n * @license\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n * @copyright Copyright 2018 E.J.I.E., S.A.\r\n *\r\n */\n(function (factory) {\n if (true) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! ../core/utils/jquery.form */ \"./src/core/utils/jquery.form.js\"), __webpack_require__(/*! ../rup.form */ \"./src/rup.form.js\"), __webpack_require__(/*! ../rup.combo */ \"./src/rup.combo.js\"), __webpack_require__(/*! datatables.net */ \"./node_modules/datatables.net/js/jquery.dataTables.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($) {\n return factory($, window, document);\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($, window, document, undefined) {\n 'use strict';\n\n var DataTable = $.fn.dataTable; // Version information for debugger\n\n DataTable.editForm = {};\n DataTable.editForm.version = '1.2.4';\n /**\r\n * Configura el componente editForm para su inicialización\r\n *\r\n * @name preConfigure\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n DataTable.editForm.preConfigure = function (dt) {\n var ctx = dt.settings()[0];\n var init = ctx.oInit.multiSelect;\n var defaults = DataTable.defaults.multiSelect;\n\n if (init === undefined) {\n init = defaults;\n } // DetailForm se convierte en función y se inicializan los botones\n\n\n ctx.oInit.formEdit.detailForm = $(ctx.oInit.formEdit.detailForm);\n ctx.oInit.formEdit.idForm = ctx.oInit.formEdit.detailForm.find('form').first();\n ctx.oInit.formEdit.id = ctx.oInit.formEdit.detailForm[0].id.replace('_detail_div', '');\n\n if (ctx.oInit.formEdit.detailForm !== undefined && $('body').find('[aria-describedby=\\'' + ctx.oInit.formEdit.detailForm[0].id + '\\']').length > 0) {\n $('body').find('[aria-describedby=\\'' + ctx.oInit.formEdit.detailForm[0].id + '\\']').remove();\n } // Obtiene el adapter y crea la barra de navegación en función de si la multiselección está o no activada\n\n\n if (ctx.oInit.multiSelect === undefined) {\n _callNavigationSelectBar(dt);\n } else {\n _callNavigationBar(dt);\n } // Inicializa el paginador del formulario de edición\n\n\n _updateDetailPagination(ctx, 1, 1); // Añade el botón de cancelar\n\n\n ctx.oInit.formEdit.buttoCancel = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_cancel');\n ctx.oInit.formEdit.buttoCancel.on('click', function () {\n _cancelPopup(ctx); // Cierra el dialog\n\n\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n });\n var idRow;\n var rowsBody = $(ctx.nTBody); // Gestiona la creación del evento de doble click para editar una fila\n\n if (ctx.oInit.multiSelect !== undefined || ctx.oInit.select !== undefined) {\n var sel = ctx.oInit.multiSelect;\n\n if (sel === undefined) {\n sel = ctx.oInit.select;\n } // Propiedad que no genera el evento de doble click en caso de existir y tener un valor true\n\n\n if (!sel.deleteDoubleClick) {\n rowsBody.on('dblclick.DT keypress', 'tr:not(.group)', function (e) {\n // Sólo selecciona si se pulsa sobre el enter o se hace click izquierdo con el ratón\n if (e.type == 'keypress' && e.which == 13 || e.type === 'dblclick') {\n idRow = this._DT_RowIndex; // Añadir la selección del mismo\n\n if (ctx.oInit.multiSelect !== undefined) {\n dt['row'](idRow).multiSelect();\n } else {\n $('tr', rowsBody).removeClass('selected tr-highlight');\n DataTable.Api().select.selectRowIndex(dt, idRow, true);\n }\n\n _getRowSelected(dt, 'PUT');\n\n DataTable.editForm.fnOpenSaveDialog('PUT', dt, idRow, ctx.oInit.formEdit.customTitle);\n $('#' + ctx.sTableId).triggerHandler('tableEditFormClickRow', ctx);\n }\n });\n }\n } // Establece el valor de las propiedades del formulario de edición.\n\n\n ctx.oInit.formEdit.loadSpinner = typeof ctx.oInit.formEdit.loadSpinner === 'boolean' ? ctx.oInit.formEdit.loadSpinner : true;\n ctx.oInit.formEdit.detailForm.settings = {\n type: ctx.oInit.formEdit.type !== undefined ? ctx.oInit.formEdit.type : $.rup.dialog.DIV,\n width: ctx.oInit.formEdit.width !== undefined ? ctx.oInit.formEdit.width : 569,\n saveDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.saveDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.saveDialog : true,\n cancelDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.cancelDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.cancelDialog : true,\n deleteDialog: ctx.oInit.formEdit.confirmDialogs !== undefined && ctx.oInit.formEdit.confirmDialogs.deleteDialog !== undefined ? ctx.oInit.formEdit.confirmDialogs.deleteDialog : true\n }; // Calcula el responsive\n\n $(window).on('resize.dtr', DataTable.util.throttle(function () {\n _addChildIcons(ctx);\n }));\n };\n /**\r\n * Inicializa el componente editForm\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n DataTable.editForm.init = function (ctx) {\n // Capturar evento de cierre\n ctx.oInit.formEdit.detailForm.on('dialogbeforeclose', function (event) {\n if (event.originalEvent !== undefined) {\n //el evento es cerrado por el aspa\n ctx.oInit.formEdit.okCallBack = false;\n } // Si es igual no se debe hacer nada\n\n\n var formSerializado = _editFormSerialize(ctx.oInit.formEdit.idForm, ctx.oInit.formEdit.serializerSplitter);\n\n if (ctx.oInit.formEdit.dataOrigin === formSerializado || !ctx.oInit.formEdit.detailForm.settings.cancelDialog) {\n _cancelPopup(ctx);\n\n return true;\n }\n\n if (ctx.oInit.formEdit.dataOrigin !== formSerializado && !ctx.oInit.formEdit.okCallBack) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.saveAndContinue'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n _cancelPopup(ctx);\n\n ctx.oInit.formEdit.okCallBack = true;\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: function CANCELFunction() {\n ctx.oInit.formEdit.okCallBack = false;\n $('#' + ctx.sTableId).triggerHandler('tableMessageCancel', ctx);\n },\n CLOSEFunction: function CLOSEFunction() {\n ctx.oInit.formEdit.okCallBack = false;\n $('#' + ctx.sTableId).triggerHandler('tableMessageClose', ctx);\n }\n });\n } // En caso de aceptar, se cierra y se limpia\n\n\n if (!ctx.oInit.formEdit.okCallBack || ctx.oInit.formEdit.okCallBack === undefined) {\n return false;\n }\n });\n };\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Local functions\r\n */\n\n /**\r\n * Initialisation of a new table. Attach event handlers and callbacks to allow\r\n * Select to operate correctly.\r\n *\r\n * This will occur _after_ the initial DataTables initialisation, although\r\n * before Ajax data is rendered, if there is ajax data\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {DataTable.settings} ctx Settings object to operate on\r\n *\r\n */\n\n\n function init(ctx) {\n var api = new DataTable.Api(ctx); // Row callback so that classes can be added to rows and cells if the item\n // was selected before the element was created. This will happen with the\n // `deferRender` option enabled.\n //\n // This method of attaching to `aoRowCreatedCallback` is a hack until\n // DataTables has proper events for row manipulation If you are reviewing\n // this code to create your own plug-ins, please do not do this!\n\n ctx.aoRowCreatedCallback.push({\n fn: function fn(row, data, index) {\n var i, ien;\n var d = ctx.aoData[index]; // Row\n\n if (d._multiSelect_selected) {\n $(row).addClass(ctx._multiSelect.className);\n } // Cells and columns - if separated out, we would need to do two\n // loops, so it makes sense to combine them into a single one\n\n\n for (i = 0, ien = ctx.aoColumns.length; i < ien; i++) {\n if (ctx.aoColumns[i]._multiSelect_selected || d._selected_cells && d._selected_cells[i]) {\n $(d.anCells[i]).addClass(ctx._multiSelect.className);\n }\n }\n },\n sName: 'select-deferRender'\n }); // On Ajax reload we want to reselect all rows which are currently selected,\n // if there is an rowId (i.e. a unique value to identify each row with)\n\n api.on('preXhr.dt.dtSelect', function () {\n // note that column selection doesn't need to be cached and then\n // reselected, as they are already selected\n var rows = api.rows({\n selected: true\n }).ids(true).filter(function (d) {\n return d !== undefined;\n });\n var cells = api.cells({\n selected: true\n }).eq(0).map(function (cellIdx) {\n var id = api.row(cellIdx.row).id(true);\n return id ? {\n row: id,\n column: cellIdx.column\n } : undefined;\n }).filter(function (d) {\n return d !== undefined;\n }); // On the next draw, reselect the currently selected items\n\n api.one('draw.dt.dtSelect', function () {\n api.rows(rows).multiSelect(); // `cells` is not a cell index selector, so it needs a loop\n\n if (cells.any()) {\n cells.each(function (id) {\n api.cells(id.row, id.column).multiSelect();\n });\n }\n });\n }); // Clean up and release\n\n api.on('destroy.dtSelect', function () {\n disableMouseSelection(api);\n api.off('.dtSelect');\n });\n }\n\n function eventTrigger(api, type, args, any) {\n if (any && !api.flatten().length) {\n return;\n }\n\n if (typeof type === 'string') {\n type = type + '.dt';\n }\n\n args.unshift(api);\n $(api.table().node()).trigger(type, args);\n }\n\n function _cancelPopup(ctx) {\n ctx.oInit.formEdit.okCallBack = false;\n var feedback = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_feedback'); //Despues de cerrar\n //Se limpia los elementos.\n\n if (ctx.oInit.formEdit.idForm.find('.error').length > 0) {\n ctx.oInit.formEdit.idForm.rup_validate('resetElements'); //nos aseguramos de borrar todo\n\n ctx.oInit.formEdit.idForm.find('.error').not('input').remove();\n ctx.oInit.formEdit.idForm.find('.rup-validate-field-error').removeClass('rup-validate-field-error');\n } //Se cierran los mensajes del feedback\n\n\n if (feedback[0].className !== '') {\n feedback.rup_feedback('hide', 0);\n }\n }\n /**\r\n * Función que añade las validaciones a un formulario.\r\n *\r\n * @name addValidation\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _addValidation(ctx) {\n var idTableDetail = ctx.oInit.formEdit.detailForm;\n var feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n var validaciones;\n\n if (ctx.oInit.formEdit.validate !== undefined) {\n validaciones = ctx.oInit.formEdit.validate.rules;\n }\n\n if (feed.length === 0) {\n feed = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n }\n\n feed.rup_feedback(ctx.oInit.feedback);\n var propertiesDefault = {\n liveCheckingErrors: false,\n showFieldErrorAsDefault: true,\n showErrorsInFeedback: true,\n showFieldErrorsInFeedback: true\n };\n var propertiesValidate = $.extend(true, {}, propertiesDefault, ctx.oInit.formEdit.propertiesValidate);\n propertiesValidate.feedback = feed;\n propertiesValidate.rules = validaciones;\n ctx.oInit.formEdit.idForm.rup_validate(propertiesValidate);\n }\n /**\r\n * Función que gestiona la carga del diálogo de añadir o editar.\r\n *\r\n * @name loadSaveDialogForm\r\n * @function\r\n * @since UDA 5.0.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {string} actionType - Acción a ajecutar en el formulario para ir al controller, basado en REST.\r\n * @param {object} row - Datos para alimentar los campos del formulario.\r\n *\r\n * @return {object}\r\n */\n\n\n function _loadSaveDialogForm(ctx, actionType, row) {\n var idForm = ctx.oInit.formEdit !== undefined ? ctx.oInit.formEdit.idForm : undefined; // Servirá para saber si la última llamada a editForm fue para añadir, editar o si aún no ha sido inicializado\n\n var lastAction = ctx.oInit.formEdit.actionType; // Botón de guardar y continuar\n\n var buttonContinue = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save_repeat'); // En caso de ser clonado el method ha de ser POST\n\n if (actionType === 'CLONE') {\n actionType = 'POST';\n buttonContinue.hide();\n } else {\n buttonContinue.show();\n } // Si el usuario ha activado los formularios dinámicos, la última acción no es la misma que la actual o el valor del identificador ha cambiado,\n // es necesario volver a obtener el formulario.\n\n\n if (_validarFormulario(ctx, lastAction, actionType, row)) {\n // Preparar la información a enviar al servidor. Como mínimo se enviará el actionType, un booleano que indique si el formulario es multipart y \n // el valor de la clave primaria siempre y cuando no contenga un string vacío.\n var defaultData = _objectSpread({\n 'actionType': actionType,\n 'isMultipart': ctx.oInit.formEdit.multipart === true ? true : false\n }, DataTable.Api().rupTable.getIdPk(row, ctx.oInit) != \"\" && {\n 'pkValue': DataTable.Api().rupTable.getIdPk(row, ctx.oInit)\n });\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterData', ctx);\n var data = ctx.oInit.formEdit.data !== undefined ? $.extend({}, defaultData, ctx.oInit.formEdit.data) : defaultData;\n $('#' + ctx.sTableId).triggerHandler('tableEditFormBeforeLoad', ctx);\n return $.post(ctx.oInit.formEdit.url !== undefined ? ctx.oInit.formEdit.url : ctx.oInit.urlBase + '/editForm', data, function (form) {\n // Guardar anterior formulario para poder comprobarlo con el recién recibido\n var tempForm = idForm !== undefined ? idForm : undefined; // Guardar referencia del formulario recibido\n\n var receivedForm = $(form).find(\"form\").addBack('form'); // Si existe un formulario previo con el mismo identificador que el recibido, se elimina\n\n if (tempForm !== undefined && tempForm.length === 1 && tempForm.attr(\"id\") === receivedForm.attr(\"id\")) {\n tempForm.remove();\n } // Insertar formulario recibido dentro del contenedor especificado\n\n\n var formContainerID = '#' + ctx.sTableId + '_detail_form_container';\n $(formContainerID).prepend(receivedForm);\n ctx.oInit.formEdit.actionType = actionType;\n ctx.oInit.formEdit.idForm = $(ctx.oInit.formEdit.detailForm).find('form').first(); // Si el diálogo no ha sido inicializado, se inicializa\n\n if (lastAction === undefined) {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormInitialize', ctx);\n } // Detectar componentes RUP e inicializarlos\n\n\n _formInitializeRUP(ctx, row, $(formContainerID + ' #' + receivedForm.attr(\"id\"))); // Añadir validaciones\n\n\n _addValidation(ctx);\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterLoad', ctx);\n }, 'html');\n } else if (!ctx.oInit.enableDynamicForms && lastAction === undefined) {\n // Entrará por aquí cuando los formularios dinámicos hayan sido desactivados (comportamiento por defecto) y se necesite inicializar el formulario por ser la primera llamada\n ctx.oInit.formEdit.actionType = actionType;\n $.when($('#' + ctx.sTableId).triggerHandler('tableEditFormInitialize', ctx)).then(function () {\n var deferred = $.Deferred(); // Detectar componentes RUP e inicializarlos\n\n _formInitializeRUP(ctx, row, idForm); // Añadir validaciones\n\n\n _addValidation(ctx);\n\n deferred.resolve();\n return deferred.promise();\n });\n } else {\n // Para cuando el formulario actual sigue siendo válido (ya sea dinámico o no)\n var deferred = $.Deferred();\n ctx.oInit.formEdit.actionType = actionType;\n deferred.resolve();\n return deferred.promise();\n }\n }\n /**\r\n * Valida los formularios para no, buscarlos.\r\n *\r\n * @name formInitializeRUP\r\n * @function\r\n * @since UDA 5.0.2 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {object} lastAction - última accion realizado.\r\n * @param {object} actionType - Tipo de acción.\r\n */\n\n\n function _validarFormulario(ctx, lastAction, actionType, row) {\n if (ctx.oInit.enableDynamicForms) {\n var lastSelectedIdUsed = ctx.oInit.formEdit.lastSelectedIdUsed;\n var lastSelected = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.oInit.formEdit.lastSelectedIdUsed = lastSelected;\n\n if (lastAction !== actionType || lastSelectedIdUsed === undefined || lastSelected !== lastSelectedIdUsed) {\n return true;\n }\n }\n\n return false;\n }\n /**\r\n * Detecta los componentes RUP del formulario y los inicializa.\r\n *\r\n * @name formInitializeRUP\r\n * @function\r\n * @since UDA 5.0.2 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto de la tabla.\r\n * @param {object} row - Datos para alimentar los campos del formulario.\r\n * @param {object} form - Formulario en el que hay que inicializar los componentes.\r\n */\n\n\n function _formInitializeRUP(ctx, row, form) {\n if (ctx.oInit.colModel !== undefined && (ctx.oInit.multiSelect !== undefined || ctx.oInit.select !== undefined)) {\n $.each(ctx.oInit.colModel, function (key, column) {\n var element = form.find('[name=\"' + column.name + '\"]'); // Comprobar que es un componente RUP y editable. En caso de no ser editable, se añade la propiedad readonly.\n\n if (column.rupType && column.editable) {\n if (column.editoptions !== undefined) {\n if (column.rupType === 'combo') {\n // Si se recibe una fila con valores, se establece el valor del campo correspondiente como el registro seleccionado en el combo.\n if (row !== undefined) {\n column.editoptions.selected = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n } // Cuando no se haya definido un elemento al que hacer el append del menú del combo, se hace al \"body\" para evitar problemas de CSS.\n\n\n if (column.editoptions.appendTo === undefined) {\n column.editoptions.appendTo = 'body';\n }\n } else if (column.rupType == 'autocomplete') {\n // Establece el valor por defecto.\n if (row !== undefined) {\n column.editoptions.defaultValue = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n }\n\n if (column.editoptions.menuAppendTo === undefined) {\n // Cuando no se haya definido un elemento al que hacer el append del menú del autocomplete, se hace al \"body\" para evitar problemas de CSS.\n column.editoptions.menuAppendTo = 'body';\n }\n } else if (column.rupType === 'select') {\n // Si se recibe una fila con valores, se establece el valor del campo correspondiente como el registro seleccionado en el select.\n if (row !== undefined) {\n column.editoptions.selected = column.name.includes('.') ? $.fn.flattenJSON(row)[column.name] : row[column.name];\n }\n } // Inicializar componente.\n\n\n element['rup_' + column.rupType](column.editoptions);\n } else if (column.searchoptions === undefined) {\n console.error($.rup_utils.format(jQuery.rup.i18nParse(jQuery.rup.i18n.base, 'rup_table.errors.wrongColModel'), column.name));\n }\n } else if (!column.editable) {\n element.prop('readonly', true);\n }\n });\n }\n }\n /**\r\n * Función que gestiona el comportamiento de abrir el dialog para añadir o editar un registro.\r\n *\r\n * @name openSaveDialog\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} actionType - Es la acción que se va a ajecutar en el formulario para ir al controller, basado en rest.\r\n * @param {object} dt - Es el objeto table.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n * @param {string} customTitle - Título personalizado.\r\n *\r\n */\n\n\n DataTable.editForm.fnOpenSaveDialog = function _openSaveDialog(actionType, dt, idRow, customTitle) {\n var ctx = dt.settings()[0]; // Mostrar spinner de carga hasta que el formulario sea visible (sólo si fue activado). La segunda comprobación, evita que aparezca el spinner cuando se pagina dentro de editForm entre registros porque para ese caso, ya existe otro spinner\n\n if (ctx.oInit.formEdit.loadSpinner && $('#' + ctx.sTableId + '_detail_div_loading').length == 0) {\n $('body').append('
' + '
' + '' + '
');\n }\n\n if (idRow == null || idRow == undefined || idRow < 0) {\n idRow = 1;\n }\n\n var row;\n\n if (ctx.json !== undefined && actionType !== 'POST') {\n //si acción es add, no hace falta coger el row.\n row = ctx.json.rows[idRow];\n } // Comprobar si existe un formulario, en caso de no existir o de no contener el action requerido, lo crea\n\n\n $.when(_loadSaveDialogForm(ctx, actionType, row)).then(function () {\n var loadPromise = $.Deferred();\n var idForm = ctx.oInit.formEdit.idForm; // Limpiar los errores en caso de haberlos\n\n var feed = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_feedback');\n var divErrorFeedback = ctx.oInit.formEdit.detailForm.find('#' + feed[0].id);\n\n if (divErrorFeedback.length > 0) {\n divErrorFeedback.hide();\n } // Limpiar los elementos\n\n\n if (idForm.find('.error').length > 0) {\n idForm.rup_validate('resetElements');\n } // Botón de guardar\n\n\n var button = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save'); // Botón de guardar y continuar\n\n var buttonContinue = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_button_save_repeat');\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditBeforeInitData', ctx);\n var rowArray = $.rup_utils.jsontoarray(row);\n var title = customTitle != (undefined && null) ? customTitle : \"\"; // Actualizar el valor de la variable por si ha sufrido cambios en la función _loadSaveDialogForm() ya que en caso de ser un CLONE, habrá sido convertido a POST\n\n actionType = ctx.oInit.formEdit.actionType;\n\n if (actionType === 'PUT') {\n // Si la opción 'direct' es verdadera, no se solicita el registro a BBDD, en su lugar, se obtiene de la tabla directamente.\n if (!ctx.oInit.formEdit.direct) {\n //se obtiene el row entero de bbdd, meter parametro opcional.\n var pk = DataTable.Api().rupTable.getIdPk(row, ctx.oInit); //se evita slash en la url GET como parámetros.Formateo de fecha.\n\n var regexSlash = new RegExp('/', 'g');\n pk = pk.replace(regexSlash, '-');\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n pk = pk.replace(regex, '/');\n var ajaxOptions = {\n url: ctx.oInit.urlBase + '/' + pk,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: 'GET',\n data: [],\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: false,\n success: function success(data) {\n row = data;\n\n if (ctx.oInit.primaryKey !== undefined && ctx.oInit.primaryKey.length === 1) {\n //si hdiv esta activo.\n // Actualizar el nuevo id que viene de HDIV.\n var idHdiv = \"\" + data[ctx.oInit.primaryKey];\n\n if (pk == ctx.multiselection.lastSelectedId) {\n ctx.multiselection.lastSelectedId = idHdiv;\n }\n\n var pos = jQuery.inArray(pk, ctx.multiselection.selectedIds);\n\n if (pos >= 0) {\n ctx.multiselection.selectedIds[pos] = idHdiv;\n }\n\n var result = $.grep(ctx.multiselection.selectedRowsPerPage, function (v) {\n return v.id == pk;\n });\n\n if (result !== undefined && result.length > 0) {\n result[0].id = idHdiv;\n }\n }\n },\n error: function error(xhr) {\n var divErrorFeedback = feed; //idTableDetail.find('#'+feed[0].id + '_ok');\n\n if (divErrorFeedback.length === 0) {\n divErrorFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxGet', ctx);\n },\n complete: function complete() {\n if (ctx.oInit.formEdit.$navigationBar.funcionParams && ctx.oInit.formEdit.$navigationBar.funcionParams.length >= 4) {\n _showOnNav(dt, ctx.oInit.formEdit.$navigationBar.funcionParams[3]);\n } // Reiniciarlo para las próximas acciones.\n\n\n ctx.oInit.formEdit.$navigationBar.funcionParams = {};\n }\n };\n loadPromise = $.rup_ajax(ajaxOptions); //Se carga desde bbdd y se actualiza la fila\n\n dt.row(idRow).data(row);\n ctx.json.rows[idRow] = row; // Recrear iconos del responsive en caso de ser necesario.\n\n _addChildIcons(ctx); //Se mantiene el checked sin quitar.\n\n\n $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(idRow).find('td.select-checkbox input[type=\"checkbox\"]').prop('checked', true);\n rowArray = $.rup_utils.jsontoarray(row);\n }\n\n $.rup_utils.populateForm(rowArray, idForm);\n var multiselection = ctx.multiselection;\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), multiselection.selectedIds);\n\n if (ctx.multiselection.selectedAll) {\n //Si es selecAll recalcular el numero de los selects. Solo la primera vez es necesario.\n indexInArray = ctx.oInit.formEdit.$navigationBar.numPosition;\n }\n\n if (indexInArray === undefined) {\n indexInArray = 0;\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n }\n\n var numTotal = multiselection.numSelected;\n\n if (ctx.oInit.multiSelect === undefined) {\n numTotal = ctx.json.recordsTotal;\n indexInArray = (Number(ctx.json.page) - 1) * ctx.aBaseJson.length;\n indexInArray = indexInArray + idRow;\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterFillData', ctx);\n\n if (ctx.oInit.formEdit.$navigationBar.funcionParams == undefined || ctx.oInit.formEdit.$navigationBar.funcionParams.length == undefined) {\n _updateDetailPagination(ctx, indexInArray + 1, numTotal);\n }\n\n DataTable.Api().rupTable.selectPencil(ctx, idRow); // Se guarda el ultimo id editado.\n\n ctx.multiselection.lastSelectedId = DataTable.Api().rupTable.getIdPk(row, ctx.oInit); // Se muestra el dialog.\n\n ctx.oInit.formEdit.$navigationBar.show(); // Si no se ha definido un 'customTitle' asignamos un valor a la variable del título del formulario\n\n if (customTitle == (undefined || null)) {\n title = $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.editCaption');\n } // Comprobamos si se desea bloquear la edicion de las claves primarias\n\n\n DataTable.Api().rupTable.blockPKEdit(ctx, actionType);\n } else if (actionType === 'POST') {\n //al ser add, s elimpian los combos\n jQuery.each($('select.rup_combo', idForm), function (index, elem) {\n jQuery(elem).rup_combo('setRupValue', '');\n });\n $.rup_utils.populateForm(rowArray, idForm);\n ctx.oInit.formEdit.$navigationBar.hide(); // Si no se ha definido un 'customTitle' asignamos un valor a la variable del título del formulario\n\n if (customTitle == (undefined || null)) {\n title = $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.addCaption');\n } // Comprobamos si hay claves primarias bloqueadas y las desbloqueamos\n\n\n DataTable.Api().rupTable.blockPKEdit(ctx, actionType);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditBeforeShowForm', ctx); // Establecemos el título del formulario\n\n ctx.oInit.formEdit.detailForm.rup_dialog(ctx.oInit.formEdit.detailForm.settings);\n ctx.oInit.formEdit.detailForm.rup_dialog('setOption', 'title', title);\n ctx.oInit.formEdit.detailForm.rup_dialog('open'); // Quitar spinner de carga porque el formulario ya es visible (si fue activado)\n\n if ($('#' + ctx.sTableId + '_formEdit_dialog_loading').length > 0) {\n $('#' + ctx.sTableId + '_formEdit_dialog_loading').remove();\n } // Establecemos el foco al primer elemento input o select que se\n // encuentre habilitado en el formulario\n\n\n $(idForm[0]).find('input,select').filter(':not([readonly])').first().focus(); // Se guardan los datos originales\n\n ctx.oInit.formEdit.dataOrigin = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter);\n ctx.oInit.formEdit.okCallBack = false;\n button.off('click');\n button.on('click', function () {\n //Funcion de validacion\n if (actionType === 'PUT') {\n var customModificar = ctx.oInit.validarModificar;\n\n if (typeof customModificar === \"function\" && customModificar(ctx)) {\n return false;\n }\n } else if (actionType === 'POST') {\n var customAlta = ctx.oInit.validarAlta;\n\n if (typeof customAlta === \"function\" && customAlta(ctx)) {\n return false;\n }\n } // Comprobar si row ha sido modificada\n // Se serializa el formulario con los cambios\n\n\n row = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter); // Se transforma\n\n row = $.rup_utils.queryStringToJson(row, ctx.oInit.formEdit.serializerSplitter, ctx.oInit.formEdit.allowAllCharacters); //listas checkbox\n\n row = _addListType(idForm, row);\n\n if (actionType === 'PUT') {\n //Solo al modificar\n $.each(ctx.oInit.primaryKey, function (index, key) {\n row[key] = ctx.json.rows[idRow][key];\n });\n }\n\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Muestra un feedback de error por caracter ilegal\n\n if (!row) {\n ctx.oInit.formEdit.okCallBack = false;\n\n var _feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n\n var _divErrorFeedback = _feed;\n\n if (_divErrorFeedback.length === 0) {\n _divErrorFeedback = $('
').attr('id', _feed[0].id + '_ok').insertBefore(_feed);\n\n _divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, _divErrorFeedback, $.rup.i18nParse($.rup.i18n.base, 'rup_global.charError'), 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxNotRow', ctx);\n } else {\n var url = actionType == 'POST' ? '/add' : '/edit'; // Comprobar si se ha definido otra URL en las propiedades, en caso afirmativo, se aplica.\n\n var property = url.substring(1) + 'Url';\n\n if (ctx.oInit.formEdit[property]) {\n url = ctx.oInit.formEdit[property];\n }\n\n _callSaveAjax(actionType, dt, row, idRow, false, idTableDetail, url, false);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonSave', ctx);\n });\n ctx.oInit.formEdit.detailForm.buttonSaveContinue = buttonContinue;\n ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType = actionType;\n buttonContinue.off('click');\n buttonContinue.on('click', function () {\n //Funcion de validacion\n if (actionType === 'PUT') {\n var customModificar = ctx.oInit.validarModificarContinuar;\n\n if (typeof customModificar === \"function\" && customModificar(ctx)) {\n return false;\n }\n } else if (actionType === 'POST') {\n var customAlta = ctx.oInit.validarAltaContinuar;\n\n if (typeof customAlta === \"function\" && customAlta(ctx)) {\n return false;\n }\n }\n\n var actionSaveContinue = ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType; // Comprobar si row ha sido modificada\n // Se serializa el formulario con los cambios\n\n row = _editFormSerialize(idForm, ctx.oInit.formEdit.serializerSplitter); // Se transforma\n\n row = $.rup_utils.queryStringToJson(row, ctx.oInit.formEdit.serializerSplitter, ctx.oInit.formEdit.allowAllCharacters); //listas checkbox\n\n row = _addListType(idForm, row);\n\n if (actionType === 'PUT') {\n //Solo al modificar\n $.each(ctx.oInit.primaryKey, function (index, key) {\n row[key] = ctx.json.rows[idRow][key];\n });\n }\n\n var idTableDetail = ctx.oInit.formEdit.detailForm; // Muestra un feedback de error por caracter ilegal\n\n if (!row) {\n ctx.oInit.formEdit.okCallBack = false;\n\n var _feed2 = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n\n var _divErrorFeedback2 = _feed2;\n\n if (_divErrorFeedback2.length === 0) {\n _divErrorFeedback2 = $('
').attr('id', _feed2[0].id + '_ok').insertBefore(_feed2);\n\n _divErrorFeedback2.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, _divErrorFeedback2, $.rup.i18nParse($.rup.i18n.base, 'rup_global.charError'), 'error');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjaxNotRow', ctx);\n } else {\n var url = actionType == 'POST' ? '/add' : '/edit'; // Comprobar si se ha definido otra URL en las propiedades, en caso afirmativo, se aplica.\n\n var property = url.substring(1) + 'Url';\n\n if (ctx.oInit.formEdit[property]) {\n url = ctx.oInit.formEdit[property];\n }\n\n _callSaveAjax(actionSaveContinue, dt, row, idRow, true, idTableDetail, url, false);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableButtonSaveContinue', ctx);\n });\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddEditAfterShowForm', ctx);\n return loadPromise;\n });\n };\n /**\r\n * Llamada al servidor con los datos de edición.\r\n *\r\n * @name _callSaveAjax\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {string} actionType - Es la acción que se va a ajecutar en el formulario para ir al controller, basado en rest.\r\n * @param {object} dt - Es el objeto table.\r\n * @param {object} row - Son los datos que se cargan.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n * @param {boolean} continuar - Si es true guarda la pagina y se queda en el dialog , si es false guarda y cierra el dialog.\r\n * @param {string} idTableDetail - Identificdor del detail de la table.\r\n * @param {string} url - Url que se añade para llamar al controller.\r\n * @param {boolean} isDeleting - Evita mostrar el diálogo de confirmación porque la función _deleteAllSelects() tiene el suyo propio.\r\n *\r\n */\n\n\n function _callSaveAjax(actionType, dt, row, idRow, continuar, idTableDetail, url, isDeleting) {\n var ctx = dt.settings()[0];\n\n var _makeAjaxCall = function _makeAjaxCall() {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormBeforeCallAjax', [ctx, actionType, url]); // Añadir filtro\n\n var feed = idTableDetail.find('#' + ctx.sTableId + '_detail_feedback');\n var msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.modifyOK');\n var validaciones = ctx.oInit.formEdit.validate;\n\n if (url === '/filter?deleteAll=true' || actionType === 'DELETE') {\n msgFeedBack = $.rup.i18nParse($.rup.i18n.base, 'rup_table.deletedOK');\n\n if (validaciones !== undefined) {\n validaciones.rules = {};\n }\n }\n\n if (ctx.oInit.masterDetail !== undefined) {\n //Asegurar que se recoge el idPadre\n var masterPkObject = DataTable.Api().masterDetail.getMasterTablePkObject(ctx);\n $('#' + ctx.sTableId + '_detail_masterPK').val($('#' + ctx.sTableId + '_filter_masterPK').val());\n row = jQuery.extend(true, row, masterPkObject);\n }\n\n var ajaxOptions = {\n url: ctx.oInit.urlBase + url,\n accepts: {\n '*': '*/*',\n 'html': 'text/html',\n 'json': 'application/json, text/javascript',\n 'script': 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript',\n 'text': 'text/plain',\n 'xml': 'application/xml, text/xml'\n },\n type: actionType,\n data: row,\n dataType: 'json',\n showLoading: false,\n contentType: 'application/json',\n async: true,\n success: function success(valor) {\n ctx.oInit.formEdit.okCallBack = true;\n ctx.oInit.formEdit.lastValue = valor;\n\n if (url !== '/filter?deleteAll=true' && actionType !== 'DELETE') {\n if (continuar) {\n //Se crea un feedback_ok, para que no se pise con el de los errores\n var divOkFeedback = idTableDetail.find('#' + feed[0].id + '_ok');\n\n if (divOkFeedback.length === 0) {\n divOkFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divOkFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n _callFeedbackOk(ctx, divOkFeedback, msgFeedBack, 'ok'); //Se informa, feedback del formulario\n\n } else {\n ctx.oInit.formEdit.detailForm.rup_dialog('close');\n\n _callFeedbackOk(ctx, ctx.oInit.feedback.$feedbackContainer, msgFeedBack, 'ok'); //Se informa feedback de la tabla\n\n } // Sobrescribir valores anteriores con los recibidos desde el servidor\n\n\n row = $.extend({}, row, valor);\n\n if (actionType === 'PUT') {\n //Modificar\n dt.row(idRow).data(row); // se actualiza al editar\n\n ctx.json.rows[idRow] = row; // Actualizamos el ultimo id seleccionado (por si ha sido editado)\n\n var posicion = 0;\n $.each(ctx.multiselection.selectedRowsPerPage, function (index, p) {\n if (p.id == ctx.multiselection.lastSelectedId) {\n posicion = index;\n return;\n }\n });\n\n if (ctx.seeker !== undefined && ctx.seeker.ajaxOption.data !== undefined && ctx.seeker.ajaxOption.data.search !== undefined && ctx.seeker.search.funcionParams !== undefined && ctx.seeker.search.funcionParams.length > 0) {\n _comprobarSeeker(row, ctx, idRow);\n }\n\n ctx.multiselection.lastSelectedId = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.multiselection.selectedRowsPerPage[posicion].id = DataTable.Api().rupTable.getIdPk(row, ctx.oInit);\n ctx.oInit.feedback.type = undefined; //se recarga el type no esta definido.\n } else {\n // Asegura a cargar los nuevos IDS.\n $.each(ctx.oInit.primaryKey, function (index, key) {\n var posibleId = row[key]; // Comprueba si la primaryKey es un subcampo\n\n if (key.indexOf('.') !== -1) {\n row[key] = DataTable.Api().rupTable.getDescendantProperty(valor, key);\n } else {\n row[key] = valor[key];\n }\n\n if (row[key] === undefined) {\n row[key] = posibleId;\n }\n }); // Se actualiza la tabla temporalmente. y deja de ser post para pasar a put(edicion)\n\n if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx);\n }\n\n var rowAux = row;\n\n if (ctx.json !== undefined) {\n $.each(ctx.json.rows, function (index, r) {\n var rowNext = r;\n dt.row(index).data(rowAux);\n rowAux = rowNext;\n });\n ctx.json.rows.pop();\n ctx.json.rows.splice(0, 0, row);\n } else {\n //es el primer registro\n dt.row.add(rowAux).draw(false);\n ctx.json = {};\n ctx.json.rows = [];\n ctx.json.rows.push(rowAux);\n } // Se guardan los datos para pasar de nuevo a editable.\n\n\n if (ctx.oInit.formEdit.saveContinueEdit) {\n ctx.oInit.formEdit.detailForm.buttonSaveContinue.actionType = 'PUT';\n DataTable.Api().rupTable.blockPKEdit(ctx, 'PUT');\n } else {\n //mantener y borrar\n ctx.oInit.formEdit.idForm.resetForm();\n }\n\n ctx.oInit.formEdit.dataOrigin = _editFormSerialize(ctx.oInit.formEdit.idForm, ctx.oInit.formEdit.serializerSplitter);\n\n if (ctx.oInit.multiSelect !== undefined) {\n ctx.oInit.feedback.type = 'noBorrar';\n dt.row().multiSelect();\n } // Se actualiza la linea\n\n\n if (ctx.json.reorderedSelection !== null && ctx.json.reorderedSelection !== undefined) {\n try {\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.json.reorderedSelection[0].pageLine;\n } catch (err) {\n console.log(err.message);\n }\n }\n /* \r\n * Filtrar para colocar cada registro en su lugar correspondiente. \r\n * Si no se filtra, aparece un error visual en la selección de registros y otro en el paginador del formulario de edición.\r\n */\n\n\n dt.ajax.reload();\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAfterInsertRow', actionType, ctx);\n }\n\n if (actionType === 'PUT') {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n }, false);\n } else {\n if (ctx.oInit.multiSelect === undefined) {\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: Number(ctx.json.page),\n line: 0\n };\n ctx.multiselection.selectedRowsPerPage[0] = arra;\n DataTable.Api().select.drawSelectId(ctx);\n }\n\n $('#' + ctx.sTableId).trigger('tableAddFormSuccessCallSaveAjax', actionType, ctx);\n }\n } else {\n // Eliminar\n ctx.oInit.feedback.type = 'eliminar';\n ctx.oInit.feedback.msgFeedBack = msgFeedBack;\n\n if (ctx.oInit.multiSelect !== undefined) {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n DataTable.Api().multiSelect.deselectAll(dt);\n }, false);\n } else if (ctx.oInit.select !== undefined) {\n dt.ajax.reload(function () {\n $('#' + ctx.sTableId).trigger('tableEditFormSuccessCallSaveAjax', actionType, ctx);\n DataTable.Api().select.deselect(ctx);\n }, false);\n }\n\n _callFeedbackOk(ctx, ctx.oInit.feedback.$feedbackContainer, msgFeedBack, 'ok'); //Se informa feedback de la tabla\n\n }\n },\n complete: function complete() {\n $('#' + ctx.sTableId).triggerHandler('tableEditFormCompleteCallSaveAjax', actionType, ctx);\n },\n error: function error(xhr) {\n var divErrorFeedback; // Si es una petición de tipo DELETE o no existe la referencia al feedback de editForm, el feedback utilizado será el de la tabla, en los demás casos, se usará el del editForm.\n\n if (actionType === 'DELETE' || feed[0] == undefined) {\n divErrorFeedback = ctx.oInit.feedback.$feedbackContainer;\n } else {\n divErrorFeedback = idTableDetail.find('#' + feed[0].id + '_ok');\n }\n\n if (divErrorFeedback.length === 0) {\n divErrorFeedback = $('
').attr('id', feed[0].id + '_ok').insertBefore(feed);\n divErrorFeedback.rup_feedback(ctx.oInit.feedback);\n }\n\n if (xhr.status === 406 && xhr.responseText !== '') {\n try {\n var responseJSON = JSON.parse(xhr.responseText);\n\n if (responseJSON.rupErrorFields) {\n if (responseJSON.rupErrorFields !== undefined || responseJSON.rupFeedback !== undefined) {\n var $form = ctx.oInit.formEdit.idForm;\n $form.validate().submitted = $.extend(true, $form.validate().submitted, responseJSON.rupErrorFields);\n $form.validate().invalid = responseJSON.rupErrorFields;\n $form.validate().showErrors(responseJSON.rupErrorFields);\n } else if (errors.rupFeedback !== undefined) {\n var mensajeJSON = $.rup_utils.printMsg(responseJSON.rupFeedback.message);\n\n _callFeedbackOk(ctx, divErrorFeedback, mensajeJSON, 'error');\n }\n }\n } catch (e) {\n // El mensaje NO es JSON\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n }\n } else {\n //cualquier error se devuelve el texto\n _callFeedbackOk(ctx, divErrorFeedback, xhr.responseText, 'error');\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormErrorCallSaveAjax', actionType, ctx);\n },\n validate: validaciones,\n feedback: feed.rup_feedback({\n type: 'error',\n block: false\n })\n }; // Se cambia el data\n\n if (ajaxOptions.data == '') {\n delete ajaxOptions.data;\n $.rup_ajax(ajaxOptions);\n } else if (isDeleting || ctx.oInit.formEdit.idForm.valid()) {\n // Obtener el valor del parámetro HDIV_STATE (en caso de no estar disponible se devolverá vacío) siempre y cuando no se trate de un deleteAll porque en ese caso ya lo contiene el filtro\n if (url.indexOf('filter?deleteAll=true') === -1) {\n // Elimina los campos _label generados por los autocompletes que no forman parte de la entidad\n $.fn.deleteAutocompleteLabelFromObject(ajaxOptions.data); // Elimina los campos autogenerados por los multicombos que no forman parte de la entidad\n\n $.fn.deleteMulticomboLabelFromObject(ajaxOptions.data, ctx.oInit.formEdit.detailForm);\n var hdivStateParamValue = $.fn.getHDIV_STATE(undefined, ctx.oInit.formEdit.idForm);\n\n if (hdivStateParamValue !== '') {\n ajaxOptions.data._HDIV_STATE_ = hdivStateParamValue;\n } // Comprueba si debe enviarse como multipart.\n\n\n if (ctx.oInit.formEdit.multipart === true) {\n ajaxOptions.enctype = 'multipart/form-data';\n ajaxOptions.processData = false;\n ajaxOptions.contentType = false;\n var formData = new FormData();\n $.each(ajaxOptions.data, function (key, value) {\n var field = ctx.oInit.formEdit.idForm.find('input[type=\"file\"][name=\"' + key + '\"]'); // Gestiona el guardado de ficheros.\n\n if (field.length != 0 && field.prop('files').length > 0) {\n $.each(field.prop('files'), function (fileIndex, fileValue) {\n formData.append(key, fileValue);\n });\n } else {\n formData.append(key, value);\n }\n });\n ajaxOptions.data = formData;\n }\n }\n\n if (ajaxOptions.enctype != 'multipart/form-data') {\n ajaxOptions.data = JSON.stringify(ajaxOptions.data);\n }\n\n $.rup_ajax(ajaxOptions);\n }\n };\n\n if (ctx.oInit.formEdit.detailForm.settings.saveDialog && !isDeleting) {\n $.rup_messages('msgConfirm', {\n title: actionType == 'POST' ? $.rup.i18nParse($.rup.i18n.base, 'rup_table.add.save') : $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.save'),\n message: actionType == 'POST' ? $.rup.i18nParse($.rup.i18n.base, 'rup_table.add.saveData') : $.rup.i18nParse($.rup.i18n.base, 'rup_table.edit.saveData'),\n OKFunction: function OKFunction() {\n _makeAjaxCall();\n\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: function CANCELFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageCancel', ctx);\n },\n CLOSEFunction: function CLOSEFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageClose', ctx);\n }\n });\n } else {\n _makeAjaxCall();\n }\n }\n /**\r\n * Llamada para crear el feedback dentro del dialog.\r\n *\r\n * @name callFeedbackOk\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {object} feedback - Div donde se va ejecutar el feedback.\r\n * @param {string} msgFeedBack - Mensaje para el feedback.\r\n * @param {string} type - Tipos del feedback, mirar en el rup.feedback..\r\n *\r\n */\n\n\n function _callFeedbackOk(ctx, feedback, msgFeedBack, type) {\n if (ctx.oInit.formEdit.disabledFeedback) {\n //no muestra el feedback\n return false;\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormFeedbackShow', ctx);\n feedback.rup_feedback('set', msgFeedBack, type);\n feedback.rup_feedback('show');\n }\n /**\r\n * Se añade el tipo de la lista.\r\n *\r\n * @name addListType\r\n * @function\r\n * @since UDA 4.2.0 // Table 1.0.0\r\n *\r\n * @param {object} idForm - Identificador del formulario.\r\n * @param {string} row - Values ya añadidos al formulario.\r\n *\r\n */\n\n\n function _addListType(idForm, row) {\n //Listas de checkbox\n $.each(idForm.find('[data-lista]'), function () {\n var name = this.dataset.lista;\n var prop = '';\n var propSplit = this.name.split(\".\");\n\n if (propSplit !== undefined && propSplit.length === 2) {\n prop = propSplit[1];\n }\n\n if (row[name] === undefined || !Array.isArray(row[name])) {\n //si no existe se crea o // si no es de tipo array\n row[name] = [];\n }\n\n var array = {};\n\n if (prop !== undefined) {\n var clave = this.dataset.clave;\n\n if (clave !== undefined) {\n //si tiene clave es porque es objeto\n var label = this.dataset.valor; //se manda el valor id.\n\n array[clave] = label;\n array[prop] = $(this).is(':checked');\n } else {\n //si no tiene clave es porque es string\n array = $(this).is(':checked');\n }\n\n row[name].push(array);\n }\n }); //Se buscan los array para que sean listas.combos con multiselect\n\n $.each(row, function (name) {\n if (this !== undefined && this.toString() === '[object Object]') {\n if ($.rup_utils.isNumeric(Object.keys(this)[0])) {\n //se asegura, que no es una lista de objetos.\n row[name] = Object.values(this);\n }\n }\n });\n return row;\n }\n /**\r\n * Actualiza la navegación del dialogo.\r\n *\r\n * @name updateDetailPagination\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} currentRowNum - Número de la posición actual del registro selecionado.\r\n * @param {integer} totalRowNum - Número total de registros seleccionados.\r\n *\r\n */\n\n\n function _updateDetailPagination(ctx, currentRowNum, totalRowNum) {\n var tableId = ctx.oInit.formEdit.$navigationBar[0].id;\n\n if (currentRowNum === 1 || currentRowNum === totalRowNum) {\n var focusedElement = document.activeElement; // Eliminar foco del elemento porque va a ser deshabilitado a continuación\n\n if ($(ctx.oInit.formEdit.detailForm).find(focusedElement).length > 0) {\n focusedElement.blur();\n }\n }\n\n if (currentRowNum === 1) {\n $('#first_' + tableId + ', #back_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', true);\n } else {\n $('#first_' + tableId + ', #back_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', false);\n }\n\n if (currentRowNum === totalRowNum) {\n $('#forward_' + tableId + ', #last_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', true);\n } else {\n $('#forward_' + tableId + ', #last_' + tableId, ctx.oInit.formEdit.detailForm).prop('disabled', false);\n }\n\n $('#rup_table_selectedElements_' + tableId).text($.rup_utils.format(jQuery.rup.i18nParse(jQuery.rup.i18n.base, 'rup_table.defaults.detailForm_pager'), currentRowNum, totalRowNum));\n }\n /**\r\n * Constructor de la barra de navegación.\r\n *\r\n * @name callNavigatorBar\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _callNavigationBar(dt) {\n var ctx = dt.settings()[0];\n ctx.oInit._ADAPTER = $.rup.adapter[jQuery.fn.rup_table.defaults.adapter];\n ctx.oInit.formEdit.$navigationBar = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_navigation');\n var settings = {}; // Funcion para obtener los parametros de navegacion.\n\n settings.fncGetNavigationParams = function getNavigationParams_multiselection(linkType) {\n var execute = false,\n changePage = false,\n index = 0,\n newPageIndex = 0,\n npos = ctx.oInit.formEdit.$navigationBar.currentPos,\n page = dt.page() + 1,\n newPage = page,\n lastPage = ctx.json.total;\n var multiselection = ctx.multiselection;\n var rowSelected;\n\n switch (linkType) {\n case 'first':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n rowSelected = multiselection.selectedRowsPerPage[0];\n rowSelected.indexSelected = 0;\n } else {\n // En el caso de que se hayan seleccionado todos los elementos de la tabla\n // Recorremos las páginas buscando la primera en la que existan elementos seleccionados\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getNextPageSelected(ctx, 1, 'next');\n\n if (Number(rowSelected.page) === page) {\n //Si es la misma pagina.buscar la linea\n rowSelected.line = _getLineByPageSelected(ctx, -1);\n } else {\n rowSelected.line = 0; // luego hay que buscar la linea\n }\n }\n\n break;\n\n case 'prev':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexPrev = ctx.oInit.formEdit.$navigationBar.currentPos.indexSelected - 1;\n rowSelected = multiselection.selectedRowsPerPage[indexPrev];\n rowSelected.indexSelected = indexPrev;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition--;\n\n var linea = _getLineByPageSelectedReverse(ctx, ctx.oInit.formEdit.$navigationBar.currentPos.line);\n\n if (linea === -1) {\n //Es que hay que cambiar de pagina.\n //buscarPAgina.\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getPrevPageSelected(ctx, page - 1);\n } else {\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n }\n }\n\n break;\n\n case 'next':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexNext = ctx.oInit.formEdit.$navigationBar.currentPos.indexSelected + 1;\n rowSelected = multiselection.selectedRowsPerPage[indexNext];\n rowSelected.indexSelected = indexNext;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition++; //2 casos: Si hay que navegar o no.\n\n var lineaNext = _getLineByPageSelected(ctx, ctx.oInit.formEdit.$navigationBar.currentPos.line);\n\n if (lineaNext === -1) {\n //Es que hay que cambiar de pagina.\n //buscarPAgina.\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getNextPageSelected(ctx, page + 1, 'next');\n rowSelected.line = 0; // luego hay que buscar la linea\n } else {\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n }\n }\n\n break;\n\n case 'last':\n // Si no se han seleccionado todos los elementos\n if (!multiselection.selectedAll) {\n var indexLast = multiselection.selectedRowsPerPage.length - 1;\n rowSelected = multiselection.selectedRowsPerPage[indexLast];\n rowSelected.indexSelected = indexLast;\n } else {\n ctx.oInit.formEdit.$navigationBar.numPosition = ctx.multiselection.numSelected - 1;\n rowSelected = ctx.oInit.formEdit.$navigationBar.currentPos;\n rowSelected.page = _getPrevPageSelected(ctx, lastPage);\n\n if (Number(rowSelected.page) === page) {\n //Si es la misma pagina.buscar la linea\n rowSelected.line = _getLineByPageSelectedReverse(ctx, ctx.aBaseJson.length);\n }\n }\n\n }\n\n _hideOnNav(dt, linkType, function () {\n var tableId = ctx.sTableId;\n\n if (Number(rowSelected.page) !== page) {\n var table = $('#' + tableId).DataTable();\n table.page(rowSelected.page - 1).draw('page'); // Se añaden los parámetros para luego ejecutar la función del dialog\n\n ctx.oInit.formEdit.$navigationBar.funcionParams = ['PUT', dt, rowSelected.line, linkType];\n } else {\n // Llamar directamente a la función\n $.when(DataTable.editForm.fnOpenSaveDialog('PUT', dt, rowSelected.line, ctx.oInit.formEdit.customTitle)).then(function () {\n _showOnNav(dt, linkType);\n }); // Solventar problemas de los componentes combo y autocomplete en los formularios de edición.\n\n _fixComboAutocompleteOnEditForm(ctx);\n }\n\n $('#first_' + tableId + '_detail_navigation' + ', #back_' + tableId + '_detail_navigation' + ', #forward_' + tableId + '_detail_navigation' + ', #last_' + tableId + '_detail_navigation', ctx.oInit.formEdit.detailForm).prop('disabled', true);\n }); // Actualizar la última posición movida\n\n\n ctx.oInit.formEdit.$navigationBar.currentPos = rowSelected;\n return [linkType, execute, changePage, index - 1, npos, newPage, newPageIndex - 1];\n };\n\n ctx.oInit.formEdit.$navigationBar.data('settings', settings);\n\n var barraNavegacion = ctx.oInit._ADAPTER.createDetailNavigation.bind(ctx.oInit.formEdit.$navigationBar);\n\n ctx.oInit.formEdit.$navigationBar.append(barraNavegacion);\n }\n\n function _fixComboAutocompleteOnEditForm(ctx) {\n // Solventar problemas de los componentes combo y autocomplete en los formularios de edición.\n if (ctx.oInit.colModel !== undefined) {\n $.each(ctx.oInit.colModel, function (key, column) {\n if (column.editable) {\n if (column.rupType === 'combo') {\n // Realizar una limpieza total para asegurar un buen funcionamiento.\n ctx.oInit.formEdit.idForm.find('[name=\"' + column.name + '\"]')['rup_combo']('hardReset');\n } else if (column.rupType === 'autocomplete') {\n // Establecer el valor por defecto del componente.\n var newDefaultValue = ctx.json.rows.find(function (row) {\n return row.id === ctx.oInit.formEdit.$navigationBar.currentPos.id;\n })[column.name];\n column.editoptions.defaultValue = newDefaultValue;\n ctx.oInit.formEdit.idForm.find('[name=\"' + column.name + '\"]').data('rup.autocomplete').$labelField.data('settings').defaultValue = newDefaultValue;\n }\n }\n });\n }\n }\n\n function _hideOnNav(dt, linkType, callback) {\n var ctx = dt.settings()[0];\n var direction = linkType === 'prev' || linkType === 'first' ? 'right' : 'left';\n var $dialogContent = $('#' + ctx.sTableId + '_detail_div .dialog-content-material');\n $dialogContent.parent().css('overflow-x', 'hidden');\n $dialogContent.hide('slide', {\n direction: direction\n }, 100, function () {\n $dialogContent.after('');\n callback();\n });\n }\n\n function _showOnNav(dt, linkType) {\n var ctx = dt.settings()[0];\n var direction = linkType === 'prev' || linkType === 'first' ? 'left' : 'right';\n var $dialogContent = $('#' + ctx.sTableId + '_detail_div .dialog-content-material');\n $('#' + ctx.sTableId + '_detail_div_loading').remove();\n $dialogContent.show('slide', {\n direction: direction\n }, 100, function () {\n $dialogContent.parent().css('overflow-x', 'auto');\n });\n }\n /**\r\n * Constructor de la barra de navegación.\r\n *\r\n * @name callNavigatorSelectBar\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _callNavigationSelectBar(dt) {\n var ctx = dt.settings()[0];\n ctx.oInit._ADAPTER = $.rup.adapter[jQuery.fn.rup_table.defaults.adapter];\n ctx.oInit.formEdit.$navigationBar = ctx.oInit.formEdit.detailForm.find('#' + ctx.sTableId + '_detail_navigation');\n var settings = {}; // Funcion para obtener los parametros de navegacion.\n\n settings.fncGetNavigationParams = function getNavigationParams_multiselection(linkType) {\n var execute = false,\n changePage = false,\n index = 0,\n newPageIndex = 0,\n npos = ctx.oInit.formEdit.$navigationBar.currentPos,\n page = dt.page() + 1,\n newPage = page,\n lastPage = ctx.json.total;\n var futurePage = page;\n\n switch (linkType) {\n case 'first':\n futurePage = 1;\n ctx.multiselection.selectedRowsPerPage[0].line = 0;\n break;\n\n case 'prev':\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.multiselection.selectedRowsPerPage[0].line - 1;\n\n if (ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line] === undefined) {\n futurePage = futurePage - 1;\n }\n\n break;\n\n case 'next':\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.multiselection.selectedRowsPerPage[0].line + 1;\n\n if (ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line] === undefined) {\n futurePage = futurePage + 1;\n }\n\n break;\n\n case 'last':\n futurePage = lastPage;\n ctx.multiselection.selectedRowsPerPage[0].line = ctx.json.rows.length - 1;\n } // Cambio de pagina\n\n\n if (Number(futurePage) !== page) {\n var table = $('#' + ctx.sTableId).DataTable();\n ctx.select.selectedRowsPerPage = {};\n ctx.select.selectedRowsPerPage.cambio = linkType;\n ctx.select.selectedRowsPerPage.page = futurePage;\n table.page(futurePage - 1).draw('page');\n } else {\n //Si no se pagina se abre directamente la funcion.\n DataTable.editForm.fnOpenSaveDialog('PUT', dt, ctx.multiselection.selectedRowsPerPage[0].line, ctx.oInit.formEdit.customTitle);\n var rowSelectAux = ctx.json.rows[ctx.multiselection.selectedRowsPerPage[0].line];\n ctx.multiselection.selectedRowsPerPage[0].id = DataTable.Api().rupTable.getIdPk(rowSelectAux, ctx.oInit);\n DataTable.Api().select.deselect(ctx);\n DataTable.Api().select.drawSelectId(ctx);\n } //Se actualiza la ultima posicion movida.\n //ctx.oInit.formEdit.$navigationBar.currentPos = rowSelected;\n\n\n var tableId = ctx.sTableId;\n $('#first_' + tableId + '_detail_navigation' + ', #back_' + tableId + '_detail_navigation' + ', #forward_' + tableId + '_detail_navigation' + ', #last_' + tableId + '_detail_navigation', ctx.oInit.formEdit.detailForm).prop('disabled', true);\n return [linkType, execute, changePage, index - 1, npos, newPage, newPageIndex - 1];\n };\n\n ctx.oInit.formEdit.$navigationBar.data('settings', settings);\n\n var barraNavegacion = ctx.oInit._ADAPTER.createDetailNavigation.bind(ctx.oInit.formEdit.$navigationBar);\n\n ctx.oInit.formEdit.$navigationBar.append(barraNavegacion);\n }\n /**\r\n * Método que obtiene la fila siguiente seleccionada.\r\n *\r\n * @name getRowSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Instancia de la tabla.\r\n * @param {string} actionType - Acción a ajecutar en el formulario para ir al controller, basado en REST.\r\n *\r\n * @return {object} Contiene el identificador, la página y la línea de la fila seleccionada.\r\n *\r\n */\n\n\n function _getRowSelected(dt, actionType) {\n var ctx = dt.settings()[0];\n var rowDefault = {\n id: 0,\n page: 1,\n line: 0\n };\n var lastSelectedId = ctx.multiselection.lastSelectedId;\n\n if (!ctx.multiselection.selectedAll) {\n $.each(ctx.multiselection.selectedRowsPerPage, function (index, p) {\n if (p.id == ctx.multiselection.lastSelectedId) {\n rowDefault.id = p.id;\n rowDefault.page = p.page;\n rowDefault.line = p.line;\n rowDefault.indexSelected = index;\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = rowDefault;\n }\n\n return false;\n }\n });\n } else {\n if (ctx.oInit.formEdit !== undefined) {\n // Indica los mostrados cuando es selectAll y no se puede calcular. El inicio es 0.\n ctx.oInit.formEdit.$navigationBar.numPosition = 0;\n }\n\n if (lastSelectedId === undefined || lastSelectedId === '') {\n // Como arranca de primeras, la página es la 1\n rowDefault.page = _getNextPageSelected(ctx, 1, 'next');\n rowDefault.line = _getLineByPageSelected(ctx, -1);\n } else {\n // Buscar la posición y la página\n var result = $.grep(ctx.multiselection.selectedRowsPerPage, function (v) {\n return v.id == ctx.multiselection.lastSelectedId;\n });\n rowDefault.page = result[0].page;\n rowDefault.line = result[0].line;\n var index = ctx._iDisplayLength * (Number(rowDefault.page) - 1);\n index = index + 1 + rowDefault.line; // Restar los deselecionados\n\n result = $.grep(ctx.multiselection.deselectedRowsPerPage, function (v) {\n return Number(v.page) < Number(rowDefault.page) || Number(rowDefault.page) === Number(v.page) && Number(v.line) < Number(rowDefault.line);\n }); // Buscar índice\n\n rowDefault.indexSelected = index - result.length;\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.numPosition = rowDefault.indexSelected - 1;\n }\n }\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = rowDefault;\n }\n } // En caso de estar en una página distinta, navegamos a ella\n\n\n if (dt.page() + 1 !== Number(rowDefault.page)) {\n var pageActual = dt.page() + 1;\n var table = $('#' + ctx.sTableId).DataTable();\n table.page(rowDefault.page - 1).draw('page');\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.funcionParams = [actionType, dt, rowDefault.line, undefined, pageActual];\n }\n }\n\n return rowDefault;\n }\n /**\r\n * Metodo que obtiene la página siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getNextPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} pageInit - Página a partir de la cual hay que mirar, en general serà la 1.\r\n * @param {string} orden - Pueder ser pre o next, en función de si necesitar ir hacia adelante o hacia atrás.\r\n *\r\n * @return integer - devuelve la página\r\n *\r\n */\n\n\n function _getNextPageSelected(ctx, pageInit, orden) {\n var pagina = pageInit;\n var pageTotals = ctx.json.total;\n\n if (orden === 'prev') {\n //Si es previo se resta.\n pageTotals = 1;\n }\n\n if (ctx.multiselection.deselectedRowsPerPage.length > 0) {\n var maxPagina = ctx.json.rows.length;\n var count = 0; //Buscar la pagina donde va estar el seleccionado.\n\n for (var page = pageInit; page < pageTotals;) {\n $.each(ctx.multiselection.deselectedRowsPerPage, function (index, p) {\n if (page === Number(p.page)) {\n count++;\n }\n\n if (count === maxPagina) {\n return false;\n }\n });\n\n if (count < maxPagina) {\n pagina = page;\n page = ctx.json.total; //Se pone el total para salir del bucle.\n }\n\n count = 0;\n\n if (orden === 'next') {\n page++;\n } else if (orden === 'prev') {\n page--;\n }\n }\n }\n\n return pagina;\n }\n /**\r\n * Metodo que obtiene la página siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getPrevPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} pageInit - Página a partir de la cual hay que mirar, en general serà la 1.\r\n *\r\n * @return integer - devuele la página\r\n *\r\n */\n\n\n function _getPrevPageSelected(ctx, pageInit) {\n var pagina = pageInit;\n var pageTotals = 1;\n\n if (ctx.multiselection.deselectedRowsPerPage.length > 0) {\n var maxPagina = ctx.json.rows.length;\n\n if (ctx.json.total === pagina) {\n //Es ultima pagina, calcular los registros{\n maxPagina = ctx.json.records % ctx._iDisplayLength;\n }\n\n var count = 0; //Buscar la pagina donde va estar el seleccionado.\n\n for (var page = pageInit; pageTotals <= page;) {\n $.each(ctx.multiselection.deselectedRowsPerPage, function (index, p) {\n if (Number(page) === Number(p.page)) {\n count++;\n }\n\n if (count === maxPagina) {\n return false;\n }\n });\n\n if (count < maxPagina) {\n pagina = page;\n pageTotals = ctx.json.total; //Se pone el total para salir del bucle.\n }\n\n count = 0;\n page--;\n }\n }\n\n return pagina;\n }\n /**\r\n * Metodo que obtiene la linea siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getLineByPageSelected\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} lineInit - Linea a partir de la cual hay que mirar, en general será la 1.\r\n *\r\n * @return integer - devuele la linea\r\n *\r\n */\n\n\n function _getLineByPageSelected(ctx, lineInit) {\n var line = -1;\n var rows = ctx.json.rows;\n $.each(rows, function (index, row) {\n if (index > lineInit) {\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), ctx.multiselection.deselectedIds);\n\n if (indexInArray === -1) {\n line = index;\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: ctx.json.page,\n line: index\n };\n\n if (ctx.oInit.formEdit !== undefined) {\n ctx.oInit.formEdit.$navigationBar.currentPos = arra;\n }\n\n return false;\n }\n }\n });\n return line;\n }\n /**\r\n * Metodo que obtiene la última linea siguiente donde esta el primer elemento o elemento seleccionado.\r\n *\r\n * @name getLineByPageSelectedReverse\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} lineInit - Linea a partir de la cual hay que mirar.\r\n *\r\n * @return integer - devuele la linea\r\n *\r\n */\n\n\n function _getLineByPageSelectedReverse(ctx, lineInit) {\n var line = -1;\n var rows = ctx.json.rows;\n\n for (var index = rows.length - 1; index >= 0; index--) {\n var row = rows[index];\n\n if (index < lineInit) {\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), ctx.multiselection.deselectedIds);\n\n if (indexInArray === -1) {\n line = index;\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: ctx.json.page,\n line: index\n };\n ctx.oInit.formEdit.$navigationBar.currentPos = arra;\n index = -1;\n }\n }\n }\n\n return line;\n }\n /**\r\n * Metodo que elimina todos los registros seleccionados.\r\n *\r\n * @name _deleteAllSelects\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _deleteAllSelects(dt) {\n var ctx = dt.settings()[0];\n var idRow = 0;\n var regex = new RegExp(ctx.oInit.multiplePkToken, 'g');\n var actionType = ctx.multiselection.selectedIds.length > 1 ? 'POST' : 'DELETE';\n\n var _doDelete = function _doDelete() {\n var row = {};\n row.filter = window.form2object(ctx.oInit.filter.$filterContainer[0]);\n\n if (ctx.multiselection.selectedIds.length > 1) {\n row.core = {\n 'pkToken': ctx.oInit.multiplePkToken,\n 'pkNames': ctx.oInit.primaryKey\n };\n row.multiselection = {};\n row.multiselection.selectedAll = ctx.multiselection.selectedAll;\n\n if (row.multiselection.selectedAll) {\n row.multiselection.selectedIds = ctx.multiselection.deselectedIds;\n } else {\n row.multiselection.selectedIds = ctx.multiselection.selectedIds;\n }\n\n _callSaveAjax(actionType, dt, row, idRow, false, ctx.oInit.formEdit.detailForm, '/filter?deleteAll=true', true);\n } else {\n row = ctx.multiselection.selectedIds[0];\n row = row.replace(regex, '/');\n\n _callSaveAjax(actionType, dt, '', idRow, false, ctx.oInit.formEdit.detailForm, '/' + row, true);\n }\n };\n\n if (ctx.oInit.formEdit.detailForm.settings.deleteDialog) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.deleteAll'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.delete'),\n OKFunction: function OKFunction() {\n _doDelete();\n\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: ctx.oInit.formEdit.cancelDeleteFunction\n });\n } else {\n _doDelete();\n }\n }\n /**\r\n * Método que serializa los datos del formulario.\r\n *\r\n * @name _editFormSerialize\r\n * @function\r\n * @since UDA 3.6.0 // Table 1.2.0\r\n *\r\n * @param {object} idForm - Formulario que alberga los datos.\r\n * @param {string} [serializerSplitter=&] - Cadena a usar para separar los campos.\r\n *\r\n * @return {string} - Devuelve los datos del formulario serializados\r\n *\r\n */\n\n\n function _editFormSerialize(idForm) {\n var serializerSplitter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '&';\n var serializedForm = '';\n var idFormArray = idForm.formToArray();\n var ultimo = '';\n var count = 0;\n $.each(idFormArray, function (key, obj) {\n if (ultimo != obj.name) {\n count = 0;\n }\n\n var valor = '';\n\n if ($(idForm).find('[name=\"' + obj.name + '\"]').prop('multiple')) {\n valor = '[' + count++ + ']';\n } else if (ultimo === obj.name) {\n //Se mete como lista\n //se hace replace del primer valor\n serializedForm = serializedForm.replace(ultimo + '=', ultimo + '[' + count++ + ']=');\n valor = '[' + count++ + ']'; //y se mete el array\n }\n\n serializedForm += obj.name + valor + '=' + obj.value;\n serializedForm += serializerSplitter;\n ultimo = obj.name;\n }); // Evitar que el último carácter sea \"&\" o el separador definido por el usuario.\n\n serializedForm = serializedForm.substring(0, serializedForm.length - serializerSplitter.length);\n return serializedForm;\n }\n /**\r\n * Metodo que comprueba el seeker.\r\n *\r\n * @name _comprobarSeeker\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} row - Son los datos que se cargan.\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {number} idRow - Identificador de la fila.\r\n *\r\n */\n\n\n function _comprobarSeeker(row, ctx, idRow) {\n var cumple = true;\n $.each(ctx.seeker.ajaxOption.data.search, function (key, obj) {\n if (row[key].indexOf(obj) === -1) {\n cumple = false;\n return false;\n }\n });\n\n if (!cumple) {\n // eliminar del seeker, por pagina y linea\t\t\n ctx.seeker.search.funcionParams = jQuery.grep(ctx.seeker.search.funcionParams, function (search) {\n return search.page !== Number(ctx.json.page) || search.pageLine !== idRow + 1;\n }); // se borra el icono\n\n $('#' + ctx.sTableId + ' tbody tr').eq(idRow).find('td.select-checkbox i.filtered-row').remove();\n $('#' + ctx.sTableId + ' tbody tr').eq(idRow).find('td i.filtered-row').remove();\n DataTable.Api().seeker.updateDetailSeekPagination(1, ctx.seeker.search.funcionParams.length, ctx);\n }\n }\n /**\r\n * Método que gestiona el bloqueo de la edición de las claves primarias.\r\n *\r\n * @name _blockPKeditForm\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {string} actionType - Método de operación CRUD.\r\n *\r\n */\n\n\n function _blockPKeditForm(ctx, actionType) {\n var blockPK = ctx.oInit.blockPKeditForm;\n var idForm = ctx.oInit.formEdit.idForm;\n\n if (blockPK) {\n // En caso de ser edición bloqueamos la modificación\n if (actionType === 'PUT') {\n $.each(ctx.oInit.primaryKey, function (key, id) {\n var input = $(idForm[0]).find(':input[name=\\'' + id + '\\']'); // Comprobamos si es un componente rup o no. En caso de serlo usamos el metodo disable.\n\n if (input.attr('ruptype') === 'date' && !input.rup_date('isDisabled')) {\n input.rup_date('disable');\n } else if (input.attr('ruptype') === 'combo' && !input.rup_combo('isDisabled')) {\n input.rup_combo('disable');\n } else if (input.attr('ruptype') === 'select' && !input.rup_select('isDisabled')) {\n input.rup_select('disable');\n } else if (input.attr('ruptype') === 'time' && !input.rup_time('isDisabled')) {\n input.rup_time('disable');\n } else if (input.attr('type') === 'checkbox') {\n if (!input.hasClass('checkboxPKBloqueado')) {\n input.addClass('checkboxPKBloqueado');\n }\n\n var valorCheck = input.is(':checked') ? 1 : 0;\n var selectorInputSustituto = $('#' + id + '_bloqueado'); // Comprobamos si es necesario cambiar el check\n\n if (selectorInputSustituto.attr('valor') !== valorCheck) {\n if (selectorInputSustituto.attr('valor') !== undefined) {\n selectorInputSustituto.remove();\n }\n\n if (valorCheck === 1) {\n input.after('');\n } else {\n input.after('');\n }\n }\n } else {\n input.prop('readOnly', true);\n } // Quitamos el foco del elemento\n\n\n input.on('mousedown', function (event) {\n event.preventDefault();\n });\n });\n } // En caso de ser clonación permitimos la edición\n else if (actionType === 'POST') {\n $.each(ctx.oInit.primaryKey, function (key, id) {\n var input = $(idForm[0]).find(':input[name=\\'' + id + '\\']'); // Comprobamos si es un componente rup o no. En caso de serlo usamos el metodo enable.\n\n if (input.attr('ruptype') === 'date' && input.rup_date('isDisabled')) {\n input.rup_date('enable');\n } else if (input.attr('ruptype') === 'combo' && input.rup_combo('isDisabled')) {\n input.rup_combo('enable');\n } else if (input.attr('ruptype') === 'select' && input.rup_select('isDisabled')) {\n input.rup_select('enable');\n } else if (input.attr('ruptype') === 'time' && input.rup_time('isDisabled')) {\n input.rup_time('enable');\n } else if (input.attr('type') === 'checkbox') {\n input.removeClass('checkboxPKBloqueado');\n $('#' + id + '_bloqueado').remove();\n } else {\n input.prop('readOnly', false);\n } // Devolvemos el foco al elemento\n\n\n input.on('mousedown', function (event) {\n $(this).off(event.preventDefault());\n input.focus();\n });\n });\n }\n }\n }\n /**\r\n * Se añaden los iconos al responsive.\r\n *\r\n * @name _addChildIcons\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _addChildIcons(ctx) {\n try {\n var hasHidden = false;\n\n var columnsVisiblity = ctx.responsive._columnsVisiblity();\n\n for (var i = 0; i < columnsVisiblity.length; i++) {\n if (!columnsVisiblity[i]) {\n if (!ctx.aoColumns[i].className || ctx.aoColumns[i].className.indexOf('never') < 0) {\n hasHidden = true;\n }\n }\n }\n\n if (ctx.responsive.c.details.target === 'td span.openResponsive') {\n //por defecto\n $('#' + ctx.sTableId).find('tbody td:first-child span.openResponsive').remove();\n\n if (hasHidden) {\n //añadir span ala primera fila\n $.each($('#' + ctx.sTableId).find('tbody td:first-child:not(.child):not(.dataTables_empty)'), function () {\n var $span = $('');\n\n if ($(this).find('span.openResponsive').length === 0) {\n $(this).prepend($span.addClass('openResponsive'));\n } else {\n //si ya existe se asigna el valor.\n $span = $(this).find('span.openResponsive');\n }\n\n if ($(this).parent().next().hasClass('child')) {\n $span.addClass('closeResponsive');\n }\n\n var $fila = $(this).parent();\n $span.click(function (event) {\n if ($fila.hasClass('editable') && $fila.find('.closeResponsive').length) {\n //no se hace nada. si esta editando\n event.stopPropagation();\n } else {\n if ($span.hasClass('closeResponsive')) {\n $span.removeClass('closeResponsive');\n } else {\n $span.addClass('closeResponsive');\n }\n }\n });\n });\n }\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditFormAddChildIcons', ctx);\n } catch (error) {}\n }\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * DataTables API\r\n *\r\n * For complete documentation, please refer to the docs/api directory or the\r\n * DataTables site\r\n */\n // Local variables to improve compression\n\n\n var apiRegister = DataTable.Api.register; // Se declara la variable de editForm para que pueda ser invocada desde cualquier sitio\n\n apiRegister('editForm.openSaveDialog()', function (actionType, dt, idRow, customTitle) {\n DataTable.editForm.fnOpenSaveDialog(actionType, dt, idRow, customTitle);\n });\n apiRegister('editForm.updateDetailPagination()', function (ctx, currentRowNum, totalRowNum) {\n _updateDetailPagination(ctx, currentRowNum, totalRowNum);\n });\n apiRegister('editForm.loadSaveDialogForm()', function (ctx, actionType, row) {\n return _loadSaveDialogForm(ctx, actionType, row);\n });\n apiRegister('editForm.getRowSelected()', function (dt, actionType) {\n return _getRowSelected(dt, actionType);\n });\n apiRegister('editForm.deleteAllSelects()', function (dt) {\n return _deleteAllSelects(dt);\n });\n apiRegister('editForm.getLineByPageSelected()', function (ctx, linea) {\n return _getLineByPageSelected(ctx, linea);\n });\n apiRegister('editForm.getLineByPageSelectedReverse()', function (ctx, linea) {\n return _getLineByPageSelectedReverse(ctx, linea);\n });\n apiRegister('editForm.addchildIcons()', function (ctx) {\n _addChildIcons(ctx);\n });\n apiRegister('editForm.fixComboAutocompleteOnEditForm()', function (ctx) {\n _fixComboAutocompleteOnEditForm(ctx);\n });\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Initialisation\r\n */\n // DataTables creation - check if select has been defined in the options. Note\n // this required that the table be in the document! If it isn't then something\n // needs to trigger this method unfortunately. The next major release of\n // DataTables will rework the events and address this.\n\n $(document).on('plugin-init.dt', function (e, ctx) {\n if (e.namespace !== 'dt') {\n return;\n }\n\n if (!ctx.oInit.noEdit && ctx.oInit.formEdit !== undefined && ctx.oInit.formEdit.activate !== false) {\n DataTable.editForm.preConfigure(new DataTable.Api(ctx));\n $('#' + ctx.sTableId).on('tableEditFormInitialize', function (event, ctx) {\n var deferred = $.Deferred();\n DataTable.editForm.init(ctx);\n $(ctx.oInit.formEdit.detailForm).rup_dialog($.extend({}, {\n type: $.rup.dialog.DIV,\n autoOpen: false,\n modal: true,\n resizable: '',\n width: ctx.oInit.formEdit.detailForm.settings.width,\n create: function create() {\n /* Se encarga de eliminar la clase que oculta los campos del formEdit. Esta clase esta presente\r\n * en el formEdit para evitar un bug visual en el que hacia que sus campos apareciesen \r\n * bajo la tabla y fueran visibles previa a la inicializacion del componente rup.dialog.\r\n */\n $('#' + ctx.sTableId + '_detail_div.rup-table-formEdit-detail').removeClass('d-none');\n }\n }, {}));\n\n if (ctx.oInit.formEdit.cancelDeleteFunction === undefined) {\n ctx.oInit.formEdit.cancelDeleteFunction = function cancelClicked() {};\n }\n\n deferred.resolve();\n return deferred.promise();\n });\n }\n });\n return DataTable.editForm;\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")))\n\n//# sourceURL=webpack://rup/./src/rup_table/rup.table.editForm.js?"); /***/ }), @@ -8722,7 +8722,7 @@ eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARR /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("/* WEBPACK VAR INJECTION */(function(jQuery) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }, _typeof(obj); }\n\n/**\r\n * Módulo que habilita la edicción mediante un formulario.\r\n *\r\n * @summary\tExtensión del componente RUP Datatable\r\n * @module\t\t\"rup.table.inlineEdit\"\r\n * @version\t1.0.0\r\n * @license\r\n * Licencia con arreglo a la EUPL, Versión 1.1 exclusivamente (la «Licencia»);\r\n * Solo podrá usarse esta obra si se respeta la Licencia.\r\n * Puede obtenerse una copia de la Licencia en\r\n *\r\n * http://ec.europa.eu/idabc/eupl.html\r\n *\r\n * Salvo cuando lo exija la legislación aplicable o se acuerde por escrito,\r\n * el programa distribuido con arreglo a la Licencia se distribuye «TAL CUAL»,\r\n * SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ni expresas ni implícitas.\r\n * Véase la Licencia en el idioma concreto que rige los permisos y limitaciones\r\n * que establece la Licencia.\r\n * @copyright Copyright 2018 E.J.I.E., S.A.\r\n *\r\n */\n(function (factory) {\n if (true) {\n // AMD\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\"), __webpack_require__(/*! datatables.net */ \"./node_modules/datatables.net/js/jquery.dataTables.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function ($) {\n return factory($, window, document);\n }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(function ($, window, document, undefined) {\n 'use strict';\n\n var DataTable = $.fn.dataTable; // Version information for debugger\n\n DataTable.inlineEdit = {};\n DataTable.inlineEdit.version = '1.2.4';\n /**\r\n * Se inicializa el componente editInline\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.4.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n DataTable.inlineEdit.init = function (dt) {\n var ctx = dt.settings()[0];\n ctx.inlineEdit = {};\n var idRow; // Se edita el row/fila.\n\n var rowsBody = $(ctx.nTBody);\n rowsBody.on('dblclick.DT keypress', 'tr:not(.group)', function (e) {\n // Solo selecciona si se pulsa sobre el enter o se hace click izquierdo col raton\n if (e.type == 'keypress' && e.which == 13 || e.type === 'dblclick') {\n if ($(this).hasClass('editable')) {\n return false;\n }\n\n idRow = this._DT_RowIndex;\n\n _editInline(dt, ctx, idRow, 'PUT');\n\n $('#' + ctx.sTableId).triggerHandler('tableEditInlineClickRow', ctx);\n }\n });\n dt.on('responsive-display', function (e, table, row, showHide) {\n //si se crea el tr hijo\n if (showHide && row.child() !== undefined) {\n row.child().on('dblclick.DT', function () {\n idRow = row.index();\n\n _editInline(dt, ctx, idRow, 'PUT');\n });\n\n if (ctx.oInit.inlineEdit.rowDefault !== undefined && ctx.oInit.inlineEdit.rowDefault === 'estadoFinal') {\n ctx.oInit.inlineEdit.rowDefault = undefined;\n\n _restaurarFila(ctx, true);\n\n _editInline(dt, ctx, row.index(), 'PUT');\n\n if (ctx.oInit.inlineEdit.currentPos !== null && ctx.oInit.inlineEdit.currentPos.actionType === 'CLONE') {\n $('#' + ctx.sTableId + ' tbody tr:not(.group)').eq(0).addClass('new');\n DataTable.Api().rupTable.selectPencil(ctx, 0);\n }\n }\n\n if ($(row.node()).hasClass('selected')) {\n row.child().addClass('selected tr-highlight');\n }\n }\n });\n $(window).on('resize.dtr', DataTable.util.throttle(function () {\n //Se calcula el responsive\n dt.responsive.recalc();\n })); //se cambia el nombre de los validadores.\n\n if (ctx.oInit.inlineEdit.validate !== undefined && ctx.oInit.inlineEdit.validate.rules !== undefined) {\n var rulesAux = ctx.oInit.inlineEdit.validate.rules;\n ctx.oInit.inlineEdit.validate.rules = {};\n $.each(rulesAux, function (name, rule) {\n ctx.oInit.inlineEdit.validate.rules[name + '_inline'] = rule;\n ctx.oInit.inlineEdit.validate.rules[name + '_inline_child'] = rule;\n });\n }\n\n var idForm = $('#' + ctx.sTableId + '_search_searchForm'); // Si no existe se crea\n\n if (idForm.length === 0) {\n var $searchForm = jQuery('
').attr('id', ctx.sTableId + '_search_searchForm');\n $('#' + ctx.sTableId).wrapAll($searchForm);\n } // Se añaden las validaciones\n\n\n var feed = ctx.oInit.feedback.$feedbackContainer;\n var validaciones;\n\n if (ctx.oInit.inlineEdit.validate !== undefined) {\n validaciones = ctx.oInit.inlineEdit.validate.rules;\n }\n\n var propertiesDefault = {\n liveCheckingErrors: false,\n showFieldErrorAsDefault: true,\n showErrorsInFeedback: true,\n showFieldErrorsInFeedback: true\n };\n var propertiesValidate = $.extend(true, {}, propertiesDefault, ctx.oInit.inlineEdit.propertiesValidate);\n propertiesValidate.feedback = feed;\n propertiesValidate.rules = validaciones;\n $('#' + ctx.sTableId + '_search_searchForm').rup_validate(propertiesValidate);\n var borrarGuardar = false;\n var borrarCancelar = false;\n\n if (ctx.oInit.buttons !== undefined && ctx.oInit.buttons.blackListButtons !== undefined) {\n if (ctx.oInit.buttons.blackListButtons === 'all') {\n borrarGuardar = true;\n borrarCancelar = true;\n } else if (ctx.oInit.buttons.blackListButtons && ctx.oInit.buttons.blackListButtons.length > 0) {\n $.each(ctx.oInit.buttons.blackListButtons, function () {\n var name = this;\n\n if (name === 'saveButton') {\n borrarGuardar = true;\n }\n\n if (name === 'cancelButton') {\n borrarCancelar = true;\n }\n });\n }\n } // Crear botones Guardar y Cancelar\n\n\n ctx.oInit.inlineEdit.myButtons = {}; // Boton Guardar\n\n if (!borrarGuardar) {\n ctx.oInit.inlineEdit.myButtons.guardar = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.save');\n },\n id: ctx.sTableId + 'saveButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnSave order-5',\n icon: 'mdi-content-save',\n displayRegex: /asss/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: true,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'save',\n action: function action(e, dt, button, config) {\n var $selector = $('#' + ctx.sTableId + ' tbody tr.editable:not(.child)');\n\n _guardar(ctx, $selector, false);\n }\n };\n }\n\n if (!borrarCancelar) {\n // Boton Cancelar\n ctx.oInit.inlineEdit.myButtons.cancelar = {\n text: function text(dt) {\n return $.rup.i18nParse($.rup.i18n.base, 'rup_table.cancel');\n },\n id: ctx.sTableId + 'cancelButton_1',\n // Campo obligatorio si se quiere usar desde el contextMenu\n className: 'btn-material-primary-high-emphasis table_toolbar_btnCancel order-6',\n icon: 'mdi-cancel',\n displayRegex: /asss/,\n // Se muestra siempre que sea un numero positivo o neutro\n insideContextMenu: true,\n // Independientemente de este valor, sera 'false' si no tiene un id definido\n type: 'cancel',\n action: function action() {\n var _cancelRow = function _cancelRow() {\n $('#' + ctx.sTableId + 'saveButton_1').prop('disabled', true);\n $('#' + ctx.sTableId + 'saveButton_1_contextMenuToolbar').addClass('disabledButtonsTable');\n $('#' + ctx.sTableId + 'cancelButton_1').prop('disabled', true);\n $('#' + ctx.sTableId + 'cancelButton_1_contextMenuToolbar').addClass('disabledButtonsTable');\n ctx.inlineEdit.lastRow = undefined;\n ctx.oInit.inlineEdit.alta = undefined; // Garantiza la deselección, evitando un error en el filtrado posterior.\n\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt);\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx);\n }\n\n dt.ajax.reload(undefined, false);\n };\n\n if (ctx.oInit.inlineEdit.settings.cancelDialog) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.saveAndContinue'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n _cancelRow();\n\n $('#' + ctx.sTableId).triggerHandler('tableMessageOk', ctx);\n },\n CANCELFunction: function CANCELFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageCancel', ctx);\n },\n CLOSEFunction: function CLOSEFunction() {\n $('#' + ctx.sTableId).triggerHandler('tableMessageClose', ctx);\n }\n });\n } else {\n _cancelRow();\n }\n }\n };\n }\n\n ctx.oInit.inlineEdit.settings = {\n saveDialog: ctx.oInit.inlineEdit.confirmDialogs !== undefined && ctx.oInit.inlineEdit.confirmDialogs.saveDialog !== undefined ? ctx.oInit.inlineEdit.confirmDialogs.saveDialog : true,\n cancelDialog: ctx.oInit.inlineEdit.confirmDialogs !== undefined && ctx.oInit.inlineEdit.confirmDialogs.cancelDialog !== undefined ? ctx.oInit.inlineEdit.confirmDialogs.cancelDialog : true,\n deleteDialog: ctx.oInit.inlineEdit.confirmDialogs !== undefined && ctx.oInit.inlineEdit.confirmDialogs.deleteDialog !== undefined ? ctx.oInit.inlineEdit.confirmDialogs.deleteDialog : true\n };\n $(window).on('resize.dtr', DataTable.util.throttle(function () {\n //Se calcula el responsive\n _addChildIcons(ctx);\n }));\n };\n /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\r\n * Local functions\r\n */\n\n /**\r\n * Initialisation of a new table. Attach event handlers and callbacks to allow\r\n * Select to operate correctly.\r\n *\r\n * This will occur _after_ the initial DataTables initialisation, although\r\n * before Ajax data is rendered, if there is ajax data\r\n *\r\n * @name init\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {DataTable.settings} ctx Settings object to operate on\r\n *\r\n */\n\n\n function init(ctx) {\n var api = new DataTable.Api(ctx); // Row callback so that classes can be added to rows and cells if the item\n // was selected before the element was created. This will happen with the\n // `deferRender` option enabled.\n //\n // This method of attaching to `aoRowCreatedCallback` is a hack until\n // DataTables has proper events for row manipulation If you are reviewing\n // this code to create your own plug-ins, please do not do this!\n\n ctx.aoRowCreatedCallback.push({\n fn: function fn(row, data, index) {\n var i, ien;\n var d = ctx.aoData[index]; // Row\n\n if (d._multiSelect_selected) {\n $(row).addClass(ctx._multiSelect.className);\n } // Cells and columns - if separated out, we would need to do two\n // loops, so it makes sense to combine them into a single one\n\n\n for (i = 0, ien = ctx.aoColumns.length; i < ien; i++) {\n if (ctx.aoColumns[i]._multiSelect_selected || d._selected_cells && d._selected_cells[i]) {\n $(d.anCells[i]).addClass(ctx._multiSelect.className);\n }\n }\n },\n sName: 'select-deferRender'\n }); // On Ajax reload we want to reselect all rows which are currently selected,\n // if there is an rowId (i.e. a unique value to identify each row with)\n\n api.on('preXhr.dt.dtSelect', function () {\n // note that column selection doesn't need to be cached and then\n // reselected, as they are already selected\n var rows = api.rows({\n selected: true\n }).ids(true).filter(function (d) {\n return d !== undefined;\n });\n var cells = api.cells({\n selected: true\n }).eq(0).map(function (cellIdx) {\n var id = api.row(cellIdx.row).id(true);\n return id ? {\n row: id,\n column: cellIdx.column\n } : undefined;\n }).filter(function (d) {\n return d !== undefined;\n }); // On the next draw, reselect the currently selected items\n\n api.one('draw.dt.dtSelect', function () {\n api.rows(rows).multiSelect(); // `cells` is not a cell index selector, so it needs a loop\n\n if (cells.any()) {\n cells.each(function (id) {\n api.cells(id.row, id.column).multiSelect();\n });\n }\n });\n }); // Clean up and release\n\n api.on('destroy.dtSelect', function () {\n disableMouseSelection(api);\n api.off('.dtSelect');\n });\n }\n\n function eventTrigger(api, type, args, any) {\n if (any && !api.flatten().length) {\n return;\n }\n\n if (typeof type === 'string') {\n type = type + '.dt';\n }\n\n args.unshift(api);\n $(api.table().node()).trigger(type, args);\n }\n /**\r\n * Función ejecutada cuando se activa el responsive.\r\n *\r\n * @name _onResponsiveResize\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n *\r\n */\n\n\n function _onResponsiveResize(dt) {\n dt.on('responsive-resize', function (e, settingsTable) {\n //si hay responsive. Param:: e,settingsTable,columns\n _addChildIcons(settingsTable.context[0]);\n });\n }\n /**\r\n * Se añade un nuevo registro.\r\n *\r\n * @name _add\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _add(dt, ctx) {\n if (ctx.multiselection.numSelected > 0) {\n $.rup_messages('msgConfirm', {\n message: $.rup.i18nParse($.rup.i18n.base, 'rup_table.checkSelectedElems'),\n title: $.rup.i18nParse($.rup.i18n.base, 'rup_table.changes'),\n OKFunction: function OKFunction() {\n _restaurarFila(ctx, true); // Abrimos el formulario\n\n\n if (ctx.oInit.seeker !== undefined) {\n DataTable.Api().seeker.limpiarSeeker(dt, ctx); // Y deselecionamos los checks y seekers\n } else {\n if (ctx.oInit.multiSelect !== undefined) {\n DataTable.Api().multiSelect.deselectAll(dt); // Y deselecionamos los checks y seekers\n } else if (ctx.oInit.select !== undefined) {\n DataTable.Api().select.deselect(ctx); // Y deselecionamos los checks y seekers\n }\n } //Crear tr ficticio\n\n\n ctx.oInit.inlineEdit.alta = true;\n dt.ajax.reload(function () {\n ctx.oInit.inlineEdit.alta = undefined;\n $('#' + ctx.sTableId + ' tbody tr:not(.group)').eq(0).addClass('new');\n\n _editInline(dt, ctx, 0, 'POST');\n });\n }\n });\n } else {\n //Crear tr ficticio\n ctx.oInit.inlineEdit.alta = true;\n dt.ajax.reload(function () {\n ctx.oInit.inlineEdit.alta = undefined;\n $('#' + ctx.sTableId + ' tbody tr:not(.group)').eq(0).addClass('new');\n\n _editInline(dt, ctx, 0, 'POST');\n });\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditInlineAddRow', ctx);\n }\n /**\r\n * Se añaden los iconos al responsive.\r\n *\r\n * @name _addChildIcons\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n *\r\n */\n\n\n function _addChildIcons(ctx) {\n var hasHidden = false;\n\n var columnsVisiblity = ctx.responsive._columnsVisiblity();\n\n for (var i = 0; i < columnsVisiblity.length; i++) {\n if (!columnsVisiblity[i]) {\n if (!ctx.aoColumns[i].className || ctx.aoColumns[i].className.indexOf('never') < 0) {\n hasHidden = true;\n }\n }\n }\n\n if (ctx.responsive.c.details.target === 'td span.openResponsive') {\n //por defecto\n $('#' + ctx.sTableId).find('tbody td:first-child span.openResponsive').remove();\n\n if (hasHidden) {\n //añadir span ala primera fila\n $.each($('#' + ctx.sTableId).find('tbody td:first-child:not(.child):not(.dataTables_empty)'), function () {\n var $span = $('');\n\n if ($(this).find('span.openResponsive').length === 0) {\n $(this).prepend($span.addClass('openResponsive'));\n } else {\n //si ya existe se asigna el valor.\n $span = $(this).find('span.openResponsive');\n }\n\n if ($(this).parent().next().hasClass('child')) {\n $span.addClass('closeResponsive');\n }\n\n var $fila = $(this).parent();\n $span.click(function (event) {\n if ($fila.hasClass('editable') && $fila.find('.closeResponsive').length) {\n // No se hace nada si esta editando\n event.stopPropagation();\n } else {\n if ($span.hasClass('closeResponsive')) {\n $span.removeClass('closeResponsive');\n } else {\n $span.addClass('closeResponsive');\n }\n }\n });\n\n if (ctx.inlineEdit !== undefined && $fila.hasClass('editable')) {\n //setTimeout(_comprobarFila(ctx,$fila), 500);\n _comprobarFila(ctx, $fila); //console.log('entro al TIMEOUT --------- ---------');\n\n }\n });\n } else {//si la edicion en linea esta activada\n } //si hay inputs guardados se reemplazan los cambios por el responsive.\n\n\n if (ctx.inlineEdit !== undefined && ctx.inlineEdit.lastRow !== undefined && ctx.inlineEdit.lastRow.rupValues !== undefined) {\n var table = $('#' + ctx.sTableId).DataTable();\n ctx.inlineEdit.lastRow.columnsHidden = table.columns().responsiveHidden();\n var $row = $('#' + ctx.sTableId + ' tbody tr.editable:not(.child)');\n\n _asignarInputsValues(ctx, $row);\n }\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditLineAddChildIcons', ctx);\n }\n /**\r\n * Método principal para la edición en línea.\r\n *\r\n * @name _editInline\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Es el objeto table.\r\n * @param {object} ctx - Contexto del Datatable.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n * @param {string} [actionType='POST'] - Método del formulario a obtener.\r\n *\r\n */\n\n\n function _editInline(dt, ctx, idRow) {\n var actionType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'POST';\n\n if (ctx.inlineEdit.lastRow !== undefined && ctx.inlineEdit.lastRow.idx !== idRow) {\n //si no es la misma fila.\n _restaurarFila(ctx, false);\n }\n\n $.when(_loadAuxForm(ctx, actionType, ctx.json.rows[idRow])).then(function () {\n var $rowSelect = $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(idRow);\n\n if (!$rowSelect.hasClass('editable')) {\n _changeInputsToRup(ctx, idRow); // Se deshabilitan los botones predefinidos de la tabla.\n\n\n DataTable.Api().buttons.disableAllButtons(ctx, ctx.ext.buttons.custom);\n } // Habilitamos en la botonera y contextMenu\n\n\n $('#' + ctx.sTableId + 'saveButton_1').prop('disabled', false);\n $('#' + ctx.sTableId + 'saveButton_1_contextMenuToolbar').removeClass('disabledButtonsTable');\n $('#' + ctx.sTableId + 'cancelButton_1').prop('disabled', false);\n $('#' + ctx.sTableId + 'cancelButton_1_contextMenuToolbar').removeClass('disabledButtonsTable'); // Cuando sea añadir registro no hay que habilitar el boton de informes\n\n if (!$rowSelect.hasClass('odd new')) {\n $('#' + ctx.sTableId + 'informes_01').prop('disabled', false);\n }\n\n DataTable.Api().seeker.enabledButtons(ctx);\n $('#' + ctx.sTableId).triggerHandler('tableInlineEdit', ctx);\n var selectores = {};\n selectores[0] = $rowSelect;\n\n if ($rowSelect.next().find('.child').length === 1) {\n selectores[1] = $rowSelect.next().find('.child');\n }\n\n $.each(selectores, function () {\n //se crea evento para los selectores creados.\n _crearEventos(ctx, this);\n });\n\n if (ctx.oInit.inlineEdit.clone !== true) {\n //Añadir la seleccion del mismo.\n if (ctx.oInit.multiSelect !== undefined) {\n dt['row'](idRow).multiSelect();\n } else {\n var rowsBody = $(ctx.nTBody);\n $('tr', rowsBody).removeClass('selected tr-highlight');\n DataTable.Api().select.selectRowIndex(dt, idRow, true);\n\n if (ctx.multiselection.selectedIds == \"\") {\n //es nuevo\n ctx.multiselection.selectedIds = [];\n }\n }\n }\n\n dt.responsive.recalc();\n\n if (ctx.oInit.inlineEdit.currentPos !== undefined && ctx.oInit.inlineEdit.currentPos.actionType !== undefined && ctx.oInit.inlineEdit.currentPos.actionType === 'CLONE' && $rowSelect.find('span.openResponsive').length === 0) {\n //revisar cuando es clone por si el responsive falla\n _addChildIcons(ctx);\n }\n });\n }\n /**\r\n * Método que obtiene la fila siguiente seleccionada.\r\n *\r\n * @name getRowSelected\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} dt - Instancia de la tabla.\r\n * @param {string} actionType - Acción a ajecutar en el formulario para ir al controller, basado en REST.\r\n *\r\n * @return {object} Contiene el identificador, la página y la línea de la fila seleccionada.\r\n *\r\n */\n\n\n function _getRowSelected(dt, actionType) {\n var ctx = dt.settings()[0];\n var rowDefault = {\n id: 0,\n page: 1,\n line: 0\n };\n var lastSelectedId = ctx.multiselection.lastSelectedId;\n\n if (!ctx.multiselection.selectedAll) {\n $.each(ctx.multiselection.selectedRowsPerPage, function (index, p) {\n if (p.id == ctx.multiselection.lastSelectedId) {\n rowDefault.id = p.id;\n rowDefault.page = p.page;\n rowDefault.line = p.line;\n rowDefault.indexSelected = index;\n\n if (ctx.oInit.inlineEdit !== undefined) {\n ctx.oInit.inlineEdit.currentPos = rowDefault;\n }\n\n return false;\n }\n });\n } else {\n if (ctx.oInit.inlineEdit !== undefined) {\n // Indica los mostrados cuando es selectAll y no se puede calcular. El inicio es 0.\n ctx.oInit.inlineEdit.numPosition = 0;\n }\n\n if (lastSelectedId === undefined || lastSelectedId === '') {\n // Como arranca de primeras, la página es la 1\n rowDefault.page = _getNextPageSelected(ctx, 1, 'next');\n rowDefault.line = _getLineByPageSelected(ctx, -1);\n } else {\n // Buscar la posición y la página\n var result = $.grep(ctx.multiselection.selectedRowsPerPage, function (v) {\n return v.id == ctx.multiselection.lastSelectedId;\n });\n rowDefault.page = result[0].page;\n rowDefault.line = result[0].line;\n var index = ctx._iDisplayLength * (Number(rowDefault.page) - 1);\n index = index + 1 + rowDefault.line; // Restar los deselecionados\n\n result = $.grep(ctx.multiselection.deselectedRowsPerPage, function (v) {\n return Number(v.page) < Number(rowDefault.page) || Number(rowDefault.page) === Number(v.page) && Number(v.line) < Number(rowDefault.line);\n }); // Buscar índice\n\n rowDefault.indexSelected = index - result.length;\n\n if (ctx.oInit.inlineEdit !== undefined) {\n ctx.oInit.inlineEdit.numPosition = rowDefault.indexSelected - 1;\n }\n }\n\n if (ctx.oInit.inlineEdit !== undefined) {\n ctx.oInit.inlineEdit.currentPos = rowDefault;\n }\n } // En caso de estar en una página distinta, navegamos a ella\n\n\n if (dt.page() + 1 !== Number(rowDefault.page)) {\n var table = $('#' + ctx.sTableId).DataTable();\n table.page(rowDefault.page - 1).draw('page');\n\n if (ctx.oInit.inlineEdit !== undefined) {\n rowDefault.actionType = actionType;\n ctx.oInit.inlineEdit.rowDefault = rowDefault;\n }\n } else {\n if (actionType === 'PUT') {\n _editInline(dt, ctx, rowDefault.line, actionType);\n } else if (actionType === 'CLONE') {\n dt.ajax.reload(undefined, false);\n rowDefault.actionType = actionType;\n ctx.oInit.inlineEdit.rowDefault = rowDefault;\n }\n }\n\n return rowDefault;\n }\n /**\r\n * Método que clona el elemento seleccionado.\r\n *\r\n * @name cloneLine\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n *\r\n * @param {object} dt - Objeto table.\r\n * @param {object} ctx - Contexto del Datatable.\r\n * @param {integer} line - Número de la fila.\r\n *\r\n */\n\n\n function _cloneLine(dt, ctx, line) {\n $('#' + ctx.sTableId).triggerHandler('tableEditInlineClone', ctx);\n dt.row(0).data(dt.row(line + 1).data());\n\n if (ctx.oInit.inlineEdit.rowDefault !== undefined) {\n ctx.oInit.inlineEdit.rowDefault.line = 0;\n } // Añadir clase necesaria para su futura gestión a la hora de guardar el registro\n\n\n $('#' + ctx.sTableId + ' tbody tr').eq(0).addClass('new');\n }\n /**\r\n * Método que obtiene la página siguiente donde está el primer elemento o elemento seleccionado.\r\n *\r\n * @name getNextPageSelected\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n * @param {integer} pageInit - Página a partir de la cual hay que mirar, en general serà la 1.\r\n * @param {string} orden - Pueder ser pre o next, en función de si necesitar ir hacia adelante o hacia atrás.\r\n *\r\n * @return integer - devuele la página\r\n *\r\n */\n\n\n function _getNextPageSelected(ctx, pageInit, orden) {\n var pagina = pageInit;\n var pageTotals = ctx.json.total;\n\n if (orden === 'prev') {\n //Si es previo se resta.\n pageTotals = 1;\n }\n\n if (ctx.multiselection.deselectedRowsPerPage.length > 0) {\n var maxPagina = ctx.json.rows.length;\n var count = 0; //Buscar la pagina donde va estar el seleccionado.\n\n for (var page = pageInit; page < pageTotals;) {\n $.each(ctx.multiselection.deselectedRowsPerPage, function (index, p) {\n if (page === Number(p.page)) {\n count++;\n }\n\n if (count === maxPagina) {\n return false;\n }\n });\n\n if (count < maxPagina) {\n pagina = page;\n page = ctx.json.total; //Se pone el total para salir del bucle.\n }\n\n count = 0;\n\n if (orden === 'next') {\n page++;\n } else if (orden === 'prev') {\n page--;\n }\n }\n }\n\n return pagina;\n }\n /**\r\n * Método que obtiene la linea siguiente donde está el primer elemento o elemento seleccionado.\r\n *\r\n * @name getLineByPageSelected\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Settings object to operate on.\r\n * @param {integer} lineInit - Linea a partir de la cual hay que mirar, en general será la 1.\r\n *\r\n * @return integer - devuele la linea\r\n *\r\n */\n\n\n function _getLineByPageSelected(ctx, lineInit) {\n var line = -1;\n var rows = ctx.json.rows;\n $.each(rows, function (index, row) {\n if (index > lineInit) {\n var indexInArray = jQuery.inArray(DataTable.Api().rupTable.getIdPk(row, ctx.oInit), ctx.multiselection.deselectedIds);\n\n if (indexInArray === -1) {\n line = index;\n var arra = {\n id: DataTable.Api().rupTable.getIdPk(row, ctx.oInit),\n page: ctx.json.page,\n line: index\n };\n\n if (ctx.oInit.inilineEdit !== undefined) {\n ctx.oInit.inilineEdit.currentPos = arra;\n }\n\n return false;\n }\n }\n });\n return line;\n }\n /**\r\n * Se restaura la línea(fila) en la edición.\r\n *\r\n * @name _restaurarFila\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n * @param {boolean} limpiar - Si es true limpia e inicializa todo y si es false solo restaura la línea.\r\n *\r\n */\n\n\n function _restaurarFila(ctx, limpiar) {\n $('#' + ctx.sTableId).triggerHandler('tableEditInlineRestaurarFilaInit', ctx);\n\n if (ctx.inlineEdit !== undefined && ctx.inlineEdit.lastRow !== undefined) {\n var positionLastRow = ctx.inlineEdit.lastRow.idx;\n var $fila = $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(positionLastRow); //Sin responsive\n\n _restaurarCeldas(ctx, $fila, $fila.find('td'), 0);\n\n var contRest = $fila.find('td:not([style*=\"display: none\"])').length;\n\n if ($fila.find('td.select-checkbox').length > 0) {\n contRest--;\n } //con responsive, desplegado\n\n\n _restaurarCeldas(ctx, $fila.next('.child'), $fila.next('.child').find(ctx.oInit.responsive.selectorResponsive), contRest);\n }\n\n if (ctx.inlineEdit !== undefined && limpiar) {\n //si se limpia, no queda ninguna marcada\n var $selectorTr = $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(positionLastRow);\n ctx.inlineEdit.lastRow = undefined;\n\n if ($selectorTr.data('events') !== undefined) {\n $selectorTr.off('keydown');\n }\n\n DataTable.Api().seeker.disabledButtons(ctx);\n ctx.oInit.feedback.$feedbackContainer.rup_feedback('hide');\n\n if ($fila !== undefined && $fila.hasClass('new')) {\n // se elimna el tr, porque no se guardo\n $fila.next('.child').remove();\n $fila.remove(); //se asegura resturar multiselection\n\n ctx.multiselection.numSelected = 0;\n ctx.multiselection.selectedIds = [];\n ctx.multiselection.selectedRowsPerPage = [];\n } //se habilitan los botones.\n\n\n ctx._buttons[0].inst.s.disableAllButtons = undefined;\n DataTable.Api().buttons.displayRegex(ctx);\n }\n\n $('#' + ctx.sTableId).triggerHandler('tableEditLineRestaurarFilaEnd', ctx);\n }\n /**\r\n *Cambia los inputs por los componentes rup.\r\n *\r\n * @name _changeInputsToRup\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Contexto del Datatable.\r\n * @param {integer} idRow - Número con la posición de la fila que hay que obtener.\r\n *\r\n */\n\n\n function _changeInputsToRup(ctx, idRow) {\n // Se procesan las celdas editables\n if (ctx.oInit.colModel !== undefined) {\n var table = $('#' + ctx.sTableId).DataTable();\n var cont = 0;\n ctx.inlineEdit.lastRow = $('#' + ctx.sTableId + ' > tbody > tr:not(.group)').eq(idRow);\n ctx.inlineEdit.lastRow.cellValues = {};\n ctx.inlineEdit.lastRow.columnsHidden = table.columns().responsiveHidden();\n ctx.inlineEdit.lastRow.submit = 0;\n ctx.inlineEdit.lastRow.idx = idRow;\n ctx.inlineEdit.lastRow.ponerFocus = false; //Si existe el responsive\n //Campos sin responsive\n\n var $target = ctx.inlineEdit.lastRow.find(ctx.oInit.responsive.details.target);\n\n if ($target.length > 0 && ctx.inlineEdit.lastRow.next().find('.child').length === 0) {\n $target.click();\n }\n\n cont = _recorrerCeldas(ctx, ctx.inlineEdit.lastRow, ctx.inlineEdit.lastRow.find('td'), cont);\n\n if (!ctx.inlineEdit.lastRow.hasClass('new') && !ctx.oInit.inlineEdit.alta) {\n DataTable.Api().rupTable.blockPKEdit(ctx, 'PUT', '_inline');\n } //Mirar los campos que estan en responsive.\n\n\n var $filaChild = ctx.inlineEdit.lastRow.next('.child');\n\n _recorrerCeldas(ctx, $filaChild, $filaChild.find(ctx.oInit.responsive.selectorResponsive), cont);\n\n if ($filaChild.length > 0 && !$filaChild.hasClass('new') && !ctx.oInit.inlineEdit.alta) {\n DataTable.Api().rupTable.blockPKEdit(ctx, 'PUT', '_inline_child');\n }\n }\n }\n /**\r\n * Método que recorre las celdas y las procesa.\r\n *\r\n * @name _recorrerCeldas\r\n * @function\r\n * @since UDA 3.7.0 // Table 1.0.0\r\n *\r\n * @param {object} ctx - Es el contexto de cada tabla.\r\n * @param {object} $fila - fila que se está editando.\r\n * @param {object} $celdas - Todas las celdas a recorrer.\r\n * @param {integer} cont - Contador para saber en que celda nos movemos, sobre todo en el responsive.\r\n *\r\n */\n\n\n function _recorrerCeldas(ctx, $fila, $celdas, cont) {\n $fila.addClass('editable');\n var colModel = ctx.oInit.colModel;\n var child = '';\n\n if ($fila.hasClass('child')) {\n child = '_child';\n $fila = $fila.prev();\n }\n\n var ocultos = 0;\n var edicion = true;\n\n if ($fila.hasClass('new') || ctx.oInit.inlineEdit.alta) {\n edicion = false;\n }\n\n $celdas.each(function () {\n var celda = $(this);\n var $celda = $(celda);\n\n if (!$celda.hasClass('select-checkbox')) {\n // Si la columna a usar está oculta, se aumenta el contador para usar la siguiente que no lo esté\n while (colModel[cont].hidden) {\n cont++;\n }\n\n var cellColModel = colModel[cont];\n\n if (cellColModel.editable === true || !edicion) {\n var $input = $('');\n\n if (cellColModel.rupType !== undefined && cellColModel.rupType === 'select') {\n $input = $('');\n\n if (cellColModel.rupType !== undefined && cellColModel.rupType === 'select') {\n $input = $('\n DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss',\n // \n DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS',\n // \n DATE: 'YYYY-MM-DD',\n // \n TIME: 'HH:mm',\n // \n TIME_SECONDS: 'HH:mm:ss',\n // \n TIME_MS: 'HH:mm:ss.SSS',\n // \n WEEK: 'GGGG-[W]WW',\n // \n MONTH: 'YYYY-MM' // \n\n };\n return hooks;\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(58)(module)))\n\n//# sourceURL=webpack://rup/./node_modules/moment/moment.js?")},function(module,exports,__webpack_require__){eval('/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }\n\n/*!\n * jQuery JavaScript Library v3.6.3\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2022-12-20T21:28Z\n */\n(function (global, factory) {\n "use strict";\n\n if (( false ? undefined : _typeof(module)) === "object" && _typeof(module.exports) === "object") {\n // For CommonJS and CommonJS-like environments where a proper `window`\n // is present, execute the factory and get jQuery.\n // For environments that do not have a `window` with a `document`\n // (such as Node.js), expose a factory as module.exports.\n // This accentuates the need for the creation of a real `window`.\n // e.g. var jQuery = require("jquery")(window);\n // See ticket trac-14549 for more info.\n module.exports = global.document ? factory(global, true) : function (w) {\n if (!w.document) {\n throw new Error("jQuery requires a window with a document");\n }\n\n return factory(w);\n };\n } else {\n factory(global);\n } // Pass this if window is not defined yet\n\n})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {\n // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n // enough that all such attempts are guarded in a try block.\n "use strict";\n\n var arr = [];\n var getProto = Object.getPrototypeOf;\n var _slice = arr.slice;\n var flat = arr.flat ? function (array) {\n return arr.flat.call(array);\n } : function (array) {\n return arr.concat.apply([], array);\n };\n var push = arr.push;\n var indexOf = arr.indexOf;\n var class2type = {};\n var toString = class2type.toString;\n var hasOwn = class2type.hasOwnProperty;\n var fnToString = hasOwn.toString;\n var ObjectFunctionString = fnToString.call(Object);\n var support = {};\n\n var isFunction = function isFunction(obj) {\n // Support: Chrome <=57, Firefox <=52\n // In some browsers, typeof returns "function" for HTML elements\n // (i.e., `typeof document.createElement( "object" ) === "function"`).\n // We don\'t want to classify *any* DOM node as a function.\n // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n // Plus for old WebKit, typeof returns "function" for HTML collections\n // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756)\n return typeof obj === "function" && typeof obj.nodeType !== "number" && typeof obj.item !== "function";\n };\n\n var isWindow = function isWindow(obj) {\n return obj != null && obj === obj.window;\n };\n\n var document = window.document;\n var preservedScriptAttributes = {\n type: true,\n src: true,\n nonce: true,\n noModule: true\n };\n\n function DOMEval(code, node, doc) {\n doc = doc || document;\n var i,\n val,\n script = doc.createElement("script");\n script.text = code;\n\n if (node) {\n for (i in preservedScriptAttributes) {\n // Support: Firefox 64+, Edge 18+\n // Some browsers don\'t support the "nonce" property on scripts.\n // On the other hand, just using `getAttribute` is not enough as\n // the `nonce` attribute is reset to an empty string whenever it\n // becomes browsing-context connected.\n // See https://github.com/whatwg/html/issues/2369\n // See https://html.spec.whatwg.org/#nonce-attributes\n // The `node.getAttribute` check was added for the sake of\n // `jQuery.globalEval` so that it can fake a nonce-containing node\n // via an object.\n val = node[i] || node.getAttribute && node.getAttribute(i);\n\n if (val) {\n script.setAttribute(i, val);\n }\n }\n }\n\n doc.head.appendChild(script).parentNode.removeChild(script);\n }\n\n function toType(obj) {\n if (obj == null) {\n return obj + "";\n } // Support: Android <=2.3 only (functionish RegExp)\n\n\n return _typeof(obj) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : _typeof(obj);\n }\n /* global Symbol */\n // Defining this global in .eslintrc.json would create a danger of using the global\n // unguarded in another place, it seems safer to define global only for this module\n\n\n var version = "3.6.3",\n // Define a local copy of jQuery\n jQuery = function jQuery(selector, context) {\n // The jQuery object is actually just the init constructor \'enhanced\'\n // Need init if jQuery is called (just allow error to be thrown if not included)\n return new jQuery.fn.init(selector, context);\n };\n\n jQuery.fn = jQuery.prototype = {\n // The current version of jQuery being used\n jquery: version,\n constructor: jQuery,\n // The default length of a jQuery object is 0\n length: 0,\n toArray: function toArray() {\n return _slice.call(this);\n },\n // Get the Nth element in the matched element set OR\n // Get the whole matched element set as a clean array\n get: function get(num) {\n // Return all the elements in a clean array\n if (num == null) {\n return _slice.call(this);\n } // Return just the one element from the set\n\n\n return num < 0 ? this[num + this.length] : this[num];\n },\n // Take an array of elements and push it onto the stack\n // (returning the new matched element set)\n pushStack: function pushStack(elems) {\n // Build a new jQuery matched element set\n var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)\n\n ret.prevObject = this; // Return the newly-formed element set\n\n return ret;\n },\n // Execute a callback for every element in the matched set.\n each: function each(callback) {\n return jQuery.each(this, callback);\n },\n map: function map(callback) {\n return this.pushStack(jQuery.map(this, function (elem, i) {\n return callback.call(elem, i, elem);\n }));\n },\n slice: function slice() {\n return this.pushStack(_slice.apply(this, arguments));\n },\n first: function first() {\n return this.eq(0);\n },\n last: function last() {\n return this.eq(-1);\n },\n even: function even() {\n return this.pushStack(jQuery.grep(this, function (_elem, i) {\n return (i + 1) % 2;\n }));\n },\n odd: function odd() {\n return this.pushStack(jQuery.grep(this, function (_elem, i) {\n return i % 2;\n }));\n },\n eq: function eq(i) {\n var len = this.length,\n j = +i + (i < 0 ? len : 0);\n return this.pushStack(j >= 0 && j < len ? [this[j]] : []);\n },\n end: function end() {\n return this.prevObject || this.constructor();\n },\n // For internal use only.\n // Behaves like an Array\'s method, not like a jQuery method.\n push: push,\n sort: arr.sort,\n splice: arr.splice\n };\n\n jQuery.extend = jQuery.fn.extend = function () {\n var options,\n name,\n src,\n copy,\n copyIsArray,\n clone,\n target = arguments[0] || {},\n i = 1,\n length = arguments.length,\n deep = false; // Handle a deep copy situation\n\n if (typeof target === "boolean") {\n deep = target; // Skip the boolean and the target\n\n target = arguments[i] || {};\n i++;\n } // Handle case when target is a string or something (possible in deep copy)\n\n\n if (_typeof(target) !== "object" && !isFunction(target)) {\n target = {};\n } // Extend jQuery itself if only one argument is passed\n\n\n if (i === length) {\n target = this;\n i--;\n }\n\n for (; i < length; i++) {\n // Only deal with non-null/undefined values\n if ((options = arguments[i]) != null) {\n // Extend the base object\n for (name in options) {\n copy = options[name]; // Prevent Object.prototype pollution\n // Prevent never-ending loop\n\n if (name === "__proto__" || target === copy) {\n continue;\n } // Recurse if we\'re merging plain objects or arrays\n\n\n if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {\n src = target[name]; // Ensure proper type for the source value\n\n if (copyIsArray && !Array.isArray(src)) {\n clone = [];\n } else if (!copyIsArray && !jQuery.isPlainObject(src)) {\n clone = {};\n } else {\n clone = src;\n }\n\n copyIsArray = false; // Never move original objects, clone them\n\n target[name] = jQuery.extend(deep, clone, copy); // Don\'t bring in undefined values\n } else if (copy !== undefined) {\n target[name] = copy;\n }\n }\n }\n } // Return the modified object\n\n\n return target;\n };\n\n jQuery.extend({\n // Unique for each copy of jQuery on the page\n expando: "jQuery" + (version + Math.random()).replace(/\\D/g, ""),\n // Assume jQuery is ready without the ready module\n isReady: true,\n error: function error(msg) {\n throw new Error(msg);\n },\n noop: function noop() {},\n isPlainObject: function isPlainObject(obj) {\n var proto, Ctor; // Detect obvious negatives\n // Use toString instead of jQuery.type to catch host objects\n\n if (!obj || toString.call(obj) !== "[object Object]") {\n return false;\n }\n\n proto = getProto(obj); // Objects with no prototype (e.g., `Object.create( null )`) are plain\n\n if (!proto) {\n return true;\n } // Objects with prototype are plain iff they were constructed by a global Object function\n\n\n Ctor = hasOwn.call(proto, "constructor") && proto.constructor;\n return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;\n },\n isEmptyObject: function isEmptyObject(obj) {\n var name;\n\n for (name in obj) {\n return false;\n }\n\n return true;\n },\n // Evaluates a script in a provided context; falls back to the global one\n // if not specified.\n globalEval: function globalEval(code, options, doc) {\n DOMEval(code, {\n nonce: options && options.nonce\n }, doc);\n },\n each: function each(obj, callback) {\n var length,\n i = 0;\n\n if (isArrayLike(obj)) {\n length = obj.length;\n\n for (; i < length; i++) {\n if (callback.call(obj[i], i, obj[i]) === false) {\n break;\n }\n }\n } else {\n for (i in obj) {\n if (callback.call(obj[i], i, obj[i]) === false) {\n break;\n }\n }\n }\n\n return obj;\n },\n // results is for internal usage only\n makeArray: function makeArray(arr, results) {\n var ret = results || [];\n\n if (arr != null) {\n if (isArrayLike(Object(arr))) {\n jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);\n } else {\n push.call(ret, arr);\n }\n }\n\n return ret;\n },\n inArray: function inArray(elem, arr, i) {\n return arr == null ? -1 : indexOf.call(arr, elem, i);\n },\n // Support: Android <=4.0 only, PhantomJS 1 only\n // push.apply(_, arraylike) throws on ancient WebKit\n merge: function merge(first, second) {\n var len = +second.length,\n j = 0,\n i = first.length;\n\n for (; j < len; j++) {\n first[i++] = second[j];\n }\n\n first.length = i;\n return first;\n },\n grep: function grep(elems, callback, invert) {\n var callbackInverse,\n matches = [],\n i = 0,\n length = elems.length,\n callbackExpect = !invert; // Go through the array, only saving the items\n // that pass the validator function\n\n for (; i < length; i++) {\n callbackInverse = !callback(elems[i], i);\n\n if (callbackInverse !== callbackExpect) {\n matches.push(elems[i]);\n }\n }\n\n return matches;\n },\n // arg is for internal usage only\n map: function map(elems, callback, arg) {\n var length,\n value,\n i = 0,\n ret = []; // Go through the array, translating each of the items to their new values\n\n if (isArrayLike(elems)) {\n length = elems.length;\n\n for (; i < length; i++) {\n value = callback(elems[i], i, arg);\n\n if (value != null) {\n ret.push(value);\n }\n } // Go through every key on the object,\n\n } else {\n for (i in elems) {\n value = callback(elems[i], i, arg);\n\n if (value != null) {\n ret.push(value);\n }\n }\n } // Flatten any nested arrays\n\n\n return flat(ret);\n },\n // A global GUID counter for objects\n guid: 1,\n // jQuery.support is not used in Core but other projects attach their\n // properties to it so it needs to exist.\n support: support\n });\n\n if (typeof Symbol === "function") {\n jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];\n } // Populate the class2type map\n\n\n jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (_i, name) {\n class2type["[object " + name + "]"] = name.toLowerCase();\n });\n\n function isArrayLike(obj) {\n // Support: real iOS 8.2 only (not reproducible in simulator)\n // `in` check used to prevent JIT error (gh-2145)\n // hasOwn isn\'t used here due to false negatives\n // regarding Nodelist length in IE\n var length = !!obj && "length" in obj && obj.length,\n type = toType(obj);\n\n if (isFunction(obj) || isWindow(obj)) {\n return false;\n }\n\n return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;\n }\n\n var Sizzle =\n /*!\n * Sizzle CSS Selector Engine v2.3.9\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2022-12-19\n */\n function (window) {\n var i,\n support,\n Expr,\n getText,\n isXML,\n tokenize,\n compile,\n select,\n outermostContext,\n sortInput,\n hasDuplicate,\n // Local document vars\n setDocument,\n document,\n docElem,\n documentIsHTML,\n rbuggyQSA,\n rbuggyMatches,\n matches,\n contains,\n // Instance-specific data\n expando = "sizzle" + 1 * new Date(),\n preferredDoc = window.document,\n dirruns = 0,\n done = 0,\n classCache = createCache(),\n tokenCache = createCache(),\n compilerCache = createCache(),\n nonnativeSelectorCache = createCache(),\n sortOrder = function sortOrder(a, b) {\n if (a === b) {\n hasDuplicate = true;\n }\n\n return 0;\n },\n // Instance methods\n hasOwn = {}.hasOwnProperty,\n arr = [],\n pop = arr.pop,\n pushNative = arr.push,\n push = arr.push,\n slice = arr.slice,\n // Use a stripped-down indexOf as it\'s faster than native\n // https://jsperf.com/thor-indexof-vs-for/5\n indexOf = function indexOf(list, elem) {\n var i = 0,\n len = list.length;\n\n for (; i < len; i++) {\n if (list[i] === elem) {\n return i;\n }\n }\n\n return -1;\n },\n booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + "ismap|loop|multiple|open|readonly|required|scoped",\n // Regular expressions\n // http://www.w3.org/TR/css3-selectors/#whitespace\n whitespace = "[\\\\x20\\\\t\\\\r\\\\n\\\\f]",\n // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n identifier = "(?:\\\\\\\\[\\\\da-fA-F]{1,6}" + whitespace + "?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+",\n // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n attributes = "\\\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)\n "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5]\n // or strings [capture 3 or capture 4]"\n "*(?:\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\"|(" + identifier + "))|)" + whitespace + "*\\\\]",\n pseudos = ":(" + identifier + ")(?:\\\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n // 1. quoted (capture 3; capture 4 or capture 5)\n "(\'((?:\\\\\\\\.|[^\\\\\\\\\'])*)\'|\\"((?:\\\\\\\\.|[^\\\\\\\\\\"])*)\\")|" + // 2. simple (capture 6)\n "((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2)\n ".*" + ")\\\\)|)",\n // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n rwhitespace = new RegExp(whitespace + "+", "g"),\n rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)" + whitespace + "+$", "g"),\n rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),\n rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),\n rdescend = new RegExp(whitespace + "|>"),\n rpseudo = new RegExp(pseudos),\n ridentifier = new RegExp("^" + identifier + "$"),\n matchExpr = {\n "ID": new RegExp("^#(" + identifier + ")"),\n "CLASS": new RegExp("^\\\\.(" + identifier + ")"),\n "TAG": new RegExp("^(" + identifier + "|[*])"),\n "ATTR": new RegExp("^" + attributes),\n "PSEUDO": new RegExp("^" + pseudos),\n "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(" + whitespace + "*(even|odd|(([+-]|)(\\\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\\\d+)|))" + whitespace + "*\\\\)|)", "i"),\n "bool": new RegExp("^(?:" + booleans + ")$", "i"),\n // For use in libraries implementing .is()\n // We use this for POS matching in `select`\n "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(" + whitespace + "*((?:-\\\\d)?\\\\d*)" + whitespace + "*\\\\)|)(?=[^-]|$)", "i")\n },\n rhtml = /HTML$/i,\n rinputs = /^(?:input|select|textarea|button)$/i,\n rheader = /^h\\d$/i,\n rnative = /^[^{]+\\{\\s*\\[native \\w/,\n // Easily-parseable/retrievable ID or TAG or CLASS selectors\n rquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n rsibling = /[+~]/,\n // CSS escapes\n // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n runescape = new RegExp("\\\\\\\\[\\\\da-fA-F]{1,6}" + whitespace + "?|\\\\\\\\([^\\\\r\\\\n\\\\f])", "g"),\n funescape = function funescape(escape, nonHex) {\n var high = "0x" + escape.slice(1) - 0x10000;\n return nonHex ? // Strip the backslash prefix from a non-hex escape sequence\n nonHex : // Replace a hexadecimal escape sequence with the encoded Unicode code point\n // Support: IE <=11+\n // For values outside the Basic Multilingual Plane (BMP), manually construct a\n // surrogate pair\n high < 0 ? String.fromCharCode(high + 0x10000) : String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);\n },\n // CSS string/identifier serialization\n // https://drafts.csswg.org/cssom/#common-serializing-idioms\n rcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n fcssescape = function fcssescape(ch, asCodePoint) {\n if (asCodePoint) {\n // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n if (ch === "\\0") {\n return "\\uFFFD";\n } // Control characters and (dependent upon position) numbers get escaped as code points\n\n\n return ch.slice(0, -1) + "\\\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";\n } // Other potentially-special ASCII characters get backslash-escaped\n\n\n return "\\\\" + ch;\n },\n // Used for iframes\n // See setDocument()\n // Removing the function wrapper causes a "Permission Denied"\n // error in IE\n unloadHandler = function unloadHandler() {\n setDocument();\n },\n inDisabledFieldset = addCombinator(function (elem) {\n return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";\n }, {\n dir: "parentNode",\n next: "legend"\n }); // Optimize for push.apply( _, NodeList )\n\n\n try {\n push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes); // Support: Android<4.0\n // Detect silently failing push.apply\n // eslint-disable-next-line no-unused-expressions\n\n arr[preferredDoc.childNodes.length].nodeType;\n } catch (e) {\n push = {\n apply: arr.length ? // Leverage slice if possible\n function (target, els) {\n pushNative.apply(target, slice.call(els));\n } : // Support: IE<9\n // Otherwise append directly\n function (target, els) {\n var j = target.length,\n i = 0; // Can\'t trust NodeList.length\n\n while (target[j++] = els[i++]) {}\n\n target.length = j - 1;\n }\n };\n }\n\n function Sizzle(selector, context, results, seed) {\n var m,\n i,\n elem,\n nid,\n match,\n groups,\n newSelector,\n newContext = context && context.ownerDocument,\n // nodeType defaults to 9, since context defaults to document\n nodeType = context ? context.nodeType : 9;\n results = results || []; // Return early from calls with invalid selector or context\n\n if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {\n return results;\n } // Try to shortcut find operations (as opposed to filters) in HTML documents\n\n\n if (!seed) {\n setDocument(context);\n context = context || document;\n\n if (documentIsHTML) {\n // If the selector is sufficiently simple, try using a "get*By*" DOM method\n // (excepting DocumentFragment context, where the methods don\'t exist)\n if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {\n // ID selector\n if (m = match[1]) {\n // Document context\n if (nodeType === 9) {\n if (elem = context.getElementById(m)) {\n // Support: IE, Opera, Webkit\n // TODO: identify versions\n // getElementById can match elements by name instead of ID\n if (elem.id === m) {\n results.push(elem);\n return results;\n }\n } else {\n return results;\n } // Element context\n\n } else {\n // Support: IE, Opera, Webkit\n // TODO: identify versions\n // getElementById can match elements by name instead of ID\n if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {\n results.push(elem);\n return results;\n }\n } // Type selector\n\n } else if (match[2]) {\n push.apply(results, context.getElementsByTagName(selector));\n return results; // Class selector\n } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {\n push.apply(results, context.getElementsByClassName(m));\n return results;\n }\n } // Take advantage of querySelectorAll\n\n\n if (support.qsa && !nonnativeSelectorCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector)) && ( // Support: IE 8 only\n // Exclude object elements\n nodeType !== 1 || context.nodeName.toLowerCase() !== "object")) {\n newSelector = selector;\n newContext = context; // qSA considers elements outside a scoping root when evaluating child or\n // descendant combinators, which is not what we want.\n // In such cases, we work around the behavior by prefixing every selector in the\n // list with an ID selector referencing the scope context.\n // The technique has to be used as well when a leading combinator is used\n // as such selectors are not recognized by querySelectorAll.\n // Thanks to Andrew Dupont for this technique.\n\n if (nodeType === 1 && (rdescend.test(selector) || rcombinators.test(selector))) {\n // Expand context for sibling selectors\n newContext = rsibling.test(selector) && testContext(context.parentNode) || context; // We can use :scope instead of the ID hack if the browser\n // supports it & if we\'re not changing the context.\n\n if (newContext !== context || !support.scope) {\n // Capture the context ID, setting it first if necessary\n if (nid = context.getAttribute("id")) {\n nid = nid.replace(rcssescape, fcssescape);\n } else {\n context.setAttribute("id", nid = expando);\n }\n } // Prefix every selector in the list\n\n\n groups = tokenize(selector);\n i = groups.length;\n\n while (i--) {\n groups[i] = (nid ? "#" + nid : ":scope") + " " + toSelector(groups[i]);\n }\n\n newSelector = groups.join(",");\n }\n\n try {\n // `qSA` may not throw for unrecognized parts using forgiving parsing:\n // https://drafts.csswg.org/selectors/#forgiving-selector\n // like the `:has()` pseudo-class:\n // https://drafts.csswg.org/selectors/#relational\n // `CSS.supports` is still expected to return `false` then:\n // https://drafts.csswg.org/css-conditional-4/#typedef-supports-selector-fn\n // https://drafts.csswg.org/css-conditional-4/#dfn-support-selector\n if (support.cssSupportsSelector && // eslint-disable-next-line no-undef\n !CSS.supports("selector(:is(" + newSelector + "))")) {\n // Support: IE 11+\n // Throw to get to the same code path as an error directly in qSA.\n // Note: once we only support browser supporting\n // `CSS.supports(\'selector(...)\')`, we can most likely drop\n // the `try-catch`. IE doesn\'t implement the API.\n throw new Error();\n }\n\n push.apply(results, newContext.querySelectorAll(newSelector));\n return results;\n } catch (qsaError) {\n nonnativeSelectorCache(selector, true);\n } finally {\n if (nid === expando) {\n context.removeAttribute("id");\n }\n }\n }\n }\n } // All others\n\n\n return select(selector.replace(rtrim, "$1"), context, results, seed);\n }\n /**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\n\n\n function createCache() {\n var keys = [];\n\n function cache(key, value) {\n // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)\n if (keys.push(key + " ") > Expr.cacheLength) {\n // Only keep the most recent entries\n delete cache[keys.shift()];\n }\n\n return cache[key + " "] = value;\n }\n\n return cache;\n }\n /**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\n\n\n function markFunction(fn) {\n fn[expando] = true;\n return fn;\n }\n /**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\n\n\n function assert(fn) {\n var el = document.createElement("fieldset");\n\n try {\n return !!fn(el);\n } catch (e) {\n return false;\n } finally {\n // Remove from its parent by default\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n } // release memory in IE\n\n\n el = null;\n }\n }\n /**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\n\n\n function addHandle(attrs, handler) {\n var arr = attrs.split("|"),\n i = arr.length;\n\n while (i--) {\n Expr.attrHandle[arr[i]] = handler;\n }\n }\n /**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\n\n\n function siblingCheck(a, b) {\n var cur = b && a,\n diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes\n\n if (diff) {\n return diff;\n } // Check if b follows a\n\n\n if (cur) {\n while (cur = cur.nextSibling) {\n if (cur === b) {\n return -1;\n }\n }\n }\n\n return a ? 1 : -1;\n }\n /**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\n\n\n function createInputPseudo(type) {\n return function (elem) {\n var name = elem.nodeName.toLowerCase();\n return name === "input" && elem.type === type;\n };\n }\n /**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\n\n\n function createButtonPseudo(type) {\n return function (elem) {\n var name = elem.nodeName.toLowerCase();\n return (name === "input" || name === "button") && elem.type === type;\n };\n }\n /**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\n\n\n function createDisabledPseudo(disabled) {\n // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n return function (elem) {\n // Only certain elements can match :enabled or :disabled\n // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n if ("form" in elem) {\n // Check for inherited disabledness on relevant non-disabled elements:\n // * listed form-associated elements in a disabled fieldset\n // https://html.spec.whatwg.org/multipage/forms.html#category-listed\n // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n // * option elements in a disabled optgroup\n // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n // All such elements have a "form" property.\n if (elem.parentNode && elem.disabled === false) {\n // Option elements defer to a parent optgroup if present\n if ("label" in elem) {\n if ("label" in elem.parentNode) {\n return elem.parentNode.disabled === disabled;\n } else {\n return elem.disabled === disabled;\n }\n } // Support: IE 6 - 11\n // Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\n\n return elem.isDisabled === disabled || // Where there is no isDisabled, check manually\n\n /* jshint -W018 */\n elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled;\n }\n\n return elem.disabled === disabled; // Try to winnow out elements that can\'t be disabled before trusting the disabled property.\n // Some victims get caught in our net (label, legend, menu, track), but it shouldn\'t\n // even exist on them, let alone have a boolean value.\n } else if ("label" in elem) {\n return elem.disabled === disabled;\n } // Remaining elements are neither :enabled nor :disabled\n\n\n return false;\n };\n }\n /**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\n\n\n function createPositionalPseudo(fn) {\n return markFunction(function (argument) {\n argument = +argument;\n return markFunction(function (seed, matches) {\n var j,\n matchIndexes = fn([], seed.length, argument),\n i = matchIndexes.length; // Match elements found at the specified indexes\n\n while (i--) {\n if (seed[j = matchIndexes[i]]) {\n seed[j] = !(matches[j] = seed[j]);\n }\n }\n });\n });\n }\n /**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\n\n\n function testContext(context) {\n return context && typeof context.getElementsByTagName !== "undefined" && context;\n } // Expose support vars for convenience\n\n\n support = Sizzle.support = {};\n /**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\n\n isXML = Sizzle.isXML = function (elem) {\n var namespace = elem && elem.namespaceURI,\n docElem = elem && (elem.ownerDocument || elem).documentElement; // Support: IE <=8\n // Assume HTML when documentElement doesn\'t yet exist, such as inside loading iframes\n // https://bugs.jquery.com/ticket/4833\n\n return !rhtml.test(namespace || docElem && docElem.nodeName || "HTML");\n };\n /**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\n\n\n setDocument = Sizzle.setDocument = function (node) {\n var hasCompare,\n subWindow,\n doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected\n // Support: IE 11+, Edge 17 - 18+\n // IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n // two documents; shallow comparisons work.\n // eslint-disable-next-line eqeqeq\n\n if (doc == document || doc.nodeType !== 9 || !doc.documentElement) {\n return document;\n } // Update global variables\n\n\n document = doc;\n docElem = document.documentElement;\n documentIsHTML = !isXML(document); // Support: IE 9 - 11+, Edge 12 - 18+\n // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)\n // Support: IE 11+, Edge 17 - 18+\n // IE/Edge sometimes throw a "Permission denied" error when strict-comparing\n // two documents; shallow comparisons work.\n // eslint-disable-next-line eqeqeq\n\n if (preferredDoc != document && (subWindow = document.defaultView) && subWindow.top !== subWindow) {\n // Support: IE 11, Edge\n if (subWindow.addEventListener) {\n subWindow.addEventListener("unload", unloadHandler, false); // Support: IE 9 - 10 only\n } else if (subWindow.attachEvent) {\n subWindow.attachEvent("onunload", unloadHandler);\n }\n } // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n // Safari 4 - 5 only, Opera <=11.6 - 12.x only\n // IE/Edge & older browsers don\'t support the :scope pseudo-class.\n // Support: Safari 6.0 only\n // Safari 6.0 supports :scope but it\'s an alias of :root there.\n\n\n support.scope = assert(function (el) {\n docElem.appendChild(el).appendChild(document.createElement("div"));\n return typeof el.querySelectorAll !== "undefined" && !el.querySelectorAll(":scope fieldset div").length;\n }); // Support: Chrome 105+, Firefox 104+, Safari 15.4+\n // Make sure forgiving mode is not used in `CSS.supports( "selector(...)" )`.\n //\n // `:is()` uses a forgiving selector list as an argument and is widely\n // implemented, so it\'s a good one to test against.\n\n support.cssSupportsSelector = assert(function () {\n /* eslint-disable no-undef */\n return CSS.supports("selector(*)") && // Support: Firefox 78-81 only\n // In old Firefox, `:is()` didn\'t use forgiving parsing. In that case,\n // fail this test as there\'s no selector to test against that.\n // `CSS.supports` uses unforgiving parsing\n document.querySelectorAll(":is(:jqfake)") && // `*` is needed as Safari & newer Chrome implemented something in between\n // for `:has()` - it throws in `qSA` if it only contains an unsupported\n // argument but multiple ones, one of which is supported, are fine.\n // We want to play safe in case `:is()` gets the same treatment.\n !CSS.supports("selector(:is(*,:jqfake))");\n /* eslint-enable */\n });\n /* Attributes\n ---------------------------------------------------------------------- */\n // Support: IE<8\n // Verify that getAttribute really returns attributes and not properties\n // (excepting IE8 booleans)\n\n support.attributes = assert(function (el) {\n el.className = "i";\n return !el.getAttribute("className");\n });\n /* getElement(s)By*\n ---------------------------------------------------------------------- */\n // Check if getElementsByTagName("*") returns only elements\n\n support.getElementsByTagName = assert(function (el) {\n el.appendChild(document.createComment(""));\n return !el.getElementsByTagName("*").length;\n }); // Support: IE<9\n\n support.getElementsByClassName = rnative.test(document.getElementsByClassName); // Support: IE<10\n // Check if getElementById returns elements by name\n // The broken getElementById methods don\'t pick up programmatically-set names,\n // so use a roundabout getElementsByName test\n\n support.getById = assert(function (el) {\n docElem.appendChild(el).id = expando;\n return !document.getElementsByName || !document.getElementsByName(expando).length;\n }); // ID filter and find\n\n if (support.getById) {\n Expr.filter["ID"] = function (id) {\n var attrId = id.replace(runescape, funescape);\n return function (elem) {\n return elem.getAttribute("id") === attrId;\n };\n };\n\n Expr.find["ID"] = function (id, context) {\n if (typeof context.getElementById !== "undefined" && documentIsHTML) {\n var elem = context.getElementById(id);\n return elem ? [elem] : [];\n }\n };\n } else {\n Expr.filter["ID"] = function (id) {\n var attrId = id.replace(runescape, funescape);\n return function (elem) {\n var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");\n return node && node.value === attrId;\n };\n }; // Support: IE 6 - 7 only\n // getElementById is not reliable as a find shortcut\n\n\n Expr.find["ID"] = function (id, context) {\n if (typeof context.getElementById !== "undefined" && documentIsHTML) {\n var node,\n i,\n elems,\n elem = context.getElementById(id);\n\n if (elem) {\n // Verify the id attribute\n node = elem.getAttributeNode("id");\n\n if (node && node.value === id) {\n return [elem];\n } // Fall back on getElementsByName\n\n\n elems = context.getElementsByName(id);\n i = 0;\n\n while (elem = elems[i++]) {\n node = elem.getAttributeNode("id");\n\n if (node && node.value === id) {\n return [elem];\n }\n }\n }\n\n return [];\n }\n };\n } // Tag\n\n\n Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {\n if (typeof context.getElementsByTagName !== "undefined") {\n return context.getElementsByTagName(tag); // DocumentFragment nodes don\'t have gEBTN\n } else if (support.qsa) {\n return context.querySelectorAll(tag);\n }\n } : function (tag, context) {\n var elem,\n tmp = [],\n i = 0,\n // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n results = context.getElementsByTagName(tag); // Filter out possible comments\n\n if (tag === "*") {\n while (elem = results[i++]) {\n if (elem.nodeType === 1) {\n tmp.push(elem);\n }\n }\n\n return tmp;\n }\n\n return results;\n }; // Class\n\n Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {\n if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {\n return context.getElementsByClassName(className);\n }\n };\n /* QSA/matchesSelector\n ---------------------------------------------------------------------- */\n // QSA and matchesSelector support\n // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\n\n rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21)\n // We allow this because of a bug in IE8/9 that throws an error\n // whenever `document.activeElement` is accessed on an iframe\n // So, we allow :focus to pass through QSA all the time to avoid the IE error\n // See https://bugs.jquery.com/ticket/13378\n\n rbuggyQSA = [];\n\n if (support.qsa = rnative.test(document.querySelectorAll)) {\n // Build QSA regex\n // Regex strategy adopted from Diego Perini\n assert(function (el) {\n var input; // Select is set to empty string on purpose\n // This is to test IE\'s treatment of not explicitly\n // setting a boolean content attribute,\n // since its presence should be enough\n // https://bugs.jquery.com/ticket/12359\n\n docElem.appendChild(el).innerHTML = "" + ""; // Support: IE8, Opera 11-12.16\n // Nothing should be selected when empty strings follow ^= or $= or *=\n // The test attribute must be unknown in Opera but "safe" for WinRT\n // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\n if (el.querySelectorAll("[msallowcapture^=\'\']").length) {\n rbuggyQSA.push("[*^$]=" + whitespace + "*(?:\'\'|\\"\\")");\n } // Support: IE8\n // Boolean attributes and "value" are not treated correctly\n\n\n if (!el.querySelectorAll("[selected]").length) {\n rbuggyQSA.push("\\\\[" + whitespace + "*(?:value|" + booleans + ")");\n } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\n\n if (!el.querySelectorAll("[id~=" + expando + "-]").length) {\n rbuggyQSA.push("~=");\n } // Support: IE 11+, Edge 15 - 18+\n // IE 11/Edge don\'t find elements on a `[name=\'\']` query in some cases.\n // Adding a temporary attribute to the document before the selection works\n // around the issue.\n // Interestingly, IE 10 & older don\'t seem to have the issue.\n\n\n input = document.createElement("input");\n input.setAttribute("name", "");\n el.appendChild(input);\n\n if (!el.querySelectorAll("[name=\'\']").length) {\n rbuggyQSA.push("\\\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:\'\'|\\"\\")");\n } // Webkit/Opera - :checked should return selected option elements\n // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n // IE8 throws error here and will not see later tests\n\n\n if (!el.querySelectorAll(":checked").length) {\n rbuggyQSA.push(":checked");\n } // Support: Safari 8+, iOS 8+\n // https://bugs.webkit.org/show_bug.cgi?id=136851\n // In-page `selector#id sibling-combinator selector` fails\n\n\n if (!el.querySelectorAll("a#" + expando + "+*").length) {\n rbuggyQSA.push(".#.+[+~]");\n } // Support: Firefox <=3.6 - 5 only\n // Old Firefox doesn\'t throw on a badly-escaped identifier.\n\n\n el.querySelectorAll("\\\\\\f");\n rbuggyQSA.push("[\\\\r\\\\n\\\\f]");\n });\n assert(function (el) {\n el.innerHTML = "" + ""; // Support: Windows 8 Native Apps\n // The type and name attributes are restricted during .innerHTML assignment\n\n var input = document.createElement("input");\n input.setAttribute("type", "hidden");\n el.appendChild(input).setAttribute("name", "D"); // Support: IE8\n // Enforce case-sensitivity of name attribute\n\n if (el.querySelectorAll("[name=d]").length) {\n rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");\n } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n // IE8 throws error here and will not see later tests\n\n\n if (el.querySelectorAll(":enabled").length !== 2) {\n rbuggyQSA.push(":enabled", ":disabled");\n } // Support: IE9-11+\n // IE\'s :disabled selector does not pick up the children of disabled fieldsets\n\n\n docElem.appendChild(el).disabled = true;\n\n if (el.querySelectorAll(":disabled").length !== 2) {\n rbuggyQSA.push(":enabled", ":disabled");\n } // Support: Opera 10 - 11 only\n // Opera 10-11 does not throw on post-comma invalid pseudos\n\n\n el.querySelectorAll("*,:x");\n rbuggyQSA.push(",.*:");\n });\n }\n\n if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {\n assert(function (el) {\n // Check to see if it\'s possible to do matchesSelector\n // on a disconnected node (IE 9)\n support.disconnectedMatch = matches.call(el, "*"); // This should fail with an exception\n // Gecko does not error, returns false instead\n\n matches.call(el, "[s!=\'\']:x");\n rbuggyMatches.push("!=", pseudos);\n });\n }\n\n if (!support.cssSupportsSelector) {\n // Support: Chrome 105+, Safari 15.4+\n // `:has()` uses a forgiving selector list as an argument so our regular\n // `try-catch` mechanism fails to catch `:has()` with arguments not supported\n // natively like `:has(:contains("Foo"))`. Where supported & spec-compliant,\n // we now use `CSS.supports("selector(:is(SELECTOR_TO_BE_TESTED))")`, but\n // outside that we mark `:has` as buggy.\n rbuggyQSA.push(":has");\n }\n\n rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));\n rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));\n /* Contains\n ---------------------------------------------------------------------- */\n\n hasCompare = rnative.test(docElem.compareDocumentPosition); // Element contains another\n // Purposefully self-exclusive\n // As in, an element does not contain itself\n\n contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {\n // Support: IE <9 only\n // IE doesn\'t have `contains` on `document` so we need to check for\n // `documentElement` presence.\n // We need to fall back to `a` when `documentElement` is missing\n // as `ownerDocument` of elements within `