La validación de números telefónicos es una parte crucial de cualquier formulario en línea. Garantizar que los usuarios ingresen números de teléfono válidos ayuda a mantener la precisión de los datos y mejora la experiencia del usuario. En este artículo, se explorará cómo realizar la validación de números telefónicos utilizando la biblioteca intlTelInput en Elementor y Bricks Builder.

¿Qué es intlTelInput?

intlTelInput es una biblioteca de JavaScript que proporciona una interfaz de usuario intuitiva para ingresar y validar números de teléfono internacionales. Esta biblioteca utiliza la base de datos de códigos de país de Google para ofrecer una experiencia de usuario fluida y precisa.

Pasos para validar números telefónicos con intlTelInput en Elementor y Bricks Builder

Para poder agregar los fragmentos de código del post, es necesario utilizar un plugin de WordPress como Code Snippets o agregarlos al archivo functions.php del tema activo en su sitio web. Estos métodos le permitirán integrar y ejecutar los fragmentos de código de manera segura y eficiente.

Es necesario que los campos de los formularios sean de tipo telefónico tel para poder integrar y utilizar la biblioteca intlTelInput.

1. Agregando la librería de intlTelInput con wp_enqueue_scripts

Utilice la función wp_enqueue_scripts para agregar los scripts necesarios de intlTelInput en su tema de WordPress. Esto asegurará que los scripts se carguen de manera adecuada y optimizada.

