We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Phalcon form, How to set selected items on dynamic multiselect

Hi guys,

I have a form for a blog article, it contains related categories, I have a categories multi select, and I got the save working, but I can't figure out how to define the selected items, I'm binding the entity to the form.

See my code below:

Action:

public function editAction()
{
    $id = (int) $this->dispatcher->getParam(0);

    if (is_numeric($id) && $id != 0) {
        $article = Blog::findFirstById($id);

        $form = new BlogArticleForm($article, [
            'edit' => true,
        ]);

        $this->view->setVar('form', $form);
    } else {
        throw new Exception('Invalid ID');
    }
}

Models:

<?php

namespace Common\NewInToday\Models;

use Phalcon\Mvc\Model;

/**
 * Class Blog
 * @package Common\NewInToday\Models
 * @author Andre Figueira <[email protected]>
 */
class Blog extends Model
{
    /**
     * @var int
     */
    protected $id;

    /**
     * @var int
     */
    protected $authorId;

    /**
     * @var string
     */
    protected $status;

    /**
     * @var string
     */
    protected $title;

    /**
     * @var string
     */
    protected $permalink;

    /**
     * @var string
     */
    protected $excerpt;

    /**
     * @var string
     */
    protected $content;

    /**
     * @var string
     */
    protected $metaTitle;

    /**
     * @var string
     */
    protected $metaKeywords;

    /**
     * @var string
     */
    protected $metaDescription;

    /**
     * @var string
     */
    protected $keywords;

    /**
     * @var string
     */
    protected $date;

    const STATUS_PUBLISHED = 'published';

    const STATUS_DRAFT = 'draft';

    /**
     * Map the table columns to camelCase.
     *
     * @return array
     */
    public function columnMap()
    {
        return [
            'id' => 'id',
            'author_id' => 'authorId',
            'status' => 'status',
            'title' => 'title',
            'permalink' => 'permalink',
            'excerpt' => 'excerpt',
            'content' => 'content',
            'meta_title' => 'metaTitle',
            'meta_keywords' => 'metaKeywords',
            'meta_description' => 'metaDescription',
            'keywords' => 'keywords',
            'date' => 'date',
        ];
    }

    public function initialize()
    {
        $this->hasOne(
            'authorId',
            'Common\NewInToday\Models\Users',
            'id',
            [
                'alias' => 'author'
            ]
        );

        $this->hasManyToMany(
            'id',
            'Common\NewInToday\Models\BlogCategoriesCategories',
            'blogId',
            'blogCategoriesId',
            'Common\NewInToday\Models\BlogCategories',
            'id',
            [
                'alias' => 'categories[]',
            ]
        );
    }

    /**
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param int $id
     * @return $this
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * @return int
     */
    public function getAuthorId()
    {
        return $this->authorId;
    }

    /**
     * @param int $authorId
     * @return $this
     */
    public function setAuthorId($authorId)
    {
        $this->authorId = $authorId;

        return $this;
    }

    /**
     * @return string
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * @param string $status
     * @return $this
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    /**
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * @param string $title
     * @return $this
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

    /**
     * @return string
     */
    public function getPermalink()
    {
        return $this->permalink;
    }

    /**
     * @param string $permalink
     * @return $this
     */
    public function setPermalink($permalink)
    {
        $this->permalink = $permalink;

        return $this;
    }

    /**
     * @return string
     */
    public function getExcerpt()
    {
        return $this->excerpt;
    }

    /**
     * @param string $excerpt
     * @return $this
     */
    public function setExcerpt($excerpt)
    {
        $this->excerpt = $excerpt;

        return $this;
    }

    /**
     * @return string
     */
    public function getContent()
    {
        return $this->content;
    }

    /**
     * @param string $content
     * @return $this
     */
    public function setContent($content)
    {
        $this->content = $content;

        return $this;
    }

    /**
     * @return string
     */
    public function getMetaTitle()
    {
        return $this->metaTitle;
    }

    /**
     * @param string $metaTitle
     * @return $this
     */
    public function setMetaTitle($metaTitle)
    {
        $this->metaTitle = $metaTitle;

        return $this;
    }

    /**
     * @return string
     */
    public function getMetaKeywords()
    {
        return $this->metaKeywords;
    }

    /**
     * @param string $metaKeywords
     * @return $this
     */
    public function setMetaKeywords($metaKeywords)
    {
        $this->metaKeywords = $metaKeywords;

        return $this;
    }

    /**
     * @return string
     */
    public function getMetaDescription()
    {
        return $this->metaDescription;
    }

    /**
     * @param string $metaDescription
     * @return $this
     */
    public function setMetaDescription($metaDescription)
    {
        $this->metaDescription = $metaDescription;

        return $this;
    }

    /**
     * @return string
     */
    public function getKeywords()
    {
        return $this->keywords;
    }

    /**
     * @param string $keywords
     * @return $this
     */
    public function setKeywords($keywords)
    {
        $this->keywords = $keywords;

        return $this;
    }

    /**
     * @return string
     */
    public function getDate()
    {
        return $this->date;
    }

    /**
     * @param string $date
     * @return $this
     */
    public function setDate($date)
    {
        $this->date = $date;

        return $this;
    }

    public function beforeSave()
    {
        if ($this->getDate() === null) {
            $this->setDate(date('Y-m-d H:i:s'));
        }
    }
}

View

<form role="form" action="dashboard/blog/save" method="post" id="edit-article-form">
<div class="row">
    <div class="col-md-9">
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">Edit Article <strong>{{ form.get('title').getValue() }}</strong></h3>
            </div><!-- /.box-header -->
            <!-- form start -->
            <div class="box-body">
                {{ form.render('id') }}
                {{ form.render('author-id') }}
                {{ form.renderDecorated('title') }}
                {{ form.renderDecorated('permalink') }}
                {{ form.renderDecorated('excerpt') }}
                {{ form.renderDecorated('content') }}
            </div><!-- End box body -->
        </div><!-- End box -->

        <div class="box box-primary collapsed-box">
            <div class="box-header with-border">
                <h3 class="box-title">Meta tags</h3>
                <div class="box-tools pull-right">
                    <button class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i></button>
                </div>
            </div><!-- /.box-header -->
            <!-- form start -->
            <div class="box-body" style="display: none">
                {{ form.renderDecorated('meta-title') }}
                {{ form.renderDecorated('meta-keywords') }}
                {{ form.renderDecorated('meta-description') }}
            </div><!-- /.box-body -->
        </div><!-- End box -->
    </div><!-- End col -->
    <div class="col-md-3">
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">Meta</h3>
            </div><!-- /.box-header -->
            <!-- form start -->
            <div class="box-body">
                {{ form.renderDecorated('status') }}
                {{ form.renderDecorated('categories[]') }}
                {{ form.renderDecorated('keywords') }}
            </div><!-- /.box-body -->

            <div class="box-footer">
                <button type="submit" class="btn btn-success">Save changes</button>
            </div>
        </div><!-- End box -->
    </div><!-- End col -->
</div><!-- End row -->

</form>

Form

<?php

namespace Guru\Dashboard\Forms;

use Common\NewInToday\Models\BlogCategories; use Phalcon\Forms\Element\Hidden; use Phalcon\Forms\Element\Select; use Phalcon\Forms\Element\Text; use Phalcon\Forms\Element\TextArea; use Phalcon\Validation\Validator\PresenceOf;

