web-dev-qa-db-ja.com

必須のフォームフィールドにテーマレベルで#required = FALSEがあるのはなぜですか?

管理されたファイルフィールドを持つフォームがあります。フォームには単一のフィールドがあります。このフィールドを必須として宣言しましたが、実際にファイルなしで送信した後、エラーが発生しました:フィールドが必要です。

このフィールドにHTML5検証を追加したかったのですが、私のカスタムtheme_file実装では、$ variables配列に#required => FALSEこのフィールド用...

この入力フィールドの上に赤いアスタリスクが付いているので、何が問題なのか本当にわかりません。

私のカスタムtheme_file:

function custom_file($variables) {
    if (! _custom_isMyTheme()) {
        return theme_file($variables);
    }

    $tpl = <<<HTML
    <div class="inputFile" style="width:390px; height:36px;">
        <div class="inputFileContainer">
            <div class="inputFileField"></div>
            <div class="inputFileButton">%s</div>
        </div>
        %s
    </div>
HTML;
    dpm($variables);//devel shows #required property as FALSE
    return sprintf($tpl, t('Select'), theme_file($variables));
}
4
Codium

つまり、ファイルID(fid)を格納するhidden入力フィールドは必須ですが、表示されるファイルアップロード要素は必須ではありません。実際の「表示された」要素は、_file.module_のfile_managed_file_process()のフォーム要素に追加されます。具体的には、そのファイルの440行目を確認してください。

_  // The file upload field itself.
  $element['upload'] = array(
    '#name' => 'files[' . implode('_', $element['#parents']) . ']',
    '#type' => 'file',
    '#title' => t('Choose a file'),
    '#title_display' => 'invisible',
    '#size' => $element['#size'],
    '#theme_wrappers' => array(),
    '#weight' => -10,
  );
_

これには_#required_プロパティがないため、デフォルトでFALSEになります。プロセスの前の方でdpm()の要素(より多くの非表示要素を含めるために展開され、必要なJavaScriptとCSSを添付して本格的な「管理対象ファイル」要素になる前)の場合、_#required => TRUE_。

フォーム要素の_#process_プロパティに、file_managed_file_process()の後に実行される関数を追加します。その中で、元の要素に_#required => TRUE_があったかどうかを確認し、それを_$element['upload']_アイテムに設定することもできます。私はまだ試していませんが、あなたが望むものを手に入れられると思います。

編集: _#after_build_に追加するだけでなく、_#process_でこれを行うのが賢明です。次に例を示します。

_<?php

function my_form_builder($form, &$form_state) {
  $form['file'] = array(
    '#type' => 'managed_file',
    '#title' => 'Upload a File',
    '#required' => TRUE,
    '#after_build' => array('my_file_element_after_build')
  );

  return $form;
}

function my_file_element_after_build($element, &$form_state) {
  // Set the 'file' element to have the same #required property as its original form element.
  $element['upload']['#required'] = $element['#required'];
  return $element;
}

?>
_
2