Elementor
Bricks
<?php
add_action( 'wp_enqueue_scripts', function(){
	wp_enqueue_style( 'intlTelInput-css', 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/css/intlTelInput.css', array(), false, false );
	wp_enqueue_script( 'intlTelInput-js', 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/intlTelInput.min.js', array(), false, false );
}, 10);
<?php
add_action( 'wp_enqueue_scripts', function(){
	$bricks_settings_string = json_encode( Bricks\Database::get_template_data( 'content' ) );
	
	if( ! strpos( $bricks_settings_string, '"type":"tel"' ) ) {
		return;
	}
	
	wp_enqueue_style( 'intlTelInput-css', 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/css/intlTelInput.css', array(), false, false );
	wp_enqueue_script( 'intlTelInput-js', 'https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/intlTelInput.min.js', array(), false, false );
}, 10);

2. Añadiendo los estilos necesarios con wp_head:

Asegúrese de añadir los estilos requeridos para intlTelInput utilizando la función wp_head en su tema de WordPress. Esto garantizará que los estilos se integren correctamente en el encabezado de su sitio web.

Elementor
Bricks
<?php
add_action( 'wp_head', function () { ?>
	<style>
		.iti {
			width: 100%;
		}
		.iti__country-list {
			border-radius: 5px;
			box-shadow: 0 3px 13px rgba(0,0,0,0.08);
		}
	</style> <?php
} );
<?php
add_action( 'wp_head', function () { 
	$bricks_settings_string = json_encode( Bricks\Database::get_template_data( 'content' ) );
	
	if( ! strpos( $bricks_settings_string, '"type":"tel"' ) ) {
		return;
	}
?> 
	<style>
		.iti-mobile .iti--container {
			z-index: 10000;
		}
	</style> 
<?php } );

3. Agregando los scripts necesarios con wp_footer para inicializar la librería en los formularios:

Agregue los scripts necesarios después del footer para inicializar la biblioteca intlTelInput en los formularios de su sitio.

Elementor
Bricks
<?php
add_action( 'wp_footer', function () { ?>
	<script>
		document.addEventListener('DOMContentLoaded', () => {
			const forms = document.querySelectorAll('.elementor-form');

			const setintlTelInput = (field, validator) => {
				const iti = window.intlTelInput(field, {
					nationalMode: true,
					initialCountry: "auto",
					geoIpLookup: function(callback) {
						fetch('https://ipinfo.io/json')
							.then(res => res.json())
							.then(data => {
							var countryCode = (data && data.country) ? data.country : "us";
							callback(countryCode);
						})
						.catch(error => console.error(error));
					},
					utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/utils.js"
				});

				// on blur: validate
				field.addEventListener('blur', function() {
					if (field.value.trim()) {
						if (iti.isValidNumber()) {
							field.value = iti.getNumber();
							validator.value = 'valid';
						} else {
							validator.value = 'error';
						}
					}
				});
			}
				
            forms.forEach((form) => {
                const telInputs = form.querySelectorAll('input[type="tel"]');

                if (!telInputs) return;

                form.addEventListener('click', () => {

                    telInputs.forEach((input) => {
                        let fieldGroup = input.parentNode,
                            fieldId = input.getAttribute('id'),
                            validator = document.createElement('input');

                        fieldId = fieldId.replace('form-field-', '');

                        validator.setAttribute('type', 'hidden');
                        validator.setAttribute('name', 'phone-validator-'+fieldId);
                        validator.setAttribute('value', '');

                        fieldGroup.insertBefore(validator, input.nextSibling);

                        setintlTelInput (input, validator);

                        let flagContainer = fieldGroup.querySelector(".iti__flag-container");
                        flagContainer.style.maxHeight = input.offsetHeight+'px';
                    });					
                }, {once: true});
            });
		});
	</script> <?php
} );
<?php
add_action( 'wp_footer', function () { 
	$bricks_settings_string = json_encode( Bricks\Database::get_template_data( 'content' ) );
	
	if( ! strpos( $bricks_settings_string, '"type":"tel"' ) ) {
		return;
	}
?> 
	<script>
		document.addEventListener('DOMContentLoaded', () => {
			const forms = document.querySelectorAll('.brxe-form');
			
			const setintlTelInput = (field, validator) => {
				const iti = window.intlTelInput(field, {
					nationalMode: true,
					initialCountry: "auto",
					geoIpLookup: function(callback) {
						fetch('https://ipinfo.io/json')
							.then(res => res.json())
							.then(data => {
							var countryCode = (data && data.country) ? data.country : "us";
							callback(countryCode);
						})
						.catch(error => console.error(error));
					},
					utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.13/js/utils.js"
				});

				// on blur: validate
				field.addEventListener('blur', function() {
					if (field.value.trim()) {
						if (iti.isValidNumber()) {
							field.value = iti.getNumber();
							validator.value = 'valid';
						} else {
							validator.value = 'error';
						}
					}
				});
			}
			
			forms.forEach((form) => {
				const telInputs = form.querySelectorAll('input[type="tel"]');
				
				if (!telInputs) return;
				
				form.addEventListener('click', () => {
					
					telInputs.forEach((input) => {
						let fieldGroup = input.parentNode,
							fieldName = input.getAttribute('name'),
							fieldId = '',
							validator = document.createElement('input');

						fieldId = fieldName.replace('form-field-', '');

						validator.setAttribute('type', 'hidden');
						validator.setAttribute('name', 'phone-validator-'+fieldId);
						validator.setAttribute('value', '');

						fieldGroup.insertBefore(validator, input.nextSibling);

						setintlTelInput (input, validator)
					});					
				}, {once: true});
			});
		});
	</script> 
<?php } );

4. Validando los formularios con PHP tanto en Elementor como en Bricks:

Implemente la validación de formularios utilizando PHP tanto en Elementor como en Bricks para asegurar que los números de teléfono ingresados por los usuarios cumplan con los requisitos establecidos.

Elementor
Bricks
<?php
add_action( 'elementor_pro/forms/validation', function ( $record, $ajax_handler ) {
	
	$raw_fields = $record->get( 'fields' );
	
	foreach ( $raw_fields as $id => $field ) {
		$field_id = $field['id'];
		$field_type = $field['type'];
		$field_value = $field['value'];
		$is_tel_field = $field_type == 'tel' ? true : false;
		
		if( $is_tel_field ) {
			$validator = sanitize_text_field($_POST["phone-validator-$field_id"]);
			
			if ( empty( $field_value ) ) {
				return;
			}
			
			if ( $validator == 'error' ) {
				$ajax_handler->add_error( $field_id, __('Invalid phone number', 'textdomain') );
			}
		}
	}
}, 10, 2 );
<?php
add_filter( 'bricks/form/validate', function( $errors, $form ) {
	$form_settings = $form->get_settings();
	$form_fields   = $form->get_fields();
	$form_id       = $form_fields['formId'];
	
	foreach( $form_settings['fields'] as $field ) {
		$field_id = $field['id'];
		$field_label = $field['label'];
		$field_type = $field['type'];
		$is_tel_field = $field_type == 'tel' ? true : false;
		
		if( $is_tel_field ) {
			$phone = $form->get_field_value( $field_id );
			$validator = sanitize_text_field($_POST['phone-validator-'.$field_id]);
			
			if ( empty( $phone ) ) {
				return;
			}
			
			if ( $validator == 'error' ) {
				$html = array(
					$field_label,
					'Invalid phone number.'
				);
				
				$errors[] = esc_html__( implode(': ', $html), 'bricks' );
			}
		}
	}

	return $errors;
}, 10, 2 );