it-swarm.dev

Come recuperare valori univoci prima di una parentesi nella query del filtro JFormFieldList?

Ho un filtro personalizzato JHtml popolato da una classe estesa JFormField. Viene aggiunto nella vista con il seguente codice:

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

Funziona come previsto ma per qualche motivo il filtro non visualizzerà il testo predefinito (- Seleziona altezza -) ma mostra invece la stringa "seleziona un'opzione" (ho incluso un altro filtro - codificato allo stesso modo - nella schermata di mostra come dovrebbe apparire).

enter image description here

Dopo alcuni scherzi ho capito che potevo risolverlo cambiando la mia query del database nella classe JFormField. La mia classe JFormField originale è la seguente:

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

Questo codice causa il problema, ma se rimuovo la funzione LOCATE dalla query funziona correttamente. Ovviamente devo mantenere la query originale, quindi questa non è un'opzione.

Per informazioni, la casella di selezione viene caricata con i valori in entrambi i casi incluso il valore predefinito, ma anche selezionando il valore predefinito verrà ripristinata la stringa "seleziona un'opzione":

enter image description here

Qualche idea su cosa sta succedendo qui?

3
doovers

Penso di aver trovato il problema. Stavo lavorando su una delle mie estensioni quando si è verificato lo stesso problema. Controlla l'output HTML e vedi se ci sono due opzioni con un valore 0.

Questa è la funzione che ha causato il 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();
}

Come puoi vedere, entrambi stiamo usando il selettore DISTINCT che è probabilmente la radice del problema. Controllando l'output HTML, ecco come appariva la selezione

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

Quindi ho modificato leggermente l'ultima parte della funzione getAdminList () per aggiungere un titolo al valore predefinito prima di inviarlo alla mia 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;

E il problema è stato risolto.

Spero che aiuti. Felice Joomla! Ng

2
Mathew Lenning

Ho pensato che la causa del problema fosse dovuta al risultato della query, quindi ho giocato un po 'con esso e ho eliminato tutte le stringhe non numeriche che sono state restituite in questo modo:

$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 ciò ha rettificato la situazione.

Ancora non capisco la causa del problema, ma almeno adesso è stato risolto.

1
doovers

Non menzioni la versione di Joomla con cui stai lavorando ma:

1) Se vuoi "- Seleziona l'altezza -" Non sono sicuro del perché lo stai avvolgendo in una funzione JText::_() chiama prima. JText::_() viene utilizzato per tradurre una chiave da un file di lingua, ad es. se lo avessi in un file in lingua inglese in /components/com_mycomponent/language/en-GB/en-GB.com_mycomponent.ini che conteneva questa riga (insieme a molti altri)

 COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT="- Select Height -"

Nota che la chiave a sinistra di = Non contiene spazi ed è codificata dal componente. Per impostazione predefinita, se la chiave non viene trovata dovresti recuperare il testo passato nella funzione, ma rimuovendo la chiamata JText::_() puoi eliminarlo come problema.

2) Dovrai aggiungere il codice per il tuo JFormField che è dove normalmente verrebbe impostato il primo oggetto, così possiamo vedere qual è il problema.

Una print_r($heightOptions) potrebbe anche far luce su ciò che sta accadendo.

Precedentemente in un JFormFieldList esteso, abbiamo anteposto il primo elemento a $options Creato dal database, ad esempio:

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

Per mostrare alcuni perfezionamenti/buone pratiche, affronterò la soluzione pubblicata di @ doovers.

$query = $db->getQuery(true)
    ->select("DISTINCT SUBSTRING_INDEX(description2, '(', 1) AS height");
    ->from("#__cadcam_disc");
    ->where("LOCATE('(', description2) > 0")
    ->order("height");
  • SUBSTRING_INDEX() è la chiamata a singola funzione equivalente a LEFT(LOCATE())
  • Un alias di tabella (a) non è necessario perché è stata eseguita una query su una sola tabella (nessuna ambiguità da risolvere).
  • Quando filtri i valori che non hanno un ( Nella tua clausola WHERE, puoi semplicemente controllare un valore LOCATE() positivo (il primo carattere dovrebbe essere nella posizione 0, ma la logica del tuo compito significa che non abbiamo bisogno di controllare se > -1, ergo > 0 farà.
  • La manipolazione di stringhe nella clausola SELECT alla quale viene assegnato un alias di colonna di height può essere indicata nella clausola ORDER BY. Questo è molto più facile per gli occhi.

Ecco un parco giochi per chiunque voglia conoscere meglio queste funzioni.

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

0
mickmackusa