Search code examples
phpzend-frameworkconcrete5

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. I have a some jquery that creates an unordered list from a textbox in my view. If your familiar with Concrete5 this is the view for the block I am adding the list to. 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.

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

<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. 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

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

db.xml

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

Solution

  • I changed around the auto.js file so it is as follows. 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. (Thanks!) Then I changed the controller.php to

    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.