因此,我一直致力于将OpenCart集成到UserFrosting (http://www.userfrosting.com/)中。基本上,我是通过使用UserFrosting将页面注入到我自己的html页面上的div来加载.load中的所有管理仪表板页面。我已接近完成,但有最后一块工作,是没有留在UF仪表板。
我将使用“目录/类别”页面作为示例来显示我正在做的事情:
这是我的html分类文件,它叫做cata-categories.html
<!DOCTYPE html>
<html lang="en">
{% include 'components/head.html' %}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<body>
<div id="wrapper">
{% include 'components/nav-account.html' %}
<div id="page-wrapper">
{% include 'components/alerts.html' %}
<ol id="categories"></ol>
<script>
$( "#categories" ).load( "../solutions/admin/index.php?route=catalog/category" );
</script>
<br>
{% include 'components/footer.html' %}
</div>
</div></div>
</body>
</html>这是通过UserFrosting的侧边栏使用sidebar.html中的以下代码访问的
{% if checkAccess('uri_manage_groups') %}
<li>
<a href="{{site.uri.public}}/cata-categories/"><i class="fa fa-tags fa-fw"></i>Categories</a>
</li>
{% endif %}该页面是通过public/index.php中用于UserFrosting的以下代码呈现的:
$app->get('/cata-categories/?', function () use ($app) {
$app->render('cata-categories.html', [
'page' => [
'author' => $app->site->author,
'title' => "Catagories",
'description' => "Catalogue Catagories.",
'alerts' => $app->alerts->getAndClearMessages()
]
]);
});为了保持在OpenCart页面上单击所有链接,我将以下脚本放在每个主.tpl的底部(例如category_list.tpl):
<script>
$("#categories").on("click", "a", function (e) {
$("#categories").load($(this).attr("href"));
e.preventDefault();
});
</script>然后,在提交表单时,我更改了控制器中的重定向(例如),以便保持在同一页上。category.php)如下:
$this->response->redirect('../../portal/cata-categories');一切都很好,现在唯一的问题是表单提交或过滤结果中的错误。例如,如果有人试图添加一个新类别,但没有填写任何信息并单击“保存”,则重定向到/admin/index.php?route=catalog/category/add,而不是在UserFrosting仪表板中。
我希望它留在我的仪表板中,并且需要在控制器中修改什么才能做到这一点,我需要一个正确的方向,我假设某种AJAX会强制它不要重新加载页面,只显示错误。与过滤器按钮一样,它显然需要将过滤器添加到URL中,因此不需要在仪表板中加载--需要一种无需刷新的过滤方法。
如果有修改OpenCart经验的人提供任何帮助,我们将非常感激,如果您需要更多关于我正在做的事情的信息,请随时询问。
发布于 2015-09-29 16:56:29
OpenCart的路由不是为AJAX请求构建的
UserFrosting和OpenCart处理POST请求的方式似乎根本不一致。如果您查看路由的代码(或者至少,我认为它是这样的,但是代码似乎没有任何代码文档,所以很难确定),您将看到以下内容:
public function add() {
$this->language->load('catalog/category');
$this->document->setTitle($this->language->get('heading_title'));
$this->load->model('catalog/category');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
$this->model_catalog_category->addCategory($this->request->post);
$this->session->data['success'] = $this->language->get('text_success');
$url = '';
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
$this->response->redirect($this->url->link('catalog/category', 'token=' . $this->session->data['token'] . $url, 'SSL'));
}
$this->getForm();
}那么这里发生了什么?似乎当您向catalog/category/add发帖时,它开始生成一个文档(我猜前三行就是这样做的),然后它处理您的POST请求(我相信$this->model_catalog_category->addCategory($this->request->post);实际上添加了这个类别)。
然后,它重新构建列出所有类别的URL (我假设),并将响应重定向到该页面(仍然在处理POST请求的服务器端代码中,请注意)。这一切都很好,而且实际上是大多数旧式(预AJAX)应用程序的工作方式,但是UF做的事情有点不同。
用户霜冻的路线(大部分)是RESTful
在UF中,POST请求是RESTful,这意味着POST请求的唯一任务是修改资源。因此,当您在UserFrosting表单中单击"submit“时,POST请求由AJAX在后台发送,在那里处理它(要么成功地更新资源并返回HTTP 200成功代码,要么由于某种原因失败并返回错误代码)。如果页面在此请求之后需要刷新或重定向,则客户端(Javascript)代码有责任这样做。
推荐
我的建议是完全放弃OpenCart的控制器,并以RESTful模式重新实现它。因此,与其使用OpenCart的add()方法,不如使用以下方法:
formCategoryAdd:生成表单以添加类别。这可能就像包装OpenCart的getForm方法一样简单。这基本上与UserFrosting的formUserCreate所做的事情是相同的。addCategory:这实际上是处理POST请求来添加一个类别。同样,在这里您可能只需要调用OpenCart的addCategory和validateForm方法。唯一的区别是,当请求完成时,不会重定向它。相反,您将向消息流添加一条成功消息(如果它成功地添加了类别),或者您将添加一条错误消息,然后返回一个适当的错误代码(如果它由于某种原因失败)。有关如何工作的示例,请参阅UserFrosting的createUser方法。然后,回到客户端,您将需要一些Javascript来处理表单提交。你基本上可以从任何一个UF页面上窃取它。假设您的表单名为add-category
<script>
$(document).ready(function() {
// Process form
$("form[name='add-category']").formValidation({
framework: 'bootstrap',
// Feedback icons
icon: {
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh'
},
fields: { "" : ""}
}).on('success.form.fv', function(e) {
// Prevent double form submission
e.preventDefault();
// Get the form instance
var form = $(e.target);
// Serialize and post to the backend script in ajax mode
var serializedData = form.serialize();
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: serializedData
}).done(function(data, statusText, jqXHR) {
// Forward to account home page on success
window.location.replace(site.uri.public);
}).fail(function(jqXHR) {
if ((typeof site !== "undefined") && site['debug'] == true) {
document.body.innerHTML = jqXHR.responseText;
} else {
console.log("Error (" + jqXHR.status + "): " + jqXHR.responseText );
// Display errors on failure
$('#userfrosting-alerts').flashAlerts().done(function() {
// Re-enable submit button
form.data('formValidation').disableSubmitButtons(false);
});
}
});
});
});
</script>如果您想减少客户端代码的重复,我已经将这个Javascript放在dev分支中的一个单独的函数中:https://github.com/alexweissman/UserFrosting/blob/dev/public/js/userfrosting.js#L58-L113
https://stackoverflow.com/questions/32833388
复制相似问题