在表单事件中,将字段'attr' => array('readonly' => 'readonly')
设置为"disabled" = "1"
。这不是理想的效果。禁用的选择字段在提交时保持空值。只读字段应保留并保持显示的值。或者我想。那么如何让价值保持不变且不变?
编辑;
隐藏字段不起作用。 choice_attr
也无济于事。
我投票结束这个问题。我没有发现任何显示已禁用的实体字段的方法,也保留了该值。如果你对这是怎么做的了解......
一个例子(在Symfony 2.8.3中):
家庭实体有六个属性,每个属性都是与Household的OneToMany关系中的实体。 (该应用程序具有其他具有相似属性的实体。)Household的Housing实体/属性具有两个属性:housing和enabled。如果应用程序的客户不再打算跟踪该属性,则可以将该属性设置为enabled = no
。
如果属性设置为enabled = no
,则可以通过在实体字段的查询构建器中包含where子句(例如->where("h.enabled=1")
)来轻松消除其在新的或编辑的家庭表单中的可用性。但是,这样做会导致disabled属性设置为null
。因此需要以某种方式保留价值。
理想的解决方案是为这些属性实体字段提供服务,既显示值又保留,如果启用则为否。
我尝试过使用事件监听器,隐藏字段choice_attr
,修改表单模板和表单主题都无济于事。例如,隐藏字段是需要实体字段时的文本。这并不意味着它无法完成,只是我没有偶然发现正确的方法。
答案 0 :(得分:0)
最终解决方案:使用Doctrine元数据获取已禁用的实体字段,表单类修改,以及对于ManyToMany关系,一些jquery和不可见模板条目的服务。
服务功能:
/**
* Create array of disabled fields of an entity object
*
* @param type $object
* @return array
*/
public function getDisabledOptions($object) {
$values = [];
$className = get_class($object);
$metaData = $this->em->getClassMetadata($className);
foreach ($metaData->associationMappings as $field => $mapping) {
if (8 > $mapping['type']) {
$fieldName = ucfirst($field);
$method = 'get' . $fieldName;
if (method_exists($object->$method(), 'getEnabled') && false === $object->$method()->getEnabled()) {
$values[] = $fieldName;
}
}
}
$manyToMany = json_decode($this->getMetaData($object), true);
foreach(array_keys($manyToMany) as $key) {
$values[] = $key;
}
return $values;
}
/**
* Get array of disabled ManyToMany options
*
* @param Object $object
* @return array
*/
public function getMetaData($object) {
$data = array();
$className = get_class($object);
$metaData = $this->em->getClassMetadata($className);
foreach ($metaData->associationMappings as $field => $mapping) {
if (8 === $mapping['type']) {
$data[$field] = $this->extractOptions($object, $field);
}
}
return json_encode($data);
}
控制器使用服务:
$searches = $this->get('mana.searches');
$disabledOptions = $searches->getDisabledOptions($household);
$metadata = $searches->getMetadata($household);
...
$form = $this->createForm(HouseholdType::class, $household, $formOptions);
...
return $this->render('Household/edit.html.twig',
array(
'form' => $form->createView(),
....
'metadata' => $metadata,
));
表单类字段示例:
->add('housing', EntityType::class,
array(
'class' => 'TruckeeProjectmanaBundle:Housing',
'choice_label' => 'housing',
'placeholder' => '',
'attr' => (in_array('Housing', $options['disabledOptions']) ? ['disabled' => 'disabled'] : []),
'label' => 'Housing: ',
'query_builder' => function (EntityRepository $er) use ($options) {
if (false === in_array('Housing', $options['disabledOptions'])) {
return $er->createQueryBuilder('alias')
->orderBy('alias.housing', 'ASC')
->where('alias.enabled=1');
} else {
return $er->createQueryBuilder('alias')
->orderBy('alias.housing', 'ASC');
}
},
))
...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Truckee\ProjectmanaBundle\Entity\Household',
'required' => false,
'disabledOptions' => [],
));
}
删除已禁用属性的Jquery:
$("input[type=Submit]").click(function () {
$("input").removeAttr("disabled");
$("select").removeAttr("disabled");
});
模板和模板的示例jquery for ManyToMany的关系:
<div id="household_options" style="display:none;">{{ metadata }}</div>
jquery的:
if (0 < $("#household_options").length) {
var house_options = JSON.parse($("#household_options").text());
$.each(house_options, function (index, item) {
$.each(item, function (k, v) {
var formAttr = 'household_' + index + '_' + v.id;
$("#" + formAttr).attr('disabled', 'disabled');
});
});
}