CakePHP 3.8 根据用户选择更改表单数据
CakePHP 3.8 Change Form Data based on User Selection
我在 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 的编辑方法中的视图显示输入字段,您可以在其中编辑文章信息,然后将它们保存到基础数据库中。在视图的底部有一个按钮 "button to check Functionality",它通过 Ajax 调用访问 ArticlesController 上的方法。 ArticlesController 上的函数 editcategory() 检索有关所选类别的信息,然后 returns 基于此信息返回的呈现视图。
单击此按钮后,我将类别和类别信息加载到屏幕上的新表单中。
<?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>
文章控制器中的"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 成功函数中。
在保存我试图编辑的类别时,出现以下错误。
错误:"Record not found in table "articlecats" 主键 [NULL]"
所以我新创建的添加到视图的表单试图保存正确的 table 和模型,但不会以某种方式在表单的创建方法中加载密钥..
我该如何进行?
已找到解决方案
我找到了在 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>
您可以编写 axaj 调用的成功函数来从 json 构建 DOM 元素,然后将它们插入您的表单中。
但我认为更简单的解决方案是将您的 ArticleController::editcategory() 数据 ($articlecat_data) 发送到将呈现您需要的表单元素的元素。
Return 这个 HTML 到你的 ajax 成功函数,并让那个函数将它插入你的表单。
所有正常的蛋糕形式惯例将以这种方式得到尊重,稍后的 post 数据将正是您所需要的。
稍微注意一下原始页面和 ajax 返回的代码段中的 id 和 class 属性,应该可以很容易地换出整个表单,只是换掉它的内部-html 或向现有表单添加更多输入。
所以我对 "CAN I USE CAKEPHP FORMHELPER TO DO SO" 的具体回答是肯定的。
我明白你的意思,所以实际上这会给我两个选择..
由于我无法从 JQuery 中创建小部件,只能创建文本和链接,选项一是使用屏幕上已经存在的表单,将其加载到我新获得的类别数据中,这样我就可以进一步使用这个。我通过将以下代码添加到我的 AJAX 调用来尝试这种方法..
结果是我在第二个表单中成功填充了 'title' 字段,但是当点击 "save Category" 按钮时,我的数据被保存到原始文章而不是文章类别,所以第一种形式的参考。
有什么方法可以从 jquery 中访问第二种形式的引用(也许通过 $id 值?)?那么有没有办法把Form的Context从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");
}
});
如果不是,我会选择第二种方法,如果我理解正确的话,从头开始创建一个新表单。
您实际上可以使用 javascript 创建新的 widgit 或任何新的 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')
但是,我仍然发现 jQuery 和 javascript 中的所有这些小题大做对于构建填充表单来说有点乏味,因为 Cake 只是一个 ajax 调用。
所以你的成功函数可以是这样的
$('form#id_of_form').replaceWith(new_form_from_ajax_call);
我在 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 的编辑方法中的视图显示输入字段,您可以在其中编辑文章信息,然后将它们保存到基础数据库中。在视图的底部有一个按钮 "button to check Functionality",它通过 Ajax 调用访问 ArticlesController 上的方法。 ArticlesController 上的函数 editcategory() 检索有关所选类别的信息,然后 returns 基于此信息返回的呈现视图。
单击此按钮后,我将类别和类别信息加载到屏幕上的新表单中。
<?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>
文章控制器中的"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 成功函数中。
在保存我试图编辑的类别时,出现以下错误。 错误:"Record not found in table "articlecats" 主键 [NULL]"
所以我新创建的添加到视图的表单试图保存正确的 table 和模型,但不会以某种方式在表单的创建方法中加载密钥..
我该如何进行?
已找到解决方案
我找到了在 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>
您可以编写 axaj 调用的成功函数来从 json 构建 DOM 元素,然后将它们插入您的表单中。
但我认为更简单的解决方案是将您的 ArticleController::editcategory() 数据 ($articlecat_data) 发送到将呈现您需要的表单元素的元素。
Return 这个 HTML 到你的 ajax 成功函数,并让那个函数将它插入你的表单。
所有正常的蛋糕形式惯例将以这种方式得到尊重,稍后的 post 数据将正是您所需要的。
稍微注意一下原始页面和 ajax 返回的代码段中的 id 和 class 属性,应该可以很容易地换出整个表单,只是换掉它的内部-html 或向现有表单添加更多输入。
所以我对 "CAN I USE CAKEPHP FORMHELPER TO DO SO" 的具体回答是肯定的。
我明白你的意思,所以实际上这会给我两个选择..
由于我无法从 JQuery 中创建小部件,只能创建文本和链接,选项一是使用屏幕上已经存在的表单,将其加载到我新获得的类别数据中,这样我就可以进一步使用这个。我通过将以下代码添加到我的 AJAX 调用来尝试这种方法..
结果是我在第二个表单中成功填充了 'title' 字段,但是当点击 "save Category" 按钮时,我的数据被保存到原始文章而不是文章类别,所以第一种形式的参考。
有什么方法可以从 jquery 中访问第二种形式的引用(也许通过 $id 值?)?那么有没有办法把Form的Context从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");
}
});
如果不是,我会选择第二种方法,如果我理解正确的话,从头开始创建一个新表单。
您实际上可以使用 javascript 创建新的 widgit 或任何新的 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')
但是,我仍然发现 jQuery 和 javascript 中的所有这些小题大做对于构建填充表单来说有点乏味,因为 Cake 只是一个 ajax 调用。
所以你的成功函数可以是这样的
$('form#id_of_form').replaceWith(new_form_from_ajax_call);