/**

  • Class BlogArticleForm
  • @package Guru\Dashboard\Forms
  • @author Andre Figueira [email protected] */ class BlogArticleForm extends BootstrapForm { public function initialize($entity = null, $options = null) { if (isset($options['edit']) && $options['edit']) { $id = new Hidden('id'); } else { $id = new Text('id'); }

      $authorId = new Hidden('author-id', [
          'value' => $this->session->get('auth')->id,
      ]);
    
      $title = new Text('title', [
          'id' => 'title',
          'placeholder' => 'Enter article title',
          'class' => 'form-control slugify',
          'autocomplete' => 'off',
          'data-slugger' => '.permalink-slug',
      ]);
    
      $title->setLabel('Title');
    
      $title->addValidators([
          new PresenceOf([
              'message' => 'Please enter a title for your article',
          ])
      ]);
    
      $permalink = new Text('permalink', [
          'id' => 'permalink',
          'placeholder' => 'Enter an article permalink',
          'class' => 'form-control permalink-slug',
          'autocomplete' => 'off',
      ]);
    
      $permalink->setLabel('Permalink');
    
      $title->addValidators([
          new PresenceOf([
              'message' => 'Please enter a permalink for your article',
          ])
      ]);
    
      $excerpt = new TextArea('excerpt', [
          'id' => 'excerpt',
          'placeholder' => 'Enter a short article description',
          'class' => 'form-control',
      ]);
    
      $excerpt->setLabel('Excerpt');
    
      $content = new TextArea('content', [
          'id' => 'content',
          'class' => 'summernote',
      ]);
    
      $content->setLabel('Content');
    
      $metaTitle = new Text('meta-title', [
          'id' => 'meta-title',
          'placeholder' => 'Enter a page title',
          'class' => 'form-control',
          'autocomplete' => 'off',
      ]);
    
      $metaTitle->setLabel('Meta title');
    
      $metaKeywords = new Text('meta-keywords', [
          'id' => 'meta-keywords',
          'placeholder' => 'Enter a page keywords',
          'class' => 'form-control',
          'autocomplete' => 'off',
      ]);
    
      $metaKeywords->setLabel('Meta keywords');
    
      $metaDescription = new Text('meta-description', [
          'id' => 'meta-description',
          'placeholder' => 'Enter a page description',
          'class' => 'form-control',
          'autocomplete' => 'off',
      ]);
    
      $metaDescription->setLabel('Meta description');
    
      $categories = new Select(
          'categories[]',
          BlogCategories::find('parentId = 0'),
          [
              'class' => 'multi-selectize',
              'using' => [
                  'id',
                  'name',
              ],
              'useEmpty' => true,
              'emptyText' => 'Select categories...',
              'multiple' => 'multiple',
          ]
      );
    
      $categories->setLabel('Categories');
    
      $status = new Select('status', [
          'published' => 'Published',
          'draft' => 'Draft',
      ]);
    
      $status
          ->setLabel('Status')
          ->setAttributes([
              'id ' => 'status',
              'class' => 'selectize',
          ])
      ;
    
      $keywords = new Text('keywords', [
          'id' => 'input-tags',
          'placeholder' => 'Enter some keywords',
      ]);
    
      $keywords->setLabel('Keywords');
    
      $this
          ->add($id)
          ->add($authorId)
          ->add($title)
          ->add($permalink)
          ->add($excerpt)
          ->add($content)
          ->add($metaTitle)
          ->add($metaKeywords)
          ->add($metaDescription)
          ->add($categories)
          ->add($status)
          ->add($keywords)
      ;

    } }

Thanks in advance



12.6k
Accepted
answer
edited Sep '15

Ok I figured out a way to do it, not sure if right or not, but it works, I was hoping the bind would do it automatically :/ but this is what I did anyways, in case it helps anyone else:

public function editAction()
{
    $id = (int) $this->dispatcher->getParam(0);

    if (is_numeric($id) && $id != 0) {
        $article = Blog::findFirstById($id);

        $form = new BlogArticleForm($article, [
            'edit' => true,
        ]);

        $selectedCategoriesModels = $article->getCategories();
        $selectedCategories = [];

        foreach ($selectedCategoriesModels as $selectedCategory) {
            $selectedCategories[] = $selectedCategory->getId();
        }

        $form->get('categories[]')->setDefault($selectedCategories);

        $this->view->setVar('form', $form);
    } else {
        throw new Exception('Invalid ID');
    }
}


65

Awesome André, this saved my day! thanks for sharing!