Создание настраиваемого типа поля формы, расширенного из стандартного поля тега

Я пытаюсь создать собственный тип поля формы для моего компонента. Функционально он должен работать так же, как и тип поля стандартной формы тега, за исключением того, что я хочу хранить теги в моей собственной таблице базы данных (вместо таблицы по умолчанию #__tags, используемой Joomla), и я хочу, чтобы все введенные теги были уникальными, поэтому в базе данных нет дубликатов.

Я начал с создания нового класса, который расширяет JFormFieldTag, но не совсем уверен, как исходить оттуда.

Любая помощь или руководство будут оценены.

1 голос | спросил jptech0313 27 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowWed, 27 Sep 2017 23:27:35 +0300 2017, 23:27:35

1 ответ


1

Я нашел, что самый простой способ сделать это - вообще не использовать поле формы тега. Я знаю, что это звучит безумно, но если вы хотите хранить теги и ассоциации тегов в своей собственной таблице базы данных, проще перейти на другой маршрут.

Лучший способ - использовать поле формы SQL, которое допускает множественные значения. Вы установите SQL для вывода из таблицы базы данных, содержащей теги. Затем в вашем методе getItem () вы получите идентификаторы тегов, связанных с вашей записью, и сохраните их как массив в соответствующем свойстве для вашего объекта (например, теги $ item->).

Затем, в шаблоне вашего представления, используйте некоторый JavaScirpt, украденный из /layouts/joomla/html/tag.php, чтобы заставить поле вести себя как поле тегов. Есть пара переменных для замены (селектор и minTermLength), но вы должны найти это довольно простым. Вот код:

jQuery(document).ready(function ($) {

        var customTagPrefix = '#new#';

        // Method to add tags pressing enter
        $('" . $selector . "_chzn input').keyup(function(event) {

            // Tag is greater than the minimum required chars and enter pressed
            if (this.value && this.value.length >= " . $minTermLength . " && (event.which === 13 || event.which === 188)) {

                // Search a highlighted result
                var highlighted = $('" . $selector . "_chzn').find('li.active-result.highlighted').first();

                // Add the highlighted option
                if (event.which === 13 && highlighted.text() !== '')
                {
                    // Extra check. If we have added a custom tag with this text remove it
                    var customOptionValue = customTagPrefix + highlighted.text();
                    $('" . $selector . " option').filter(function () { return $(this).val() == customOptionValue; }).remove();

                    // Select the highlighted result
                    var tagOption = $('" . $selector . " option').filter(function () { return $(this).html() == highlighted.text(); });
                    tagOption.attr('selected', 'selected');
                }
                // Add the custom tag option
                else
                {
                    var customTag = this.value;

                    // Extra check. Search if the custom tag already exists (typed faster than AJAX ready)
                    var tagOption = $('" . $selector . " option').filter(function () { return $(this).html() == customTag; });
                    if (tagOption.text() !== '')
                    {
                        tagOption.attr('selected', 'selected');
                    }
                    else
                    {
                        var option = $('<option>');
                        option.text(this.value).val(customTagPrefix + this.value);
                        option.attr('selected','selected');

                        // Append the option and repopulate the chosen field
                        $('" . $selector . "').append(option);
                    }
                }

                this.value = '';
                $('" . $selector . "').trigger('liszt:updated');
                event.preventDefault();

            }
        });
    });

Наконец, вернитесь к своей модели и измените метод save () для обработки входов тегов и сохранения данных в вашей базе данных. Что-то вроде этого прекрасно работает:

if(isset($data['tags'])){
    // store the data locally
    $tags = $data['tags'];

    // remove the data from the array
    unset($data['tags']);

    // check whether the provided tag is new or old
    $tagIds = array();
    $newtags = array();
    foreach($tags as $tag){
        if(strpos($tag, '#') !== false){
            // this is a new tag
            $newtags[] = str_replace('#new#', '', strtolower($tag));
        }else{
            // this is an existing tag
            $tagIds[] = (int)$tag;
        }
    }

    // handle any new tags
    if($newtags){

        // create the new tag records
        $query = $db->getQuery(true);
        $query->insert($db->quoteName('#__my_component_tags'));
        $query->columns($db->quoteName('tag'));
        foreach($newtags as $tag){
            $query->values($db->quote($tag));
        }
        $db->setQuery($query);
        if($db->execute()){

            // get the IDs of these tags
            $query = $db->getQuery(true);
            $query->select($db->quoteName('id'));
            $query->from($db->quoteName('#__my_component_tags'));
            $query->where($db->quoteName('tag') . ' IN(' . join(',', $db->quote($newtags)) . ')');
            $db->setQuery($query);
            if($newtagIds = $db->loadColumn()){

                // combine the new IDs with the existing ones
                $tagIds = array_merge($tagIds, $newtagIds);
            }else{
                $this->setError('Unable to retrieve IDs of newly created tags');
                return false;
            }                       
        }else{
            $this->setError('Unable to create new tags');
            return false;
        }
    }

    // associate this item with all of its selected tags, ignoring duplicates and removing 
    if($tagIds){

        // craft the SQL value strings
        $values = array();
        foreach($tagIds as $tagId){
            $values[] = '(' . (int)$tagId . ',' . (int)$table->id . ')';
        }

        // build and set the query
        $db->setQuery('INSERT INTO ' . $db->quoteName('#__my_component_tag_map') . ' (' . $db->quoteName('tag') . ',' . $db->quoteName('my_record') . ') VALUES ' . join(',', $values) . ' ON DUPLICATE KEY UPDATE ' . $db->quoteName('my_record') . ' = ' . $db->quoteName('my_record') . ';');
        if(!$db->execute()){
            $this->setError('Unable to associate tags to landing page');
            return false;
        }

        // remove all tags that are no longer associated with this record
        $query = $db->getQuery(true);
        $query->delete($db->quoteName('#__my_component_tag_map'));
        $query->where($db->quoteName('tag') . ' NOT IN(' . join(',', $tagIds) . ')');
        $query->where($db->quoteName('my_record') . '=' . (int)$table->id);
        $db->setQuery($query);
        if(!$db->execute()){
            $this->setError('Unable to remove old tag associations');
            return false;
        }
    }else{
        // remove all tags
        $query = $db->getQuery(true);
        $query->delete($db->quoteName('#__my_component_tag_map'));
        $query->where($db->quoteName('my_record') . '=' . (int)$table->id);
        $db->setQuery($query);
        if(!$db->execute()){
            $this->setError('Unable to remove all old tag associations');
            return false;
        }
    }

    // delete any tags that no longer have an association
    $db->setQuery('DELETE FROM ' . $db->quoteName('#__my_component_tags') . ' WHERE ' . $db->quoteName('id') . ' NOT IN(SELECT DISTINCT ' . $db->quoteName('tag') . ' FROM ' . $db->quoteName('#__my_component_tag_map') . ');');
    if(!$db->execute()){
        $this->setError('Unable to remove unassociated tags');
        return false;
    }
}else{
    // delete any paths that no longer have an association
    $db->setQuery('DELETE FROM ' . $db->quoteName('#__my_component_tags') . ' WHERE ' . $db->quoteName('id') . ';');
    if(!$db->execute()){
        $this->setError('Unable to remove unassociated tags');
        return false;
    }
}

Надеюсь, это поможет.

ответил Zachary Draper 27 12017vEurope/Moscow11bEurope/MoscowMon, 27 Nov 2017 21:17:31 +0300 2017, 21:17:31

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132