在Concrete5中,我如何更新块编辑视图以显示保存在数据库中的当前值


In Concrete5 how do I update my block edit view to show the current values saved in the database?

我有一段代码可以动态创建一个产品功能列表,并将所有值放在一个由换行符分隔的字符串中,然后保存到数据库中。当这个字符串被传递到视图时,我会以无序列表的形式输出。当我编辑块时,它不会显示列表中已经存在的内容,所以每次需要编辑块时我都必须重新键入所有功能,即使它不是功能列表(我有一些标题和其他文本区域)。如果我把php变量放进我的编辑页面,它会显示我保存了什么,但我需要它立即添加到列表中,而不是单独显示。我基本上需要它来"自动追加到"我的<ul>。这是我的密码。。。

controller函数将列表保存在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);
    }

我的edit.php-这将在列表中显示它。如果我只放echo $features,它就会输出字符串。

echo '<div class="ccm-block-field-group">';
echo '<h2>' . t('Features') . '</h2>';
echo '<input type="text" id="inputList" />';
echo '<button type="button" id="addList">Add</button>';
echo $features = explode("'n", $features);
        foreach ($features as $feature) {
            echo '<li class="currentFeatures">' . $feature . '</li>';
        };
echo '<ul class="featureList">';
echo '</ul>';
echo '</div>';

myauto.js-处理列表的创建

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()
    });

最后是我的db.xml 的一部分

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

你会想做一些类似于我在另一个问题中为"视图"解释的事情(https://stackoverflow.com/a/14968046/477513)。

您想将列表从字符串更改为数组(通过explode("'n", $features)),然后在这些特性上运行javascript。由于这基本上与当有人通过文本框添加新项目时所做的javascript相同,因此您需要将所有代码移动到一个函数中,并在这两种情况下调用该函数(否则,您将复制和粘贴相同的代码,这违反了"不要重复自己"规则,并不可避免地在未来导致错误)。所以你的auto.js代码可能看起来像这样:

var listItemCounter = 0;
function addItem(text) {
    if (text.length) {
        listItemCounter++;
        var itemHtml = '<li data-id="' + listItemCounter + '">'
                     + text
                     + '<button data-id="' + listItemCounter + '">x</button>'
                     + '</li>';
        var inputHtml = '<input type="hidden" name="features[]" value="' + text + '" data-id="' + listItemCounter + '" />';
        $('ul.featureList').append(itemHtml);
        $('ul.featureList').after(inputHtml);
    }
}
function removeItem(id) {
    $('input[data-id="' + id + '"]').remove();
    $('li[data-id="' + id + '"]').remove();
}
$("#addList").click(function() {
    additem($("#inputList").val());
});
$('ul').on('click','button', function(el) {
    var id = $(this).attr('data-id');
    removeItem(id);
});

然后在您的edit.php文件中,添加此代码以输出保存的数据,并在每个文件上调用addItem函数:

<?php
//populate existing data when edit dialog is first opened
$featuresPHPArray = explode("'n", $features);
$featuresJSArray = Loader::helper('json')->encode($featuresPHPArray);
?>
<script>
var savedItems = <?php echo $featuresJSArray; ?>;
$.each(savedItems, function() {
    addItem(this);
});
</script>