Julius'Lab

Javascript

(Formidable) Limitar mes de un datepicker al mes en curso

Para limitar el mes de un datepicker en Formidable, usar este código en Code Snippets:

add_action('frm_date_field_js', 'limit_date_field_to_current_month');
function limit_date_field_to_current_month($field_id){
  if($field_id == 'field_FIELDKEY'){ // change FIELDKEY to the key of the date field
    $first_day_of_month = date('Y-m-01');
    $last_day_of_month = date('Y-m-t');
    $first_day_js = date('n-j-Y', strtotime($first_day_of_month));
    $last_day_js = date('n-j-Y', strtotime($last_day_of_month));
    
    echo "
      ,minDate: new Date('{$first_day_js}')
      ,maxDate: new Date('{$last_day_js}')
      ,dateFormat: 'dd/mm/yy'
      ,showMonthAfterYear: false
      ,monthNames: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre']
      ,monthNamesShort: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre']
    ";
  }
}

Este código fue escrito por ChatGPT (https://chatgpt.com/c/983f82d5-fc89-466d-95ad-790f116960ab) basado en el código dado por Formidable en https://formidableforms.com/knowledgebase/frm_date_field_js/#kb-custom-dynamic-date-range

Curiosamente, en monthNamesShort estaban los nombres de tres caracteres de los meses (‘ene’,’feb’,’mar’, etc) pero se los tuve que cambiar ya que sólo toma el nombre en ese array, y ChatGPT no lo solucionó.

NOTA: IMPORTANTE que la línea ,dateFormat:’dd/mm/yy’ tenga ese formato para que la fecha elegida sea aceptada por el formulario.

(Formidable) Limitar mes de un datepicker al mes en curso Leer más »

(Formidable,Javascript) Checkboxes de Dynamic Fields – Aplicar JS para contar y limitar checkboxes

Formidable tiene un par de códigos en JS que cuentan y limitan las Checkboxes de un Checkbox field:

Count number of checked boxes:

Limit the number of checked boxes

 
Estos códigos funcionan muy bien con los campos Checkbox nativos de Formidable,pero no funcionan con los checkboxes creados por un Dynamic field.

Para esto, ChatGPT me ayudó a adaptar los scripts para que funcionen con los Dynamic/Checkboxes fields:

Limita los checkboxes seleccionados a un número arbitrario (en este caso 3):

jQuery(document).ready(function($) {
    var limit = 3; // Change this to your desired limit
    // Use event delegation to handle dynamic checkboxes
    $(document).on('change', 'input[name="item_meta[973][]"]', function() {
        var checkbox_num = $('input[name="item_meta[973][]"]:checked').length;
        if (checkbox_num > limit) {
            this.checked = false;
        }
    });
});

Cambiar 973 al ID del Dynamic/checkboxes field.

Cuenta los checkboxes seleccionados y coloca el valor en cualquier lugar:

jQuery(document).ready(function($) {
    // Use event delegation to handle dynamic checkboxes
    $(document).on('change', 'input[name="item_meta[973][]"]', function() {
        var val1 = $('input[name="item_meta[973][]"]:checked').length;
        $("#field_checkLimit").val(val1);
    });
});

Cambiar 973 al ID del Dynamic/checkboxes field, y dar nombre de class checkLimit a cualquier contenedor (div, span, etc.) en el que quiera colocarse el número de checkboxes seleccionadas.

Este es el script de los dos códigos combinados, para que lo haga todo junto:

jQuery(document).ready(function($) {
    var limit = 3; // Change this to your desired limit
    $(document).on('change', 'input[name="item_meta[973][]"]', function() {
        // Limit the number of checked checkboxes
        var checkbox_num = $('input[name="item_meta[973][]"]:checked').length;
        if (checkbox_num > limit) {
            this.checked = false;
        }

        // Count checked checkboxes
        var val1 = $('input[name="item_meta[973][]"]:checked').length;
        $("#field_checkLimit").val(val1);
    });
});

(Formidable,Javascript) Checkboxes de Dynamic Fields – Aplicar JS para contar y limitar checkboxes Leer más »

(Formidable/JavaScript) Hacer que un campo Dinámico dispare otro campo (mientras Lógica Condicional de Formidable no funciona)

En un mundo perfecto, un campo dinámico debería poder «disparar» (trigger) la visualización de otro campo, si la lógica condicional de este campo se pone en:
In a perfect world, a Dynamic field should be able to trigger the displaying of another field, if Conditional Logic of the latter is set like this:

Show this field if any/all of the following match:
Field1 is equal to anything

Pero actualmente no funciona. Formidable alega que está al tanto de este problema, pero aún no tienen fecha de arreglo.
But it currently does not work. Formidable is allegedly aware of this issue, but they don’t have a fix date yet.

Así que, este es mi arreglo (gracias a ChatGPT):
So, this is my fix (thanks to ChatGPT:

<script>
jQuery(document).ready(function($){
// Hide field by default
	$("#frm_field_775_container").css('display','none');

	$(document).on('change', 'select[name="item_meta[773]"]', function(){ //select[name='item_meta[994]']
		var show;

		var val1 = $("select[name='item_meta[773]']").val();
		console.log("Selected value:", val1);
		if (val1 !== '' && val1 !== '0' && val1 !== '-1' && val1 !== ' ')
			{show = true;console.log("showing");}
		else
			{show = false;console.log("hidden");}

		if(show){
			$("#frm_field_775_container").css('display','block');
		}else{
			$("#frm_field_775_container").css('display','none');
		}
	});
});
</script>

Field773 es el campo Dinámico que dispara. Field775 es el campo inicialmente oculto que se muestra al elegir algo en el campo Dinámico.
Field773 is the triggering Dynamic field. Field775 is the field, initially hidden, that shows up when chosing something in the Dynamic field.

(Formidable/JavaScript) Hacer que un campo Dinámico dispare otro campo (mientras Lógica Condicional de Formidable no funciona) Leer más »

(Formidable/Divi) Resolver problema de enlaces de Calendario en Divi

Usando el tema Divi, los enlaces de la vista de Calendario de Formidable no funcionan de manera adecuada. Sólo hacen scroll un poco hacia abajo y no llevan al mes previo o siguiente.

La solución reside en agregar este script en Javascript (usando el plugin Simple Custom CSS and JS):

document.addEventListener('DOMContentLoaded', function() {
  var previousLink = document.querySelector('a.frmcal-prev');
  var nextLink = document.querySelector('a.frmcal-next');
  if (previousLink) {
    previousLink.href = previousLink.href.replace(/#.*/, '');
  }
  if (nextLink) {
    nextLink.href = nextLink.href.replace(/#.*/, '');
  }
});

Este script quita la parte: #frmcal-1411 de los enlaces (1411 en mi caso, es el id de mi vista Calendario), y los transforma de:

https://mysite.com/calendar/?frmcal-year=2023&frmcal-month=04#frmcal-1411

a:

https://mysite.com/calendar/?frmcal-year=2023&frmcal-month=04

Y con eso, el problema se resuelve.

(Formidable/Divi) Resolver problema de enlaces de Calendario en Divi Leer más »

(Formidable, Javascript) Recargar la página después que se ha enviado un formulario en un Bootstrap Modal

Un formulario insertado en un Bootstrap Modal (add-on de Formidable) no refrescará automáticamente la página, ocurriendo que, a la hora de hacer clic fuera de la ventana modal y luego abrir la modal de nuevo, mostrará el mismo formulario con el mensaje de éxito o error. Manualmente hay que recargar la página con el navegador.

Para evitar esto, hay que:

1. En los Ajustes del formulario > Al Enviar: Mostrar el formulario con el mensaje de confirmación.

2. Ajustes > Ajax > Activar Enviar este formulario con Ajax.

3. En los mensajes Al Enviar y Al Actualizar, colocar el siguiente javascript:

<script>
    setTimeout("window.location.reload(true);",2000);
</script> 

Siendo 2000 el número de milisegundos para que recargue la página.

(Formidable, Javascript) Recargar la página después que se ha enviado un formulario en un Bootstrap Modal Leer más »

(Javascript) Función para convertir cifras a texto (probar y pulir)

<script>
document.getElementById("numero").addEventListener("keyup",function(e){
    document.getElementById("texto").innerHTML=NumeroALetras(this.value);
});
 
 
function Unidades(num){
 
  switch(num)
  {
    case 1: return "UN";
    case 2: return "DOS";
    case 3: return "TRES";
    case 4: return "CUATRO";
    case 5: return "CINCO";
    case 6: return "SEIS";
    case 7: return "SIETE";
    case 8: return "OCHO";
    case 9: return "NUEVE";
  }
 
  return "";
}
 
function Decenas(num){
 
  decena = Math.floor(num/10);
  unidad = num - (decena * 10);
 
  switch(decena)
  {
    case 1:
      switch(unidad)
      {
        case 0: return "DIEZ";
        case 1: return "ONCE";
        case 2: return "DOCE";
        case 3: return "TRECE";
        case 4: return "CATORCE";
        case 5: return "QUINCE";
        default: return "DIECI" + Unidades(unidad);
      }
    case 2:
      switch(unidad)
      {
        case 0: return "VEINTE";
        default: return "VEINTI" + Unidades(unidad);
      }
    case 3: return DecenasY("TREINTA", unidad);
    case 4: return DecenasY("CUARENTA", unidad);
    case 5: return DecenasY("CINCUENTA", unidad);
    case 6: return DecenasY("SESENTA", unidad);
    case 7: return DecenasY("SETENTA", unidad);
    case 8: return DecenasY("OCHENTA", unidad);
    case 9: return DecenasY("NOVENTA", unidad);
    case 0: return Unidades(unidad);
  }
}//Unidades()
 
function DecenasY(strSin, numUnidades){
  if (numUnidades > 0)
    return strSin + " Y " + Unidades(numUnidades)
 
  return strSin;
}//DecenasY()
 
function Centenas(num){
 
  centenas = Math.floor(num / 100);
  decenas = num - (centenas * 100);
 
  switch(centenas)
  {
    case 1:
      if (decenas > 0)
        return "CIENTO " + Decenas(decenas);
      return "CIEN";
    case 2: return "DOSCIENTOS " + Decenas(decenas);
    case 3: return "TRESCIENTOS " + Decenas(decenas);
    case 4: return "CUATROCIENTOS " + Decenas(decenas);
    case 5: return "QUINIENTOS " + Decenas(decenas);
    case 6: return "SEISCIENTOS " + Decenas(decenas);
    case 7: return "SETECIENTOS " + Decenas(decenas);
    case 8: return "OCHOCIENTOS " + Decenas(decenas);
    case 9: return "NOVECIENTOS " + Decenas(decenas);
  }
 
  return Decenas(decenas);
}//Centenas()
 
function Seccion(num, divisor, strSingular, strPlural){
  cientos = Math.floor(num / divisor)
  resto = num - (cientos * divisor)
 
  letras = "";
 
  if (cientos > 0)
    if (cientos > 1)
      letras = Centenas(cientos) + " " + strPlural;
    else
      letras = strSingular;
 
  if (resto > 0)
    letras += "";
 
  return letras;
}//Seccion()
 
function Miles(num){
  divisor = 1000;
  cientos = Math.floor(num / divisor)
  resto = num - (cientos * divisor)
 
  strMiles = Seccion(num, divisor, "MIL", "MIL");
  strCentenas = Centenas(resto);
 
  if(strMiles == "")
    return strCentenas;
 
  return strMiles + " " + strCentenas;
 
  //return Seccion(num, divisor, "UN MIL", "MIL") + " " + Centenas(resto);
}//Miles()
 
function Millones(num){
  divisor = 1000000;
  cientos = Math.floor(num / divisor)
  resto = num - (cientos * divisor)
 
  strMillones = Seccion(num, divisor, "UN MILLÓN", "MILLONES");
  strMiles = Miles(resto);
 
  if(strMillones == "")
    return strMiles;
 
  return strMillones + " " + strMiles;
 
  //return Seccion(num, divisor, "UN MILLON", "MILLONES") + " " + Miles(resto);
}//Millones()
 
function NumeroALetras(num,centavos){
  var data = {
    numero: num,
    enteros: Math.floor(num),
    centavos: (((Math.round(num * 100)) - (Math.floor(num) * 100))),
    letrasCentavos: "",
  };
  if(centavos == undefined || centavos==false) {
    data.letrasMonedaPlural="PESOS";
    data.letrasMonedaSingular="PESO";
  }else{
    data.letrasMonedaPlural="CENTAVOS";
    data.letrasMonedaSingular="CENTAVO";
  }
 
  if (data.centavos > 0)
    data.letrasCentavos = "CON " + NumeroALetras(data.centavos,true);
 
  if(data.enteros == 0)
    return "CERO " + data.letrasMonedaPlural + " " + data.letrasCentavos;
  if (data.enteros == 1)
    return Millones(data.enteros) + " " + data.letrasMonedaSingular + " " + data.letrasCentavos;
  else
    return Millones(data.enteros) + " " + data.letrasMonedaPlural + " " + data.letrasCentavos;
}//NumeroALetras()
</script>

(Javascript) Función para convertir cifras a texto (probar y pulir) Leer más »

(Formidable/Javascript) Convertir a Title Case el texto ingresado

Añadir el siguiente código en After Fields (Campos Después):

<script>
   function titleCase(string) {
      var sentence = string.toLowerCase().split(" ");
      for(var i = 0; i< sentence.length; i++){
         sentence[i] = sentence[i][0].toUpperCase() + sentence[i].slice(1);
      }
   return (sentence.join(" "));
   }
</script>

Del campo que se requiera transformar, buscar la caja correspondiente en Ajustes > Personalizar HTML, y sustituir el [input] por:

[input onblur="this.value = titleCase(this.value);"]

El método onblur ocurre cuando se pierde el foco del campo. Si se desea que ocurra mientras se escribe, usar onkeyup.

(Formidable/Javascript) Convertir a Title Case el texto ingresado Leer más »

(Formidable/Javascript/RegEx) Quitar todas las etiquetas de un texto (RegEx way)

Se tienen dos campos: uno con RTF (text-rtf) y otro como texto normal (text-norm).
El objetivo es copiar el texto ingresado en text-rtf a text-norm despojándolo de todas las etiquetas HTML.
De pilón, despojar también de la entidad &nbsp; y otros semovientes similares que vayan apareciendo.

Se coloca en Personalizar HTML > «Campos después» (Fields after) del formulario, el siguiente código:

<script type="text/javascript">
jQuery( document ).ready( function ( $ ) { //COPIA DE text-rtf A text-norm
    $( '#field_text-rtf' ).change ( function () { //source field key
        var originalValue = $( "#field_text-rtf" ).val(); //source field key
        var newValue = originalValue.replace( /(<([^>]+)>)|&nbsp;/ig, '');
        $( "#field_text-normal" ).val( newValue ); //destination field key
        $( "#field_text-normal" ).change(); //destination field key
    });
});
</script>

La clave es el RegEx que está dentro del método Replace:

/(<([^>]+)>)|&nbsp;/ig

El cual se divide con la entidad «|» (or) para buscar también la entidad &nbsp;.
El RegEx sólo para las etiquetas es

/(<([^>]+)>)/ig

(Formidable/Javascript/RegEx) Quitar todas las etiquetas de un texto (RegEx way) Leer más »

(Formidable) Limitar número de caracteres con Javascript

Como siempre, poner el script en Personalizar HTML > «Campos después» (Fields after) del formulario.

<script type="text/javascript">
jQuery(document).ready(function($){ // Limita número de caracteres a 20
    $('#field_CLAVE_CAMPO').change(function(){ // Cambiar CLAVE_CAMPO al field key necesario
        if($(this).val().length>20){
             $(this).val($(this).val().substr(0, 20)); // Cambiar ambos 20 por el límite deseado
        }
    });
});
</script>

Sin embargo, este código no funciona para impedir escribir más de 20 caracteres, simplemente «trunca» el texto ingresado después del vigésimo caracter. En caso de que quiera impedirse que se pase de 20 caracteres, usar el built-in de Formidable sólo en texto normal, no en RTF.

Tomado y corregido de Limit number of characters en Formidable Forms hooks for developers.

(Formidable) Limitar número de caracteres con Javascript Leer más »

(Javascript – Formidable) Accionar un campo Toggle de acuerdo al valor de un campo de selección

Colocar este código en la sección Campos Después (Fields After) en Personalizar HTML del formulario.

<script type="text/javascript">
jQuery(document).ready(function($){
  $('select[name="item_meta[530]"]').change(function(){ //530 es el campo de selección (dropdown)
     var val1 = $("select[name='item_meta[530]']").val();
     if (val1 == 'Pendiente' || val1 == 'Por entregar' || val1 == 'En proceso' || val1 =='Incumplimiento')
     {$("#field_bloqueado").attr("checked", true);} // "bloqueado" es el key del campo toggle a accionar
     else if (val1 == '' || val1 == 'Rechazado' || val1 == 'Cancelado' || val1 =='Concretado')
     {$("#field_bloqueado").attr("checked", false);}
     $("#field_bloqueado").change();
  });
});
</script>
<script type="text/javascript">
jQuery(document).ready(function($){
var oldValue = '';
var dynamic_field = document.getElementById("field_dfe");
var hidden_field = document.getElementById("field_hidden");
var aTimer;
var counter;

$(dynamic_field).change(function(){
oldValue = $("#field_just_show_it").val() ;
if (!(aTimer == undefined) ) clearInterval(aTimer) ;
counter = 0 ;
aTimer = setInterval(function(){
var newValue = $("#field_just_show_it").val() ;
counter ++ ;
if ( (newValue != oldValue) ){
if (newValue != oldValue && newValue != undefined) {
hidden_field.value = newValue;
oldValue = newValue;
$(hidden_field).change();
}
clearInterval(aTimer) ;
}
} , 100) ;
}) ;
}) ;

</script>

(Javascript – Formidable) Accionar un campo Toggle de acuerdo al valor de un campo de selección Leer más »