Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load default (selected) values from database #366

Closed
prigal opened this issue Apr 7, 2014 · 8 comments
Closed

How to load default (selected) values from database #366

prigal opened this issue Apr 7, 2014 · 8 comments

Comments

@prigal
Copy link

prigal commented Apr 7, 2014

Hi,

I read issue #77 but I still doesn't understand how to initialize my selectize select with selected values from database.

JS

$( document ).ready(function() {
    $('#shop_brands').selectize({
        plugins: ['remove_button'],
        delimiter: ',',
        persist: false,
        preload: true,
        openOnFocus: true,
        valueField: 'id',
        labelField: 'title',
        searchField: ['title'],
        maxOptions: 10,
        options: [],
        create: false,
        render: {
            option: function(item, escape) {
                return '<div>' +escape(item.title)+'</div>';
            }
        },
        load: function(query, callback) {
            if (!query.length) return callback();
            $.ajax({
                url: '/admin/brands/search',
                type: 'GET',
                dataType: 'json',
                data: {
                    q: query
                },
                error: function() {
                    callback();
                },
                success: function(res) {
                    callback(res.data);
                }
            });
        }
    });
});

HTML :

<div class="form-group">
                    <div class="col-md-12">

                        <label class="control-label" for="shop_brands">{{{ Lang::get('admin/shops/table.brands') }}}</label>
                        <select class="form-control" name="brands[]" id="shop_brands" multiple>
                           <?php 
                                if($mode=='edit'){
                                    foreach ($shop->brands as $brand) {
                                        $tojson=array('id'=>$brand->id,'title'=>$brand->title);
                                        echo '<option value="' . htmlentities($brand->id) . '" data-data="' . htmlentities(json_encode($tojson)) . '">' . htmlentities($brand->title) . '</option>';
                                    }
                                }
                            ?>
                        </select>
                    </div>
                </div>

When I look the generated HTML I found this, it seems correct :

                <div class="form-group">
                    <div class="col-md-12">

                        <label class="control-label" for="shop_brands">Brands</label>
                        <select class="form-control" name="brands[]" id="shop_brands" multiple>
                           <option value="1" data-data="{&quot;id&quot;:1,&quot;title&quot;:&quot;Le temps des cerises&quot;}">Le temps des cerises</option>
                               <option value="6" data-data="{&quot;id&quot;:6,&quot;title&quot;:&quot;Scarlett Ross&quot;}">Scarlett Ross</option>                      </select>
                    </div>
                </div>

But when I load the page in the browser, these 2 values aren't shown in the selectize field...

The load function works well, because when I start typing something in the field, it shows me results.

Where am I wrong ? Thanks for your help.

@agborkowski
Copy link

same as #364

@prigal
Copy link
Author

prigal commented Apr 7, 2014

Oky thanks but I'm surprise there isn't something simpler !

@geordee
Copy link

geordee commented Apr 8, 2014

I do not think what I have written is the best or elegant way of solving this. Recently I tried to trigger events on the original select and handle it elsewhere. Currently I am reading the Selectize code to see how else can it be adapted.

@prigal
Copy link
Author

prigal commented Apr 8, 2014

Ok for future users, inspired by geordee work (#364) this is my implementation with a multi select field :

Place and hidden id field in your edit form :

<input type="hidden" name="saved_id" id="saved_id" value="{{{$shop->id}}}" />

No need to add options via php code in your edit form :

<div class="form-group">
                    <div class="col-md-12">
                        <label class="control-label" for="shop_brands">{{{ Lang::get('admin/shops/table.brands') }}}</label>
                        <select class="form-control" name="brands[]" id="shop_brands" multiple></select>
                    </div>
                </div>

in your JS, set your selectize options (read comments) :

$('#shop_brands').selectize({
        plugins: ['remove_button'],
        delimiter: ',',
        persist: false,
        preload: true,
        openOnFocus: true,
        valueField: 'id',
        labelField: 'title',
        searchField: ['title'],
        maxOptions: 10,
        options: [],
        create: false,
        initData: true, // Boolean to know if it's the first load
        remoteUrl: '/admin/brands/search', // Classic remote load URL
        initUrl: '/admin/shops/'+$('#saved_id').val()+'/loadBrands', // First remote load URL to load defaults
        render: {
            option: function(item, escape) {
                return '<div>' +escape(item.title)+'</div>';
            }
        },
        load: Selectizer.loadOptions
    });

And before this build the Selectizer module :

var Selectizer = function () {
      return {
        loadOptions: function (query, callback) {
          var selectize = this;
          var url = selectize.settings.remoteUrl; // Classic URL
          if (selectize.settings.initData === true) { 
            url = selectize.settings.initUrl; // If first time; load the Init URL
          }

          // The Ajax call
          $.ajax({
            url: url,
            type: 'GET',
            dataType: 'json',
            data: {
              q: query
            },
            error: function() {
              callback();
            },
            success: function(data) {
              callback(data.data);
              if (selectize.settings.initData === true) { // If it's the first time
                for (var key in data.data) {  // important stuff :)
                   var obj = data.data[key];
                   selectize.addOption(JSON.stringify(obj)); // Add an option to the select.
                   selectize.addItem(obj.id); // Tell selectize that this new option is selected. 
                }
                selectize.settings.initData = false; // Next load won't be the first init one. 
              }
            }
          });
        },
      };
    }();

In your controller (here I use PHP and Laravel, but it's the same with a RAILS app) you have to return Json for both of your remote URLs.

  • /admin/brands/search : return results with what the user enter in the field
  • /admin/shops/{shop_id}/loadBrands : return default results

Many thanks geordee.

@geordee
Copy link

geordee commented Apr 9, 2014

I have updated my question (and closed the ticket). There is a much better way to do it using data-data attribute.

@prigal
Copy link
Author

prigal commented Apr 9, 2014

Yes it's the method I tried in the first place (look at my first post) but it wasn't working for me, maybe because of the "multiple select" context...

@allaniftrue
Copy link

same as mine, it doesn't doesnt fully render the values pulled from the database. Sometimes it displays 2 out of 3 or totally empty.

@joallard
Copy link
Member

I don't fully understand the issue on a skim and whether it still needs resolution, but if it's still something needed, please make a new issue enhancement request and link here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants