• sfDependentSelectPlugin ordenado por texto

    sfDependentSelectPlugin ordenado por texto

    Utilicé este interesante plugin para mostrar select box dependientes. En concreto para mostrar un select box de “Sector” y “Puesto”, siendo los puestos dependientes del sector elegido.

    El plugin funciona bien, pero tiene un problema y es que los valores de los selects, tanto del padre como del dependiente, no muestra los valores ordenados por el texto, sino por el ID del registro al que se refiere.  Ni siquiera poniendo la opción “order_by” al declarar el widget:

     

    this->widgetSchema[“puesto_id”] = new sfWidgetFormDoctrineDependentSelect(array(‘model’ => ‘Puesto’,
                                                                                                                                                                              ‘depends’ => ‘Sector’,
                                                                                                                                                                              ‘add_empty’ => true,
                                                                                                                                                                              ‘ajax’ => true,
                                                                                                                                                                              ‘ref_method’ => ‘getSectorId’,
                                                                                                                                                                              ‘url’ => sfContext::getInstance()->getController()->genUrl(‘sfDependentSelectAuto/_ajax’),
                                                                                                                                                                              ‘cache’ => true,
                                                                                                                                                                              // the same of sfWidgetForm{Doctrine|Propel}Choice are available ¿?
                                                                                                                                                                              ‘order_by’ => array(‘nombre’, ‘asc’),
                                                                                                                                                                              ‘method’ => ‘__toString’,
                                                                                                                                                                              ‘key_method’ => ‘getId’,
                                                                                                                                                             ) );

     

    Para solventar este problema, he modificado el código del archivo SelectDependiente.js, dentro del método mostrar, sustituyendo

    this.agregarOpcion(valor, this.opciones[this.grupo][valor]);

    por:

    var ordered = new Array();

    // Ordenamos array
    for (var valor in this.opciones[this.grupo]){
         var elemento = new Array();
          elemento[“id”] = valor;
         elemento[“text”] = this.opciones[this.grupo][valor];
         var found = false;
         for (var valor2 in ordered){
              if (elemento[“text”] < ordered[valor2][“text”]){
                   ordered.splice(valor2, 0, elemento);
                   found = true;
                   break;
              }
         }
         if (!found)
              ordered.push(elemento);
    } // Fin orden

    // Agregamos los elementos ordenados
    for (var i in ordered)
         this.agregarOpcion(ordered[i][“id”], ordered[i][“text”]);

     

    El cambio es válido para cualquier proyecto que utilice SelectDependiente.js, sin ser estrictamente necesario que se utilice bajo el framework de Symfony.

    Espero que este post ayude a aquellos usuarios que se hayan encontrado con este problema al utilizar este útil javascript.

  • En Symfony, es muy tedioso configurar uno a uno los distintos mensajes de error al enviar un formulario.

    El método tradicional para un widget en concreto es (dentro de la clase del formulario):

    class ProductoForm extends BaseProductoForm
    {
      public function configure()
      {

         […]

         $this->validatorSchema[“email”]->setMessage(“invalid”, “El email es inválido”);

      } 

    }

    Este error solo se mostrará en el caso de que el email sea inválido y habría que hacerlo uno a uno en todos los validadores de todos los campos.

     

    Para crear un mensaje genérico para todos los widgets de cualquier formulario:

    Para esto hay que introducir el siguiente código en la clase configuration de la aplicación:

    class frontendConfiguration extends sfApplicationConfiguration{

    public function configure()
    {
      sfValidatorBase::setDefaultMessage(‘required’,’Obligatorio’);
      sfValidatorBase::setDefaultMessage(‘invalid’, ‘Inválido’);
      sfValidatorBase::setDefaultMessage(‘max_length’, “%value% es muy largo (%max_length% caracteres max.)”);
    }
    }

    De esta forma, cuando nos dejamos un campo obligatorio aparecerá el texto “Obligatorio”, en lugar de “Required”, etc.

     

    Para que este mensaje sea multiidioma:

    En ese caso primero hay que cargar el helper I18N:

    $this->loadHelpers(array(‘I18N’));

    Y así ya podemos utilizar la función de internacionalización:

    if (sfContext::hasInstance()){

      sfValidatorBase::setDefaultMessage(‘required’,__(‘Obligatorio’));

    }

    Lo de comprobar si tiene una instancia es porque sino da problemas a la hora de hacer algunas operaciones desde la línea de comandos de symfony, como limpiando caché symfony cc.