argerim / select2-rails

Integrate Select2 javascript library with Rails asset pipeline
https://github.com/argerim/select2-rails
965 stars 374 forks source link

Can not get/set ajax data on rails 5.2 NOT WORK #184

Open rollyar opened 6 years ago

rollyar commented 6 years ago

Hi, I have rails 5.2 and ruby 2.5.1, i installed "gem rails-select2" and added to application.js

//= require select2-full
//= require select2_locale_es  

and added to application.scss

@import "select2";
@import "select2-bootstrap";

and this is sample of call in provider.coffe.erb

$('#provider_provider_type_id').select2
    ajax:
      url: '<%= url.admin_provider_types_path(format: :json) %>'
      dataType: 'json'
      delay: 250
      cache: true
      data: (term, page) ->
        {
          q: term
          page: page
        }
      results: (data) ->
        myResults = []
        $.each data, (index, provider_type) ->
          myResults.push
            'id': provider_type.id
            'text': provider_type.description
          return
        { results: myResults }
    minimumInputLength: 3
    initSelection: (element, callback) ->
      if element.val().length > 0
        data = element.data('pre')
        serv_data =
          id: data['id']
          text: data['description']
        callback serv_data

and this is a fragment of view

  <div class="form-group required">
        <%= f.label :provider_type_id, type: 'number', class: 'col-sm-4 control-label required' %>
        <div class="col-sm-8">
          <%= f.text_field :provider_type_id, class: "form-control",
                          'data-pre' => "#{@provider.provider_type.to_json unless @provider.provider_type_id.blank?}" %>
        </div>
      </div>

what is wrong, what make bad? Tanks for your help!

bsa7 commented 4 years ago

Hi! This example working for me in Rails 5:

  1. haml _form.html.haml:

    = f.association :company, as: :select,
      collection: [['All', nil], [f.object.company.name, f.object.company_id]],
      label: "Company",
      required: true,
      input_html: { class: 'select2', data: { url: company_suggestions_url } }
  2. coffee initializer select2.initializer.coffee:

    $(document).on 'ready', ->
    Select2Helper.initialize()
  3. coffee helper select2.helper.coffee:

    class window.Select2Helper
    @initialize: ->
    select2DomElements = document.querySelectorAll('select.select2')
    select2DomElements.forEach (select2) ->
      url = select2.getAttribute('data-url')
      labelMethod = select2.getAttribute('data-label-method')
      containsOption = select2.getAttribute('data-contains-option')
      ajax = undefined
    
      if url != null
        ajax =
          url: url
          dataType: 'json'
          delay: 250
          data: (params) ->
            query = {}
            query[select2.id] = (params.query || {}).term || params.term
    
            { contains_option: containsOption, query: params.term, label_method: labelMethod }
          processResults: (data, params) ->
            res = []
            res.push(id: 'contains:', text: 'Все', html: 'All') if data.length
            for item in data
              id = undefined
              html = undefined
              if typeof item == 'string'
                id = item
                html = item
              else if Array.isArray(item)
                [html, id] = item
              else if typeof item == 'object' && item.id
                if item.text || item.html
                  { id, text, html } = item
                else
                  id = item.id
                  delete item.id
                  html = item[Object.keys(item)[0]]
              text = html.replace(/<[^>]+>/g, '')
              item =
                id: id
                html: html
                text: text
                title: text
    
              res.push(item)
    
            { results: res }
    
      $(select2).select2
        allowClear: true
        language: 'en-EN'
        placeholder: 'All'
        minimumResultsForSearch: 0
        multiple: select2.getAttribute('multiple')
        ajax: ajax
    
      $(select2).on "select2:clear", (evt) ->
        $(this).on "select2:opening.cancelOpen", (evt) ->
          evt.preventDefault()
          $(this).off("select2:opening.cancelOpen")
    
    @formatResult: (node) ->
    if typeof (node.id) is 'string' && /^contains:/.test(node.id)
      node.html = $("<span class=\"contains\">#{node.text}</span>")
    else if typeof (node.id) is 'string' && /^<.+\/>$/
      node.html = $(node.html)
    node
  4. my application.js:

    ...
    //= require select2-full
    //= require select2_locale_ru
    ...
    //= require select2_init.

How it working:

  1. haml is rendered this html:

    <select class="form-control select required select2 select2-hidden-accessible" data-url="https://.../company_suggestions" required="required" aria-required="true" name="company" id="company" data-select2-id="company" tabindex="-1" aria-hidden="true">
    <option value="" data-select2-id="2"></option>
    <option selected="selected" value="2" data-select2-id="3">Macdonalds1</option>
    </select>
  2. After dom ready select2.initialize search all select.select2 elements in DOM and initialized its all.