如何解决Ajax 回调未重建表单 drupal 8
我创建了一个表单,它有两个 ajax 回调,但它们似乎都没有按预期工作,回调后 form_state 没有重建
namespace Drupal\dashboard\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;
use Drupal\commerce_price\Price;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_order\Entity\Order;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use CommerceGuys\Addressing\AddressFormat\AddressField;
use Drupal\dashboard\DashboardRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* UI to update a record.
*
* @ingroup scorecards
*/
class AcfDataUpdateForm extends FormBase {
/**
* Our database repository service.
*
* @var \Drupal\scorecards\scorecardsRepository
*/
protected $repository;
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'acf_data_update_form';
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$form = new static($container->get('dashboard.repository'));
$form->setStringTranslation($container->get('string_translation'));
$form->setMessenger($container->get('messenger'));
return $form;
}
/**
* Construct the new form object.
*/
public function __construct(DashboardRepository $repository) {
$this->repository = $repository;
}
/**
* Sample UI to update a record.
*/
public function buildForm(array $form,FormStateInterface $form_state,$order_id = NULL) {
$items = $this->repository->get_order_items($order_id);
$mark_pack = 6;
$uid = \Drupal::currentUser()->id();
$config = \Drupal::config('dashboard.settings');
foreach($items as $item){
if($item->purchased_entity == 6 || $item->purchased_entity == 7 || $item->purchased_entity == 8){
$mark_pack = $item->purchased_entity;
}
}
$form['#prefix'] = '<div id="package_design_wrapper-container">';
$form['#suffix'] = '</div>';
$form['order_id'] = array(
'#type' => 'hidden','#default_value' => $order_id,);
$form['package'] = array(
'#type' => 'container','#prefix' => '<div class="message" id="message"></div>','#attributes' => array('id' => 'marketing-package-wrapper'),);
$form['package']['marketing_package'] = array(
'#type' => 'radios','#default_value' => $mark_pack,'#options' => array(
6 => $this
->t('Standard <span>'.$this->getPrice(6).'</span>'),7 => $this
->t('Premium <span>'.$this->getPrice(7).'</span>'),8 => $this
->t('Premium + <span>'.$this->getPrice(8).'</span>'),),'#disabled' => true,);
$form['package']['designation'] = array(
'#type' => 'textfield','#prefix' => $this->t('<h3>your designation</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),'#attributes' => array('placeholder' => 'Type Here'),);
$form['package']['photograph'] = array(
'#type' => 'managed_file','#upload_location' => 'public://acf_profile_photos','#multiple' => FALSE,'#upload_validators' => [
'file_validate_is_image' => [],'file_validate_extensions' => array('png jpg jpeg'),'file_validate_size' => array(25600000)
],'#required' => true,'#title' => $this->t('<h3>your photograph</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),);
$form['package']['date'] = array(
'#type' => 'radios','#default_value' => 1,'#options' => $this->getDates(),'#prefix' => $this->t('<h3>Award Slot</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),'#ajax' => [
'wrapper' => 'wrapper-dropdown','callback' => '::getAwardSlots','method' => 'replace','effect' => 'fade','event' => 'change','progress' => [
'type' => 'throbber','message' => NULL,],);
$form['package']['award_slot'] = array(
'#type' => 'radios','#options' => $form_state->getValue('date') ? $this->getAwardSlotOptions($form_state->getValue('date')) : $this->getAwardSlotOptions('2021-04-21'),'#prefix' => '<div id="wrapper-dropdown">','#suffix' => '</div>',);
$form['package']['bio'] = array(
'#type' => 'textarea','#prefix' => $this->t('<h3>Individual Bio</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>'),);
$form['package']['plaque_type'] = array(
'#type' => 'radios','#default_value' => 'remote','#options' => array(
'remote' => $this
->t('remote'),'event' => $this
->t('event'),'#prefix' => $this->t('<h3>Plaque Type</h3>'),);
$form['package']['shipping_address'] = array(
'#type' => 'container','#states' => array(
'visible' => array(
':input[name="plaque_type"]' => array(
'value' => 'remote',);
$form['package']['shipping_address']['markup'] = array(
'#markup' => ' <h3>shipping address</h3><p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>',);
$form['package']['shipping_address']['address'] = array(
'#type' => 'address','#default_value' => ['country_code' => 'US'],'#used_fields' => [
AddressField::GIVEN_NAME,AddressField::FAMILY_NAME,AddressField::ORGANIZATION,AddressField::ADDRESS_LINE1,AddressField::ADDRESS_LINE2,AddressField::LOCALITY,AddressField::POSTAL_CODE,'#available_countries' => ['US'],'#attributes' => array('class' => array('edit-address')),);
$form['package']['save'] = array(
'#type' => 'submit','#submit' => ['::submitPackageDetails'],'#name' => 'mark-save','#value' => t('Save'),'#validate' => ['::validatePackageDetails'],'#prefix' => '<div class="row"><div class="col-md-6">','#ajax' => [
'wrapper' => 'package_design_wrapper-container',);
$form['package']['submit'] = array(
'#type' => 'submit','#name' => 'mark-submit','#value' => t('Submit'),'#prefix' => '<div class="col-md-6">','#suffix' => '</div></div>',);
$form['terms'] = array(
'#type' => 'checkBox','#title' => t('I have read the <a href="/terms-of-service">terms & conditions</a> and agree to comply with them. '),'#prefix' => '<div class="row mb-3"><div class="col-12 col-sm-12 col-md-12 col-lg-12">',);
$form['#theme'] = 'acf_data_update_form';
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form,FormStateInterface $form_state) {
echo "<pre>";
print_r($form_state->getValues());
die;
$old = $this->repository->save_old_data($old_data,$order_id,$user_id);
$this->messenger()->addMessage($this->t('Saved old data @entry (@count row updated)',[
'@count' => $old,'@entry' => print_r($old_data,TRUE),]));
if(!empty($old)){
$count = $this->repository->update_nominee($entry,$user_id);
$this->messenger()->addMessage($this->t('Updated entry @entry (@count row updated)',[
'@count' => $count,'@entry' => print_r($entry,]));
}
$form_state->setRedirect('scorecards.scorecard_entry_list');
}
public function validatePackageDetails(array &$form,FormStateInterface $form_state){
$fields = array('designation','date','award_slot','plaque_type','bio','photograph');
$add_fields = array('given_name','family_name','organization','address_line1','locality','postal_code');
$valid = true;
if($form_state->getValue('plaque_type') == 'remote'){
$add = $form_state->getValue('address');
foreach($add_fields as $field){
if(empty($add[$field])){
$form_state->setErrorByName($add[$field],'Please enter a valid detail');
}
}
}
foreach($fields as $field){
if(empty($form_state->getValue($field))){
$form_state->setErrorByName($field,'Please enter a valid detail');
}
}
}
public function submitPackageDetails(array &$form,FormStateInterface $form_state){
$fields = array('designation','photograph');
$add_fields = array('given_name','postal_code');
if($form_state->getValue('plaque_type') == 'remote'){
$add = $form_state->getValue('address');
}
$data = array();
$pid = $form_state->getValue('marketing_package');
foreach($fields as $field){
$data[$field] = $form_state->getValue($field);
}
$data['status'] = 0;
$triggering_element = $form_state->getTriggeringElement();
$button_name = $triggering_element['#name'];
if($button_name == 'mark-submit'){
$data['status'] = 1;
}
$order_id = $form_state->getValue('order_id');
$pid = $form_state->getValue('marketing_package');
$entry = $this->repository->saveAcfDetails($order_id,$pid,$data);
$entry_add = $this->repository->saveShippingDetails($order_id,$add);
$this->setFilePermanent($form_state->getValue('photograph'));
if($entry && $entry_add){
$form_state->setRebuild(TRUE);
$this->messenger->addMessage(t('Your data has been saved successfully!'));
}
else{
$this->messenger->addMessage(t('Your data cannot be Saved'));
}
}
function getPrice($id){
$variation = \Drupal\commerce_product\Entity\Productvariation::load($id);
return str_replace('USD','$',$variation->getPrice());
}
function setFilePermanent($image_id){
if(!empty($image_id)) {
$file = \Drupal\file\Entity\File::load($image_id[0]);
if (isset($file) and is_object($file)) {
$file->setPermanent(); // FILE_STATUS_PERMANENT;
$file->save();
}
}
}
function getDates(){
$config = $this->config('dashboard.settings');
$start_date = $config->get('conference_start_date');
$no_days = $config->get('no_days');
$dates = array();
for($i = 1; $i <= $no_days; $i++){
$j = $i-1;
$date = strtotime("{$j} day",strtotime($start_date));
$new_date = date("d-M-Y",$date);
$dates[date("Y-m-d",$date)] = 'DAY '.$i.'<span>('.$new_date.')</span>';
}
return $dates;
}
function getAwardSlots(array &$form,FormStateInterface $form_state){
$form_state->setValue('date',$form_state->getValue('date'));
$form_state->setRebuild(TRUE);
return $form['package']['award_slot'];
}
function getAwardSlotOptions($date){
$terms = \Drupal::entityManager()->getStorage('taxonomy_term')->loadByProperties(array('name' => $date));
$term = reset($terms);
$award_slots = $term->get('field_award_slot');
$slots = array();
foreach($award_slots as $award_slot){
$slots[$award_slot->value] = $award_slot->value;
}
return $slots;
}
}
我也为此表单创建了一个模板
<div class="row">
<div class="col-12 col-sm-12 col-md-9 col-lg-9">
<div class="package_border">
<div class="wellcome_back">
<div class="row">
<div class="col-12 col-sm-12 col-md-12 col-lg-12">
<h3>Awardee Deliverables</h3>
</div>
</div>
</div>
<div class="package_header">
<div class="row">
<div class="col-12 col-sm-12 col-md-5 col-lg-5">
<div class="package_header_batch">
<img src="/modules/custom/dashboard/images/package.jpg">
<div>
<h2>Marketing package</h2>
<p>Lorem Ipsum is simply</p>
</div>
</div>
</div>
{% if form.package.marketing_package %}
<div class="col-12 col-sm-12 col-md-7 col-lg-7">
{{ form.package.marketing_package }}
</div>
{% endif %}
</div>
</div>
<div class="designation_content_wrapper">
<div class="designation_content">
{{ form.package|without('marketing_package','shipping_address','submit','save') }}
{% if form.package.plaque_type %}
<h3>plaque</h3>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry</p>
<div class="row mb-5">
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<figure class="plaque_figure">
{% set images = getPlaqueBadge() %}
<img src="{{ images.plaque }}" width="100%">
</figure>
</div>
<div class="col-12 col-sm-12 col-md-6 col-lg-6">
<div class="plaque_type_wrapper">
{{ form.package.plaque_type }}
</div>
</div>
</div>
{% endif %}
{% if form.package.shipping_address %}
{{ form.package.shipping_address }}
{% endif %}
{{ form.package.save }}
{{ form.package.submit }}
</div>
</div>
</div>
{{ form|without('package') }}
</div>
<div class="col-12 col-sm-12 col-md-3 col-lg-3">
<aside class="package_aside">
<div class="package_aside_wrapper">
<h5>jump to</h5>
<ul class="package_aside_list">
<li>
<a href="#" class="active">designation</a>
</li>
<li>
<a href="#">photograph</a>
</li>
<li>
<a href="#">award slot</a>
</li>
<li>
<a href="#">individual boi</a>
</li>
<li>
<a href="#">plaque</a>
</li>
<li>
<a href="#">plaque type</a>
</li>
<li>
<a href="#">shipping address</a>
</li>
</ul>
</div>
</aside>
</div>
</div>
实际发生的是,在执行 ajax 回调之后,form_state 仍然有用户提交的值,而这些值不应该。如果有人知道我在这里做错了什么,请帮忙。
解决方法
这有点旧,但也许可以帮助某人:)
首先 - 你不能在 ajax 回调中修改 $form_state
- 所以 $form_state->setRebuid()
不会有效果。
如 AJAX form docs 中所述,您应该只返回标记、可渲染数组或 AjaxCommand。
这里需要做的是在ajax回调中修改元素的值,更像这样:
function getAwardSlots(array &$form,FormStateInterface $form_state){
$date = $form_state->getValue('date')
$form['package']['award_slot']['#options'] = $this->getAwardSlotOptions($date);
return $form['package']['award_slot'];
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。