在我的应用程序中,我有很多模块和很多带有自己小部件的表单
我一直在尝试全局'取消设置','隐藏'或'制作只读'小部件。
我知道可以在表单的 configure()函数中为一个小部件执行此操作,但我正在寻找更好的解决方案,如果可能的话,以全局方式。改变所有模块形式并跟踪它们可能会很痛苦
线程可能有点长,但我认为它很容易理解问题。非常感谢你,如果你有时间阅读它:)
我已经构建了一个带有Timestampable行为的简单新闻模块来测试一些选项,但它们仍然没有工作。
TbNews
id
作为主键scontent
作为保存新闻内容的文本字段。created_at
作为日期时间。 (时间戳行为)updated_at
作为日期时间。 (时间戳行为)
TbNews schema.yml:
TbNews: connection: doctrine_master tableName: tb_news columns: id: type: integer(8) fixed: false unsigned: false primary: true autoincrement: true scontent: type: string(64000) fixed: false unsigned: false primary: false notnull: true autoincrement: false actAs: Timestampable: created: name: created_at type: timestamp format: Y-m-d H:i:s options: notnull: false required: false updated: name: updated_at type: timestamp format: Y-m-d H:i:s options: notnull: false required: false
表单中的TbNews updated_at
(例如,这里只写了updated_at列):
class TbNewsForm extends PluginTbNewsForm { public function configure() { $this->setWidgets(array( 'updated_at' => new sfWidgetFormDateTime(), )); $this->setValidators(array( 'updated_at' => new sfValidatorDateTime(array('required' => false)), )); } }
TbNews的模板_form.php updated_at :
测试了很多选项,手动渲染updated_at:“echo $ form ['updated_at']”并且不渲染它。
<?php echo $form->renderHiddenFields(false) ?>
update_at
列的全局测试: lib/form/doctrine/BaseFormDoctrine.class.php
:
sfWidgetFormInputHidden()
,窗口小部件不会在模板中呈现。
abstract class BaseFormDoctrine extends sfFormDoctrine { public function setup() { $value_updated_at = $this->getObject()->updated_at; unset($this->widgetSchema['updated_at']); unset($this->validatorSchema['updated_at']); $this->widgetSchema['updated_at'] = new sfWidgetFormInputHidden(); $this->widgetSchema['updated_at']->setOption('is_hidden', 'true'); $this->widgetSchema['updated_at']->setOption('type', 'hidden'); $this->setDefault('updated_at', $value_updated_at); $this->setWidget('updated_at', new sfWidgetFormInputHidden(array('value'=>$value_updated_at))); //$this->setWidget('updated_at', $this->widgetSchema['updated_at']); } }
updated_at
,但它未显示为只读。似乎不适用于sfWidgetFormDateTime
。
$this->widgetSchema['updated_at']->setAttribute('readonly', 'readonly');
BaseFormDoctrine
不是在所有Form模块中全局更改窗口小部件的正确方法,或者我的测试中可能存在错误。
TbNewsForm configure()
中使用上述代码,我们可以轻松地将窗口小部件从一种类型更改为另一种类型,并单独呈现或隐藏它,并且它可以正常工作。
非常感谢你花时间阅读它,欢迎任何评论或解决方案:)
答案 0 :(得分:0)
更改BaseFormDoctrine
课程对您没有帮助。表单的小部件在给定表单的基类中设置(在您的情况下为BaseTbNewsForm
),因此它们将覆盖BaseFormDoctrine
类中所做的任何更改。
如果你想对每个表单执行相同的操作但不想重写每个类中的代码,你可以创建一个实用程序类,并在表单'configure()
函数中调用它的方法。
我认为没有更改Doctrine / Symfony内部的全局选项(你必须改变生成基类的方式)。
答案 1 :(得分:0)
我找到了一种有效的方法,但它可能不是最好的解决方案,因为它涉及修改symfony的源代码。核心文件中的函数: setupInheritance() :所有表单后都会调用 sfFormDoctrine.class.php 设置小部件和验证器,如果我们在那里添加代码,我们的更改将全局适用于所有表单。
在下面的示例中,将取消设置所有窗口小部件'created_at'和'updated_at',然后将其设置为隐藏:
/**
* Used in generated forms when models use inheritance.
*/
protected function setupInheritance()
{
if (isset($this))
{
$oWidgetSchema = $this->getWidgetSchema();
if (isset($oWidgetSchema))
{
$screatedcolumn = "created_at";
$supdatedcolumn = "updated_at";
//if ($this->isNew()) //we can add a check for new records
//we can also add checks for frontend or backend
//$request = sfContext::getInstance()->getRequest();
//$this->url = 'http'.($request->isSecure() ? 's' : '').'://'. $request->getHost();
//$suri_params = $request->getParameterHolder()->getAll();
//set [created_at] as hidden field widget, and set its default value to the Original one before sending it to Timestampable.php Listener.
if ( $oWidgetSchema->offsetExists($screatedcolumn) )
{
$value_created_at = $this->getObject()->created_at;
unset($this->widgetSchema[$screatedcolumn]);
$this->widgetSchema[$screatedcolumn] = new sfWidgetFormInputHidden();
$this->widgetSchema[$screatedcolumn]->setOption('is_hidden', 'true');
$this->widgetSchema[$screatedcolumn]->setOption('type', 'hidden');
//unset($this->validatorSchema[$screatedcolumn]); //unset its validator to make sure values are not checked by default, optional.
$this->setDefault($screatedcolumn, $value_created_at);
}
//set [updated_at] as hidden field widget, and set its default value to time() before sending it to Timestampable.php Listener.
if ( $oWidgetSchema->offsetExists($supdatedcolumn) )
{
//$value_updated_at = $this->getObject()->updated_at;
unset($this->widgetSchema[$supdatedcolumn]);
$this->widgetSchema[$supdatedcolumn] = new sfWidgetFormInputHidden();
$this->widgetSchema[$supdatedcolumn]->setOption('is_hidden', 'true');
$this->widgetSchema[$supdatedcolumn]->setOption('type', 'hidden');
//unset($this->validatorSchema[$supdatedcolumn]); //unset its validator to make sure values are not checked by default, optional.
$this->setDefault($supdatedcolumn, time());
}
}
}