module RedmineCrm module FormTagHelper # Allows include select2 into your views. # # ==== Examples # select2_tag 'city_id', '...' # select2_tag 'city_id', options_for_select(...) # select2_tag 'tag_list', nil, :multiple => true, :data => [{ id: 0, text: 'deal' }, ...], :tags => true, :include_hidden => false %> # select2_tag 'tag_list', options_for_select(...), :multiple => true, :style => 'width: 100%;', :url => '/tags', :placeholder => '+ add tag', :tags => true %> # # You may use select_tag options and additional options. # # ==== Additional options # * :url Allows searches for remote data using the ajax. # * :data Load dropdown options from a local array if +url+ option not set. # * :placeholder Supports displaying a placeholder value. # * :include_hidden Adds hidden field after select when +multiple+ option true. Default value true. # # Note: The HTML specification says when +multiple+ parameter passed to select and all options got deselected # web browsers do not send any value to server. # # In case if you don't want the helper to generate this hidden field you can specify # include_hidden: false option. # # Also aliased as: select2 # # select2 'city_id', options_for_select(...) # def select2_tag(name, option_tags = nil, options = {}) id = sanitize_to_id(name) placeholder = options[:placeholder] || 'Select ...' content_for(:header_tags) { select2_assets } result = select_tag(name, option_tags, options) if options[:multiple] && options.fetch(:include_hidden, true) result << hidden_field_tag("#{name}[]", '') end result << javascript_tag(<<-JS) $(function () { $('select#' + '#{id}').select2({ #{select2_data_source_options(options)}, #{select2_tags_options(options)}, placeholder: '#{placeholder}' }); }); JS end alias select2 select2_tag # Transforms select filter field into select2 # # ==== Examples # transform_to_select2 'issue_tags', url: auto_complete_tags_url # transform_to_select2 'manager_id', format_state: 'formatStateWithAvatar', min_input_length: 1, url: '/managers' # # ==== Options # * :url Defines URL to search remote data using the ajax. # * :format_state Defines template of search results in the drop-down. # * :min_input_length Minimum number of characters required to start a search. Default value 0. # * :width Sets the width of the control. Default value '60%'. # def transform_to_select2(field, options = {}) return if field.empty? result = ''.html_safe unless @transform_to_select2_included result << javascript_include_tag('select2_helpers', plugin: 'redmine_crm') @transform_to_select2_included = true end result << javascript_tag(<<-JS) select2Filters['#{field}'] = { url: '#{options[:url].to_s}', formatState: #{options.fetch(:format_state, 'undefined')}, minimumInputLength: #{options.fetch(:min_input_length, 0)}, width: '#{options.fetch(:with, '60%')}' }; JS end private def select2_data_source_options(options = {}) if options[:url].to_s.empty? "data: #{options.fetch(:data, []).to_json}" else "ajax: { url: '#{options[:url]}', dataType: 'json', delay: 250, data: function (params) { return { q: params.term }; }, processResults: function (data, params) { return { results: data }; }, cache: true }" end end def select2_tags_options(options = {}) if options.fetch(:tags, false) "tags: true, tokenSeparators: [','], createTag: function (params) { var term = $.trim(params.term); if (term === '' || term.indexOf(',') > -1) { return null; // Return null to disable tag creation } return { id: term, text: term } }" else 'tags: false' end end end end