CakePHP 3.8根据用户选择更改表单数据

时间:2020-01-27 11:16:27

标签: javascript php cakephp wamp

我处于CakePHP 3环境中,在该环境中,我处于“文章”控制器中的“编辑操作”上。

控制器上的第一个功能是标准编辑功能。 这将以表格的形式加载文章的现有数据,因此您可以轻松地对其进行编辑。

public function edit($id){

    $article_categories = $this->Articles->Articlecats->find('list');
    $this->set('article_categories', $article_categories);

    $article = $this->Articles->get($id);

    // if you are not just landing on page but making the save 
    if ($this->request->is(['post', 'put'])) {

        // disable entity creation, not entirely sure what this does.. 
        $this->Articles->patchEntity($article, $this->request->getData());

        // Set the user_id from the session.
        $article->user_id = $this->Auth->user('id');

        if ($this->Articles->save($article)) {

            $this->Flash->success(__('Your article has been updated.'));
            return $this->redirect(['action' => 'index']);

        }

        // check if there are errors in editing and print them
        if ($article->getErrors()){

            // Entity failed validation 
            // print_r($article->getErrors());
            $this->Flash->error(__('Please correct values and try again.'));                

        }

    $this->Flash->error(__('Unable to update your article.'));

    }

    $this->set('article_pass', $article);    

}

ArticlesController的edit方法中的视图显示输入字段,您可以在其中输入Article信息,然后将其保存到基础数据库中。在视图的底部,有一个“检查功能的按钮”按钮,该按钮通过Ajax调用访问ArticlesController上的方法。 ArticlesController上的函数editcategory()检索有关所选类别的信息,然后基于此信息返回渲染视图。

单击此按钮后,我会将类别和类别信息加载到屏幕上的新表格中。

<?php echo $this->Html->script('http://code.jquery.com/jquery.min.js'); ?> 

<!-- File: templates/Articles/edit.php -->

<h1>Edit Article</h1>
<?php
    echo $this->Form->create($article_pass);
    echo $this->Form->control('user_id', ['type' => 'hidden']);
    echo $this->Form->control('title');
    echo $this->Form->control('body', ['rows' => '3']);
    echo $this->Form->select('articlecat_id', $article_categories, ['id' => 'article_cat']);     
    echo $this->Form->button(__('Save Article'));
    echo $this->Form->end();

    $csrfToken = $this->request->getParam('_csrfToken');

    // self written element in View 
    // echo $this->articlecatCreate->create();

?>

<button id="edit_category">Button to check functionality</button>

<div id="ajax_data"></div>


<script>

    var csrf_token = <?php echo json_encode($csrfToken) ?>;  

    $(window).load(function() {   

        // get article category data from controller method through ajax call 
        // populate the form with them      
        $('#edit_category').click(function(){

            var targeturl = "http://wampprojects/composer_cakephptut/articles/editcategory"; 

            var category_selected = $('#article_cat').children("option:selected").val();
            console.log(category_selected);

            // need to check if this statement works?? 
            if ($('#article_cat').children("option:selected").val()){

                $.ajax({
                    type: 'post',
                    url: targeturl,
                    headers: {'X-CSRF-Token': csrf_token},
                    data: {category: category_selected},
                    success: function(result){

                        console.log(result);

                        // create a form with a POST action that links to database 
                        $('#ajax_data').html(result);


                    }
                });

            }else{

                console.log("no cat selected");

            }
        });
    });
</script>

Articles Controller中的“ editcategory()”方法。

public function editcategory(){

    $this->loadModel('Articlecats');    

    $category_id = $this->request->getData('category'); 
    $articlecat_data = $this->Articlecats->get($category_id);
    $this->set('articlecat_pass', $articlecat_data);

    debug($articlecat_data);

    $this->render('element/articlecatcreate', 'ajax'); 

}

在ArticlesController的editCategory()方法中,我检索有关所选类别的信息。然后,我渲染一个依赖于我检索到的数据的帮助程序视图,称为“ articlecatcreate”。

<h1>Edit ArticleCategory</h1>
<div>
    <?php echo $articlecat_pass['id'] ?>
    <?php echo $articlecat_pass['title'] ?>    

    <?php
    // you miss a primary key, it does try to save to the right table 
    echo $this->Form->create($articlecat_pass);
    echo $this->Form->control('user_id', ['type' => 'hidden']);
    echo $this->Form->control('title');
    echo $this->Form->button(__('Save Article'));
    echo $this->Form->end();

    ?>

