# vim: set expandtab tabstop=2 shiftwidth=2 fileencoding=utf-8:
#
# Por compartir entre motores que operen sobre msip
# jquery ahora debe venir reciente por webpacker exportando a ambiente global con expose-loader,
# ver gem https://gitlab.com/pasosdeJesus/msip/wiki/Pasando-de-sprockets-a-webpacker-con-Rails-6
#//= require cocoon
#//= require msip/geo
#//= require msip/ubicacionpre
#//= require msip/motor_es5
# HTML
# Remplaza las opciones de un cuadro de seleccion por unas nuevas
# @idsel es identificación del select
# @nuevasop Arreglo de hashes con nuevas opciones, cada una tiene propiedades
# para la id (por omision id) y la etiqueta (por omisión nombre).
# @usachosen Es verdadero si y solo si el cuadro de selección usa chosen
# @cid campo con id en cada elemento de @nuevasop por omision id
# @cetiqueta campo con etiqueta en cada elemento de @nuevasop por omision nombre
# @opvacia Incluye opción vacia entre las posibles
@msip_remplaza_opciones_select = (idsel, nuevasop, usachosen = false, cid = 'id',
cetiqueta = 'nombre', opvacia = false) ->
s = $("#" + idsel)
if (s.length != 1)
alert('msip_remplaza_opciones_select: no se encontró ' + idsel)
return
sel = s.val()
nh = ''
if opvacia
nh = ""
nuevasop.forEach( (v) ->
id = v[cid]
nh = nh + ""
)
s.html(nh)
if usachosen
$('#' + idsel).trigger("chosen:updated");
return
# Escapa cadena por presentar para evitar HTML
# De https://stackoverflow.com/questions/6234773/can-i-escape-html-special-chars-in-javascript
@msip_escapaHtml = (cadena) ->
cadena.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'")
# Actualiza opciones de cuadros de selección que dependen de datos de un
# formulario anidado
#
# @params idfuente id en html del formulario anidado
# @params posfijo_id_fuente posfijo para identificaciones de campos con
# valores para opciones
# @params posfijo_etiqueta_fuente posfijo para identificaciones de campos
# con etiquetas para opciones
# @params seldestino lista de selectores que identifica cuadros de selección
# dependientes de la fuente y que serán modificados
@msip_actualiza_cuadros_seleccion_dependientes = (idfuente, posfijo_id_fuente, posfijo_etiqueta_fuente, seldestino, opvacia = false) ->
nuevasop = []
lobj = $('#' + idfuente + ' .nested-fields[style!="display: none;"]')
lobj.each((k, v) ->
id = $(v).find('input[id$=' + posfijo_id_fuente + ']').val()
etiqueta = $(v).find('input[id$=' + posfijo_etiqueta_fuente + ']').val()
nuevasop.push({id: id, etiqueta: etiqueta})
)
seldestino.forEach( (sel) ->
$(sel).each((i,r) ->
conch = $(r).hasOwnProperty('chosen')
msip_remplaza_opciones_select($(r).attr('id'), nuevasop, conch, 'id', 'etiqueta', opvacia)
)
)
return
# Actualiza opciones de cuadros de selección que dependen de datos de un
# formulario anidado. Etiquetas de opciones se calculan con función.
#
# @params idfuente id en html del formulario anidado
# @params posfijo_id_fuente posfijo para identificaciones de campos con
# valores para opciones
# @params fun_etiqueta función que retorna etiqueta que corresponde a una
# opción
# @params seldestino lista de selectores que identifica cuadros de selección
# dependientes de la fuente y que serán modificados
@msip_actualiza_cuadros_seleccion_dependientes_fun_etiqueta = (idfuente, posfijo_id_fuente, fun_etiqueta, seldestino, opvacia = false) ->
nuevasop = []
lobj = $('#' + idfuente + ' .nested-fields[style!="display: none;"]')
lobj.each((k, v) ->
id = $(v).find('input[id$=' + posfijo_id_fuente + ']').val()
etiqueta = fun_etiqueta($(v))
nuevasop.push({id: id, etiqueta: etiqueta})
)
seldestino.forEach( (sel) ->
$(sel).each((i,r) ->
conch = $(r).hasOwnProperty('chosen')
msip_remplaza_opciones_select($(r).attr('id'), nuevasop, conch, 'id', 'etiqueta', opvacia)
)
)
return
# Intenta eliminar una fila añadida con coocon
# @fila fila por eliminar de una tabla dinámica manejada por cocoon
# @prefijo_url Preijo del URL al cual enviar requerimientos AJAX para eliminar
# se le concatenará la identificación i.e prefijo_url/id/ (se espera json)
# y se le agregaría antes el punto de montaje
# @seldep Lista de selectores a los cuadros de selección que dependen
# de la fila por eliminar (si existen esta función no eliminará la fila
# sino alertará).
@msip_intenta_eliminar_fila = (fila, prefijo_url, seldep) ->
# Evitar ejecutar 2 veces en menos de 2 segundos (suele pasar con
# rails+turbolinks+jquery)
t = Date.now()
d = -1
if (window.ajax_t)
d = (t - window.ajax_t) / 1000
window.ajax_t = t
if (d == -1 || d > 2)
# encontrar id de registro por eliminar
bid = fila.find('input[id$=_id]')
if (bid.length != 1)
return false
ide = +$(bid[0]).val()
if (seldep != null)
num = 0
seldep.forEach( (sel) ->
$(sel + ' option:selected').each(() ->
if (+$(this).val() == ide)
num+=1
)
)
if (num>0)
alert('Hay elementos que depende de este (' + num + '). ' +
' Eliminelos antes.')
return false
root = window
purl = prefijo_url
if prefijo_url.substr(0, root.puntomontaje.length) != root.puntomontaje
purl = root.puntomontaje + prefijo_url
$.ajax({
url: purl + ide,
type: 'DELETE',
dataType: 'json',
beforeSend: ((xhr) ->
# Ensure CSRF-Token is sent
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'))
),
success: ((response) ->
$(fila).remove()
),
error: ((response) ->
if response.status != 0 && response.responseText != ''
alert('Error: el servicio respondio con: ' +
response.status + '\n' + response.responseText)
)
})
return true
# JAVASCRIPT
# Añade endsWith a la clase String
# http://stackoverflow.com/questions/280634/endswith-in-javascript
if (typeof String.prototype.endsWith != 'function')
String.prototype.endsWith = (suffix) ->
return this.indexOf(suffix, this.length - suffix.length) != -1
@msip_meses = ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic']
# Retorna una fecha localizada a partir de una fecha ISO
@msip_retorna_fecha_localizada = (fecha, formato_fecha) ->
fecha_sep = msip_partes_fecha_localizada(fecha, formato_fecha)
mes_nom = @msip_meses[fecha_sep[1] - 1]
pc = mes_nom.substring( 0, 1 )
pcmayus = pc.toUpperCase()
resto = mes_nom.substring( 1 )
mes_nom_cap = pcmayus + resto
return fecha_sep[2].toString() + '/' + mes_nom_cap + '/' + fecha_sep[0].toString()
# Retornas partes de una fecha en un formato dado
@msip_partes_fecha_localizada = (fecha, formato_fecha) ->
if (formato_fecha == 'dd/M/yyyy' || formato_fecha == 'dd-M-yyyy')
anio = +fecha.slice(7,11)
dia = +fecha.slice(0,2)
nmes = fecha.slice(3,6)
if typeof nmes != 'undefined' && @msip_meses.includes(nmes.toLowerCase())
mes = @msip_meses.indexOf(nmes.toLowerCase()) + 1
else
mes = 6
else if typeof fecha == 'string'
anio = +fecha.slice(0,4)
mes = +fecha.slice(5,7)
dia = +fecha.slice(8,10)
else
anio = 1900
mes = 1
dia = 1
return [anio, mes, dia]
# Verifica que una fecha sea válida
# De: http://stackoverflow.com/questions/8098202/javascript-detecting-valid-dates
@fecha_valida = (text) ->
date = Date.parse(text)
if (isNaN(date))
return false
comp = text.split('-')
if (comp.length != 3)
return false;
y = parseInt(comp[0], 10)
m = parseInt(comp[1], 10)
d = parseInt(comp[2], 10)
date = new Date(y, m - 1, d);
return (date.getFullYear() == y &&
date.getMonth() + 1 == m && date.getDate() == d);
# AJAX
# Llamada a API
# (recordar en rails responder con render json: objeto, status:ok,
# donde objeto es un objeto --no una cadena o entero)
#
# @root
# @ruta ruta (sin punto de montaje)
# @datos Datos por enviar
# @funproc Funcion para procesar respuesta
@msip_ajax_recibe_json = (root, ruta, datos, funproc) ->
msip_arregla_puntomontaje(root)
# Evitar cargar de la misma ruta 2 veces en menos de 2 segundos
# (suele pasar con rails+turbolinks+jquery)
t = Date.now()
d = -1
if (root.msip_ajax_recibe_json_t)
if (root.msip_ajax_recibe_json_t[ruta])
d = (t - root.msip_ajax_recibe_json_t[ruta]) / 1000
else
root.msip_ajax_recibe_json_t = {}
root.msip_ajax_recibe_json_t[ruta] = t
if (d == -1 || d > 2)
rutac = root.puntomontaje + ruta + ".json"
$.ajax({
url: rutac,
data: datos,
dataType: 'json',
method: 'GET'
}).fail( (jqXHR, texto) ->
alert('Error - ' + texto )
).done( (e, r) ->
funproc(root, e)
)
return true
# Envía con ajax a la ruta especificada junto con los datos, espera
# respuesta html de la cual extrae una parte con selector selresp y
# lo usa para volver a pintar el elemento con selector selelem
@msip_envia_ajax_datos_ruta_y_pinta= (ruta, datos, selresp, selelem, metodo='GET', tipo='html', concsrf = false ) ->
root = window
t = Date.now()
d = -1
if (root.msip_envia_ajax_t)
d = (t - root.msip_envia_ajax_t)/1000
root.msip_envia_ajax_t = t
if (d == -1 || d > 2)
msip_arregla_puntomontaje(root)
token = $('meta[name="csrf-token"]').attr('content');
rutac = root.puntomontaje + ruta + ".js"
$.ajax({
url: rutac,
data: datos,
dataType: tipo,
beforeSend: ((xhr) ->
if concsrf
xhr.setRequestHeader('X-CSRF-Token', token)
),
method: metodo
}).fail( (jqXHR, texto) ->
alert("Error con ajax a " + rutac + ": " + texto)
).done( (e, r) ->
if selresp != '' && selelem != ''
t=$(e).find(selresp)[0]
if (selresp == selelem)
$(selelem).replaceWith(t)
else
$(selelem).html(t)
$('[data-behaviour~=datepicker]').datepicker({
format: root.formato_fecha,
autoclose: true,
todayHighlight: true,
language: '<%= Rails.configuration.i18n.default_locale %>'
})
return
)
return
# Envia con AJAX datos del formulario, junto con el botón submit,
# evitando duplicaciones y volviendo a pintar el formulario.
# @param idf Id de formulario
# @param listaidsrempl Lista de ids por repintar
# @param metodo GET, POST, PUT
# @param tipo json, script, xml o html (html puede ser interceptado
# por redirect_to con turbolinks y presentado automáticamente en navegador)
# @param alertaerror Presentar alerta en caso de error (true/false)
# @param vcommit Valor para commit
#
@msip_enviarautomatico_formulario_y_repinta = (idf, listaidsrempl,
metodo='GET', alertaerror=true, vcommit='Enviar') ->
root = window
t = Date.now()
d = -1
if (root.msip_enviarautomatico_t)
d = (t - root.msip_enviarautomatico_t)/1000
root.msip_enviarautomatico_t = t
f = $('form[id=' + idf + ']')
root.msip_enviarautomatico_idf = idf
root.msip_enviarautomatico_l = listaidsrempl
# NO se permite mas de un envio en 2 segundos
if (f.length ==1 && (d == -1 || d > 2))
a = f.attr('action')
vd = f.serializeArray()
vd.push({name: 'commit', value: vcommit})
vd.push({name: '_msip_enviarautomatico', value: 1})
vd.push({name: '_msip_enviarautomatico_y_repinta', value: 1})
dat = $.param(vd)
# En ocasiones lanza 2 veces seguidas el mismo evento.
# Evitamos enviar lo mismo.
if (!root.dant || root.dant != d)
root.dant = d
$.ajax({
url: a,
data: dat,
method: metodo,
dataType: 'html',
beforeSend: ((xhr) ->
# Asegurar envio de Token CSRF
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'))
),
error: ((response) ->
if alertaerror && response.status != 0 && response.responseText != ''
alert('Error: el servicio respondió: ' +
response.status + '\n' + response.responseText)
),
success: ( (e, r, j) ->
listaidsremp = root.msip_enviarautomatico_l
listaidsremp.forEach((idf) ->
t = $(e).find('#' + idf)[0]
#$('#' + idf).replaceWith(t)
$('#' + idf).html(t.innerHTML)
)
return
)
})
return
# Envia con AJAX datos del formulario, junto con el botón submit,
# evitando duplicaciones.
# @param f Formulario jquery-sado
# @param metodo GET, POST, PUT
# @param tipo json, script, xml o html (html puede ser interceptado
# por redirect_to con turbolinks y presentado automáticamente en navegador)
# @param alertaerror Presentar alerta en caso de error (true/false)
# @param vcommit Valor para commit
#
@msip_enviarautomatico_formulario = (f, metodo='GET', tipo='script',
alertaerror=true, vcommit='Enviar', agenviarautom = true) ->
root = window
t = Date.now()
d = -1
if (root.msip_enviarautomatico_t)
d = (t - root.msip_enviarautomatico_t)/1000
root.msip_enviarautomatico_t = t
# NO se permite mas de un envio en 2 segundos
if (d == -1 || d > 2)
a = f.attr('action')
vd = f.serializeArray()
vd.push({name: 'commit', value: vcommit})
if agenviarautom
vd.push({name: '_msip_enviarautomatico', value: 1})
dat = $.param(vd)
# En ocasiones lanza 2 veces seguidas el mismo evento.
# Evitamos enviar lo mismo.
if (!root.dant || root.dant != d)
root.dant = d
$.ajax({
url: a,
data: dat,
method: metodo
dataType: tipo
beforeSend: ((xhr) ->
# Asegurar envio de Token CSRF
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'))
),
error: ((response) ->
if alertaerror && response.status != 0 && response.responseText != ''
alert('Error: el servicio respondió: ' +
response.status + '\n' + response.responseText)
)
})
return
# Antes de visitar un enlace, producto de presionar un elemento ,
# agrega al URL destino datos de formulario
@msip_completa_enlace = (elema, idruta, rutagenera) ->
if idruta == null
f = $(elema).closest('form')
else
f = $("form[action$='" + idruta + "']")
d = f.serialize()
d += '&commit=Enviar'
root = window;
msip_arregla_puntomontaje(root)
if (root.puntomontaje != '/' || rutagenera[0] != '/') && rutagenera.substring(0, root.puntomontaje.length) != root.puntomontaje
rutagenera = root.puntomontaje + rutagenera
e = rutagenera + '?' + d
$(elema).attr('href', e)
# Ejecuta función con respuesta que recibe mendiante AJAX
# rutajson Ruta del API que respondera JSON (sin punto de montaje, ni .json)
# params Parametros por pasar a consulta AJAX
# f Función por llamar
# descerr Descripcion por presentar en caso de que el JSON no responda
# root Donde se almacenan objetos globales
@msip_funcion_tras_AJAX = (rutajson, params, f, descerr, root = window) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_funcion_tras_AJAX_t)
d = (t - root.msip_funcion_tras_AJAX_t)/1000
root.msip_funcion_tras_AJAX_t = t
# NO se permite mas de un envio en 2 segundos
if (d > 0 && d <= 2)
return
x = $.getJSON(root.puntomontaje + rutajson + ".json", params)
x.done((res) ->
f(root, res)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + params + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# Ejecuta función que recibe un parametro además de root y la respuesta que
# recibe mendiante AJAX
# rutajson Ruta del API que respondera JSON (sin punto de montaje, ni .json)
# params Parametros por pasar a consulta AJAX
# f Función por llamar
# p1 Parametro por pasara a la funcion f
# descerr Descripcion por presentar en caso de que el JSON no responda
# root Donde se almacenan objetos globales
@msip_funcion_1p_tras_AJAX = (rutajson, params, f, p1, descerr, root = window) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_funcion_1p_tras_AJAX_t)
d = (t - root.msip_funcion_1p_tras_AJAX_t)/1000
root.msip_funcion_1p_tras_AJAX_t = t
# NO se permite mas de un envio en 1 segundos
if (d > 0 && d <= 1)
return
x = $.getJSON(root.puntomontaje + rutajson + ".json", params)
x.done((res) ->
f(root, res, p1)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + params + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# Cambia cuadro de texto con cadena que recibe mediante AJAX
# rutajson Ruta del API que respondera JSON (sin punto de montaje), se
# supone que respondera un objeto json de la forma {res: cadena}
# params Parametros por pasar a consulta AJAX
# iddest Id del campo de texto destino
# descerr Descripcion por presentar en caso de que el JSON no responda
# f Función por llamar despues de llenar campo
# root Donde se almacenan objetos globales
@msip_cambia_cuadrotexto_AJAX = (rutajson, params, iddest, descerr, f = null, root = window) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_cambia_cuadrotexto_AJAX_t)
d = (t - root.msip_cambia_cuadrotexto_AJAX_t)/1000
root.msip_cambia_cuadrotexto_AJAX_t = t
# NO se permite mas de un envio en 2 segundos
if (d > 0 && d <= 2)
return
x = $.getJSON(root.puntomontaje + rutajson + ".json", params)
x.done((datos) ->
$('#' + iddest).val(datos['res'])
if f != null
f(root)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + params + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# Elige una opción de un campo select con base en un dato solicitado con AJAX
# $elem Elemento jquery del campo origen
# rutajson Ruta del API que respondera JSON (sin punto de montaje)
# lid Arreglo de parejas [idsel, campores] donde idsel es id del campo
# select por modificar y campores es campo por usar de la respuesta
# JSON
# descerr Descripcion por presentar en caso de que el JSON no responda
# f Función por llamar despues de cambiar opción
# root Donde se almacenan objetos globales
@msip_elige_opcion_select_con_AJAX = ($elem, rutajson, lid, descerr, f = null, root = window) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_elige_opcion_select_con_AJAX_t)
d = (t - root.msip_elige_opcion_select_con_AJAX_t)/1000
root.msip_elige_opcion_select_con_AJAX_t = t
# NO se permite mas de un envio en 2 segundos
if (d > 0 && d <= 2)
return
val = $elem.val()
x = $.getJSON(root.puntomontaje + rutajson + ".json")
x.done((datos) ->
lid.forEach( (p) ->
$('#' + p[0]).val(datos[p[1]])
)
if f != null
f(root)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + param + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# Cambia un campo select con base en valor de otro campo
# $elem Elemento jquery del otro campo (opciones de select dependen)
# idsel Id. del select por modificar
# rutajson Ruta del API que respondera JSON (sin punto de montaje)
# nomparam Parametro para el API JSON que irá con el valor de $elem
# descerr Descripcion por presentar en caso de que el JSON no responda
# root Donde se almacenan objetos globales
# paramfiltro Enviar parámetro de la forma { filtro: { nomparam: val} }
# cid Campo en el JSON resultantes de la consulta AJAX que corresponderá
# al id de cada elemento del campo de seleccion
# cnombre Campo en el JSON resultante de la consula AJAX que corresponderá al
# nombre de cada elemento del campo de seleccion (si es presenta_nombre
# además pasará parametro presenta_nombre al hacer la consulta para
# que el controlador responda con presenta_nombre de Msip::Modelo)
# f Función por llamar despues de cambiar el cuadro de seleccion
@msip_llena_select_con_AJAX = ($elem, idsel, rutajson, nomparam, descerr, root = window, paramfiltro = false, cid = 'id', cnombre = 'nombre', f = null) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_llena_select_con_AJAX_t)
d = (t - root.msip_llena_select_con_AJAX_t)/1000
root.msip_llena_select_con_AJAX_t = t
# NO se permite mas de un envio en 2 segundos
if (d > 0 && d <= 2)
return
val = $elem.val()
param = {}
param[nomparam] = val
if cnombre == 'presenta_nombre'
param['presenta_nombre'] = 1
if paramfiltro
param = {filtro: param}
x = $.getJSON(root.puntomontaje + rutajson, param)
x.done((datos) ->
msip_remplaza_opciones_select(idsel, datos, true, cid, cnombre)
if f != null
f(root)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + param + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# Cambia un campo select con base en valor de otro campo
# rutajson Ruta del API que respondera JSON (sin punto de montaje)
# params Parametros por pasar a consulta AJAX
# idsel Id. del select por modificar
# descerr Descripcion por presentar en caso de que el JSON no responda
# root Donde se almacenan objetos globales
# cid Campo en el JSON resultantes de la consulta AJAX que corresponderá
# al id de cada elemento del campo de seleccion
# cnombre Campo en el JSON resultante de la consula AJAX que corresponderá al
# nombre de cada elemento del campo de seleccion (si es presenta_nombre
# además pasará parametro presenta_nombre al hacer la consulta para
# que el controlador responda con presenta_nombre de Msip::Modelo)
# f Función por llamar despues de cambiar el cuadro de seleccion
# opvacia Si es verdadero agrega opción vacía al cuadro de selección
@msip_llena_select_con_AJAX2 = (rutajson, params, idsel, descerr, root = window, cid = 'id', cnombre = 'nombre', f = null, opvacia = false) ->
msip_arregla_puntomontaje(root)
t = Date.now()
d = -1
if (root.msip_llena_select_con_AJAX2_t)
d = (t - root.msip_llena_select_con_AJAX2_t)/1000
root.msip_llena_select_con_AJAX2_t = t
rv = ""
if root.msip_llena_select_con_AJAX2_rv
rv = root.msip_llena_select_con_AJAX2_rv
root.msip_llena_select_con_AJAX2_rv = rutajson
pv = {}
if root.msip_llena_select_con_AJAX2_pv
pv = root.msip_llena_select_con_AJAX2_pv
root.msip_llena_select_con_AJAX2_pv = params
# NO se permite mas de un envio a la misma ruta con los mismos parámetros en menos de 2 segundos
if (d > 0 && d <= 2 && rutajson == root.msip_llena_select_con_AJAX2_r && params == root.msip_llena_select_con_AJAX2_p)
return
x = $.getJSON(root.puntomontaje + rutajson, params)
x.done((datos) ->
##debugger
msip_remplaza_opciones_select(idsel, datos, true, cid, cnombre, opvacia)
if f != null
f(root)
)
x.fail((m1, m2, m3) ->
alert(
'Problema ' + descerr + '. ' + params + ' ' + m1 + ' ' + m2 + ' ' + m3)
)
# AUTOCOMPLETACIÓN
# Para autocompletación busca regitros que coincidan con lo ingresado por
# usuario en el campo s
#
# @param s {object} es campo texto con foco donde se busca
# @param sel_id {string} selector de campo donde quedará identificación
# @param fuente {mixed} arreglo, url o función que busca y retorna
# datos de la forma label: 'l1', value: 'v1'
#
# @return {void}
@busca_gen= (s, sel_id, fuente) ->
s.autocomplete({
source: fuente,
minLength: 2,
select: ( event, ui ) ->
if (ui.item)
$(sel_id).val(ui.item.value) if sel_id != null
s.val(ui.item.label)
event.stopPropagation()
event.preventDefault()
})
return
# PERSONA
# Elije una persona en autocompletación
@msip_autocompleta_persona = (label, id, divcp, root) ->
msip_arregla_puntomontaje(root)
cs = id.split(";")
id_persona = cs[0]
pl = []
ini = 0
for i in [0..cs.length] by 1
t = parseInt(cs[i])
pl[i] = label.substring(ini, ini + t)
ini = ini + t + 1
# pl[1] cnom, pl[2] es cape, pl[3] es cdoc
d = "&id_persona=" + id_persona
d += "&ac_orgsocial_persona=" + true
a = root.puntomontaje + 'personas/datos'
$.ajax({
url: a,
data: d,
dataType: "json"
}).fail( (jqXHR, texto) ->
alert("Error con ajax " + texto)
).done( (e, r) ->
divcp.find('[id$=_attributes_id]').val(e.id)
divcp.find('[id$=_attributes_nombres]').val(e.nombres)
divcp.find('[id$=_attributes_apellidos]').val(e.apellidos)
divcp.find('[id$=_attributes_sexo]').val(e.sexo)
tdocid = divcp.find('[id$=_attributes_tdocumento_id] option:contains(' + e.tdocumento + ')').val()
divcp.find('[id$=_tdocumento_id]').val(tdocid)
divcp.find('[id$=_numerodocumento]').val(e.numerodocumento)
divcp.find('[id$=_anionac]').val(e.anionac)
divcp.find('[id$=_mesnac]').val(e.mesnac)
divcp.find('[id$=_dianac]').val(e.dianac)
divcp.find('[id$=_cargo]').val(e.cargo)
divcp.find('[id$=_correo]').val(e.correo)
)
return
# Busca persona por nombre, apellido o identificación
# s es objeto con foco donde se busca persona
@msip_busca_persona_nombre = (s) ->
root = window
msip_arregla_puntomontaje(root)
cnom = s.attr('id')
v = $("#" + cnom).data('autocompleta')
if (v != 1 && v != "no")
$("#" + cnom).data('autocompleta', 1)
divcp = s.closest('.campos_persona')
if (typeof divcp == 'undefined' || divcp.length == 0)
alert('No se ubico .campos_persona')
return
$("#" + cnom).autocomplete({
source: root.puntomontaje + "personas.json",
minLength: 2,
select: ( event, ui ) ->
if (ui.item)
msip_autocompleta_persona(ui.item.value, ui.item.id, divcp, root)
event.stopPropagation()
event.preventDefault()
})
return
# MSIP
# Pone / al final de root.puntomontaje (que debe corresponder al
# punto de montaje de la aplicación) o lo inicializa en / si no hay
#
# @param root espacio para poner variables globales
@msip_arregla_puntomontaje = (root) ->
root.puntomontaje = '/' if typeof root.puntomontaje == 'undefined'
root.puntomontaje += '/' if root.puntomontaje[root.puntomontaje.length-1] != '/'
@msip_pone_tema = (root, tema) ->
$('.table-striped>tbody>tr:nth-child(odd)').css('background-color', tema.fondo_lista)
$('.navbar').css('background-image', 'linear-gradient(' + tema.nav_ini + ', ' + tema.nav_fin + ')')
$('.navbar-default .navbar-nav>li>a').css('color', tema.nav_fuente)
$('.navbar-default .navbar-brand').css('color', tema.nav_fuente)
$('.navbar-light .navbar-nav .nav-link').attr('style', 'color: ' + tema.nav_fuente + ' !important')
$('.navbar-light .navbar-brand').attr('style', 'color: ' + tema.nav_fuente + ' !important')
$('.dropdown-menu').css('background-color', tema.nav_fin)
$('.dropdown-item').css('color', tema.nav_fuente)
$('.dropdown-item').hover(
->
$(this).css({'color' : tema.color_flota_subitem_fuente, 'background-color': tema.color_flota_subitem_fondo})
->
$(this).css({'color' : tema.nav_fuente, 'background-color': tema.nav_fin})
)
$('.alert-success').css('color', tema.alerta_exito_fuente)
$('.alert-success').css('background-color', tema.alerta_exito_fondo)
$('.alert-danger').css('color', tema.alerta_problema_fuente)
$('.alert-danger').css('background-color', tema.alerta_problema_fondo)
$('.btn').css('background-image', 'linear-gradient(to bottom, ' + tema.btn_accion_fondo_ini + ', ' + tema.btn_accion_fondo_fin + ')')
$('.btn').css('color', tema.btn_accion_fuente)
$('.btn-primary').css('background-image', 'linear-gradient(to bottom, ' + tema.btn_primario_fondo_ini + ', ' + tema.btn_primario_fondo_fin + ')')
$('.btn-primary').css('color', tema.btn_primario_fuente)
$('.btn-danger').css('background-image', 'linear-gradient(to bottom, ' + tema.btn_peligro_fondo_ini + ', ' + tema.btn_peligro_fondo_fin + ')')
$('.btn-danger').css('color', tema.btn_peligro_fuente)
$('body').css('background-color', tema.fondo)
$('.card').css('background-color', tema.fondo)
$('.msip-sf-bs-input:not(.form-check-input)').css('background-color', tema.fondo)
$('.msip-sf-bs-input:not(.form-check-input)').css('color', tema.color_fuente)
$('.page-link').attr('style', 'background-color: ' + tema.fondo + ' !important')
$('body').css('color', tema.color_fuente)
$('table').css('color', tema.color_fuente)
# Elije ubicacionpre en autocompletación
# Tras autocompletar disparar el evento msip:autocompletada-ubicacionpre
@msip_autocompleta_ubicacionpre = (etiqueta, id, ubipre, root) ->
msip_arregla_puntomontaje(root)
#cs = id.split(";")
#ubicacionpre_id = cs[0]
#debugger
ubipre.find('[id$=ubicacionpre_id]').val(id)
ubipre.find('[id$=ubicacionpre_texto]').val(etiqueta)
ubipre.find('[id$=ubicacionpre_mundep_texto]').val(etiqueta)
$(document).trigger("msip:autocompletada-ubicacionpre")
return
# Busca ubicacionpre por nombre de municipio o departamento en Colombia
# s es objeto con foco donde se busca ubicacionpre
@msip_busca_ubicacionpre_mundep = (s) ->
root = window
msip_arregla_puntomontaje(root)
cnom = s.attr('id')
v = $("#" + cnom).data('autocompleta')
if (v != 1 && v != "no")
$("#" + cnom).data('autocompleta', 1)
# Buscamos un div con clase div_ubicacionpre dentro del cual
# están tanto el campo ubicacionpre_id como el campo
# ubicacionpre_mundep_texto
ubipre = s.closest('.div_ubicacionpre')
if (typeof ubipre == 'undefined')
alert('No se ubico .div_ubicacionpre')
return
if $(ubipre).find("[id$='ubicacionpre_id']").length != 1
alert('Dentro de .div_ubicacionpre no se ubicó ubicacionpre_id')
return
if $(ubipre).find("[id$='ubicacionpre_mundep_texto']").length != 1
alert('Dentro de .div_ubicacionpre no se ubicó ubicacionpre_mundep_texto')
return
$("#" + cnom).autocomplete({
source: root.puntomontaje + "ubicacionespre_mundep.json",
minLength: 2,
select: ( event, ui ) ->
if (ui.item)
msip_autocompleta_ubicacionpre(ui.item.value, ui.item.id, ubipre, root)
event.stopPropagation()
event.preventDefault()
})
return
# Busca ubicacionpre por nombre pais, nombre dep, nombre mun, nombre clase
# s es objeto con foco donde se busca ubicacionpre
@msip_busca_ubicacionpre = (s) ->
root = window
msip_arregla_puntomontaje(root)
cnom = s.attr('id')
v = $("#" + cnom).data('autocompleta')
if (v != 1 && v != "no")
$("#" + cnom).data('autocompleta', 1)
# Buscamos un div con clase div_ubicacionpre dentro del cual
# están tanto el campo ubicacionpre_id como el campo
# ubicacionpre_texto
ubipre = s.closest('.div_ubicacionpre')
if (typeof ubipre == 'undefined')
alert('No se ubico .div_ubicacionpre')
return
if $(ubipre).find("[id$='ubicacionpre_id']").length != 1
alert('Dentro de .div_ubicacionpre no se ubicó ubicacionpre_id')
return
if $(ubipre).find("[id$='ubicacionpre_texto']").length != 1
alert('Dentro de .div_ubicacionpre no se ubicó ubicacionpre_texto')
return
$("#" + cnom).autocomplete({
source: root.puntomontaje + "ubicacionespre.json",
minLength: 2,
select: ( event, ui ) ->
if (ui.item)
msip_autocompleta_ubicacionpre(ui.item.value, ui.item.id, ubipre, root)
event.stopPropagation()
event.preventDefault()
})
return
## BITACORA
@msip_registra_cambios_para_bitacora = (root) ->
if $('input.bitacora_cambio').length > 0
root.bitacora_estado_inicial_formulario=$('input.bitacora_cambio').closest('form').serializeArray()
$(document).on('submit', 'form:has(.bitacora_cambio)', (e) ->
root.bitacora_estado_final_formulario=$('input.bitacora_cambio').closest('form').serializeArray()
cambio = {}
di = {}
root.bitacora_estado_inicial_formulario.forEach((v) ->
di[v.name]=v.value
)
df = {}
root.bitacora_estado_final_formulario.forEach((v) ->
df[v.name]=v.value
if typeof di[v.name] == 'undefined'
cambio[v.name] = [null, v.value]
)
for i, e of di
if typeof df[i] == 'undefined'
cambio[i] = [e, null]
else if df[i] != e && i.search(/\[bitacora_cambio\]/) < 0
cambio[i] = [e, df[i]]
$('input.bitacora_cambio').val(JSON.stringify(cambio))
)
return
# LOCALE
@msip_reconocer_decimal_locale_es_CO = (n) ->
if n == ""
return 0
i = 0
r = ""
while i= '0' && n[i] <='9'
r = r + n[i]
i++
return parseFloat(r)
@msip_inicializaMotor = (conenv = true) ->
window.puntomontaje = "<%= Rails.configuration.relative_url_root %>"
if conenv && <%= !ENV['RAILS_RELATIVE_URL_ROOT'] || ENV['RAILS_RELATIVE_URL_ROOT'] == "" ? "false" : "true" %>
window.puntomontaje = "<%= ENV['RAILS_RELATIVE_URL_ROOT'] %>"
msip_arregla_puntomontaje(window)
# Formularios con departamento/municipio sin llenar autom. coordenadas
window.msip_sincoord = false;
#<% puts "formato_fecha: ", Rails.configuration.x.formato_fecha %>
#<% puts "relative_url_root: ", Rails.configuration.relative_url_root %>
# Formato de campos de fecha con datepicker
window.formato_fecha = '<%= Rails.configuration.x.formato_fecha && Rails.configuration.x.formato_fecha.to_s != "{}" ? Rails.configuration.x.formato_fecha.to_s : "yyyy-mm-dd" %>'
window.msip_idioma_predet = '<%= Rails.configuration.i18n.default_locale %>'
MsipInicializaMotorES5()
# Prepara eventos comunes al usar msip
# @param root espacio para poner variables globales
@msip_prepara_eventos_comunes = (root, sincoord = false, conenv = true) ->
if typeof(root.formato_fecha) == 'undefined'
msip_inicializaMotor(conenv)
$('[data-behaviour~=datepicker]').datepicker({
format: root.formato_fecha,
autoclose: true,
todayHighlight: true,
language: '<%= Rails.configuration.i18n.default_locale %>'
})
$('[data-toggle="tooltip"]').tooltip()
$(document).on('cocoon:after-insert', (e) ->
$('[data-behaviour~=datepicker]').datepicker({
format: root.formato_fecha
autoclose: true
todayHighlight: true
language: '<%= Rails.configuration.i18n.default_locale %>'
})
$('[data-toggle="tooltip"]').tooltip()
)
# Chosen-jquery
$('.chosen-select').chosen
allow_single_deselect: true
no_results_text: '<%= I18n.t('No hay resultados') %>',
placeholder_text_single: '<%= I18n.t('Seleccione una opción') %>',
placeholder_text_multiple: '<%= I18n.t('Seleccione algunas opciones') %>',
width: '100%'
# Caso especial de tooltips para campos con chosen
$('select[data-toggle="tooltip"]').each( (v, e) ->
ej = $(e)
t = ej.attr('data-original-title')
id = ej.attr('id')
ns = '#' + id+'_chosen .chosen-choices'
$(ns).attr('title', t)
$(ns).attr('data-toggle', 'tooltip')
)
# Pone colores de acuerdo al tema
msip_ajax_recibe_json(root, 'temausuario', {}, msip_pone_tema)
jQuery ->
$("a[rel~=popover], .has-popover").popover()
$("a[rel~=tooltip], .has-tooltip").tooltip()
# Al cambiar país se recalcula lista de departamentos
$(document).on('change', 'select[id$=_id_pais]', (e) ->
llena_departamento($(this), root, sincoord)
)
$(document).on('change', 'select[id$=_pais_id]', (e) ->
llena_departamento($(this), root, sincoord)
)
# Al cambiar departamento se recalcula lista de municipios
$(document).on('change', 'select[id$=_id_departamento]', (e) ->
llena_municipio($(this), root, sincoord)
)
$(document).on('change', 'select[id$=_departamento_id]', (e) ->
llena_municipio($(this), root, sincoord)
)
# Al cambiar municipio se recalcula lista de centros poblados
$(document).on('change', 'select[id$=_id_municipio]', (e) ->
llena_clase($(this), root, sincoord)
)
$(document).on('change', 'select[id$=_municipio_id]', (e) ->
llena_clase($(this), root, sincoord)
)
# Al cambiar centro poblado se deja tipo de ubicación en Urbano
$(document).on('change', 'select[id$=_id_clase]', (e) ->
pone_tipourbano($(this))
)
$(document).on('change', 'select[id$=_clase_id]', (e) ->
pone_tipourbano($(this))
)
$('#mundep').on('focusin', (e) ->
msip_arregla_puntomontaje(root)
busca_gen($(this), null, root.puntomontaje + "mundep.json")
)
$(document).on('click', 'a.enviarautomatico[href^="#"]', (e) ->
msip_enviarautomatico_formulario($('form'), 'POST', 'json', false)
return
)
$(document).on('change', 'select[data-enviarautomatico]',
(e) ->
msip_enviarautomatico_formulario($(e.target.form))
)
$(document).on('change', 'input[data-enviarautomatico]',
(e) ->
#debugger
# No procesa selección de fecha, pero si cuando se teclea
#if typeof $(e.target).attr('data-behaviour') == 'undefined' || e.bubbles
msip_enviarautomatico_formulario($(e.target.form))
)
# Rotador: http://blog.emaillenin.com/2014/06/showing-a-spinnerloading-cursor-icon-for-rails-4-turbolink.html
iniciaRotador = ->
$("html").css "cursor", "progress"
return
detieneRotador = ->
$("html").css "cursor", "auto"
return
$(document).on('turbo:click', (event) ->
if event.target.getAttribute('href').charAt(0) == '#'
return event.preventDefault()
)
$(document).on "page:fetch", iniciaRotador
$(document).on "page:receive", detieneRotador
return
@msip_ejecutarAlCargarPagina = (root) ->
console.log('Msip: Ejecutando al cargar pagina')
if typeof(window.formato_fecha) == 'undefined'
msip_inicializaMotor()
$('[data-behaviour~=datepicker]').datepicker({
format: root.formato_fecha,
autoclose: true,
todayHighlight: true,
language: '<%= Rails.configuration.i18n.default_locale %>'
})
$('[data-toggle="tooltip"]').tooltip()
$(document).on('cocoon:after-insert', (e) ->
$('[data-behaviour~=datepicker]').datepicker({
format: root.formato_fecha
autoclose: true
todayHighlight: true
language: '<%= Rails.configuration.i18n.default_locale %>'
})
$('[data-toggle="tooltip"]').tooltip()
)
# Chosen-jquery
$('.chosen-select').chosen
allow_single_deselect: true
no_results_text: '<%= I18n.t('No hay resultados') %>',
placeholder_text_single: '<%= I18n.t('Seleccione una opción') %>',
placeholder_text_multiple: '<%= I18n.t('Seleccione algunas opciones') %>',
width: '100%'
# Caso especial de tooltips para campos con chosen
$('select[data-toggle="tooltip"]').each( (v, e) ->
ej = $(e)
t = ej.attr('data-original-title')
id = ej.attr('id')
ns = '#' + id+'_chosen .chosen-choices'
$(ns).attr('title', t)
$(ns).attr('data-toggle', 'tooltip')
)
# Pone colores de acuerdo al tema
msip_ajax_recibe_json(root, 'temausuario', {}, msip_pone_tema)
jQuery ->
$("a[rel~=popover], .has-popover").popover()
$("a[rel~=tooltip], .has-tooltip").tooltip()
evento = new Event('msip:cargado');
document.dispatchEvent(evento);
@msip_edadDeFechaNacFechaRef = (anionac, mesnac, dianac, anioref, mesref, diaref) ->
if typeof anionac == 'undefined' || anionac == ''
return -1
if typeof anioref == 'undefined' || anioref == ''
return -1
na = anioref - anionac
if typeof mesnac != 'undefined' && mesnac != '' && mesnac > 0 &&
typeof mesref != 'undefined' && mesref!= '' && mesref > 0 &&
mesnac >= mesref
if mesnac > mesref || (dianac != 'undefined' && dianac != '' &&
dianac > 0 && diaref != 'undefined' && diaref!= '' &&
diaref > 0 && dianac > diaref)
na--
return na;
$(document).on('focusin', 'input[id^=orgsocial_orgsocial_persona_attributes][id$=nombres]', (e) ->
msip_busca_persona_nombre($(this))
)