作業フィールドウィジェットフォームを単独で表示できますか?


21

ノード編集フォーム全体のコンテキスト外にフィールドウィジェットフォームを埋め込むことに興味があります。

過去にdrupal_get_formを使用して完全なフォームを表示しましたが、それは単独のフィールドフォームには適用されないようです。

作業フィールドウィジェットフォームを表示できますか?そうするための最良の方法は何でしょうか?

フィールドウィジェットと「通常の」フォームの両方は非常に似ているように見えるので、これが不可能な場合、ウィジェットフォームを通常のフォームに「変更」するには何が必要でしょうか。

この質問は似たようなことを求めているように見えますが、その答えはわかりません。その答えはhook_field_widget_form_alterの使用を指定してます。私が理解していないのは、フィールドフォームを作成する方法ではなく、フィールドフォームを表示する方法です。

回答:


18

VBOはmodify.action.incで次のようなことを行います。

$form_key = 'bundle_' . $bundle_name;
$form[$form_key] = array(
  '#type' => 'fieldset',
  '#title' => $label,
  '#parents' => array($form_key),
);  
field_attach_form($context['entity_type'], $entity, $form[$form_key], $form_state, LANGUAGE_NONE);  

そのため、エンティティタイプ、エンティティ(バンドルキーセットのみの空のオブジェクト、実際に使用されるもの)、ウィジェットが追加されるフォーム、および言語が必要です。ウィジェットをフォームのより深く($ formではなく、私がしたように$ form [$ form_key]に、またはさらに深く)埋め込みたい場合、そのフォーム配列には#parentsを設定する必要があります。

もちろん、これにより、そのエンティティタイプとバンドルに属するすべてのフィールドのウィジェットが埋め込まれることに注意してください。これがアタッチ関数の記述方法です。それを回避するには、かなり多くのコードを再発明する必要があります。面倒な作業を行う実際のコードを参照してください。私がしているのは、フィールドインスタンスを調べて、各$ field_nameを取得し、そのフィールドタイプが興味のない場合、$form[$form_key][$field_name]['#access'] = FALSE; それらのウィジェットを見えないように設定します。

編集:さて、ctoolsにはctools_field_invoke_field()があり、理論的にはフィールドごとに作業することができます。私はそれを使ったことがありません。上記のテキストは私の直接の経験です。


素晴らしい答え。私は1日の大半をこれで作業しましたが、望みどおりに機能しました。バウンティが授与され、OPがこれを正しい答えとして受け入れることをお勧めします。私はダミーのコンテンツタイプを作成することになり#access = FALSE、このコンテキストではハックのように見える設定をする代わりに、他のコンテンツタイプのようにフィールドを制御できます。
レサリオン

私が恐れていたことを確認していただきありがとうございます。単一フィールドウィジェットは、それ自体では実際には使用できないということです。
SMTF

7

私はttkによって提案された機能を集中的に使用していましたが、最近の更新は物事を台無しにしたと思います...

以下は、Drupal 7.22およびctools 7.x-1.3で動作する以前のソリューションの新しいバージョンです。

したがって、前の投稿のように、次のようにカスタム関数を呼び出します。

my_field_attach_form('field_body', 'node', 'blog',  $node, $form, $form_state, LANGUAGE_NONE);

エンティティバンドルがパラメータになっていることに注意してください。これは、ユーザーの編集にもこの機能を使用していたためです。このように、分類用語やその他のエンティティにも使用できます。

そして、my_field_attach_form次のように定義されます:

function my_field_attach_form($field_name, $entity_type, $bundle, $entity, &$form, &$form_state, $langcode = NULL) {

  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );

  // Append to the form
  ctools_include('fields');
  $field_instance = field_info_instance($entity_type, $field_name, $bundle);
  $form += (array) ctools_field_invoke_field($field_instance, 'form', $entity_type, $entity, $form, $form_state, $options);
}

この機能により時間を大幅に節約できました。


5

ctools_field_invoke_field()メソッドを使用したソリューションは次のとおりです。カスタムフォーム関数で、次を追加します。

$form = array();
$node = new stdClass();
$node->type = 'blog';
my_field_attach_form('field_body', 'node', $node, $form, $form_state, LANGUAGE_NONE);

ここで、my_field_attach_form関数は以下のように定義されます

function my_field_attach_form($field_name, $entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
  // Set #parents to 'top-level' if it doesn't exist.
  $form += array('#parents' => array());

  // If no language is provided use the default site language.
  $options = array(
    'language' => field_valid_language($langcode),
    'default' => TRUE,
  );
  module_load_include("inc","ctools","includes/fields");
  $form += (array) ctools_field_invoke_field($field_name, 'form', $entity_type, $entity, $form, $form_state, $options);
}

サイトでctoolsを有効にする必要があることに注意してください。Drupalにデフォルトでこのようなヘルパー関数が含まれていないのは残念です。


2

ctoolsメソッドを機能させることができなかったため、代わりにこの方法で実行することにしました。

このコードはフォーム関数内にあるため、$ formと$ form_stateは既に渡されます。

function form_function($form, &$form_state) {

最初に、表示したいフィールドを持つタイプの空のノードを作成します。

    $entity = new stdClass();
    $entity->title = "Temp Object";
    $entity->type = "node_type";
    node_object_prepare($entity);

フォーム変数を複製したので、オリジナルを壊すことはありません。

    $temp_form       = $form;
    $temp_form_state = $form_state;
    field_attach_form("node", $entity, $temp_form, $temp_form_state);

探しているフィールドを引き出して、フォームに追加します。

    $form["field"] = $temp_form["existing_field"];
}

このメソッドを使用して、カスタムフォームに分類選択ウィジェット、分類チェックボックスウィジェット、および階層選択ウィジェットをレンダリングしました。(分類オートコンプリートウィジェットは表示されますが、送信時にエラーがスローされます)

最後にレンダリングして印刷する

drupal_render(drupal_get_form("form_function"))

これは、カスタムフォームでフィールドウィジェットを使用する簡単な方法のようです。ただし、既存のバンドルに依存します。私の場合、ダミーのコンテンツタイプを使用して、必要に応じてフィールドを作成および構成します。それは少しハックですが、他の方法にも必要です。注:上記のctools_field_invoke_field()方法も同様に機能します。
ベルンハルトフュルスト

0

私は個々のフィールドからフォームを作成しました

field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $form, $form_state);

これは、次のような任意の形式で使用できる必要なウィジェットフォームを返す必要があります

 $custom_form['form_element_to_display'] = field_default_form('entity_type', $entity, $field,$field_instance,LANGUAGE_NONE,$default_value, $custom_form, $custom_form_state);

上記の2つのパラメーターの値を取得するには、次を使用します。

$field = field_info_field($field_name);
$field_instance = field_info_instance('node', $field_name, $node_type);

他のパラメーターについては、ここで APIリンクを確認できます

これにより、コンテンツタイプフィールドで定義されたデフォルトのウィジェットフォームが返されます。

これが誰かを助けることを願っています:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.