Note that there are some explanatory texts on larger screens.

plurals
  1. POYii CJuiAutoComplete for Multiple values
    primarykey
    data
    text
    <p>I am a Yii Beginner and I am currently working on a Tagging system where I have 3 tables:</p> <ul> <li><p>Issue (id,content,create_d,...etc)</p></li> <li><p>Tag (id,tag)</p></li> <li><p>Issue_tag_map (id,tag_id_fk,issue_id_fk)</p></li> </ul> <p>In my <code>/Views/Issue/_form</code> I have added a <a href="http://www.yiiframework.com/extension/multicomplete/" rel="nofollow">MultiComplete</a> Extension to retrieve multiple tag ids and labels,</p> <p>I have used an <code>afterSave</code> function in order to directly store the <code>Issue_id</code> and the autocompleted <code>Tag_id</code>s in the <code>Issue_tag_map</code> table, where it is a <code>HAS_MANY</code> relation.</p> <p>Unfortunately Nothing is being returned.</p> <p>I wondered if there might be a way to store the autocompleted Tag_ids in a temporary attribute and then pass it to the model's <code>afterSave(</code>) function.</p> <p>I have been searching for a while, and this has been driving me crazy because I feel I have missed a very simple step! </p> <p>Any Help or advices of any kind are deeply appreciated!</p> <p><em>MultiComplete in <code>Views/Issue/_form</code></em>:</p> <pre><code> &lt;?php echo $form-&gt;labelEx($model, 'Tag'); $this-&gt;widget('application.extension.MultiComplete', array( 'model' =&gt; $model, 'attribute' =&gt; '', //Was thinking of creating a temporary here 'name' =&gt; 'tag_autocomplete', 'splitter' =&gt; ',', 'sourceUrl' =&gt; $this-&gt;createUrl('Issue/tagAutoComplete'), // Controller/Action path for action we created in step 4. // additional javascript options for the autocomplete plugin 'options' =&gt; array( 'minLength' =&gt; '2', ), 'htmlOptions' =&gt; array( 'style' =&gt; 'height:20px;', ), )); echo $form-&gt;error($model, 'issue_comment_id_fk'); ?&gt; </code></pre> <p><em>AfterSave in <code>/model/Issue</code></em>:</p> <pre><code> protected function afterSave() { parent::afterSave(); $issue_id = Yii::app()-&gt;db-&gt;getLastInsertID(); $tag; //here I would explode the attribute retrieved by the view form // an SQL with two placeholders ":issue_id" and ":tag_id" if (is_array($tag)) foreach ($tag as $tag_id) { $sql = "INSERT INTO issue_tag_map (issue_id_fk, tag_id_fk)VALUES(:issue_id,:tag_id)"; $command = Yii::app()-&gt;db-&gt;createCommand($sql); // replace the placeholder ":issue_id" with the actual issue value $command-&gt;bindValue(":issue_id", $issue_id, PDO::PARAM_STR); // replace the placeholder ":tag_id" with the actual tag_id value $command-&gt;bindValue(":tag_id", $tag_id, PDO::PARAM_STR); $command-&gt;execute(); } } </code></pre> <p>And this is the Auto Complete sourceUrl in the Issue model for populating the tags:</p> <pre><code> public static function tagAutoComplete($name = '') { $sql = 'SELECT id ,tag AS label FROM tag WHERE tag LIKE :tag'; $name = $name . '%'; return Yii::app()-&gt;db-&gt;createCommand($sql)-&gt;queryAll(true, array(':tag' =&gt; $name)); </code></pre> <p>actionTagAutoComplete in /controllers/IssueController:</p> <pre><code>// This function will echo a JSON object // of this format: // [{id:id, name: 'name'}] function actionTagAutocomplete() { $term = trim($_GET['term']); if ($term != '') { $tags = issue::tagAutoComplete($term); echo CJSON::encode($tags); Yii::app()-&gt;end(); } } </code></pre> <p><strong>EDIT</strong></p> <p>Widget in form:</p> <pre><code> &lt;div class="row" id="checks" &gt; &lt;?php echo $form-&gt;labelEx($model, 'company',array('title'=&gt;'File Company Distrubution; Companies can be edited by Admins')); ?&gt; &lt;?php $this-&gt;widget('application.extension.MultiComplete', array( 'model' =&gt; $model, 'attribute' =&gt; 'company', 'splitter' =&gt; ',', 'name' =&gt; 'company_autocomplete', 'sourceUrl' =&gt; $this-&gt;createUrl('becomEn/CompanyAutocomplete'), 'options' =&gt; array( 'minLength' =&gt; '1', ), 'htmlOptions' =&gt; array( 'style' =&gt; 'height:20px;', 'size' =&gt; '45', ), )); echo $form-&gt;error($model, 'company'); ?&gt; &lt;/div&gt; </code></pre> <p>Update function:</p> <pre><code> $model = $this-&gt;loadModel($id); ..... if (isset($_POST['News'])) { $model-&gt;attributes = $_POST['News']; $model-&gt;companies = $this-&gt;getRecordsFromAutocompleteString($_POST['News'] ['company']); ...... ...... getRecordsFromAutocompleteString(): public static cordsFromAutocompleteString($string) { $string = trim($string); $stringArray = explode(", ", $string); $stringArray[count($stringArray) - 1] = str_replace(",", "", $stringArray[count($stringArray) - 1]); $criteria = new CDbCriteria(); $criteria-&gt;select = 'id'; $criteria-&gt;condition = 'company =:company'; $companies = array(); foreach ($stringArray as $company) { $criteria-&gt;params = array(':company' =&gt; $company); $companies[] = Company::model()-&gt;find($criteria); } return $companies; } </code></pre> <p><strong>UPDATE</strong> since the "value" porperty is not implemented properly in this extension I referred to extending this function to the model:</p> <pre><code> public function afterFind() { //tag is the attribute used in form $this-&gt;tag = $this-&gt;getAllTagNames(); parent::afterFind(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload