Guía 71 – Plugin «Select2_ajax»

Un desarrollador de PHPRunner me escribió indicándome que tenía problemas en utilizar el «lookup» del plugin «Select2» en ventana «popup» y que le gustaría disponer de la funcionalidad de «dependencia», similar a la funcionalidad estándar del «lookup» de PHPRunner.

Si recordáis el «lookup» estándar de PHPRunner tiene las siguientes funcionalidades:

  • Múltiples formas de «lookup«. Para tablas con muchos valores tiene el tipo «Ajax».
  • Valor inicial
  • La funcionalidad de «AutoFill«, que permite rellenar otros campos con valores recuperados del «lookup«.
  • El filtrado de valores por dependencia de un valor recuperado/informado, previamente.

Hace unos días, Sergey, nos facilitó un plugin (Multi-Columnas) que nos indicaba que tenía resuelto el tema de la dependencia, así que me puse a intentar implementar en el plugin «Select2», las mismas funcionalidades que tiene el «lookup» estándar de PHPRunner.

Objetivo

Dotar al plugin «Select2» de la misma funcionalidad que el componente de «lookup»  estándar de PHPRunner.

DEMO: https://fhumanes.com/select2_dependence

DEMO:  https://fhumanes.com/s2_car/

El ejemplo se ha hecho utilizando en nuevo plugin «select2_ajax» que está disponible en la página de los plugines.

Solución Técnica

El nuevo plugin «Multi-Columna», que nos facilitó Sergey, al menos la copia que me bajé del portal de XlineSoft, está incompleto en lo referente a la «dependencia», nos obstante he tomado soluciones del mismo para resolver mi problema.

El nuevo plugin «select2_ajax» ejecuta el acceso a la base de datos en el momento que te posicionas en él, por lo que utilizo variables de sesión para guardar el SQL de acceso a la base de datos y el filtrado de los valores. Según se va aportando letras en el campo de diálogo se va repitiendo los «select» recuperando los valores que se ajustan a todos los criterios .
Se puede limitar el número de respuesta con la sentencia «limit» de MySQL, por lo que es una excelente solución para tablas muy grandes.

Para pasar el valor de dependencia utilizo una variable de sesión, definida entre los parámetros y  asociada al nombre (id) del campo receptor en la pantalla.

La funcionalidad que requería, creo que está resuelta perfectamente, pero no todo el código lo he podido poner en el plugin.

En el ejemplo he programado la misma funcionalidad con el «lookup» estándar de PHPRunner y con el nuevo plugin «select2_ajax».

Como complemento al plugin he creado estas 3 funciones de JavaScript:

/*
Función para borrar contenido del campo Select2
*/
function clearSelect2(ctrl){
var field = ctrl.valContId;
$('#select2-'+field+'-container').html('');
$('#'+field).html('');
}

/*
Función para cargar variables de sesión en el server
Parámetros:
  - name: Key de $_SESSION.
  - value: Valor a poner en variable de sessión
  - ctrField: Campo "control", del lookup destino (sólo para Select2)
*/
function setSession(name,value,ctrField = null){
var destination = '';
if ( ctrField != null) {
  destination = ctrField.valContId;
}
$.ajax({
    async: false,
     cache: false,
     type: 'POST',  //  SEND with POST method
     url: 'setSession_ajax.php',  // Destination file (the PHP that manages the data)
     data: { 
      name: name,
      value: value,
      fieldDest: destination
      } // Data that are sent
     }).done(function( msg ) {  // Function that runs if everything has gone well
      console.log("Response the Function setSession: "+msg );
      
     }).fail(function (jqXHR, textStatus, errorThrown){ // Function that runs if something has gone wrong
      // We show the message with the error that has been produced
      console.log("The following error occured: "+ textStatus +" "+ errorThrown);
    });
}


/*
Función para hacer los AutoFill manualmente para solucionar esta función con los Plugins
Parámetros:
  - url: Url absoluta o relativa de la ejecución Ajax
  - ctrlParam: Objeto Control del campo que se enviará cómo parámetro
  - fieldControlArray: Array de objetos Control que será los receptores de los valores devueltos. Se aplicarán por orden

Autofill function manually to solve this function with plugins
Parameters:
- url: absolute or relative url of Ajax execution
- ctrlParam: Control object of the field that will be sent as parameter
- fieldControlArray: array of control objects that will be the receptors of the returned values. Will be applied in order
*/
function AutoFill(url,crtlParam, fieldControlArray){

    pvalue = crtlParam.getValue(); // We collect the value of the field from the form
   ajaxUrl = url;
    // Setting function and receives response with AJAX
    $.ajax({
    async: false,
     cache: false,
     type: 'POST',  //  SEND with POST method
     url: ajaxUrl,  // Destination file (the PHP that manages the data)
     data: { param: pvalue} // Data that are sent
     }).done(function( msg ) {  // Function that runs if everything has gone well
      msgArr = msg.split(";");
      if ( msgArr[0] == '1' ) { // Is OK
      for (let i = 0; i < fieldControlArray.length; i++) {
        var ctrl = fieldControlArray[i];
        ctrl.setValue(msgArr[i+2]); // Put Value
        console.log("Correct operation, recovered value: "+ msgArr[i+2]);
      } 
      } else { // Is KO
        // alert("The following error occured: "+msgArr[2]);
      console.log("The following error occured: "+msgArr[2]);
      }
     }).fail(function (jqXHR, textStatus, errorThrown){ // Function that runs if something has gone wrong
      // We show the message with the error that has been produced
      console.log("The following error occured: "+ textStatus +" "+ errorThrown);
    });
  }

