使用UserFrosting

时间:2015-09-28 23:33:30

标签: php jquery ajax opencart userfrosting

所以我一直在努力将OpenCart集成到UserFrosting(http://www.userfrosting.com/)。基本上我通过使用.load将页面注入我自己的html页面上的div,在UserFrosting仪表板中加载所有管理仪表板页面。我差不多完成了但最后一件工作还没有留在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经验的人提供的任何帮助,如果您需要更多关于我正在做的事情的信息,请随时提出。

1 个答案:

答案 0 :(得分:2)

OpenCart的路由不是为AJAX请求构建的

UserFrosting和OpenCart处理POST请求的方式似乎从根本上说是不一致的。如果您查看catalog/category/add route的代码(或者至少,我认为它是什么,但代码似乎没有任何代码内文档,所以它&#39;很难确定,你会看到这个:

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的工作方式略有不同。

UserFrosting的路由(主要)是RESTful

在UF中,POST请求为RESTful,这意味着POST请求的 only 任务是修改资源。所以当你点击&#34;提交&#34;在UserFrosting表单中,POST请求在后台由AJAX调度,在那里进行处理(成功更新资源并返回HTTP 200成功代码,或由于某种原因失败并返回错误代码) 。如果在此请求之后需要刷新或重定向页面,客户端(Javascript)代码负责执行此操作

建议

我的建议是完全丢弃OpenCart的控制器,并以RESTful模式重新实现它。因此,不应使用OpenCart的add()方法,而应使用以下方法:

  1. formCategoryAdd:生成表单以添加类别。这可能就像OpenCart的getForm方法的包装一样简单。这基本上与UserFrosting formUserCreate所做的事情相同。
  2. addCategory:这实际上处理POST请求以添加类别。同样,您可能需要在此处执行任何操作,而不是调用OpenCart的addCategoryvalidateForm方法。唯一的区别是您在完成请求后不会重定向请求。相反,您将向消息流添加成功消息(如果成功添加类别),或者您将添加错误消息然后返回相应的错误代码(如果由于某种原因失败) 。有关此方法如何工作的示例,请参阅UserFrosting的createUser方法。
  3. 然后,回到客户端,您需要一些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