it-swarm.com.de

Erstellen eines benutzerdefinierten Formularfeldtyps, erweitert um ein Standard-Tag-Feld

Ich versuche, einen benutzerdefinierten Formularfeldtyp für meine Komponente zu erstellen. Funktionell sollte es genauso funktionieren wie der Standardtyp für Tag-Formularfelder, außer dass ich die Tags in meiner eigenen Datenbanktabelle speichern möchte (anstatt der von Joomla verwendeten Standardtabelle #__tags) und alle eingegebenen Tags zwingen möchte, dort eindeutig zu sein sind keine Duplikate in der Datenbank.

Ich habe zunächst eine neue Klasse erstellt, die JFormFieldTag erweitert, bin mir aber nicht sicher, wie ich von dort aus vorgehen soll.

Jede Hilfe oder Anleitung wäre dankbar.

1
jptech0313

Ich habe herausgefunden, dass es am einfachsten ist, das Tag-Formular-Feld überhaupt nicht zu verwenden. Ich weiß, das hört sich verrückt an, aber wenn Sie die Tags und Tag-Zuordnungen in Ihrer eigenen Datenbanktabelle speichern möchten, ist es einfacher, einen anderen Weg zu gehen.

Am besten verwenden Sie ein SQL-Formularfeld, das Mehrfachnennungen zulässt. Sie werden die SQL so einstellen, dass sie aus Ihrer Datenbanktabelle mit den Tags abruft. Rufen Sie dann in der getItem () -Methode Ihres Modells die IDs der Tags ab, die Ihrem Datensatz zugeordnet sind, und speichern Sie sie als Array in der entsprechenden Eigenschaft für Ihr Objekt (z. B. $ item-> tags).

Verwenden Sie als Nächstes in der Vorlage Ihrer Ansicht JavaScirpt, das aus /layouts/joomla/html/tag.php gestohlen wurde, damit sich das Feld wie das Feld tags verhält. Es gibt ein paar Variablen zu ersetzen (Selektor und minTermLength), aber Sie sollten das ziemlich einfach finden. Hier ist der Code:

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

            }
        });
    });

Kehren Sie schließlich zu Ihrem Modell zurück und ändern Sie die save () -Methode, um die Tag-Eingaben zu verarbeiten und die Daten in Ihrer Datenbank zu speichern. So etwas funktioniert gut:

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

Ich hoffe das hilft.

1
Zachary Draper