Estas funciones se utilizan con el plugin «select2_ajax», pero se pueden utilizar perfectamente sin el plugin.

De esta forma he resuelto la carga del fichero de las nuevas funciones de JavaScript.

Estos códigos se apoyan en la funcionalidad del código del server (PHP), con nombres:

setSession_ajax.php

<?php
require_once("include/dbcommon.php"); // DataBase PHPRunner

if (!isset($_POST['name']) || !isset($_POST['value']) ) { //  Control of the call and verification of the existence of the parameter
  echo("Please provide a Name + Value.");
  die();
}
$name = $_POST['name'];
$value = $_POST['value'];
$field = $_POST['fieldDest'];

if ( $field == '') {
  $_SESSION[$name] = $value;
} else {
  $_SESSION[$name][$field] = $value; // Para Select2
}

echo("Created session variable [".$name."]: " . $value);
?>

ajax_AutoFill_1.php

<?php
require_once("include/dbcommon.php"); // DataBase PHPRunner

if (!isset($_POST['param'])) { //  Control of the call and verification of the existence of the parameter
  echo("0;;Please provide a Param.");
  die();
}
$param = $_POST['param'];

// Get the highest value that exists in the database
$rs = DB::Query("SELECT CodigoProvincia FROM rp_provincia WHERE NombreProvincia = '$param'");
$field_1 = $rs->value("CodigoProvincia"); //  To control if there is a response to the query
if ( $field_1 == NULL ) {
  $$field_1 = '';                     //  If there is no record loaded puts the value 0
}

echo "1;Ok, Good answer;$field_1";
?>

En este caso, este fichero de programa hay que personalizarlo para el acceso a la información y el número de valores que hay que recoger.

Así pues, el plugin hace lo básico, y las demás funcionalidades que ofrecen estos código se ejecutan desde el evento «JavaScript Onload event»:

Hay que poner el mismo código en la página EDIT y ADD.

Para aquellos que estéis empezando a programar en JavaScript y/o PHP, creo que este ejemplo os va a gustar mucho porque podréis aprender muchos detalles.

Para cualquier duda, poneros en contacto conmigo a través de mi email: [email protected]

Os dejo el proyecto para que lo podáis instalar en vuestro PC y podáis hacer las adaptaciones que necesitéis.

Ampliación: 29 de agosto 2024
Se ha ampliado el artículo para explicar:

  • Que se ha actualizado el plugin «Select2_ajax» porque tal y como estaba, no se podía dejar sin valor un campo que tuviese aplicado este plugin.
  • Se ha creado otro ejemplo, que entiendo es más fácil de entender, ya que el originalmente puesto, por el modelo de datos que utiliza estaba un poco «retorcida» la lógica de funcionamiento y podía generar confusión en su uso.

Este es el modelo de datos del nuevo ejemplo llamado «s2_car» y se muestra 3 lookups dependientes.

DEMO:  https://fhumanes.com/s2_car/

El código JavaScript de ADD y EDIT es:

var ctrl_s2_manufacturer_id = Runner.getControl(pageid,'s2_manufacturer_id'); 
var ctrl_s2_model_id = Runner.getControl(pageid,'s2_model_id');
var ctrl_s2_engine_id = Runner.getControl(pageid,'s2_engine_id');

setSession('s2_filter_manufacturer',ctrl_s2_manufacturer_id.getValue(), ctrl_s2_model_id); 

ctrl_s2_manufacturer_id.on('change', function() {
  console.log("Change Manufacturer");
  setSession( 's2_filter_manufacturer',ctrl_s2_manufacturer_id.getValue(), ctrl_s2_model_id);
  ctrl_s2_model_id.setValue('');
  ctrl_s2_engine_id.setValue('');
  clearSelect2(ctrl_s2_model_id);
  clearSelect2(ctrl_s2_engine_id);
});

ctrl_s2_model_id.on('change', function() {
  console.log("Change Model");
  setSession( 's2_filter_model',ctrl_s2_model_id.getValue(), ctrl_s2_engine_id);
  ctrl_s2_engine_id.setValue('');
   clearSelect2(ctrl_s2_engine_id);
});

ctrl_s2_engine_id.on('change', function() {
  console.log("Change Engine");	
});

Adjuntos

Archivo Tamaño de archivo Descargas
zip PHPrunner 10.7 + backup de base de datos 137 KB 335
zip s2_car : PHPRunner 10.7 + backup de Base de Datos 74 KB 56

Blog personal para facilitar soporte gratuito a usuarios de React y PHPRunner