我的页面上有三个表单,用于过滤和排序数据对象的视图。
问题是提交一个表单后,由于 FormAction 重定向回当前 URL 而不保留查询字符串,因此另一个表单设置的 URL 参数丢失。有没有办法把它们结合起来?
因此,如果我的网址看起来像
domaint.tld?color=blue&size=l
并且在使用排序表单后,新参数将仅应用于当前网址,如 domaint.tld?color=blue&size=l&sort=TitleASC
,而不是删除已设置的参数?
我的代码的重要部分看起来像这样
return $form
->setFormMethod('GET')
->setFormAction($this->Link() . '#produkte') // todo: join links?!
->disableSecurityToken()
->loadDataFrom($this->request->getVars());
我已经尝试将
$this->Link
替换为 $_SERVER['REQUEST_URI']
,但这是新的请求。即使使用之前设置的参数对链接进行硬编码(仅用于测试目的)也会替换链接,而不考虑设置的参数。
看起来你已经差不多了。在我回答之前有一个问题 - 我不确定提交 GET 方法是否会覆盖所有现有的查询参数,或者是否会根据需要附加/覆盖它们。虽然这与 SilverStripe 无关,但值得一提的是,如果它阻碍了您的实现设计(在覆盖的情况下)。这可能取决于用户代理。这不是我以前考虑过的事情。
您可能知道,表单方法是返回 Form 对象的方法,并且是表单默认提交自身的地方。这意味着在工厂制造过程中,GET 参数被忽略(默认值基本上是
$controller->Link($factory_name)
)。因此,当您使用 setFormAction
时,您此时还需要考虑查询字符串。您可以按照您的暗示使用 Controller::join_links
,或者自己构建字符串,我认为这并不特别重要,只要 action=
上生成的 <form>
属性正确反映这一点即可。
您需要考虑的第二件事是
FormAction
。这完全是用户定义的,使用 Controller::redirectBack
只是重建路由 - 它不使用请求(AFAIK)。如上所述,此时您需要再次考虑完整的 $request->getVars
。除此之外,它应该是一帆风顺的……不考虑这篇文章的开头警告。
您可以修改您的
$this->Link()
并向其中添加所有重要的 get-vars。 Controller::join_links()
是好帮手。例如。 Controller::join_links('?foo=1', '?bar=2')
将导致 ?foo=1&bar=2
。
我曾经遇到过类似的问题并写过它。
在控制器中,您可以覆盖
Link()
方法来获取所有参数:
public function Link($action = '')
{
$base = parent::Link($action);
foreach(['foo', 'bar'] as $getParam) {
if ($this->request->getVar($getParam)) {
$additionalParams[] = $getParam . '=' . $this->request->getVar($getParam);
}
}
return Controller::join_links($base, '?' . join('&', $additionalParams));
}