简体   繁体   English

如何将动态创建的列表传递给控制器​​以保存到数据库中?

[英]How do I pass a dynamically created list to the controller to save into the database?

I am working in Concrete5 and am new to the MVC concept. 我正在Concrete5中工作,并且是MVC概念的新手。 I have a some jquery that creates an unordered list from a textbox in my view. 我有一些jQuery,可以从视图中的文本框创建无序列表。 If your familiar with Concrete5 this is the view for the block I am adding the list to. 如果您熟悉Concrete5,这就是我要添加列表的块的视图。 It is basically a list of features for a product. 它基本上是产品的功能列表。 This view needs to save the list to the database base file. 该视图需要将列表保存到数据库基础文件。 Usually this is done pretty simply using a variable that the information gets saved to (aka this is how everything else in the view is saved). 通常,这很简单,只需使用一个将信息保存到的变量即可(也就是保存视图中其他所有内容的方式)。 The problem I am having is I do not know how to use the controller to pass the unordered list from the view to the controller to the database so that it saves it. 我遇到的问题是我不知道如何使用控制器将无序列表从视图传递到控制器到数据库,以便将其保存。 Any help and sample code would be appreciated. 任何帮助和示例代码将不胜感激。 I'm pretty sure I need to write a php function in my controller to get the list but I am not sure what the code would be. 我很确定我需要在控制器中编写一个php函数来获取列表,但是我不确定代码是什么。

auto.js auto.js

$("#addList").click(function() {
    var text = $("#inputList").val() + '<button>x</button>';
    if(text.length){
        $('<li />', {html: text}).appendTo('ul.featureList')
        };
});
$('ul').on('click','button', function(el){
    $(this).parent().remove()
});

add/edit.php 添加/ edit.php

<div class="ccm-block-field-group">
<h2><?php echo t('Features') ?></h2>

Right now 'features' is the name of the field in my database file db.xml The area featureList is where the list get generated into. 现在,“功能”是我的数据库文件db.xml中字段的名称。区域featureList是生成列表的位置。 I know it needs to be changed around a bit to work, just not sure. 我知道它需要进行一些更改才能起作用,只是不确定。

<?php echo $form->textarea('features', $features, array());?>
<input type="test" id="inputList" />
<button type="button" id="addList">Add</button> 
<ul class="featureList"></ul>
</div>

view.php view.php

echo "<h2>{$proName}</h2>";
echo "{$description}";
echo "<h3>{$features}</h3>";
echo "<h2>{$price}</h2>";
echo "<p>{$priceInfo}</p>";

db.xml db.xml

<field name="features" type="X2"></field>