</div>

它可以通过“ $('#ajax_data')。html(result);”方法正确地将文章类别数据加载到视图的新部分中,该新部分将添加到现有视图中。在ajax成功函数中。

在保存我要编辑的类别时,出现以下错误。 错误:“在表“ articlecats”中找不到具有主键[NULL]的记录”

因此,我新添加到视图中的表单试图保存在正确的表和模型上,但是没有以某种方式将密钥加载到表单的create方法中。

我该如何进行?

解决方案

我找到了在form-> create方法$ options参数中设置控制器和动作的解决方案。

因此,您渲染的元素的代码必须为:

<h1>Edit ArticleCategory</h1>

<div>

    <?php

    // you miss a primary key, it does try to save to the right table 
    echo $this->Form->create($articlecat_pass, ['url' => ['controller' => 'Articlecats', 'action' => 'edit']]);
    echo $this->Form->control('user_id', ['type' => 'hidden']);
    echo $this->Form->control('title');
    echo $this->Form->button(__('Save Article'));
    echo $this->Form->end();

    ?>

</div>

3 个答案:

答案 0 :(得分:1)

您实际上可以使用javascript创建新的widgits或任何新的DOM节点。考虑一下我在附近的一个随机项目的jQuery代码段:

$(this).replaceWith(
    '<a class="remove" id="' + $(this).attr('id') 
        + '" href="' + webroot + 'shop/remove/' + $(this).attr('id') 
        + '" title="Remove item">' 
        + '<img src="' + webroot + 'img/icon-remove.gif" alt="Remove" />' +
    '</a>'
);

您可以轻松获得对第二种表格的引用:

$('form#id_of_form')

但是,尽管如此,当Cake只是一个ajax调用时,我发现在jQuery和javascript中进行的所有这些麻烦对于构建填充表单都有些繁琐。

所以您的成功功能可能类似于

$('form#id_of_form').replaceWith(new_form_from_ajax_call);

答案 1 :(得分:0)

您可以编写axaj调用的成功函数,以便从json构建DOM元素,然后将其插入表单中。

但是我认为一个更简单的解决方案是将ArticleController :: editcategory()数据($ articlecat_data)发送到一个元素,该元素将呈现所需的表单元素。

将此HTML返回到您的Ajax成功函数,并让该函数将其插入到表单中。

所有正常的蛋糕形式约定都将以这种方式得到遵守,以后的帖子数据将正是您所需要的。

稍微注意一下原始页面和ajax返回的代码段中的id和class属性,应该可以轻松地交换整个表单,仅交换其内部HTML或向现有表单添加更多输入。

所以我对“我可以使用CAKEPHP FORMHELPER这样做吗”的具体答案是。

答案 2 :(得分:0)

我明白你的意思了,所以实际上这将给我两个选择。

由于我无法在JQuery中创建窗口小部件,只能创建文本和链接,因此选择之一是使用屏幕上已经存在的表单,并用我新获取的类别数据加载它,以便我可以进一步使用它。我通过将以下代码添加到我的AJAX调用中来尝试这种方法。

结果是我成功填写了第二个表单中的“标题”字段,但是当单击“保存类别”按钮时,我的数据保存到了原始文章而不是文章类别,因此第一个引用形成。

我是否可以通过jquery访问第二种形式的引用(也许通过$ id值?)?那么有没有办法从JQuery更改表单的上下文?

            $.ajax({
                type: 'post',
                url: targeturl,
                headers: {'X-CSRF-Token': csrf_token},
                data: {category: category_selected},
                success: function(result){

                    console.log(result);

                    // POPULATE AN EXISTING FORM WITH NEW DATA AND TOGGLE DISPLAY VALUE! 
                    var article = JSON.parse(result); 

                    // you can populate existing form fields
                    // how can you access the form id field? 
                    // id = "article_cat_create"
                    $("#article_cat_create").val(article);
                    console.log(article[0]['title']);
                    $("#article_cat_title").val(article[0]['title']);                        

                    // which value do you need to set in formhelper?? 
                    $('#article_cat_create').css("display", "block");                        


                }
            });

否则,我将采用第二种方法,如果我正确理解的话,那就是从头开始创建新表格。