如何在我自己的 Joomla 组件中存储和恢复网格的滚动位置?

Posted

技术标签:

【中文标题】如何在我自己的 Joomla 组件中存储和恢复网格的滚动位置?【英文标题】:How can I store and restore the scroll position of a grid in my own Joomla component? 【发布时间】:2013-09-22 07:48:27 【问题描述】:

我正在开发一个 Joomla 组件,在 de 管理员部分有一个(非常常见的)网格视图。当我单击网格中某个项目的发布图标时,页面将重新加载,并且发布状态将更改为已发布/未发布。但是在页面重新加载后,我希望网格滚动到我单击发布图标时所在的滚动位置,这样我就可以看到我刚刚更改的项目。

我已经尝试实现滚动位置的存储和恢复,几乎完全类似于在页面加载之间存储/恢复搜索过滤器的方式:

1)在模板(views/mygrid/tmpl/default.php)中我添加了一个隐藏字段:

<input type="hidden" name="page_scroll" value="0" id="page_scroll" />

2) 在同一个文件中,我在表单的 onsubmit 属性中添加了一些代码来填充该字段:

<form id="adminForm" name="adminForm" method="post" onsubmit="document.getElementById('page_scroll').value = window.pageYOffset;">

3)在模型(models/mygrid.php,类扩展自 JModelList)中,我将这些行添加到 populateState 函数中:

protected function populateState($ordering = null, $direction = null) 
  ..
  $pageScroll = $app->getUserStateFromRequest( $this->context.'.page.scroll', 'page_scroll', '0', 'string');
  $this->setState( 'page.scroll', $pageScroll );
  ..

4)在视图(views/mygrid/view.html.php,从JView扩展的类)中我在显示函数中添加了这一行:

function display($tpl = null) 
..
  $this->state = $this->get('State');
..

5) 最后,回到模板(views/mygrid/tmpl/default.php),我在文件末尾添加了这个小脚本:

<script type="text/javascript">
  window.scrollTo( 0, <?php echo $this->state->get('page.scroll') ?> );
</script>

对我来说,它看起来非常漂亮、干净和正确,但它就是拒绝工作。当我将以下调试行添加到最后一个脚本时,它总是给我 0:

alert( <?php echo $this->state->get('page.scroll') ?> );

谁能告诉我我忽略了什么?非常感谢!

【问题讨论】:

逻辑对我来说很有意义。我会在每一步之后开始回显/提醒该值,以确保它达到那个点。 【参考方案1】:

在David Fritsch的鼓励下,我再次非常彻底地调试并找到了答案!不是一件事,而是两件事出了问题!对于有同样问题的人,或者为任何想要存储/恢复页面滚动的人完成本“手册”,我将解释:

1) 这第一件事是最重要的。当您在“mygrid”视图中应用过滤器时,表单被提交并立即再次加载相同的视图,但现在应用了新的过滤器。这就是为什么我的问题中的第 3 步适用于过滤器的原因。

但是...当您单击网格项目的发布状态时,表单已提交,但现在带有任务“mygriditem.publish”或“mygriditem.unpublish”!因此没有达到我回答的第 3 步,因为现在调用了“mygriditem”控制器而不是“mygrid”控制器。只有在那之后,页面才会第二次重新加载以重定向回“mygrid”视图。但是'page_scroll'不再在请求中了!!

解决方案:我的问题中的第 3 步必须复制到 mygriditem 控制器的发布任务函数(controllers/mygriditem.php,类扩展自 JControllerForm),例如:

public function publish( $key = null, $urlVar = null )

    JFactory::getApplication()->getUserStateFromRequest( 'com_mycomponent.mygrid.page.scroll', 'page_scroll', '0', 'string' );

    return parent::publish( $key, $urlVar );

使用“取消发布”功能执行相同操作后,它起作用了!!

2) 我还忽略了第二件事,这使它非常混乱:表单的 onsubmit 事件处理程序仅在单击提交按钮时执行,而不是在您使用 Javascript 提交表单时执行,例如:

onclick="this.form.submit()"

我觉得我应该保持简短。 Joomla 提供了一个函数,让您可以在模板(views/mygrid/tmpl/default.php)中使用它:

onclick="submitform(task)"

注意使用此函数(间接)提交adminForm,然后onsubmit事件处理程序将被执行。

我希望这对某人有所帮助。 :)

【讨论】:

以上是关于如何在我自己的 Joomla 组件中存储和恢复网格的滚动位置?的主要内容,如果未能解决你的问题,请参考以下文章

Joomla - 在我的组件中显示一篇文章

如何在joomla组件中仅获取和显示选中的项目

我可以在我的组件中使用 Joomla 插件吗

Joomla! 2.5 生成的URL中的组件菜单类型参数

Joomla:如何将一种表单用于前端和后端视图?

在 joomla 组件中,我应该在哪里存储数据库函数,以及如何调用它们?