Как в Concrete5 обновить вид редактирования блока, чтобы отображались текущие значения, сохраненные в базе данных?

У меня есть код, который динамически создает список характеристик продукта и объединяет все значения в одну строку, разделенную символами новой строки, и сохраняется в базе данных. Когда эта строка передается в представление, я вывожу как неупорядоченный список. Когда я иду редактировать блок, он не показывает, что уже есть в списке, поэтому мне приходится заново вводить все функции каждый раз, когда мне нужно отредактировать свой блок, даже если это не список функций (у меня есть некоторые заголовки и другие текстовые области) . Если я помещу переменную php на свою страницу редактирования, она покажет мне, что было сохранено, но мне нужно, чтобы она была немедленно добавлена ​​в список и не отображалась отдельно. Мне в основном нужно, чтобы он «автоматически добавлял к моему <ul>. Вот мой код...

функция контроллера для сохранения списка в 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>';

мой auto.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>

person user2066695    schedule 21.02.2013    source источник


Ответы (1)


Вы захотите сделать что-то похожее на то, что я объяснил для «представления» в другом вопросе ( 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>
person Jordan Lev    schedule 21.02.2013
comment
это не работает. Я ничего не получаю. Должен ли я добавлять что-то новое в свой edit.php? Также можно ли поместить php-код в файл .js? Просто интересовался. - person user2066695; 22.02.2013
comment
Я очень ценю вашу помощь. Я дам вам знать, когда этот блок будет готов, и размещу его в сообществе C5 бесплатно. - person user2066695; 22.02.2013
comment
Кроме того, мне не нужен он как список, прежде чем он будет запущен через jQuery, только когда он выводится в список. Мне просто нужно получить значения (используя взрыв) и заполнить их как <li> в ul.feature List - person user2066695; 22.02.2013
comment
вы совершенно правы - не можете запустить php в файле js. Извините за это, я обновил свой ответ, чтобы отразить это - person Jordan Lev; 22.02.2013
comment
классно!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! он обновляет и помещает его в список функций !!!!!!!!!!!! Однако есть одна небольшая проблема... он не будет добавлять новые элементы в список, может быть, function addItem(text) имеет текст в качестве параметра, а #inputList получает значение? - person user2066695; 22.02.2013
comment
Вы спасаете мои волосы от выпадения! - person user2066695; 22.02.2013
comment
Функция addList .click не работает. Он даже не предупредит. - person user2066695; 22.02.2013
comment
Починил это!!!!!!!!!!!!!!!!!!!!! Внутри $("#addList").click(function(){}) у addItem($("#inputList").val()); была строчная буква i вместо прописной. - person user2066695; 22.02.2013
comment
рад, что вы исправили это! Как насчет того, чтобы принять мой ответ, чтобы я получил от этого небольшую репутацию? - person Jordan Lev; 23.02.2013