PageSourceSearch

https://carpeta.aytocomillas.es/sta/pages/webapps/js/uiBasicValidation.js?ver=2605.0.5

js aytocomillas.es collected 2026-10-02 10:12:57 UTC 29,877 bytes, 875 lines download raw bytes

1var activeSubForm = 0;
2
3function configureValidations() {
4
5	// fix date validation for chrome
6	
7    jQuery.extend(jQuery.validator.methods, {
8        date: function (value, element) {
9            if (value)
10            {
11                try
12                {
13                	jQuery.datepicker.parseDate('dd/mm/yy', value);
14                }
15                catch (ex)
16                {
17                    return false;
18                }
19            }
20            return true;
21        	/*
22        	var isChrome = window.chrome;
23            // make correction for chrome
24            if (isChrome) {
25            	var validDate = /^(\d{2})\/(\d{2})\/(\d{4})?$/;    
26                return this.optional(element) || validDate.test(value);
27            }
28            // leave default behavior
29            else {
30                return this.optional(element) || 
31                !/Invalid|NaN/.test(new Date(value));
32            }
33            */
34        }
35    }); 	
36	
37    // Mensajes por defercto SIN traducción
38    // ------------------------------------
39    // Estos literales son sobreescritos por los literales definidos en CFG_APP como VALTXT_xxxxx de forma automatica
40    // mediante un fichero de recursos creado dinamicamente al arrancar la STA, que contiene la funcion: translateLiterals.
41    
42	jQuery.extend(jQuery.validator.messages, {
43	    required: "Campo obligatorio",
44	    remote: "Please fix this field.",
45	    email: "El formato del mail no es válido",
46	    url: "Por favor introduzca una url válida",
47	    date: "Por favor introduzca una fecha válida",
48	    dateISO: "Please enter a valid date (ISO).",
49	    number: "Por favor introduzca un numero correcto.",
50	    currency: "Formato incorrecto. Ejemplo: 100.00",
51	    digits: "Please enter only digits.",
52	    creditcard: "Please enter a valid credit card number.",
53	    equalTo: "Please enter the same value again.",
54	    accept: "Please enter a value with a valid extension.",
55	    maxlength: jQuery.validator.format("No se admiten más de {0} caracteres"),
56	    minlength: jQuery.validator.format("Introduzca al menos {0} caracteres"),
57	    rangelength: jQuery.validator.format("Please enter a value between {0} and {1} characters long."),
58	    range: jQuery.validator.format("Please enter a value between {0} and {1}."),
59	    max: jQuery.validator.format("Please enter a value less than or equal to {0}."),
60	    min: jQuery.validator.format("Please enter a value greater than or equal to {0}."),
61	    checkRequired: "Debe leer y aceptar las condiciones de uso.",
62	    adr_required: "El campo de la dirección es obligatorio.",
63	    upload: "No ha adjuntado ningún documento",
64	    base_inside: jQuery.validator.format("La base imponible calculada debe estar entre {0} y {1}."),
65	    base_outside: "La base imponible calculada no puede sobrepasar {0}."
66	    	
67	});
68	
69	// A continuación se definen los METODOS creados para la STA
70	// los parametros son el nombre del metodo, la funcion de validación y el literal del error
71	// los: addClassRules siven para asociar una clase a una validación y de paso poder especificar las expresiones regulares si se requiere.
72	// jQuery.validator.methods.XXXXX se usa para definir la funcion de validación de un metodo existente
73	// --------------------------------------------------------------------------------------------------
74	
75	jQuery.validator.addMethod(
76		    "phone",
77		    function(value, element, regexp) {
78		        var check = false;
79		        return this.optional(element) || regexp.test(value);
80		    },
81		    "El teléfono no es válido."
82		);
83	
84	
85	jQuery.validator.methods.email = function( value, element ) {
86  		return this.optional( element ) || /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test( value );
87	}		
88	
89	jQuery.validator.addClassRules("phone", {
90		phone : /^\+?\d{1,3}?[- .]?\(?(?:\d{2,3})\)?[- .]?\d\d\d[- .]?\d\d\d$/
91		});	
92	
93	jQuery.validator.addMethod(
94		    "numeric",
95		    function(value, element, regexp) {
96		        var check = false;
97		        return this.optional(element) || regexp.test(value);
98		    },
99		    "Sólo se admiten números."
100		);
101	
102	jQuery.validator.addMethod("soloLetras", function (value, element) {
103
104		if (this.optional(element)) return true;
105
106		// ❌ 1. Detectar '
107		if (/'/i.test(value)) return false;
108
109		// ❌ 2. Detectar caracteres no permitidos
110		// Permite letras latinas (mayúsculas y minúsculas, con tildes, diéresis, ñ, ç, ø, æ, å, ß...),
111		// espacios, apóstrofos, guiones, puntos y punto volado.
112		if (/[^\p{Script=Latin}\s'.\-·]/u.test(value)) return false;
113
114		// ❌ 3. Detectar múltiples espacios
115		if (/\s{2,}/.test(value)) return false;
116
117		// ❌ 4. Detectar múltiples apóstrofes
118		if (/'{2,}/.test(value)) return false;
119
120		// ❌ 5. Detectar espacios al inicio o al final
121		if (/^\s+|\s+$/.test(value)) return false;
122
123		// ❌ 6. Detectar apóstrofo solo al final
124		if (/'+$/.test(value)) return false;
125
126		return true;
127
128	}, "Formato inválido. Solo se permiten letras, apóstrofes ('), diéresis y acentos. No use espacios innecesarios ni símbolos no permitidos.");
129		
130	jQuery.validator.addClassRules("solo-letras", {
131	    soloLetras: true
132	});
133		
134	// Esta entrada deberia ser anulada ja que digits ya hace esto
135	jQuery.validator.addClassRules("numeric", {
136		numeric : /^[\d]+$/
137		});	
138	
139	jQuery.validator.methods.range = function (value, element, param) {
140	    var globalizedValue = value.replaceAll(".","").replace(",", ".");
141	    return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
142	}
143	jQuery.validator.methods.max = function (value, element, param) {
144	    var globalizedValue = value.replaceAll(".","").replace(",", ".");
145	    return this.optional( element ) || globalizedValue <= param;
146	}	
147	
148	jQuery.validator.methods.number = function (value, element) {
149	    return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value); 
150	}
151	
152	jQuery.validator.addMethod(
153		    "currency",
154		    function(value, element, regexp) {
155		        var check = false;
156		        return this.optional(element) || regexp.test(value);
157		    }
158		    ,"Formato incorrecto. Ejemplo: 1.200,00"		    
159		);
160	
161	jQuery.validator.addClassRules("currency", {
162		currency :  /^\s*-?((\d{1,3}(\.(\d){3})*)|\d*)(,\d{1,2})?\s?(\u20AC)?\s*$/ 
163		//currency : /^(\d+)(\,\d{1,2})?$/
164		});	
165	
166	jQuery.validator.addMethod(
167		    "checkRequired",
168		    function(value, element) {
169		        //var check = false;
170		        //return this.optional(element) || regexp.test(value);
171		    	console.log('check if checkbox is checked');
172		        return jQuery(element).is(':checked');		        
173		    }
174		);	
175	
176	
177	jQuery.validator.addMethod("subFormRequired",
178			function(value, element)
179			{
180				alert('appling subForm validation');
181				//var jQueryelement = jQuery(element);
182				if ((element).parents(".sub-form-" + activeSubForm).length)
183				{
184					return !this.optional(element);
185				}
186				return "dependency-mismatch";
187			},
188			jQuery.validator.messages.required);
189	
190	
191	jQuery.validator.addMethod(
192		    "maxDate",
193		    function(value, element, params) {
194		    	var dateMax = jQuery.datepicker.parseDate('dd/mm/yy',params);
195		    	var dateEntered = jQuery.datepicker.parseDate('dd/mm/yy',value);
196		    	return dateEntered <= dateMax;
197		    }
198		);
199	jQuery.validator.addMethod(
200		    "maxDateToday",
201		    function(value, element, params) {
202		    	var dateEntered = jQuery.datepicker.parseDate('dd/mm/yy',value);
203		    	return dateEntered <= new Date();
204		    }
205		);
206	jQuery.validator.addMethod(
207		    "minDate",
208		    function(value, element, params) {
209		    	var dateMin = jQuery.datepicker.parseDate('dd/mm/yy',params);
210		    	var dateEntered = jQuery.datepicker.parseDate('dd/mm/yy',value);
211		    	return dateEntered >= dateMin;
212		    }
213		);
214	jQuery.validator.addMethod(
215		    "minDateToday",
216		    function(value, element, params) {
217		    	var dateEntered = jQuery.datepicker.parseDate('dd/mm/yy',value);
218		    	return dateEntered >= new Date();
219		    }
220		);
221
222	jQuery.validator.addMethod(
223		    "notario",
224		    function(value, element) {
225		        return jQuery('#notario-dboid').val()!='';
226		    }
227		);
228	
229	jQuery.validator.addMethod(
230		    "epigrafe",
231		    function(value, element) {
232		        return jQuery('#epigrafe-dboid').val()!='';
233		    }
234		);
235	
236	jQuery.validator.addMethod(
237		    "upload",
238		    function(value, element) {
239		    	return jQuery(element).closest('.widget-upload-files').find('.file-uploaded-item').length  != 0;
240		    }
241		);
242	//jQuery.validator.addClassRules("upload", { upload: true});		
243
244	
245	jQuery.validator.addMethod(
246		    "adr_required",
247		    function(value, element) {
248		    	console.log('direccion: validando dirección');
249		    	if (jQuery('#'+ jQuery(element).prop('id') + '_ID').length > 0)
250		    		return jQuery('#'+ jQuery(element).prop('id') + '_ID').val() != '';
251		    	else if (jQuery(element).is(':hidden') )
252		    		return jQuery(element).val() != '-1';
253		    	else 
254		    		return jQuery(element).val() != '';
255		    }
256		);
257	jQuery.validator.addMethod(
258		    "base_inside",
259		    function(value, element) {
260		    	return jQuery(element).closest('.liqsec-param-concepto-form').data('base-inside') != 'out';
261		    },
262		    function (params, element) {
263		    	var parent = jQuery(element).closest('.liqsec-param-concepto-form');
264		    	if (parent.parent().hasClass('base-detallada'))
265		    		return jQuery.validator.format(jQuery.validator.messages.base_outside,parent.data('base-inside-max'));
266		    	else
267		    		return jQuery.validator.format(jQuery.validator.messages.max,parent.data('base-inside-max'));
268		    }
269		);
270	
271	jQuery.validator.addMethod(
272		    "validarNif",
273		    function(value, element) {
274		    	console.log('validando el nif');
275				//Si cambia el NIF volvemos a mostrar el botón para validar de nuevo
276				//quitamos los mensajes de OK o KO y los cuadros de nombre y apellido o cif
277				jQuery("#botonValidarBox").removeAttr('hidden');
278				jQuery('.iziModal #repre-plataforma-validate-response-ko').removeClass('visible').addClass('oculto');
279				jQuery('.iziModal #repre-plataforma-validate-response-ok').removeClass('visible').addClass('oculto');
280				jQuery('.iziModal #repre-plataforma-persona-fisica').removeClass('visible').addClass('oculto');
281				jQuery('.iziModal #repre-plataforma-persona-juridica').removeClass('visible').addClass('oculto');
282				
283		    	return window._NIFValidator.checkAll(value);
284		    },
285		    "El NIF/DNI/NIE indroducido no es válido."		   
286		);
287		
288	jQuery.validator.addMethod(
289		    "validarDNI",
290		    function(value, element) {
291		    	console.log('validando el DNI');
292		    	return window._NIFValidator.checkDNI(value);
293		    },
294		    "El DNI indroducido no es válido."		   
295		);
296	
297	jQuery.validator.addMethod(
298		    "validarNIE",
299		    function(value, element) {
300		    	console.log('validando el NIE');
301		    	return window._NIFValidator.checkTR(value);
302		    },
303		    "El NIE o tarjeta de residencia introducida no es válida."		   
304		);
305	
306	jQuery.validator.addMethod(
307		    "base_over",
308		    function(value, element) {
309		    	return jQuery(element).closest('.liqsec-param-concepto-form').data('base-over') != 'out';
310		    },
311		    "El valor introducido hace exceder el importe máximo por concepto: 9999999.99 €"
312		);
313	
314	jQuery.validator.addMethod(
315		    "baseParametrica",
316		    function(value, element) {
317			    
318			    var globalizedValue = value.replaceAll(".","").replace(",", ".");
319			    return this.optional(element) || (globalizedValue <= 9999999.9999 && /^\s*-?((\d{1,3}(\.(\d){3})*)|\d*)(,\d{1,4})?\s*$/.test(value)); 
320		    },
321		    "El número introducido no puede superar 9999999.9999 y sólo se admiten hasta 4 decimales"		   
322		);
323			
324	// CODIGO PARA LA VALIDACIÓN DE LA REFERENCIA CATASTRAL PASADO DESDE MADRID
325	jQuery.validator.addMethod(
326		"validarReferenciaCatastral",
327		function (refCat) 
328		{
329			if (!refCat || refCat.length !== 20) 
330			{
331		    	return false;
332		    }
333	
334		  	refCat = refCat.toUpperCase();
335		  	const dcEsperado = refCat.substring(18, 20);
336		  	const subcadena1 = refCat.substring(0, 7) + refCat.substring(14, 18);
337		  	const subcadena2 = refCat.substring(7, 14) + refCat.substring(14, 18);
338		
339		  	const dc1 = window.calcularDigitoControlReferenciaCatastral(subcadena1);
340		  	const dc2 = window.calcularDigitoControlReferenciaCatastral(subcadena2);
341		
342		  	return dcEsperado === (dc1 + dc2);
343		},
344		"La referencia catastral introducida no es válida."
345	);	
346	// FIN CODIGO DE REFERENCIA CATASTRAL
347	
348	// Validar que se ha validado la representación del NIF
349	jQuery.validator.addMethod(
350		    "nif-repre-validated",
351		    function(value, element) {
352		    	console.log('validación: validando la validación del NIF');
353		    	return sta.representacionValidada == true;
354		    }
355		);	
356	
357}
358	
359/* FUNCIONES CUSTOMIZADAS
360 * -------------------------------------------------------------------
361 */
362
363// Función que coloca el error. Solo se ejecuta la primera vez que se detecta el error:
364sta.customValidation.customErrorPlacement = function(error, element)
365{
366	var ele = jQuery(element);
367	if (error.text()=='') return;
368	//console.log('JQUERY_VALIDATION: ErrorPlacement:' + error + '. Element: ' + ele.prop('id'));
369	
370	// Se indica por accesibilidad que etiqueta indica el error del campo 
371	ele.attr('aria-errormessage',error.prop('id'));
372	error.attr('role','status');
373	
374	
375//	var direccion = ele.closest('.address-control');
376//	if (direccion.length)
377//	{
378//		var contenedorErrores = direccion.find('.wrap-error-address'); 
379//		contenedorErrores.append(error);
380//		contenedorErrores.show();
381//	}
382//	else
383	{
384		var conceptoPadre = ele.closest('html:not(.responsive) .liqsec-param-concepto-edit');
385		if (conceptoPadre.length)
386		{	
387			var contenedorErrores = jQuery('#'+ conceptoPadre.attr('id').replace('liqConceptEdit', 'liqConceptErrors')); 
388			contenedorErrores.append(error);
389		}
390		else 
391		{
392			var inlineAction = ele.closest('.inline-input-action');
393			if (inlineAction.length)
394			{
395				inlineAction.append(error);		
396			}
397			else
398			{
399				var composed = ele.closest('.field-body.composed');
400				if (composed.length)
401				{
402					if (composed.find('.composed-info').children().length == 0)
403						composed.find('.composed-info').append(error);		
404				}
405				else
406				{
407					var wrapctrl = ele.closest('.ui-in');
408					if (wrapctrl.length)
409					{
410						wrapctrl.parent().append(error);		
411					}
412					else
413					{
414						var upload = ele.closest('.widget-upload-files');
415						if (upload.length)
416						{	
417							var contenedorErrores = upload.find('.wrap-error-file'); 
418							contenedorErrores.append(error);
419							contenedorErrores.show();
420						}
421						else
422						{
423							var padre = ele.parent();
424							if (padre.hasClass('error-horizontal'))
425							{
426								padre.parent().parent().append(jQuery('<tr/>').append(jQuery('<td colspan="100"/>').append(error)));
427							}
428							else
429							{
430								padre.append(error);
431							}
432						}
433					}
434				}
435			}
436		}
437	}
438};
439
440// Función que se lanza en cada validación. Sirve para tratar de forma agrupada los mensajes de error,
441// Se lanza tanto si hay errores como si no los hay
442// Si se usa esta función no se llama al hightlight, que es para el trato indiviudal de ca
442da control.
443// Nosotros la usamos para las 2 cosas: 1. trato individual recorriendo la lista de elementos (asi no hay que sobreescribir el hightlight) 
444//								        2. buscando si hay un wrapper para incorporar ahí los errores.
445
446sta.customValidation.customErrorShow = function (e, el) {
447	console.log('JQUERY_VALIDATION: customErrorShow: errores: ' + el.length + ' , element: ' + jQuery(el).prop('id'));
448	
449	// trata por defecto:
450	this.defaultShowErrors();	
451	
452	// se tratan todos los elementos afectados individualmente:
453	jQuery(el).each(function(){
454		var field = jQuery(this.element).closest('.field');
455		if (field.length)
456		{
457			jQuery(el).attr('aria-invalid','true');		
458			field.addClass('invalid');
459			// Si es de un grupo, se marca como erroneo
460			if (field.hasClass('liqsec-param-concepto-form-box'))
461				field.closest('.liqsec-param-concepto-edit').addClass('invalidEdit');
462		}
463	});
464	
465	// Si exsite un wrapper para los errores se muestra un alert con enlace a los errores 
466	if (jQuery('.wrapErrors').length > 0 && el.length)
467	{
468		if (jQuery('*:visible > .wrapErrors .warning.informativo-inline').length == 0 )
469		{	//'<svg class="icon ' + ops.status + '"><use xlink:href="#icon-' + ops.status + '"></use></svg>'	
470			
471			
472			var elerror = jQuery('<a class="Icon warning informativo-inline" role="alert" href="javascript:;"/>').append(
473					(sta.responsive?'<svg class="icon icon-warning"><use xlink:href="#icon-warning"></use></svg>':'') 		
474			).append(sta.literales.form_error);
475			elerror.on('click',function(){
476				cleanFormErrors();      
477				window._FormValidator.form();
478			});
479			jQuery('.wrapErrors').append(elerror);			
480		}
481	}
482
483}
484//sta.customValidation.customUnhighlight = function (element, errorClass, validClass)
485//{
486//	if ( element.type === "radio" ) {
487//		this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
488//	} else {
489//		jQuery( element ).removeClass( errorClass ).addClass( validClass );
490//	}
491//}
492
493// Función que se executa cada vez que se resuelve un error en un elemento:
494// Lo usamos para el tratado extra de clases y para limpiar las 'marcas' de errores del formulario con el cleanFormErrors.
495sta.customValidation.customErrorSuccess = function (label,elemento)
496{
497	console.log('JQUERY_VALIDATION: customErrorSuccess: ' + jQuery(elemento).prop('id') + ', label: ' + label);
498	if (label.text()=='') label.remove();
499	
500	var field = jQuery(elemento).closest('.field');
501	if (field.length)
502		field.removeClass('invalid');	
503	
504	jQuery(elemento).removeClass('invalidMessage');
505	jQuery(elemento).attr('aria-invalid',null);		
506
507
508	cleanFormErrors();      
509}	
510
511// Función que se usa cuando se intenta hacer submit sobre un formulario con error/es
512sta.customValidation.customInvalidHandler = 	function(form, validator) {
513	//console.log('JQUERY_VALIDATION: InvalidHandler');
514	irAlError();
515
516}
517
518//Función para controlar cuando se trata un elemento y cuando no en el FOCUSOUT
519sta.customValidation.customOnfocusout = function (element,event){
520    if (!jQuery(element).hasClass('autocompletar') && !jQuery(element).hasClass('no-autoval') &&
521    	!this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) )
522    {
523        this.element( element );
524    }
525}
526
527// Función para controlar cuando se trata un elemento y cuando no en el KEYUP
528sta.customValidation.customOnkeyup = function (element,event){
529    if (!jQuery(element).hasClass('autocompletar') && !jQuery(element).hasClass('no-autoval') && !jQuery(element).hasClass('not-on-type') &&
530    	!this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) 
531    {
532        this.element( element );
533    }
534	
535}
536
537// Función pra limpiar los errores si ya se han resuelto:
538var cleanFormErrors = function()
539{
540	console.log('cleanFormErrors -> invalids: ' + jQuery('input.invalidMessage:visible').length);	
541	if (jQuery('input.invalidMessage:visible').length == 0)
542	{
543		if (jQuery('*:visible > .wrapErrors a').length > 0)
544		{
545			//jQuery('.wrapErrors').empty();
546			jQuery('.wrapErrors a').remove();
547			console.log('clean form -> removing');	
548		}
549	} 	
550}
551
552// Función para ir al error:
553var irAlError = function()
554{
555	var origen;
556	if (jQuery('.wrapErrors .alert').length > 0)
557			origen = jQuery(jQuery('.wrapErrors .alert')[0]);
558		else	
559			origen = jQuery(document.activeElement);
560	
561	var validator = window._FormValidator;
562	//validator.form();
563	
564	if (!validator.numberOfInvalids())
565        return;
566    var element = jQuery(validator.errorList[0].element);
567    if (element.hasClass('upload-input'))
568    	element = element.closest('.head');
569    else if (element.hasClass('required_hidden'))
570    {
571    	var next = element.next('.ui-selectmenu-button');
572    	if (next.length > 0)
573    		element = element.next();
574    }	
575    if(element.position())
576    {
577        if(element.offset().top -20 < jQuery(window).scrollTop())
578        {
579            //scroll up
580            jQuery('html,body').animate({scrollTop:element.offset().top - 20}, 800,function(){});
581            origen.effect('transfer',{ to: element, className: 'transfer-error' }, 750, function(){element.focus()});
582        }
583        else
584        {
585        	origen.effect('transfer',{ to: element, className: 'transfer-error' }, 750, function(){element.focus()});
586        }   	
587    }
588}
589	
590function destroyValidation(validator) {
591	validator.resetForm();
592
593	jQuery( validator.currentForm )
594		.off( ".validate" )
595		.removeData( "validator" )
596		.find( ".validate-equalTo-blur" )
597			.off( ".validate-equalTo" )
598			.removeClass( "validate-equalTo-blur" )
599		.find( ".validate-lessThan-blur" )
600			.off( ".validate-lessThan" )
601			.removeClass( "validate-lessThan-blur" )
602		.find( ".validate-lessThanEqual-blur" )
603			.off( ".validate-lessThanEqual" )
604			.removeClass( "validate-lessThanEqual-blur" )
605		.find( ".validate-greaterThanEqual-blur" )
606			.off( ".validate-greaterThanEqual" )
607			.removeClass( "validate-greaterThanEqual-blur" )
608		.find( ".validate-greaterThan-blur" )
609			.off( ".validate-greaterThan" )
610			.removeClass( "validate-greaterThan-blur" );
611};
612
613function buildValidations()
614{
615	configureValidations();
616	var form = jQuery(document.forms["webAppPageForm"]);
617
618	// Se destruye el anterior para asegurar que se crea el nuestro customizado:
619	//var validator = jQuery.data( form[0], "validator" );
620	//destroyValidation(validator); 
621	
622	window._FormValidator = form.validate(
623	{
624		ignore: ":hidden:not(.required_hidden), .ocultar input, .ocultar select, input[readonly],.address-control:not(:visible) *",
625		focusInvalid: false,
626		errorClass: "invalidMessage",
627		errorElement: "label",
628		errorPlacement: sta.customValidation.customErrorPlacement,
629		showErrors: sta.customValidation.customErrorShow,
630		//unhighlight: sta.customValidation.customUnhighlight,
631		success: sta.customValidation.customErrorSuccess,	
632		invalidHandler: sta.customValidation.customInvalidHandler,
633		onfocusout: sta.customValidation.customOnfocusout,
634		onkeyup: sta.customValidation.customOnkeyup
635	});
636	console.log('Applaying rules');
637	applyRules();	
638	
639	window._NIFValidator = new NIF_CIFValidator();
640	
641	//Add the new function to reset 1 field:
642	window._FormValidator['cleanElement'] = function (param_element_name) {
643	    var element_name = "";
644	    if (param_element_name.substring(0, 1) == "#") {
645	        element_name = param_element_name.substring(1);
646	    } else {
647	        element_name = param_element_name;
648	    }
649	    // Se elimina la etiqueta de error
650	    jQuery('label.invalidMessage[for=' + element_name + ']').remove();
651	    
652	    // se eliminan los estilos
653	    jQuery('#' + element_name).removeClass(this.settings.errorClass).removeClass(this.settings.validClass);
654	};	
655}
656
657function validateForm(sourceElement) {
658	
659	// si estamos dentro de un formulario modal, se lanza la prevalidación	 
660	if (jQuery(sourceElement).closest('form.iziModal').length > 0)
661	{
662		if (window._FormValidator2 != undefined)	
663			return window._FormValidator2.form();
664	}
665	else
666	{
667		if (window._FormValidator.prevalidate != undefined)
668			window._FormValidator.prevalidate();
669		return window._FormValidator.form();
670	}
671	return true
672}
673
674
675function validateFomAddCallback(funcion,append) {
676
677	console.log('añadir Pre validate callback');	
678	if (append && window._FormValidator.prevalidate != undefined)
679	{
680		prefunc = window._FormValidator.prevalidate;
681		window._FormValidator.prevalidate = function(){
682			funcion();
683			prefunc();
684		};
685	}
686	else
687		window._FormValidator.prevalidate = funcion;		 	
688}
689
690var preSetRules = new Array();
691
692var applyRules = function()
693{
694	jQuery.map(preSetRules,function(optionObject,index){
695			
696		//obj.datepicker("option", optionObject['opcion'], optionObject['valor']);
697		var fecha = jQuery("#" + optionObject['id']);
698		if (fecha.length > 0)
699		{
700			fecha.rules("add", optionObject['rule']);
701		}			
702	});
703}
704
705var addRule = function(id,valor)
706{
707	console.log('Adding rule to: '+ id);
708	var jObj = jQuery("#" + id);
709	var optionObject = { id:id,rule: valor};	
710	preSetRules.push(optionObject);
711}
712
713
714/*
715Validador de NIF, CIF, y Tarjeta de residencia por javascript.
716Sin licencia.
717Distribuido en: http://www.microteching.com/
718Autor: ticnology coop.v. (http://www.ticnology.es/)
719*/
720function NIF_CIFValidator() {
721
722this.isJuridica = function(id){
723	// Si no empieza por alguna de las letras de personas juridicas es fisica:
724	return (/^[ABCDEFGHJNPRQSUVW]/.test(id));	
725}
726	
727this.NIF_Letters = "TRWAGMYFPDXBNJZSQVHLCKET";
728this.NIF_regExp = "^\\d{8}[a-zA-Z]{1}$";
729this.CIF_regExp = "^[a-zA-Z]{1}\\d{7}[a-jA-J0-9]{1}$";
730
731this.checkAll = function (value) {
732	if (this.checkNIF(value)) { // Comprueba el CIF
733		return true;
734	} else if (this.checkESPECIALES(value)) { // Comprueba casos especiales KLM
735		return true;
736	} else if (this.checkTR(value)) { // Comprueba tarjeta de residencia
737		return true;
738	} else if (this.checkDNI(value)) { // Comprueba el NIF
739		return true;
740	} else { // Si no pasa por ninguno es false.
741		return false;
742	}
743}
744
745// VALIDA EL DNI
746this.checkDNI = function (nif) {
747	// Comprueba la longitud. Los DNI antiguos tienen 7 digitos.
748	if ((nif.length != 8) && (nif.length != 9)) return false;
749	if (nif.length == 8) nif = '0' + nif; // Ponemos un 0 a la izquierda y solucionado
750
751	// Comprueba el formato
752	var regExp = new RegExp(this.NIF_regExp);
753	if (!nif.match(regExp)) return false;
754
755	var
756	let = nif.charAt(nif.length - 1);
757	var dni = nif.substring(0, nif.length - 1)
758	var letra = this.NIF_Letters.charAt(dni % 23);
759	return (letra ==
760		let.toUpperCase());
761}
762
763//VALIDA TARJETA DE RESIDENCIA
764this.checkESPECIALES = function (tr) {
765	if (tr.length != 9) return false;
766	if ((tr.charAt(0).toUpperCase() != "K") && (tr.charAt(0).toUpperCase() != "L") && (tr.charAt(0).toUpperCase() != "M")) return false;
767	return this.checkDNI('0' + tr.substring(1, tr.length));
768}
769
770
771// VALIDA TARJETA DE RESIDENCIA
772this.checkTR = function (tr) {
773	if ((tr.length != 10) && (tr.length != 9)) return false;
774	if ((tr.charAt(0).toUpperCase() != "X") && 
775		(tr.charAt(0).toUpperCase() != "Y") &&
776		(tr.charAt(0).toUpperCase() != "Z")) return false;
777
778	var leftNum = '0';
779	if (tr.charAt(0).toUpperCase() == "Y")		
780		leftNum = '1';
781	if (tr.charAt(0).toUpperCase() == "Z")
782		leftNum = '2';
783	if (tr.length == 9) {
784		return this.checkDNI(leftNum + tr.substring(1, tr.length));
785	} else {
786		return this.checkDNI(tr.substring(1, tr.length));
787	}
788}
789
790// VALIDA NIF
791this.checkNIF = function(cif) {
792    // 1. Normalización y limpieza
793    var tempStr = cif.toUpperCase().trim();
794    
795    // 2. Validación de formato estricto: 
796    // Una letra inicial válida + 7 números + un carácter alfanumérico final
797    var regex = /^[ABCDEFGHJPQRSUVW][0-9]{7}[A-J0-9]$/;
798    if (!regex.test(tempStr)) return false;
799
800    var v1 = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9];
801    var suma = 0;
802
803    // 3. Cálculo del algoritmo
804    // Empezamos en i=1 para saltar la letra inicial y llegamos hasta el 7
805    for (var i = 1; i < 7; i += 2) {
806        // Posiciones impares (1, 3, 5, 7)
807        suma += v1[parseInt(tempStr.charAt(i))];
808        // Posiciones pares (2, 4, 6)
809        suma += parseInt(tempStr.charAt(i + 1));
810    }
811    // Sumamos la última posición impar (la séptima posición del string)
812    suma += v1[parseInt(tempStr.charAt(7))];
813
814    // 4. Obtener el dígito de control esperado
815    var unidad = suma % 10;
816    var digitoControlEsperado = (unidad === 0) ? 0 : 10 - unidad;
817    var letraControlEsperada = "JABCDEFGHI"[digitoControlEsperado];
818
819    // 5. El carácter de control real (posición 8)
820    var dc = tempStr.charAt(8);
821
822    // 6. Validación según el tipo de entidad
823    var letraInicial = tempStr.charAt(0);
824    
825    // Algunas entidades solo admiten letra como DC, otras solo número
826    // Pero la J (Sociedad Civil) y otras permiten ambos
827    return (dc == digitoControlEsperado) || (dc == letraControlEsperada);
828}
829
830//FUNCIONES AUXILIARES PARA LA VALIDACIÓN DE LA REFERENCIA CATASTRAL
831window.calcularDigitoControlReferenciaCatastral = 
832function (cadena) 
833{
834	const LETRAS_CONTROL = "MQWERTYUIOPASDFGHJKLBZX";
835	const PESOS = [13, 15, 12, 5, 4, 17, 9, 21, 3, 7, 1];
836    let suma = 0;
837
838	for (let i = 0; i < cadena.length; i++) 
839	{
840    	const c = cadena.charAt(i);
841	    let valor;
842	
843	    if (/\d/.test(c)) {
844	      valor = parseInt(c, 10);
845	    } else {
846	      valor = letraANumero(c);
847	    }		
848	    suma += valor * PESOS[i];
849	}
850
851  	const resto = suma % 23;
852  	return LETRAS_CONTROL.charAt(resto);
853}
854
855function letraANumero(letra) 
856{
857	if (letra === 'Ñ') 
858  	{
859    	return 15;
860  	}	
861  	const code = letra.charCodeAt(0);
862  	if (code >= 65 && code <= 78) 
863	{ // A - N
864    	return code - 65 + 1;
865  	} else if (code >= 79 && code <= 90) 
866	{ // O - Z
867    	return code - 79 + 16;
868  	} else 
869	{
870    	return 0; // carácter no válido
871  	}
872}
873//FIN FUNCIONES AUXILIARES PARA LA VALIDACIÓN DE LA REFERENCIA CATASTRAL
874
875}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.