Schlagwörter Speichern

Hallo,

ich möchte Schlagwörter zu einem Datensatz hinzufügen. Da ich nicht sicher bin, wie man das am besten macht, erlaube ich mir, hier zu fragen. Ich möchte nicht (wie schon öfter) etwas machen, das sich im Nachhinein als schlecht geeignet herausstellt.

Methode 1:

Ich erzeuce ein Feld in der Tabelle Noten, z.B. Schlagwoerter, in welchem der Benutzer die Schlagwörter - eventuell durch Beistriche getrennt, eingeben kann. Um die Schreibarbeit zu erleichtern, könnte eine Auswahlliste mit Schlagwörtern dienen. Die Auswahlliste wird durch eine Tabelle Schlagwoerter befüllt. Per JavaScript bzw. JQuery müsste dann das ausgewählte Schlagwort in das Input Feld eingefügt (bzw. hinzugefügt) werden.

Das Suchen nach einem bestimmten Schlagwort in der GridView ist einfach.

Nachteil: Viele redundante Einträge.

Methode 2:

Das ganze irgendwie mit Beziehungen lösen - aber da blicke ich nicht ganz durch, glaube ich.

Ich brauche da wohl eine Hilfstabelle mit Noten_Id und Schlagwort_Id als Fremdschlüssel, die auf den jeweiligen Primärschlüssel in der Tabelle Noten und Schlagwoerter verweisen. Ich nenne diese Verbindungstabelle tbl_noten_schlagw.

Dann muss ich eine MANY_MANY Relation definieren - im Model Noten, denke ich:


public function relations()

    {

        return array(

            'schlagwoerter'=>array(self::MANY_MANY, 'Schlagwoerter', 

                    'tbl_noten_schlagw(Noten_Id, Schlagw_Id)'),

        );

    }

}

Bin ich da auf dem richtigen Weg oder schießt man da mit Kanonen auf Spatzen?

Und dann wäre ja noch das Problem, dass man in einer Grid_View, die auf der Notentabelle beruht, nach Schlagwörtern suchen sollte können.

Bitte um Nachsicht für die Anfängerfragen.

Definitiv Methode 2 für das vorgestellte Szenario. Um dann in GridView die Schlagwortsuche zu realisieren zB hier mal schauen Related search in GridView

Für die Eingabe der Schlagwörter eignet sich Select2Row sehr gut.

Damit ist sowohl eine manuelle Eingabe inkl. Autocomplete möglich als auch eine Auswahl per Dropdownliste.

Im folgenden Beispiel können einer Adresse z.B. mehrere Gruppen/Kategorien zugewiesen werden, die mit Trennzeichen (tokenSeparators) eingeben werden können:


$arrCat= Addresscategory::model()->findColumn('kurzbez');

Sort( $arrCat);

echo $form->select2Row($model, 'gruppe',

    array('asDropDownList'=> false,

        'options'=> array(

            'tags'=> $arrCat,

            'placeholder'=> 'bitte wählen...',

            'width'=> '40%',

            'tokenSeparators'=> array(';', ',', ' ')  

        )

    )

);

Die Spalte im Grid ist wie folgt definiert:


                array(

                    'header'=> 'Gruppe',

                    'name'=> 'gruppe_such_id',

                    'value'=> '$data->gruppe',

                    'filter'=> CHtml::listData( Addresscategory::model()->DropdownListing(), 'id', 'name', 'group')

                )



Im Model muss bei Search dann entsprechend gefiltert werden:


            $gid= $this->gruppe_such_id;

            if ( $gid <> null) {

                $criteria->addCondition( 't.id IN (SELECT id FROM tbl_addresscategory_assignment ass '.

                                         'WHERE ass.address_id= t.id AND ass.addresscategory_id= :gruppenid)' );

                $criteria->params[':gruppenid']= $gid;

            }

Select2Row ist das eine Yii Erweiterung?

Sehe ich das richtig: Das Beispiel passt zu Methode 1 - wie in meinem Posting beschrieben.

Gruß

Ferdinand

Select2 ist eine Erweiterung, die in Yii Booster enthalten ist:

http://yiibooster.clevertech.biz/widgets/forms_inputs/view/select2.html

Mein Codeauszug bezieht sich auf ActiveForm:

http://yiibooster.clevertech.biz/widgets/forms/view/activeform.html

Es gibt aber auch eine spezielle eigenständige Extension:

http://www.yiiframework.com/extension/select2/

In meinem Beispiel entspricht "Gruppen" deinen Schlagwörten.

Ich verwende das virtuelle Feld Gruppe. Im Model lese ich über getGruppe die zugeordneten Gruppen aus der Tabelle tbl_addresscategory_assignment und schreibe sie getrennt mit "," in einen String, der letztendlich bei $form->select2Row landet.


    public function getGruppe()

    {

        $groups= $this->addresscategories;


        $g= '';

        foreach ($groups as $group){

            $g= (($g=='') ? '': $g.','). $group->kurzbez;

        }

        return $g;

    }

Über setGruppe werden die Änderungen wieder gespeichert:


   public function setGruppe( $value)

    {

        $this->updateCategories( $this->_oldCategories, $value);

    }

Wenn du auf die Verbindungstabelle verzichtest und einfach ein String- oder Memofeld in der Notentabelle anlegst, in die die Schlagwörter direkt eingetragen werden, dann sollte das wie mit "echo $form->select2Row…" beschrieben schon ausreichen.

Danke für den Versuch, mir zu helfen.

Ich habe mir nun die Yii-Extension ESelect2 heruntergeladen.

Im Formular habe ich nach längerem Probieren die Anzeige einer Schlagwortliste aus der Tabelle Schlagwoerter geschafft.

