web-dev-qa-db-ja.com

setFieldAttributeによる単一のJFormオプションの削除

私は小さなコンポーネントに取り組んでおり、$someoptionJFormから特定のオプションを削除する必要があります。たとえば、$someoption == 1次に、このオプションを削除する必要があります<option value="1">COM_MY_FIELD2</option>

hiddenを使用してフィールド全体をsetFieldAttributeに設定する方法を知っていますが、オプションを1つだけ削除するにはどうすればよいですか?

XMLフォームの部分は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset>
        <field name="field1" type="radio" default="0" label="COM_MY_LABEL1" class="btn-group btn-group-yesno">
            <option value="0">COM_MY_FIELD1</option>
            <option value="1">COM_MY_FIELD2</option>
            <option value="2">COM_MY_FIELD3</option>
        </field>

        ...

これがモデルのpreprocessForm関数です。

protected function preprocessForm(JForm $form, $data, $group = '')
{
    $app        = JFactory::getApplication();

    ...

    if ($app->isClient('site')) {
        if ($someoption == 1) {
            // this sets the whole field to hidden
            $form->setFieldAttribute('field1', 'type', 'hidden'); 
        }
    }
    parent::preprocessForm($form, $data, $group);
}       

...
2
Mike

小さな問題あなたの質問は、_<option>_はフィールド属性ではなくXMLの要素であるため、フィールド属性のメソッドを使用して設定または削除することはできません。

ただし、PHP DOM拡張機能の次のようなメソッドを使用して、これらの要素を削除できます。

_// $myradioForm = new Form('MyRadioForm'); // this is just a Joomla Form object. You use your own Form in your code like $form for example.

// if ($someoption == 1)

$doc = new DOMDocument;

// load your xml file from a path
$doc->load($file); // example: $file = JPATH_ADMINISTRATOR . '/components/com_mycomponent/models/forms/myradio.xml'

$myFormDoc = $doc->documentElement;

// we retrieve the element and remove it from the form - could be item(1) or item(2) too
$myFieldToRemove = $myFormDoc->getElementsByTagName('option')->item(0);
$parent = $myFieldToRemove->parentNode; // we define the parent node

$parent->removeChild($myFieldToRemove); // removing the element

$fieldsNew = $doc->saveXML(); // $fieldsnew here is the form without the removed option

$myradioForm->load($fieldsNew); // you load the form again and it is now without the removed option
echo $myradioForm->renderFieldset('radiogroup'); // change 'radiogroup' to whatever your fieldset name is
_

コードにたくさんのコメントがあって申し訳ありませんが、この方法で理解を深めることができれば幸いです。上記をフォローして使用できることを願っています(試してみて動作します)。

[〜#〜]更新[〜#〜]

@mickが指摘したように、上記のスニペットは、フォームに多数のラジオフィールドが存在する場合には適用できないため、ターゲットフィールドをより正確に選択する必要があります。したがって、これらのフォームでは通常そうであるように、より多くの無線フィールドがある場合は、以下のようなgetElementsByTagName()メソッドを使用する必要があります。

_$myFieldToRemove = $myFormDoc->getElementsByTagName('field')->item(0)->firstChild->nextSibling;
_

ここで、item(0)はフォームのラジオフィールドですが、任意の選択にすることができます。 _firstChild->nextSibling_は選択したラジオフィールドの最初のオプション要素で、_lastChild->previousSibling_はフィールドの3番目のオプションです。または

_$myRadioField = $myFormDoc->getElementsByTagName('field')->item(1);
$optionToDelete = $myRadioField->childNodes->item(3); // as the second option in the field.
_

PHP DOMの使用方法の学習についての詳細であるため、これをこの質問の主要な部分とは見なしません。

1
Zollie

これが私がやったことです:

protected function preprocessForm(JForm $form, $data, $group = '')
{
    $app        = JFactory::getApplication();

    ...

    if ($app->isClient('site')) {
        // remove the field from the form. this is not realy needed, because if the third parameter on setField is true, the field gets replaced
        $form->removeField('field1');
        // create a new XML field
        $element = new SimpleXMLElement('<field name="field1"  default="0" type="radio" />');
         // create only the options i need
        if ($someoption == 1) {
                $option = $element->addChild('option', JText::_('COM_MY_FIELD2'));
                $option->addAttribute('value', 2);
        }
        // add the new field back into the form (replacing the old one if it exists)
        $form->setField($element, $group, true);
    }
    parent::preprocessForm($form, $data, $group);
}       

...
1
Mike

別のオプションとして、2つのバージョンのフィールドを/ formsフォルダー内の個別の.xmlファイルに配置し、どちらをロードするかを決定することもできます。

If ($option == 1)
{ 
    $form->loadFile('field_with_option');
}
else
(
    $form->loadFile('field_without_option');
}

../mycomponent/models/forms/field_with_option.xmlには、

    <field name="field1" type="radio" default="0" label="COM_MY_LABEL1" class="btn-group btn-group-yesno">
        <option value="0">COM_MY_FIELD1</option>
        <option value="1">COM_MY_FIELD2</option>
        <option value="2">COM_MY_FIELD3</option>
    </field>

そして../mycomponent/models/forms/field_without_option.xmlには

    <field name="field1" type="radio" default="0" label="COM_MY_LABEL1" class="btn-group btn-group-yesno">
        <option value="0">COM_MY_FIELD1</option>
        <option value="2">COM_MY_FIELD3</option>
    </field>

もともと私は質問を最初に読んだとき、今朝Zollieの答えのようなものに沿って考えていましたが、Mikeの解決策に基づいてこれはほとんど同じですが、フィールド定義をコードから除外し、/ formsの.xmlに戻しますそれは属しています。

更新-23/11 @zollieの答えをもう一度読んだので、私はDOMオブジェクトではなく、フォームオブジェクトをステップ実行してそこにあるオプションを削除するのを見ていました。同様のコードになります。

1
Irata