web-dev-qa-db-ja.com

JFormFieldList Filterクエリで括弧の前に一意の値を取得するにはどうすればよいですか?

JHtml拡張クラスが入力されたJFormFieldカスタムフィルターがあります。次のコードでビューに追加されます。

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

これは意図したとおりに機能しますが、何らかの理由でフィルターがデフォルトのテキスト(-高さの選択-)を表示せず、代わりに「オプションの選択」文字列を表示します(同じ方法でコーディングされた別のフィルターをスクリーンショットに含めました)それがどのように見えるべきかを示してください)。

enter image description here

いじくり回した後、JFormFieldクラスのデータベースクエリを変更することで修正できることがわかりました。私の元のJFormFieldクラスは次のとおりです:

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

このコードが原因で問題が発生しますが、クエリからLOCATE関数を削除すると問題なく機能します。もちろん、元のクエリを保持する必要があるため、これはオプションではありません。

情報については、選択ボックスにはデフォルト値を含む両方の場合の値がロードされますが、デフォルト値を選択した場合でも、「オプションの選択」文字列に戻ります。

enter image description here

ここで何が起こっているのでしょうか?

3
doovers

問題を見つけたと思います。同じ問題が発生したとき、私は自分の拡張機能の1つに取り組んでいました。 HTML出力を確認し、値が0の2つのオプションがあるかどうかを確認します。

これは問題を引き起こした機能です

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

ご覧のとおり、どちらもDISTINCTセレクターを使用していますが、これはおそらく問題の原因です。 HTML出力をチェックすると、これはselectがどのように見えるかです

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

そのため、getAdminList()関数の最後の部分を少し変更して、デフォルトにタイトルを追加してからビューに送信しました。

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;

そして問題は解決されました。

これがお役に立てば幸いです。 Happy Joomla!ng

2
Mathew Lenning

問題の原因はクエリの結果にあると考えたので、少し遊んで、返された数値以外の文字列をすべて削除しました。

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

そして、それは状況を修正しました。

問題の原因はまだわかりませんが、少なくとも現在は修正されています。

1
doovers

使用しているJoomlaのバージョンについては言及していませんが、

1)「-高さの選択-」が必要な場合、なぜ JText::_() 最初に呼び出します。 JText::_()は、言語ファイルからキーを変換するために使用されます。この行が含まれている_/components/com_mycomponent/language/en-GB/en-GB.com_mycomponent.ini_の英語ファイルでこれを(他の多くのファイルとともに)持っている場合

_ COM_MYCOMPONENT_PLACEHOLDER_SELECT_HEIGHT="- Select Height -"
_

_=_の左側のキーにはスペースがなく、コンポーネントによってキーが付けられていることに注意してください。デフォルトでは、キーが見つからない場合は、関数に渡されたテキストを取得する必要がありますが、JText::_()呼び出しを削除することで、その問題を排除できます。

2)最初の項目が通常設定されるJFormFieldのコードを追加する必要があるため、問題は何ですか。

print_r($heightOptions)は、何が起こっているのかについていくつかの光を当てることもできます。

以前は拡張JFormFieldListで、データベースから作成された_$options_に最初の項目を追加しました。例:

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

いくつかの改良点/ベストプラクティスを示すために、@ dooversの投稿されたソリューションを取り上げます。

_$query = $db->getQuery(true)
    ->select("DISTINCT SUBSTRING_INDEX(description2, '(', 1) AS height");
    ->from("#__cadcam_disc");
    ->where("LOCATE('(', description2) > 0")
    ->order("height");
_
  • SUBSTRING_INDEX()は、LEFT(LOCATE())と同等の単一の関数呼び出しです。
  • 照会されるテーブルは1つしかないため(解決のあいまいさはありません)、テーブルエイリアス(a)は必要ありません。
  • WHERE句に_(_がない値を除外する場合、正のLOCATE()値を確認するだけです(最初の文字は_0_の位置にありますが、タスクのロジックは、_> -1_、ergo _> 0_が実行するかどうかを確認する必要がないことを意味します。
  • heightの列エイリアスが指定されたSELECT句の文字列操作は、ORDER BY句で参照できます。これは目に優しいです。

これらの機能をよりよく知りたい人のための遊び場があります。

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

0
mickmackusa