Newer
Older
dmpopidor / app / views / shared / _accessible_combobox.html.erb
<% if !models.nil? %>
  <% json = {} %>
  <% models.map{|m| json[m[attribute]] = m.id} %>

  <input type="text" name="<%= name %>" id="<%= id %>" 
         class="js-combobox <%= classes %>" list="<%= id %>_list" 
         placeholder="<%= _('Begin typing to see a filtered list') %>"
         data-combobox-prefix-class="combobox"
         data-combobox-case-sensitive="no"
         data-combobox-search-option="containing"
         data-combobox-allow-suggestion-on-empty="true"
         value="<%= default_selection[attribute] unless default_selection.nil? %>" />
  <datalist id="<%= id %>_list">
    <% models.each do |model| %>
      <option value="<%= model[attribute] %>" />
    <% end %>
  </datalist>

  <!-- The JQuery accessible combobox doesn't allow for an id to be present in the value attribute -->
  <!-- so we use this hidden input to store the selected id -->
  <!-- the selected id is found after the combobox loses focus by finding the selected item in the crosswalk json -->
  <input type="hidden" id="<%= id.gsub("_#{attribute}", "_id") %>" name="<%= name.gsub("_#{attribute}]", "_id]") %>"
         value="<%= default_selection.id unless default_selection.nil? %>" />

  <span role="" id="<%= id %>_error" class="error-tooltip left-indent"></span>

  <script type="text/javascript">
    var <%= id %>_crosswalk = <%= raw JSON.generate(json) %>;
    
    // When the user selects a value from the combobox, place the corresponding id in the hidden field
    $(document).ready(function(){
      var combo = $("#<%= id %>");
      var clear = $(combo).siblings(".combobox-clear-button");
      
      // Pull the id out of the json hash based on the text the user selected
      $(combo).keyup(function(){
        var selection = <%= id %>_crosswalk[$(this).val()];
        $("#<%= id.gsub("_#{attribute}", "_id") %>").val(selection === 'undefined' ? '' : selection).change();
      }).focus(function(){
        var selection = <%= id %>_crosswalk[$(this).val()];
        $("#<%= id.gsub("_#{attribute}", "_id") %>").val(selection === 'undefined' ? '' : selection).change();
      });
      
      // Initialize the clear buttons on load
      // Replace the default js-combobox clear button [X] with a fontawesome icon
      $(clear).html('<i class="fa fa-times-circle" aria-hidden="true"></i>');
      $(clear).css("display", $(combo).val().trim().length <= 0 ? 'none' : 'inline');
  
      // Function to hide/show the clear button when text changed in the dropdown
      // -------------------------------------------------------------
      $(combo).keyup(function(){
        $(clear).css("display", $(combo).val().trim().length <= 0 ? 'none' : 'inline');
      }).change(function(){
        $(clear).css("display", $(combo).val().trim().length <= 0 ? 'none' : 'inline');
      });

      // Hide the clear button if it gets clicked
      // -------------------------------------------------------------
      $(clear).click(function(){
        $(this).css("display", 'none');
        $(combo).val("").focus();//.keyup();
      });
      
      // Display the error message if the value in the auto complete is not an item from the list
      $(combo).on('keyup', function(){
        if(<%= id %>_crosswalk[$(this).val().trim()] == undefined && $(this).val().trim().length > 1){
          $("#<%= id %>_error").html("<%= error %>").attr('role', 'alert');
          $("#<%= id %>").addClass('red-border');
        }else{
          $("#<%= id %>_error").html("").attr('role', '');
          $("#<%= id %>").removeClass('red-border');
        }
      });
      $("#<%= id %>").on('change', function(){
        if($(this).val().trim().length > 1){
          $("#<%= id %>_error").html("").attr('role', '');
          $("#<%= id %>").removeClass('red-border');
        }else{
          $("#<%= id %>_error").html("<%= error %>").attr('role', 'alert');
          $("#<%= id %>").addClass('red-border');
        }
      });
      
    });
  </script>
<% else %>
  <span id="<%= id %>_no_items"><%= _('No items available.') %></span>
<% end %>