/**
* Contiene las funciones para simplificar el uso de algunos componentes de framework 7.
* Además de la inicialización automática del objeto app
* @see <a href="https://framework7.io/" target="_blank">Documentación Framework 7</a>
* @module Fw7_App
*/
var urlSrv = window.location.origin;
var mobile = false;
/**
* Indica si se está usando un dispositivo móvil
* @type {boolean}*/
var isMobile = {
Android: function () {
return navigator.userAgent.match(/Android/i);
},
BlackBerry: function () {
return navigator.userAgent.match(/BlackBerry/i);
},
iOS: function () {
return navigator.userAgent.match(/iPhone|iPad|iPod/i);
},
Opera: function () {
return navigator.userAgent.match(/Opera Mini/i);
},
Windows: function () {
return navigator.userAgent.match(/IEMobile/i);
},
any: function () {
return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
}
};
if (isMobile.any()) mobile = true;
var pickersF7 = {};
var autocomplete = {};
var autocompleteProps = {};
// Dom7
var $$ = Dom7;
/**
* Objeto de la aplicación framework 7, tiene unas configuraciones por defecto,
* el texto de los botones de alerta, el formato del calendario, mensaje para smart select, entre otros
* @type {object} */
var app = new Framework7({
root: '#form1', // App root element
id: 'io.framework7.formBPMCo', // App bundle ID
name: '', // App name
theme: 'auto', // Automatic theme detection
dialog: {
buttonOk: 'ACEPTAR',
buttonCancel: 'CANCELAR'
},
navbar: {
hideOnPageScroll: false,
iosCenterTitle: false
},
calendar: {
monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
monthNamesShort: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
dayNames: ['Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo'],
dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'],
touchMove: true,
animate: true,
closeOnSelect: true,
dateFormat: 'dd/mm/yyyy'
},
smartSelect: {
appendSearchbarNotFound: 'No se encontraron resultados',
closeOnSelect: true
}
});
var mainView = app.views.create('.view-main', {
url: '/'
});
/**
*Se encarga de inicializar un calendario para los celulares, trabaja como los combos en IOS
*@param {string} id id del campo que tendrá el picker
*@param {function} funcionCallBack Función que se dispara al seleccionar la fecha
*@param {Array} objValues Arreglo con el año inicial y el año final
*@param {function} fnChange Función que se dispara al cambiar el día, o el mes o el año
*@example fechaPicker('t8', ValidarViajesEnFecha, [2018, 2019]);
*/
function fechaPicker(id, funcionCallBack, objValues, fnChange) {
var today = new Date();
today.setMonth(today.getMonth() + 1);
var pickerInline = app.picker.create({
inputEl: '#' + id,
rotateEffect: true,
renderToolbar: function () {
return '<div class="toolbar">' +
'<div class="toolbar-inner">' +
'<div class="right">' +
'<a href="#" class="link sheet-close popover-close">Aceptar</a>' +
'</div>' +
'</div>' +
'</div>';
},
value: [today.getDate(), today.getMonth(), today.getFullYear()],
formatValue: function (values) {
return formatFecha(values[0]) + '/' + formatFecha(values[1]) + '/' + values[2];
},
cols: [
// Days
{
values: (function () {
if (objValues == null || objValues.dias == null || objValues.dias.length == 0) {
var arr = [];
for (var i = 1; i <= 31; i++) { arr.push(i); }
return arr;
}
return objValues.dias;
})(),
},
// Months
{
values: (function () {
if (objValues == null || objValues.meses == null || objValues.meses.length == 0) {
var arr = [];
for (var i = 1; i <= 12; i++) { arr.push(i); }
return arr;
}
return objValues.meses;
})(),
displayValues: (function () {
var arr = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
if (objValues == null || objValues.meses == null || objValues.meses.length == 0) {
return arr;
} else {
var arrN = [];
for (var i = 0; i < objValues.meses.length; i++) {
arrN.push(arr[objValues.meses[i] - 1]);
}
return arrN;
}
})(),
textAlign: 'left'
},
// Years
{
values: (function () {
if (objValues == null || objValues.anios == null || objValues.anios.length == 0) {
var arr = [];
for (var i = 1950; i <= 2030; i++) { arr.push(i); }
return arr;
}
return objValues.anios;
})(),
}
],
on: {
open: function (picker) {
setPickerDate(picker);
picker.$el.find('.popover-close').on('click', function () {
if (funcionCallBack != null && funcionCallBack != '') {
funcionCallBack();
}
});
},
change: function (picker, values, displayValues) {
var daysInMonth = new Date(picker.value[2], picker.value[1] * 1, 0).getDate();
if (values[0] > daysInMonth) {
picker.cols[0].setValue(daysInMonth);
}
if (fnChange != null) {
fnChange.apply(picker, [picker.$inputEl]);
}
},
}
});
pickersF7[id] = pickerInline;
}
/**
*Pone la fecha actual en el picker para móviles {@link fechaPicker}
*@param {object} picker objeto picker creado en la función
*@param {function} funcionCallBack Función que se dispara al seleccionar la fecha
*/
function setPickerDate(picker) {
if (getFecha) {
if (picker.cols.length == 0) { return }
var vFecha = (picker.$inputEl.val() == '') ? getAhora(true) : picker.$inputEl.val();
vFecha = getFecha(vFecha);
picker.cols[0].setValue(vFecha.getDate());
picker.cols[1].setValue(vFecha.getMonth() + 1);
picker.cols[2].setValue(vFecha.getFullYear());
} else {
console.error('Falta incluir el script de calendario.js');
}
}
function formatFecha(num) {
num = parseInt(num);
if (num <= 9)
return '0' + num;
return num.toString();
}
/**
*Genera una sugerencia simple que carga los datos bajo el campo de texto
*@param {string} input id del input que será sugenrecia
*@param {string} metodo Ruta del método en el backEnd para el llamad ajax
*@param {string} placeHolder Nombre que aparecerá antes de escribir
*@param {string} campoValor El nombre del campo que se tomará como valor con los datos que vienen del servidor
*@param {function} funcionCallBack Función que se invocará al seleccioar una opción de la sugerencia,
*devuelve el objeto completo con los datos seleccionados
*@param {string} campoMostrar El nombre del campo que vienen del servidor y se mostrará en la lista
*@param {function} fnRender Función que se invoca antes de renderizar el listado
*@param {string} params concatenación de los valores de parametros para la consulta al backEnd, el orden del campo a consultar
*@example
autocompleteFw('t1', 'e_EFG.ajax_p100.getHotel', 'Hoteles', 'pvNombre', function (value) {
if (value.length == 1 && value[0] != undefined) {
_$('#' + input).val(value[0].pvNombre);
}
}, 'pvNombre', null, 'pais|{0}|sociedad');
*@deprecated usar la función autocompleteFw2
*{@link autocompleteFw2}
*/
function autocompleteFw(input, metodo, placeHolder, campoValor, funcionCallBack, campoMostrar, fnRender, params) {
var texto = (campoMostrar == null || campoValor == '') ? campoValor : campoMostrar;
var autocompleteTypeahead = app.autocomplete.create({
inputEl: '#' + input,
openIn: 'dropdown',
preloader: true, //enable preloader
highlightMatches: true,
notFoundText: 'No se encontraron resultados',
/* If we set valueProperty to "id" then input value on select will be set according to this property */
valueProperty: campoValor, //object's "value" property name
textProperty: texto, //object's "text" property name
typeahead: true,
dropdownPlaceholderText: placeHolder,
source: function (query, render) {
var autocomplete = this;
var results = [];
if (query.length === 0) {
render(results);
return;
}
// Show Preloader
autocomplete.preloaderShow();
var parametros = query;
if (params != null)
parametros = params.join('|').format(query);
appRequest(metodo, parametros, function (data) {
// Hide Preoloader
autocomplete.preloaderHide();
if (fnRender != null)
data = fnRender.apply(this, [data, query]);
// Render items by passing array with result items
render(data);
});
},
on: {
autocompleteClosed: function (value) {
if (funcionCallBack != null && funcionCallBack != '')
funcionCallBack(value.value);
},
},
});
}
/**
*Genera una sugerencia simple que carga los datos bajo el campo de texto
*@param {string} input id del input que será sugenrecia
*@param {string} metodo Ruta del método en el backEnd para el llamad ajax
*@param {string} placeHolder Nombre que aparecerá antes de escribir
*@param {string} campoValor El nombre del campo que se tomará como valor con los datos que vienen del servidor
*@param {function|object} funcionCallBack Función que se invocará al seleccioar una opción de la sugerencia,
*o un objeto donde se definen las funciones de open, close, autocompleteClosed, change, render
*devuelve el objeto completo con los datos seleccionados
*@param {string} campoMostrar El nombre del campo que vienen del servidor y se mostrará en la lista
*@param {function} fnRender Función que se invoca antes de renderizar el listado
*@param {string} params concatenación de los valores de parametros para la consulta al backEnd, el orden del campo a consultar
*@param {Array} dataLocal Si se desea cargar con valores locales la sugerencia
*@example
autocompleteFw2('t1', 'e_EFG.ajax_p100.getHotel', 'Hoteles', 'pvNombre', function (value) {
if (value.length == 1 && value[0] != undefined) {
_$('#' + input).val(value[0].pvNombre);
}
}, 'pvNombre', null, 'pais|{0}|sociedad', null);
*/
function autocompleteFw2(id, metodo, placeHolder, campoValor, funcionCallBack, campoMostrar, fnRender, params, dataLocal) {
if (dataLocal == null) dataLocal = [];
var funcionesSug = { 'open': null, 'autocompleteClosed': null, 'close': null, 'change': null, 'render': null };
if (funcionCallBack != null && funcionCallBack != '' && typeof funcionCallBack == 'object') {
funcionesSug.open = funcionCallBack.open;
funcionesSug.autocompleteClosed = funcionCallBack.autocompleteClosed;
funcionesSug.close = funcionCallBack.close;
funcionesSug.change = funcionCallBack.change;
funcionesSug.render = funcionCallBack.render;
}
if (funcionCallBack != null && funcionCallBack != '' && typeof funcionCallBack == 'function')
funcionesSug.autocompleteClosed = funcionCallBack;
if (fnRender != null && fnRender != '' && typeof fnRender == 'function')
funcionesSug.render = fnRender;
var texto = (campoMostrar == null) ? campoValor : campoMostrar;
if (campoMostrar == null)
campoMostrar = campoValor;
var autocompleteTypeahead = app.autocomplete.create({
openerEl: '#_' + id,
openIn: 'popup',
preloader: true,
notFoundText: 'No se encontraron resultados',
prms: params,
valueProperty: campoValor, //object's "value" property name
textProperty: texto, //object's "text" property name
closeOnSelect: true,
searchbarPlaceholder: placeHolder,
source: function (query, render) {
var autocomplete = this;
var results = [];
if (dataLocal.length == 0 && query.length === 0) {
render(results);
return;
}
if (dataLocal.length > 0) {
if (query.length > 0)
results = dataLocal.filter(x => x[campoMostrar].toLowerCase().indexOf(query.toLowerCase()) != -1);
render(results);
return;
}
// Show Preloader
autocomplete.preloaderShow();
var parametros = query;
if (params != null)
parametros = params.join('|').format(query);
// Do Ajax request to Autocomplete data
appRequest(metodo, parametros, function (data) {
// Hide Preoloader
autocomplete.preloaderHide();
if (funcionesSug.render != null)
data = funcionesSug.render.apply(this, [data, query]);
// Render items by passing array with result items
render(data);
});
},
on: {
open: function (el) {
var sug = this;
if (dataLocal.length > 0 && sug.value.length == 0) {
sug.$el.find('input').val('a');
sug.$el.find('input').trigger('change');
}
setTimeout(function () { sug.$el.find('input').focus();}, 500);
verCerrarIframe();
if (funcionesSug.open != null)
funcionesSug.open.apply(this, [el]);
},
autocompleteClosed: function (data) {
if (funcionesSug.autocompleteClosed != null)
funcionesSug.autocompleteClosed.apply(this, [data.value]);
},
close: function (el) {
verCerrarIframe();
if (funcionesSug.close != null)
funcionesSug.close.apply(this, [el]);
},
change: function (data) {
if (funcionesSug.change != null)
funcionesSug.change.apply(this, [data]);
}
},
});
autocomplete[id] = autocompleteTypeahead;
autocompleteProps[id] = { 'metodo': metodo, 'params': params, 'campoValor': campoValor};
}
function appRequest(metodo, parametros, fnSuccess){
app.request({
url: `${urlSrv}/API/APIV1.asmx/DT2JSON2`,
method: 'POST',
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
data: {
method: metodo,
parameters: parametros
},
success: fnSuccess
});
}
/**
*Cargar un valor por defecto en la sugerencia
*@param {string} id id del campo que es sugerencia ya inicializada
*@param {string} valor valor que se quiere poner en la sugerencia, debe ser un valor válido según el backend
*@example setValueAutocompleteFw2('t1', 'Hotel Estelar')
*/
function setValueAutocompleteFw2(id, valor) {
if (autocompleteProps[id] != null) {
var parametros = valor;
if (autocompleteProps[id].params != null)
parametros = autocompleteProps[id].params.join('|').format(valor);
var metodo = autocompleteProps[id].metodo;
appRequest(metodo, parametros, function (data) {
if (data != null && data.length > 0) {
var campoVal = autocompleteProps[id].campoValor;
var objDataSug = data.find(x => x[campoVal] == valor);
if (objDataSug != null)
autocomplete[id].value.push(objDataSug);
}
});
}
}
/**
*Se invoca automáticamente para que los links funcionen de manera correcta, pero deben tener un nodo
*padre con la clase <b>fw7Link</b>
*/
function processLinks() {
var links = document.querySelectorAll('.fw7Link a');
for (var i = 0; i < links.length; i++) {
links[i].classList.add('link');
links[i].classList.add('external');
}
}
processLinks();
function verCerrarIframe() {
try {
var modals = document.querySelectorAll('.modal-in');
var display = (modals.length > 0) ? 'none' : '';
window.parent.document.getElementById('closeButton').style.display = display;
} catch (E) { }
}
$('.popup').on('popup:open', function (e, popup) {
verCerrarIframe();
});
$('.popup').on('popup:close', function (e, popup) {
verCerrarIframe();
});
/**
*Se encarga de evitar un error cuando los smartSelects están en modales
*/
function f7SmartSelectFix() {
if (app) {
var f7SmartS = _$('.smart-select');
f7SmartS.each(function () {
var ssLink = _$(this);
var s = ssLink.find('select');
ssLink.addClass(s.prop('id'));
var data = ssLink.data();
var ss = app.smartSelect.create(app.utils.extend({
el: this
}, data));
ss.view = mainView;
ss.off('open');
ss.off('close');
ss.on('open', function () { verCerrarIframe(); });
ss.on('close', function () {
if (_$(this.selectEl).prop('multiple') != null && _$(this.selectEl).prop('multiple')) {
var arrV = _$(this.selectEl).val();
if (arrV[0] == '') {
arrV.splice(0, 1);
_$(this.selectEl).val(arrV);
}
}
verCerrarIframe();
});
});
} else {
console.error('No existe F7 app inicializada');
}
}
/**
*Se encarga de cargar los smart select con los textos de los campos ocultos
*/
function f7SmartSelectSetVal() {
var f7SmartS = _$('.smart-select');
f7SmartS.each(function () {
if (_$(this).hasClass('noFixVal'))
return;
var ssLink = _$(this);
var txS = _$(ssLink).parent().find('input[type="hidden"]').val();
txS = (txS == null) ? '' : txS;
if (txS == '') {
txS = _$(ssLink).parent().find('select option:selected').text();
if (txS != '' && txS.toUpperCase() != 'SELECCIONE')
_$(ssLink).parent().find('input[type="hidden"]').val(txS);
}
var select = _$(ssLink).parent().find('select');
var ss = app.smartSelect.get(ssLink);
if (ss != null) {
if (select.val() == null || select.val().toString() == '')
txS = '';
app.smartSelect.get(ssLink).setValue('');
if (ss.multiple)
app.smartSelect.get(ssLink).setValue(txS.split(','));
else
app.smartSelect.get(ssLink).setValue(txS);
}
});
}
/**
*Se encarga de bloquear todos los smartSelect
*@param {boolean} bloq true para bloquear, falso para desbloquear
*/
function f7SmartSelectBloq(bloq) {
if (bloq) {
var f7SmartS = _$('.smart-select');
f7SmartS.each(function () {
_$('<div class="ssBloq"></div>').insertBefore(this);
});
} else {
_$('.ssBloq').remove();
}
}
/**
*Refresca el valor de un smartSelect
*@param {string} cual id jQuery del combo
*@param {string} valor el valor que va a quedar en el combo
*@param {string} idVal id jQuery del campo asociado que tiene el texto
*@param {boolean} noChange true si desea que no se invoque el change del combo, false o null para invocarlo
*@example f7SetSelect('#s3', 'PJ', '#_ts3', true);
*/
function f7SetSelect(cual, valor, idVal, noChange) {
_$(cual).val(valor);
if (noChange == null)
_$(cual).trigger('change');
if (idVal == null)
idVal = cual + '_';
app.smartSelect.get(cual.replace('#', '.')).setValue(_$(idVal).val());
}
/**
*Se encarga de bloquear los smartSelect indicados
*@param {boolean} bloq true para bloquear, falso para desbloquear
*@param {Array} arrIds arreglo con los ids de los combos a bloquear o desbloquear
*@example f7SmartSelectBloqForIds(true, ['s2','s3','s4']);
*/
function f7SmartSelectBloqForIds(bloq, arrIds) {
for (var i = 0; i < arrIds.length; i++) {
var ss = _$('#' + arrIds[i]).parents('.smart-select');
if (bloq)
_$('<div class="ssBloq"></div>').insertBefore(ss[0]);
else
ss.parent().find('.ssBloq').remove();
}
}