3つの公開フィルター(製造元、タイプ、モデル)、3つのオプションリスト(プリンターボキャブラリーへの用語参照)があるビューがあります。
語彙:プリンター(3レベル)
-- HP
---- xxx
------ xxxx
-- Apple
---- xxxx
------ xxxxxx
-- Dell
---- xxxx
------- xxxxx
-- ...
-- ...
(thousands of terms)
Form API AJAXはビューの公開フォームでは機能しないため、公開されたフォームフィールドに対してそれらを依存選択することができません。したがって、jQueryを使用して公開フォームフィールドを「依存選択/カスケード選択」。
基本的に、まず、views_exposed_form_alter()のすべてのオプションを空にします。
$form['manufacturer_id']['#options'] = $form['type_id']['#options'] = $form['model_id']['#options'] = array();
次に、それに応じてオプションリストにjQueryコードを入力します。
しかし、「違法な選択が検出されました」と表示されます。ページの読み込み、フォームの送信時。 Drupalフォーム検証メカニズムにより、フォームの送信は禁止されています。
私がフォームのオプションを削除したため、jQueryによって生成されたオプションが元のフォームデータに付属していないことをフォームの検証が検出します。選択ボックスの値が、定義されたオプションに存在しません。
だから私はとしてフォームの検証でフォームの検証を削除しようとしました:
unset($form['#validate']);
それでも機能しない場合は、不正な選択エラーが残ります。
============更新済み=================
以下の@kiamlalunoの回答に触発されて、私が思いついた唯一の解決策は、コアをハック/パッチすることです。これが私がしたことです:
編集済み/includes/form.inc
:(2014年の行)
私はコードを削除しました:
$element['#needs_validation'] = TRUE;
追加:
// if not these fields, mark for validation as usual.
// so if are these fields, validation will be passed.
if ($element['#name'] != 'manufacturer_id' &&
$element['#name'] != 'type_id' &&
$element['#name'] != 'model_id' ) {
$element['#needs_validation'] = TRUE;
}
機能し、公開されたフォーム選択オプションは検証をバイパスしました。
しかし私の解決策は非常に醜いコアを変更しました。
コアに触れずに他の解決策はあるのでしょうか?これらの公開フォームフィールドの検証をバイパスするにはどうすればよいですか?
ありがとう!
これらのエラーを示す関数は _ form_validate() で、次のコードが含まれています。
_ // Validate the current input.
if (!isset($elements['#validated']) || !$elements['#validated']) {
// The following errors are always shown.
if (isset($elements['#needs_validation'])) {
// ...
if (isset($elements['#options']) && isset($elements['#value'])) {
if ($elements['#type'] == 'select') {
$options = form_options_flatten($elements['#options']);
}
else {
$options = $elements['#options'];
}
if (is_array($elements['#value'])) {
$value = in_array($elements['#type'], array('checkboxes', 'tableselect')) ? array_keys($elements['#value']) : $elements['#value'];
foreach ($value as $v) {
if (!isset($options[$v])) {
form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));
watchdog('form', 'Illegal choice %choice in !name element.', array('%choice' => $v, '!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR);
}
}
}
// ...
}
_
フォームに検証ハンドラがあるかどうかにかかわらず、関数は常に実行されます。
_$form['#needs_validation']
_をFALSE
に設定することもできますが、 _ form_builder_handle_input_element() はTRUE
に設定します。関数は form_builder() から呼び出され、次に drupal_process_form() または drupal_rebuild_form() から呼び出されます。
_ // Mark all posted values for validation.
if (isset($element['#value']) || (!empty($element['#required']))) {
$element['#needs_validation'] = TRUE;
}
_
_form_builder_handle_input_element()
が呼び出された後、form_builder()
は、フォーム要素に設定された任意の #process 関数を呼び出します。
_ // Handle input elements.
if (!empty($element['#input'])) {
_form_builder_handle_input_element($form_id, $element, $form_state);
}
// Allow for elements to expand to multiple elements, e.g., radios,
// checkboxes and files.
if (isset($element['#process']) && !$element['#processed']) {
foreach ($element['#process'] as $process) {
$element = $process($element, $form_state, $form_state['complete form']);
}
$element['#processed'] = TRUE;
}
_
また、フォーム要素に設定された #after_build 関数を呼び出します。
_ // The #after_build flag allows any piece of a form to be altered
// after normal input parsing has been completed.
if (isset($element['#after_build']) && !isset($element['#after_build_done'])) {
foreach ($element['#after_build'] as $function) {
$element = $function($element, $form_state);
}
$element['#after_build_done'] = TRUE;
}
_
次のようなコードを実行する_#after_build
_関数を設定できます。
_function mymodule_remove_validation($form_element) {
unset($form_element['#needs_validation']);
return $form_element;
}
_
unset($form_element['#needs_validation'])
ではなく_form_validate()
のifステートメントがisset($elements['#needs_validation'])
をチェックするため、私は!empty($elements['#needs_validation'])
を使用しています。
このように、フォーム要素は_#needs_validation
_をTRUE
に設定せず、Drupalはフォーム要素の戻り値をチェックしません。取得できる値、またはテキストフィールド文字列の長さが必要以上に長い。
フォーム検証ハンドラが実行されるのを避けられないと考えています。
Form_alterではなく、テーマ機能に空の '#options'が必要です。この場合、検証では「不正な選択エラー」は表示されません。
まず、views_exposed_form_alter()で、カスタムテーマ関数を選択に追加します。
$form['manufacturer_id']['#theme'][] = 'select_empty';
$form['type_id']['#theme'][] = 'select_empty';
$form['model_id']['#theme'][] = 'select_empty';
次に、モジュールまたはtemplate.phpファイルで新しいテーマ関数を作成します。
function THEME_NAME_theme($existing, $type, $theme, $path) {
return array(
'select_empty' => array(
'render element' => 'element',
),
);
}
function THEME_NAME_select_empty($vars) {
// Empty select values and add one fake option for correct theming.
$vars['element']['#options'] = array(
'All' => t('All'),
);
// return default select.
return theme('select', $vars)
}
IIRC、Drupal 6.から始まるフォームAPIの検証を無効にすることはできません。Drupalでオプションを空にする代わりに、jQueryでそれらを空にすることができます。このようにして、オプションは= Drupal側で、検証エラーはトリガーされません。
ハードパーツが更新され、使用可能な色が追加され、AJAXを通じてフィルターの形状が変更されます。 AJAX UIに基づいて値を更新するように公開されたフィルターに指示することはできますが、UIは素晴らしいです。残念ながら、それはまだ不可能です。実際、公開することはできません。動的な値を提供するためのフィルターは、あらゆる種類を検討するのに論理的です。AJAXを介して自身を更新する必要があるため、変更できない場合 HPE0-Y53 PDF Dumps