Wie aber kommt durch Klick auf einen Listeneintrag das Schlagwort in mein InputFeld Anmerkung:


        

<?php echo $form->labelEx($model,'Anmerkung'); ?>

<?php echo $form->textField($model,'Anmerkung',array('size'=>40,'maxlength'=>74)); ?>

<?php echo $form->error($model,'Anmerkung'); ?> <?php

$Schlagwoerter = CHtml::listData(Schlagwoerter::model()->findAll(), 'Id', 'Schlagwort');

$this->widget('ext.select2.ESelect2', array(

      'model'=>$model,

      'attribute'=>'Anmerkung',

      'data'=>$Schlagwoerter,

)); ?>



Ich verstehe die Bedeutung des Schlüssels attribute im config Array des Widgets nicht. Ich habe angenommen, mit dem Schlüssel attribute ist das Feld gemeint, in welches das gewählte Schlagwort eingetragen werden soll. :blink:

Tut mir leid, ich blicke einfach nicht durch.

Willst du das Feld wirklich zwei mal auf dem Bildschirm haben?

Verwende doch lieber hiddenField, damit nur das Select2 Widget sichbar ist.

Es muss dann im Widget eine Referenz auf das hiddenfield erfolgen:




  'selector'=>'#Anmerkung'



wodurch man sich ‘model’=>$model und ‘attribute’=>‘Anmerkung’ dann sparen kann, da die Speicherung ja über das hiddenfield erfolgt.

In den Kommentaren gibt es noch einige Beispiele:

http://www.yiiframework.com/extension/select2

Ich möchte, dass nach Auswahl eines Schlagwortes aus der DropDown Liste, das angeklickte Schlagwort im Input Feld Anmerkung an den vorhandenen String angehängt wird ev. durch Beistrich getrennt. Deswegen brauche ich dieses Texteingabefeld Anmerkung auf der Ansicht.

Ich habe die Beipiele angeschaut aber ich werde nicht klug daraus.

Bin sehr dankbar für jeden weiteren Tipp, da ich offenbar auf der Leitung stehe.

Folgendes ergibt ein Eingabefeld mit Tagging-Funktion:


echo $form->textField($model,'Anmerkung', array('size'=>40, 'maxlength'=>74, 'id'=>'test'));


echo CHtml::textField('Anmerkung', '', array('id'=>'test'));

$this->widget('ext.select2.ESelect2', array(

    'selector'=>'#test',

    'options' => array(

        'tags'=> array('Null', 'Eins', '2', '3')

    )

));

Eine Mehrfachauswahl ist möglich, die gewählten Tags werden als "String" in $model->Anmerkung gespeichert, z.B. "Null,Eins"


<?php echo $form->textField($model,'Anmerkung',array('size'=>40,'maxlength'=>74, 'id'=>'Anm')); ?>

$Schlagwoerter = CHtml::listData(Schlagwoerter::model()->findAll(), 'Schlagwort', 'Schlagwort');

        $this->widget('ext.select2.ESelect2', array(

            'model'=>$model,

            'attribute'=>'Anmerkung',

            'tags'=>$Schlagwoerter,

//          'selector'=>'#Anm'

Ich erhalte einen Error:


Eigenschaft "ESelect2.tags ist nicht definiert.

Wenn ich die Eigenschaft selector setze, wird die DropdownBox gleich gar nicht angezeigt :unsure:

Aber das aus der Liste ausgewählte Schlagwort wird in der Tabelle im Feld "Anmerkung" gespeichert, wenn ich die Formulardaten abschicke. Allerdings möchte ich ja gleich nach dem Klick sehen, dass das bzw. die Schlagwörter hinzugefügt worden sind …

Das muss ich wohl selber mit JQuery lösen, sehe ich das richtig?

Drei Gründe, warum es nicht läuft:

Tags ist ein Unterelement von ‘options’, siehe mein Code oben.

Attribute ist überflüssig.

Da CHtml::listData() kein einfaches Array liefert, besser folgendes verwenden:


$Schlagwoerter= Schlagwoerter::model()->findColumn('Schlagwort');

Ja, das hatte ich übersehen :blink:

Die Methode findColumn() scheint es nicht zu geben:


Weder Schlagwoerter noch zugehörige Behavior haben einen Scope "findColumn".

Stimmt, das gehört zu folgender Extension:

Ich habe das Problem jetzt mit Yii Bordmitteln und ein bisschen JQuery gelöst.

Durch Auswahl eines Schlagwortes aus der DropDownBox wird dieses sofort zum bereits vorhanden Inhalt des Feldes Anmerkungen hinzugefügt:

Der ganze Code befindet sich in


views/schlagwoerter/_form.php

:




<?php echo $form->labelEx($model,'Anmerkung'); ?>

<?php echo $form->textField($model,'Anmerkung',array('size'=>40,'maxlength'=>74)); ?>

<?php echo $form->error($model,'Anmerkung'); ?>


<label>Schlagwort zu Anmerkungen hinzufügen</label>

<?php $Schlagwoerter = CHtml::listData(Schlagwoerter::model()->findAll(), 'Id', 'Schlagwort');

echo CHTML::dropDownList('Schlagwoerter','0',$Schlagwoerter,array('title'=>'Ein Schlagwort aus der Liste wählen')); ?>

und weiter oben der JQuery Code:


Yii::app()->clientScript->registerScript('addSchlagwort',"

$('#Schlagwoerter').change(function() {

  var oldValue = $('#Noten_Anmerkung').val();

  var newValue = $(this).find(':selected').text();

  if ( oldValue ) var separator = ', ';

  else separator = '';

  $('#Noten_Anmerkung').val(oldValue + separator + newValue);

})",CClientScript::POS_READY);

Danke trotzdem herzlich für die Anregungen.