0

我在 Ubuntu 9.10 上使用带有 Propel ORM 的 Symfony 1.3.2。

我开发了一种使用 AJAX 动态填充所选国家/地区城市的选择小部件的表单。

在保存表单上输入的数据之前,我验证了表单。如果验证失败,则将表单返回给用户进行更正。但是,由于国家列表是动态生成的,因此为更正而呈现的表单没有选择有效的城市(它是空的,因为国家小部件尚未更改)。

这对用户来说很不方便,因为这意味着他们必须选择另一个国家(因此会触发更改事件),然后更改回他们选择的原始国家,然后最终选择他们最后选择的城市。

所有这一切都是强加给用户的,因为另一个(可能不相关的)字段没有生效。

我尝试了 $form->getValue('widget_name'),在 $form->bind() 之后立即调用,但似乎(事实上,IIRC,如果表单无法验证,所有值都重置为 null) - 确实如此不行。

我目前正在尝试一个令人讨厌的 hack,它涉及通过 $_POST 直接访问输入(即受污染的)数据,并将它们设置为 flash 变量 - 但我觉得这是一个非常讨厌的 hack)

我正在尝试做的是一个常见的用例场景 - 有没有更好的方法来做到这一点,而不是使用 $_POST 等进行黑客攻击?

4

1 回答 1

1

对于这个确切的问题,我所做的是将表单发布到生成它的同一操作中,并且在该操作中,我将任何选定的国家/地区/城市作为 POST 变量并将它们传递回模板(无论验证如何) . 然后,在模板中,我使用 JQuery 将选择值设置为原来的值。当验证通过时,它们就会被使用。如果没有,它们会被传递回模板。

如果您可以在 JQuery 中容忍一点 PHP,您可以在模板中执行此操作:

$(document).ready(function()
{
   $("#country-select").val('<?php echo $posted_country; ?>');
});

如果您使用这种方法,请不要忘记第一次在您的模板中初始化 $this->posted_country ,否则 Jquery 会感到困惑。

我想你也可以使用 $this->form->setWidget(...)->setDefault(...) 或类似的东西,但我还没有找到使用 $_POST 的方法,因为访问元素似乎需要绑定否则形式。

更新代码以响应以下评论:

if($_POST['profile']['country_id'] != '') 
{
    $this->posted_country = $_POST['profile']['country_id'];
    $q = Doctrine_Query::create()
        ->select('c.city_id, c.city_name')
        ->from('City c')
        ->where('c.country_id = ?', $this->posted_country);     
    $cities = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
    foreach($cities as $city) $list[$city[0]] = $city[1];
    $this->form->setWidget('city_id', new sfWidgetFormChoice(array('choices' => array('' => 'Please select') + $list)));
}

所以...我从帖子中获取国家/地区,我用它查询数据库,获取城市,然后将城市重新放入下拉列表中。然后在模板中,您可以使用 $this->posted_city 之类的内容设置默认选定城市(如果存在,这也将是一个 POST 变量)。

于 2010-03-09T10:29:56.793 回答