With concrete5 blocks, there are two different situations you could be in: 使用concrete5块,您可能会遇到两种不同的情况:

  1. admin user is editing the block (or adding a new block), and you want to save this data to the database. 管理员用户正在编辑块(或添加新块),并且您想将此数据保存到数据库中。
  2. public user is viewing the block, but the block view itself has a form (for example, a contact form block) and you want to do something when the public form is submitted (for example, send a notification email to an admin that someone has filled out the form, or store the submission in a database for future review). 公共用户正在查看该阻止,但是该阻止视图本身具有一个表单(例如,联系人表单阻止),并且您希望在提交公共表单时执行某些操作(例如,向管理员发送通知电子邮件,告知某人已填写表格,或将提交的内容存储在数据库中以备将来查看。

If you're talking about situation #1, you need to put some custom code in the controller's save() method. 如果您正在谈论情况#1,则需要在控制器的save()方法中放入一些自定义代码。 If you're talking about situation #2, you need to create your own action method in the controller, AND you need to actually have a <form> in the view.php file. 如果要讨论情况2,则需要在控制器中创建自己的操作方法,并且实际上需要在view.php文件中具有<form>

UPDATE: Based on the sample code you added to your question, here is the solution: The only way your data can get back to the server is via a form POST. 更新:根据您添加到问题中的示例代码,以下是解决方案:数据可以通过POST表单返回服务器的唯一方法。 <li> elements are not form fields, and hence the data in them doesn't get POST'ed with the form. <li>元素不是表单字段,因此其中的数据不会与表单一起发布。 So when you add the new <li> element to the page, you should also add a hidden form field, like so: 所以,当你添加新的<li>元素的页面,你应该添加一个隐藏的表单字段,就像这样:

    var listItemCounter = 0;
$("#addList").click(function() {
        listItemCounter++;
    var text = $("#inputList").val() + '<button data-id="' + listItemCounter + '">x</button>'; //assign a unique id number to this button, so it knows which hidden field to remove when clicked
    if(text.length){
        $('<li />', {html: text}).appendTo('ul.featureList');
        $('<input type="hidden" name="features[]" value="' + text + '" data-id="' + listItemCounter + '" />').insertAfter('ul.featureList');
    };
});
$('ul').on('click','button', function(el){
        $('input[data-id="' + $(this).attr('data-id') + '"]').remove(); //remove the hidden field so it does not get POSTed when user saves
    $(this).parent().remove();
});

Now, in your block's controller.php file, you will want to add a save() method that will take all of the data from those hidden fields, combine them and put them into the "features" field that you declared in your db.xml file: 现在,在块的controller.php文件中,您将想要添加一个save()方法,该方法将从这些隐藏字段中获取所有数据,将它们组合在一起,并将它们放入您在数据库中声明的“功能”字段中。 xml文件:

public function save($args) {
    $args['features'] = implode("\n", $args['features']); //combine all feature items into one string, separated by "newline" characters
    parent::save($args);
}

Finally, in your view.php file, you can convert the list of features (which was saved to the database as one string, with each item separated by a "newline" character) like so: 最后,在您的view.php文件中,可以转换功能列表(将其作为一个字符串保存到数据库中,每个项目之间用“换行符”分隔),如下所示:

<?php echo nl2br($features); ?>

Or if you want to output it as separate list items, you could do something like this: 或者,如果您要将其输出为单独的列表项,则可以执行以下操作:

<ul>
<?php
$features = explode("\n", $features);
foreach ($features as $feature) {
    echo '<li>' . $feature . '</li>';
}
?>
</ul>

You dont pass stuff from the view to the controller. 您不会将内容从视图传递到控制器。 The controller is executed BEFORE the view, so you only pass from controller to view. 控制器是在视图之前执行的,因此您只能从控制器传递到视图。

Try accessing the stuff you pass from jquery to your application using 尝试使用以下方法访问从jquery传递到应用程序的内容

$this->getRequest()->getParam('yourParametersName');

inside the controller. 在控制器内部。

Lucian 卢西恩

I changed around the auto.js file so it is as follows. 我更改了auto.js文件,如下所示。 Seems to work fine. 似乎工作正常。

var listItemCounter = 0;
$("#addList").click(function() {
    listItemCounter++;
    var text = $("#inputList").val(); //assign a unique id number to this button, so it knows which hidden field to remove when clicked
    var buttonDataId = text + '<button data-id="' + listItemCounter + '">x</button>';
    if(text.length){
        $('<li />', {html: buttonDataId}).appendTo('ul.featureList');
        $('<input type="hidden" name="features[]" value="' + text + '" data-id="' + listItemCounter + '" />').insertAfter('ul.featureList');
        };
});
$('ul').on('click','button', function(el){
    $('input[data-id="' + $(this).attr('data-id') + '"]').remove();//remove the hidden field so it does not get POSTed when user saves
    $(this).parent().remove()
});

I left the view the same as what Jordan Lev put. 我的观点与乔丹·列夫(Jordan Lev)一样。 (Thanks!) Then I changed the controller.php to (谢谢!)然后我将controller.php更改为

public function save($args) { $args['features'] = implode("\\n", $args['features']);//combine all feature items into one string, separated by "newline" characters parent::save($args); }

If anyone sees any problems or a better way to put my code please let me know! 如果有人发现任何问题或更好的方式放置我的代码,请告诉我! My new problem now is once it is saved, if I go to edit the list, it wipes out my past entries and saves the new one. 我的新问题是保存后,如果我去编辑列表,它将清除我以前的条目并保存新的条目。 If anyone knows the function I would have to write to show the current list and add to it when editing that would be great. 如果有人知道该功能,那么我将不得不编写该程序以显示当前列表,并在编辑时将其添加到列表中。 Please give some example code. 请提供一些示例代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM