ti-enxame.com

Como recuperar valores exclusivos antes de um parêntese na consulta de filtro JFormFieldList?

Eu tenho um filtro personalizado JHtml preenchido por uma classe estendida JFormField. É adicionado na visualização com o seguinte código:

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

Funciona como pretendido, mas por algum motivo o filtro não exibirá o texto padrão (- Selecionar Altura -), mas exibirá a sequência "selecione uma opção" (incluí outro filtro - codificado da mesma maneira) na captura de tela para mostre como deve ser).

enter image description here

Depois de algumas discussões, descobri que poderia corrigi-lo alterando minha consulta ao banco de dados na classe JFormField. Minha classe JFormField original é a seguinte:

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;
    }
}

Esse código causa o problema, mas se eu remover a função LOCATE da consulta, ela funcionará bem. Obviamente, preciso manter a consulta original, para que essa não seja uma opção.

Para informações, a caixa de seleção é carregada com os valores nos dois casos, incluindo o valor padrão, mas mesmo a seleção do valor padrão será revertida para a sequência "selecione uma opção":

enter image description here

Alguma ideia do que está acontecendo aqui?

3
doovers

Eu acho que encontrei o problema. Eu estava trabalhando em uma das minhas próprias extensões quando o mesmo problema surgiu. Verifique a saída HTML e veja se há duas opções com um valor 0.

Esta é a função que causou o 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 você pode ver, nós dois estamos usando o seletor DISTINCT, que provavelmente é a raiz do problema. Verificando a saída HTML, é assim que o select se parece

<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>

Então, alterei a última parte da função getAdminList () para adicionar um título ao padrão antes de enviá-lo para minha exibição.

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;

E o problema foi resolvido.

Eu espero que isso ajude. Feliz Joomla! Ng

2
Mathew Lenning

Imaginei que a causa do problema se resumia ao resultado da consulta, então brinquei um pouco com ela e retirei todas as seqüências não numéricas que foram retornadas da seguinte forma:

$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");

E isso retificou a situação.

Ainda não entendo a causa do problema, mas pelo menos está corrigido agora.

1
doovers

Você não menciona a versão do Joomla com a qual está trabalhando, mas:

1) Se você está querendo "- Selecione Altura -" Não sei ao certo por que você o está envolvendo em um JText::_() ligue primeiro. JText::_() é usado para converter uma chave de um arquivo de idioma, por exemplo se você o tiver em um arquivo em inglês em /components/com_mycomponent/language/en-GB/en-GB.com_mycomponent.ini, que contenha essa linha (junto com muitos outros)

 COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT="- Select Height -"

Observe que a chave à esquerda do = Não possui espaços e é digitada pelo componente. Por padrão, se a chave não for encontrada, você deverá retornar o texto passado para a função, mas, removendo a chamada JText::_(), você poderá eliminá-la como o problema.

2) Você precisará adicionar o código para o seu JFormField, que é onde o primeiro item normalmente seria definido, para que possamos ver qual é o problema.

Um print_r($heightOptions) também pode lançar alguma luz sobre o que está acontecendo.

Anteriormente, em um JFormFieldList estendido, anexamos o primeiro item a $options Criado a partir do banco de dados, por exemplo:

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

Para mostrar alguns aprimoramentos/práticas recomendadas, abordarei a solução 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() é a chamada de função única equivalente a LEFT(LOCATE())
  • Um alias de tabela (a) não é necessário porque há apenas uma tabela sendo consultada (sem ambiguidade a ser resolvida).
  • Ao filtrar valores que não possuem um ( Na sua cláusula WHERE, basta verificar um valor LOCATE() positivo (o primeiro caractere estaria na posição 0, mas a lógica da sua tarefa significa que não precisamos verificar se > -1, ergo > 0 funcionará.
  • A manipulação de string na cláusula SELECT, que recebe um alias de coluna de height, pode ser referida na cláusula ORDER BY. Isso é muito mais fácil para os olhos.

Aqui está um playground para quem quer conhecer melhor essas funções.

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

0
mickmackusa