やあ、
ユーザー名を入力できるフォームを作成しようとしています。ボタンを押して動的に新しいテキストフィールドを追加したい。私は 次の質問 にもとづいてコードを作成しました(drupal 8も使用しており、おそらく機能するはずなので)。
ただし、残念ながらフィールドは追加されません。現在使用しているコードは次のようになります。
<?php
/**
* @file
* Contains \Drupal\bulk_email\Form\EmailForm.
*/
namespace Drupal\bulk_email\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;
class EmailForm extends FormBase {
public function getFormId() {
return "bulk_email_form";
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#tree'] = TRUE;
$form['users'] = array(
'#type' => 'fieldset',
'#title' => t('Users'),
'#prefix' => '<div id="users-wrapper">',
'#suffix' => '</div>',
);
$num_users = $form_state->getValue('num_users');
if (empty($num_users)) {
$num_users = 1;
}
for ($i = 0; $i < $num_users; $i++) {
$form['users'][$i] = array(
'#type' => 'textfield',
'#description' => t('Select a user.'),
);
}
$form['users']['users_more'] = array(
'#type' => 'submit',
'#value' => t('Add one'),
'#submit' => array($this, 'bulk_email_addfieldsubmit'),
'#ajax' => array(
'callback' => array($this, 'bulk_email_add_more_callback'),
'wrapper' => 'users-wrapper',
),
);
$form['actions'] = array('#type' => 'actions');
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send'),
);
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
// submit code
}
public function bulk_email_addfieldsubmit(array &$form, FormStateInterface $form_state) {
$num_users = $form_state->get('num_users') + 1;
$form_state->set('num_users', $num_users);
$form_state->setRebuild(TRUE);
}
public function bulk_email_add_more_callback(array &$form, FormStateInterface $form_state) {
return $form['users'];
}
}
?>
細かい部分が欠けている可能性が高いですが、見つからないようです...どんな助けでもありがたいです。
敬具。
私は間違っているかもしれませんが、bulk_email_add_more_callbackが実際には呼び出されないと想定して、ajaxコールバックをに変更してみることもできます。
'#ajax' => array(
'callback' => '::bulk_email_add_more_callback',
'wrapper' => 'users-wrapper',
),
そして、実際のコールバックで、completeformから値を取得します。これが私の問題でした。すべての値が正しいのですが、古い値を返しました。
public function bulk_email_add_more_callback(array &$form, FormStateInterface $form_state) {
$form = $form_state->getCompleteForm()
return $form['users'];
}
私は自分の問題に対する解決策を見つけられず、それが設計上の悪い決定なのかバグなのか疑問に思い始めました。
とにかく、他のユーザーのために、私は次の回避策を使用しました:
まず、これらの余分なフィールドを追加するときにすべてのコードを削除しました。ユーザー名を入力する実際のテキストフィールドのみを残しました。次に、user-collectionという新しい非表示フィールドを追加しました。
残りは、カスタムJavaScriptを追加することによって行われました。このスクリプトは、(オートコンプリートに基づいて)ユーザー名が入力されたかどうかを検出します。次に「;」を追加しますuser-collectionの値に。次に、テキストフィールドをクリアします。結果は、入力されたすべてのユーザー名を含むユーザーコレクションフィールドです。最後に、ユーザーの収集の内容を示す視覚的なフィードバックも追加しました(解析後)。
それは回避策であり、私にもかなりの努力を要しましたが、何もしないよりはましです。
Ajaxリクエストで送信が呼び出されるかどうかを確認しましたか?
_public function bulk_email_addfieldsubmit(array &$form, FormStateInterface $form_state) {
$num_users = $form_state->get('num_users') + 1;
$form_state->set('num_users', $num_users);
_
そうでない場合は、このコードをbuildForm()
に配置できます。この場合、トリガー要素が正しいかどうかを確認する必要があります。
もう1つの小さな問題、buildForm()
のこの行:
_$num_users = $form_state->getValue('num_users');
_
get('num_users')
はユーザー入力用であるため、getValue()
にする必要があります。
このようなものを使用できます。
if (!empty($form_state['values']['field_name'])) {
$form[]=array();//add your form elements to be shown after submit.
}
else {
$form[]=array();//here your original form.
}
return $form;
フォームに追加を送信
$form_State['rebuild']=true;
私も同じシナリオです。 drupal 8.でajaxを使用して、テキストフィールドを動的に正常に追加および削除できます。私は以下のコードを添付しました。実際に、サンプルのfapiモジュールに従って、add moreフォームを使用していると思いますか?
fapiに問題があり、drupal 8.にフォームを追加します。パッチもそこにあります。自分でシナリオのコードを修正しました。
最初のステップ: formstate変数のロジックの背後で作業しています。フィールドを動的に加算または減算するformstate変数の値。
最初にフォーム関数を作成するときは$ form ['#tree'] = TRUE;プロパティを設定する必要があります。次に、送信関数で適切な送信値を取得できるのはあなただけです。
$veritas_id = $form_state->get('veritas_id');
if ($veritas_id === NULL) {
$veritas_id = $form_state->set('veritas_id', 0);
$veritas_id = 0;
}
2番目のステップ
$form['veritasIds'] = [
'#type' => 'fieldset',
//'#title' => $this->t('#ID'),
'#prefix' => '<div id="veritas-id-wrapper">',
'#suffix' => '</div>',
];
$form['veritasIds']['actions']['add_name'] = [
'#type' => 'submit',
'#limit_validation_errors' => array(),
'#value' => t('add row'),
//'#name'=>$veritas,
'#submit' => array('::addOneVeritas'),
'#ajax' => [
'callback' => '::addmoreCallbackVeritas',
'wrapper' => 'veritas-id-wrapper',
],
'#attributes' => array('class'=> array('btn-transparent')),
];
//if ($num_names > 1) {
$form['veritasIds']['actions']['remove_name'] = [
'#type' => 'submit',
'#limit_validation_errors' => array(),
'#value' => t('delete row'),
'#submit' => array('::removeoneVeritas'),
'#ajax' => [
'callback' => '::addmoreCallbackVeritas',
'wrapper' => 'veritas-id-wrapper',
],
'#name'=>t('veritasremove'),
'#attributes' => array('class'=> array('btn-transparent')),
'#suffix' => t('<div class="id-wrapper">#ID</div>'),
];
for ($i = 0; $i < $veritas_id; $i++) {
$form['veritasIds']['id'][$i] = [
'#type' => 'textfield',
'#attributes' => array('class'=> array('veritas-addfield')),
//'#title' => t('Name'),
];
}
ここで作成されたフィールドセットです。フィールドセット内では、行を追加してボタンを削除するだけで、追加された動的フィールドがそこにあります。
番目のステップ $ form_state-> setCached(FALSE);送信が必要であり、ajaxコールバック関数は
public function addmoreCallbackVeritas(array &$form, FormStateInterface $form_state) {
$veritas_id = $form_state->get('veritas_id');
return $form['veritasIds'];
}
public function addOneVeritas(array &$form, FormStateInterface $form_state) {
$veritas_id = $form_state->get('veritas_id');
$add_button1 = $veritas_id + 1;
$form_state->set('veritas_id', $add_button1);
$form_state->setRebuild();
}
これについて疑問があれば遠慮なく尋ねてください