Javascript Symfony-自定义字段类型表单_小部件呈现
长话短说,在对这一点进行了大量研究并找到了一些关于如何扩展现有字段类型、如何继承现有字段类型、如何在后端更改某些内容的信息后,我来这里是想问一个问题 对当前问题的简短解释: 我需要一个EntityType字段ChoiceType-HTMLSelect来使用我自己的过滤逻辑,并从ajax调用中动态提取结果,立即替换下拉列表中列出的选项 现行守则: 在FormType.php中Javascript Symfony-自定义字段类型表单_小部件呈现,javascript,php,symfony,twig,widget,Javascript,Php,Symfony,Twig,Widget,长话短说,在对这一点进行了大量研究并找到了一些关于如何扩展现有字段类型、如何继承现有字段类型、如何在后端更改某些内容的信息后,我来这里是想问一个问题 对当前问题的简短解释: 我需要一个EntityType字段ChoiceType-HTMLSelect来使用我自己的过滤逻辑,并从ajax调用中动态提取结果,立即替换下拉列表中列出的选项 现行守则: 在FormType.php中 //in buildForm { $builder->add('trainer', EntityType::
//in buildForm
{
$builder->add('trainer', EntityType::class, [
'class' => Trainer::class,
'choices' => $training->trainer_list ?? [],
'label' => 'seminar.trainer.form.trainer.label',
'placeholder' => 'form.trainer.placeholder',
'required' => false,
'attr' => ['class' => 'trainer2select'] // has no outcome whatsoever?!
])
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'onPreSubmit']);
}
function onPreSubmit(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$trainer = $this->em->getRepository(Trainer::class)->find($data['trainer']);
$form->add('trainer', EntityType::class, [
'class' => Trainer::class,
'data' => $trainer,
'label' => 'seminar.trainer.form.trainer.label',
'placeholder' => 'form.trainer.placeholder',
'required' => false,
]);
}
在树枝上:
{% if field == 'trainer' %}
{{ form_row(attribute(form, field), {'id': 'trainer'}) }}
{% else %}
{{ form_row(attribute(form, field)) }}
{% endif %}
{% block javascripts %}
<script>
var lastTime;
var timeoutEvents = [];
$(document).ready(() => {
function trainer_changed() {
let input = event.target;
lastTime = Date.now();
timeoutEvents.push(setTimeout(() => {
if (Date.now() - lastTime < 150)
return;
jQuery.ajax({
url: '{{ path('trainer_select_ajax') }}',
type: 'GET',
data: {
search: input.value,
start: {{ seminar.event.start.date | date('Y-m-d') }},
end: {{ seminar.event.end.date | date('Y-m-d') }}
},
success: function (trainers) {
let trainer = $('#trainer');
trainer.get(0).options.length = 1; // reset all options, except for the default
trainers.forEach(tr => {
trainer.append(new Option(tr.text, tr.id));
});
let search = $($("input.select2-search__field").get(1));
if (search.get(0)) {
search.get(0).oninput = null; // detach our event handler so we don't loop
search.trigger('input'); // rebuild the dropdown choices
search.get(0).oninput = trainer_changed; // reattach our event handler
}
}
});
lastTime = Date.now();
timeoutEvents.forEach(e => {
clearTimeout(e);
});
}, 200));
}
function select_opened() {
let trainerinput = $('input.select2-search__field').get(1);
if (trainerinput) {
trainerinput.oninput = trainer_changed;
}
}
$('#select2-trainer-container').click(select_opened);
});
</script>
{% endblock %}
显然,EntityType字段是使用select2扩展名呈现的。显然,我可以用javascript替换该功能,但我只想定义我自己的“AjaxEntityType”,该form_小部件按照我的意愿呈现。我可以在多个项目中使用它,而不用使用一些愚蠢的技巧,比如提供默认类名和调用javascript在全局加载页面后更改呈现方式。所以怎么办
我检查过的资源对我想要实现的目标几乎毫无价值,还有更多
编辑以澄清:我正在寻找的最佳情况是,一个自定义字段类型始终呈现为的最简单示例,它将始终被调用$'FieldTypeWidget'。选择2{ajax:{foo},搜索函数:{bar}
在这里,我可以找到一个如何在捆绑包中提供此功能的示例,但在我的应用程序中是否有更简单的方法?我想说,您看到的是中所解释的内容 以下是根据您的需要稍加修改的示例: src/Form/Type/AjaxEntityType.php 还请注意文档页面中的便利提示: 您可以进一步自定义用于渲染的每个子级的模板 选择类型。在这种情况下要替代的块称为“块” 名称+条目+元素名称标签、错误或小部件,例如 自定义您需要的Shipping小部件的子项的标签 要定义{%block shipping\u entry\u label%}。。。{%endblock%} 还请记住,正如稍后在同一页上所述,表单模板覆盖必须正确注册: config/packages/twig.yaml 那就用它吧:
$builder->add('trainer', AjaxEntityType::class, [ class => Trainer::class, ]);
也值得一读:
执行魔术的实际代码位:
这是否有用:?正如您在我的代码中看到的,我已经在使用表单事件将正确的实体放入后端的表单中。我想要的是定义一个自定义EntityType,当我将其定义为where和how时,它将始终(无论在何处使用)呈现到目前为止,我甚至无法真正找到symfony的form_小部件决定如何呈现它自己的类型。在浏览文档时,我不知何故跳过了这一部分,因为twig似乎不是正确的查看位置。谢谢!
{% use 'form_div_layout.html.twig' %}
{% block ajaxEntity_widget %}
{{ parent() }}
<script>
$('#{{ form.vars.id }}').select2({ajax: {foo}, searchFunction: {bar}});
</script>
{% endblock %}
twig:
form_themes:
- 'form/fields.html.twig'
# you might have this configuration already,
# for example, if you use bootstrap theming.
# If so, just copy the configured template path stated here
# in the 'use' statement of the file form/fields.html.twig
$builder->add('trainer', AjaxEntityType::class, [ class => Trainer::class, ]);