it-swarm-es.tech

¿Cómo recuperar valores únicos antes de un paréntesis en la consulta del filtro JFormFieldList?

Tengo un filtro personalizado JHtml poblado por una clase extendida JFormField. Se agrega en la vista con el siguiente código:

JHtmlSidebar::addFilter(
    '- Select Height -',
    'filter_height',
    JHtml::_('select.options', $heightOptions, "value", "text", $this->state->get('filter.height'), true)
);

Funciona según lo previsto, pero por alguna razón el filtro no mostrará el texto predeterminado (- Seleccionar altura -) sino que muestra la cadena "seleccionar una opción" (he incluido otro filtro, codificado de la misma manera) en la captura de pantalla para muestra cómo debería ser).

enter image description here

Después de jugar un poco, descubrí que podía solucionarlo cambiando la consulta de mi base de datos en la clase JFormField. Mi clase original JFormField es la siguiente:

JFormHelper::loadFieldClass('list');

class JFormFieldHeight extends JFormFieldList
{
    protected $type = 'Height';

    public function getOptions()
    {
        $options = array();

        $db     = JFactory::getDbo();
        $query  = $db->getQuery(true);

        $query->select("DISTINCT LEFT(a.description2, LOCATE('(', a.description2) - 1) AS height");
        $query->from('#__cadcam_disc AS a');
        $query->order("LEFT(a.description2, LOCATE('(', a.description2) - 1)");

        $db->setQuery($query);
        $options = $db->loadObjectList();

        if ($db->getErrorNum()) {
            JError::raiseWarning(500, $db->getErrorMsg());
        }

        return $options;
    }
}

Este código causa el problema, pero si elimino la función LOCATE de la consulta, funciona bien. Obviamente, necesito mantener la consulta original para que esta no sea una opción.

Para obtener información, el cuadro de selección se carga con los valores en ambos casos, incluido el valor predeterminado, pero incluso al seleccionar el valor predeterminado se revertirá a la cadena "seleccionar una opción":

enter image description here

Alguna idea de lo que está pasando aquí?

3
doovers

Creo que encontré el problema. Estaba trabajando en una de mis propias extensiones cuando surgió el mismo problema. Verifique la salida HTML y vea si hay dos opciones con un valor 0.

Esta es la función que causó el problema.

public function getAdminList()
{
    $db = JFactory::getDbo();
    $query  = $db->getQuery(true);

    $query->select('DISTINCT notify.admin_to_notify AS id');
    $query->from('#__babelu_exams_notification_profiles AS notify');

    $query->select('admin.name');
    $query->join('LEFT', '#__users AS admin ON admin.id = notify.admin_to_notify');

    $query->order('admin.name');

    $db->setQuery($query);
    return $db->loadObjectList();
}

Como puede ver, ambos estamos usando el selector DISTINCT, que probablemente sea la raíz del problema. Verificando la salida HTML, así es como se veía la selección

<select name="filter[admin]" id="filter_admin" class="span12 small chzn-done" onchange="this.form.submit()" style="display: none;">
   <option value="">
       Filter by Administrator
   </option>
   <option value="0" selected="selected">
       Not Assigned
   </option>
   <option value="0" selected="selected"></option>
</select>

Así que cambié ligeramente la última parte de la función getAdminList () para agregar un título al predeterminado antes de enviarlo a mi vista.

result = $db->loadObjectList();
    if ($result[0]->id == 0)
    {
        $result[0]->name = JText::_('COM_BABELU_EXAMS_RESULTS_NONE_ASSIGNED');
    }
    else
    {
        $notAssigned = new stdClass();
        $notAssigned->name = JText::_('COM_BABELU_EXAMS_RESULTS_NONE_ASSIGNED');
        $notAssigned->id = 0;
        array_unshift($result, $notAssigned);
    }

    return $result;

Y el problema fue resuelto.

Espero que esto ayude. Feliz Joomla! Ng

2
Mathew Lenning

Pensé que la causa del problema se debía a cuál era el resultado de la consulta, así que jugué un poco y eliminé las cadenas no numéricas que se devolvieron así:

$query->select("DISTINCT LEFT(a.description2, LOCATE('(', a.description2) - 1) AS height");
$query->from('#__cadcam_disc AS a');
$query->where("LEFT(a.description2, LOCATE('(', a.description2) - 1) > 0");
$query->order("LEFT(a.description2, LOCATE('(', a.description2) - 1) + 0");

Y eso rectificó la situación.

Todavía no entiendo la causa del problema, pero al menos ahora está solucionado.

1
doovers

No mencionas la versión de Joomla con la que estás trabajando pero:

1) Si quieres "- Seleccionar Altura -" No estoy seguro de por qué lo estás envolviendo en una función JText::_() llamar primero. JText::_() se utiliza para traducir una clave de un archivo de idioma, p. si tenía esto en un archivo de idioma inglés en /components/com_mycomponent/language/en-GB/en-GB.com_mycomponent.ini que tenía esta línea (junto con muchos otros)

 COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT="- Select Height -"

Tenga en cuenta que la tecla a la izquierda de = No tiene espacios y está codificada por el componente. De forma predeterminada, si no se encuentra la clave, debe recuperar el texto pasado a la función, pero al eliminar la llamada JText::_() puede eliminar eso como un problema.

2) Deberá agregar el código para su JFormField, que es donde normalmente se configuraría el primer elemento, para que podamos ver cuál es el problema.

Una print_r($heightOptions) también podría arrojar algo de luz sobre lo que está sucediendo.

Anteriormente en un JFormFieldList extendido, anteponemos el primer elemento a $options Creado a partir de la base de datos, por ejemplo:

$noneSelected = new stdClass;
$noneSelected->value = '';
$noneSelected->text = '- ' . JText::_('COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT') . ' -';
array_splice($options, 0, 0, array($noneSelected));
0
Craig

Como una cuestión de mostrar algunas mejoras/mejores prácticas, abordaré la solución publicada de @ doovers.

$query = $db->getQuery(true)
    ->select("DISTINCT SUBSTRING_INDEX(description2, '(', 1) AS height");
    ->from("#__cadcam_disc");
    ->where("LOCATE('(', description2) > 0")
    ->order("height");
  • SUBSTRING_INDEX() es la llamada de función única equivalente a LEFT(LOCATE())
  • No es necesario un alias de tabla (a) porque solo se está consultando una tabla (no hay ambigüedad que resolver).
  • Al filtrar valores que no tienen un ( En su cláusula WHERE, puede verificar si hay un valor positivo LOCATE() (el primer carácter estaría en la posición 0, pero la lógica de su tarea significa que no necesitamos verificar si > -1, ergo > 0 lo hará.
  • La manipulación de cadenas en la cláusula SELECT a la que se le da un alias de columna de height se puede hacer referencia en la cláusula ORDER BY. Esto es mucho más fácil para los ojos.

Aquí hay un parque infantil para cualquiera que quiera conocer mejor estas funciones.

https://www.db-fiddle.com/f/ci6ZfAQAPkbMKtak4T5kbm/

0
mickmackusa