【发布时间】:2016-07-22 06:46:13
【问题描述】:
我正在使用 Symfony 2.7 创建一个 ToDo 列表。 Form 包含列表名称的简单文本字段和items 的集合:
class TodoType extends AbstractType {
public function getName() {
return 'todo_list';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\TodoList',
));
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', 'text', array(
'label' => 'Name',
...
))
->add('create', 'submit', array(
'label' => 'Save',
...
));
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$todoList = $event->getData();
$form = $event->getForm();
$form
->add('items', 'collection', array(
'type' => 'todo_list_item_type',
'allow_add' => true,
'allow_delete' => true,
//'by_reference' => false,
'data' => ($todoList != null ? $todoList->getItems() : null),
));
});
}
}
}
这很好用。 items 数组使用“数组样式”名称包含在表单中:
<form ...>
...
<ul class="sortable">
<li>
<input id="todo_list_items_0_name" class="item-name form-control" type="text" value="Shopping" placeholder="Name" required="required" name="todo_list[items][0][name]">
</li>
<li>
<input id="todo_list_items_1_name" class="item-name form-control" type="text" value="Wash car" placeholder="Name" required="required" name="todo_list[items][1][name]">
</li>
...
<ul>
现在我想使用jQuery Sortable Plugin 重新排序项目。这工作正常。用户可以根据自己的喜好重新排序项目。但是,这对项目的存储顺序没有任何影响。
我认为问题很明显: 可排序插件仅更改 DOM 中项目的位置,而项目名称(包括其数组索引)保持不变。因此,Item0 在提交表单时仍然有index = 0,无论它在列表中的新位置如何。
是否有任何内置解决方案来解决这个问题? 到目前为止,我发现的唯一解决方案是监听可排序插件的 stop 事件(重新排序完成后触发)并手动使用一些 JavaScript 查找/替换字段名称中的索引号。这当然可行,但很容易受到字段名称更改的影响。例如,如果将来的 Symfony 版本将使用 some_field_name_0 而不是 some_field_0_name,则替换代码将不再起作用。
另一种解决方案是使用附加字段 sortOrder 扩展 Item 类,并将此信息作为隐藏字段包含在表单中。我仍然需要使用 JS 手动更新这个索引,但至少我可以更好地控制格式。
但是我想知道是否没有更简单的方法。对集合类型进行排序并没有什么特别之处。那么也许有一个开箱即用的解决方案?
【问题讨论】:
标签: javascript jquery forms symfony jquery-ui-sortable