ncbo/bioportal_web_ui

View on GitHub
app/views/shared/_ontology_picker_advanced.html.erb

Summary

Maintainability
Test Coverage

<script type="text/javascript">

var abbreviationMap = <%= @onts_for_js.html_safe %>;
var groupsMap = <%= @groups_for_js.html_safe %>;
var categoriesMap = <%= @categories_for_js.html_safe %>;
var ontsInGroupsOrCategories = <%= @onts_in_gp_or_cat_for_js.html_safe %>;
var winHeight = jQuery(window).height();
var ontSelectListPos = { top: 0, left: 0, width: 0 };
var allSelected = false;
var alignToDOMId = <%=(align_to_dom_id || @select_id).to_json.html_safe%>;

jQuery(document).ready(function(){
  ontSelectListPos.top = jQuery("#"+alignToDOMId).offset().top;
  ontSelectListPos.left = jQuery("#"+alignToDOMId).offset().left;
  ontSelectListPos.width = jQuery("#"+alignToDOMId).width();

  // Watch for changes in the entry of the select list
  jQuery("#<%=@select_id%>").change(function(e) {
    ontLabelToAbbr();
    syncFromList();
  });

  // Reset labels on page load and make sure checkbox is in sync
  ontLabelToAbbr();
  syncFromList();

  // Hide the advanced select when focusing in the chosen select box
  jQuery("#"+alignToDOMId).bind("focus", hideAdvancedSelect);

  // Hide the advanced select when clicking anywhere except in advanced select
  jQuery('html').click(function() {
    hideAdvancedSelect();
  });

  // Hide advanced select when hitting escape
  jQuery(document).keyup(function(e) {
    if (e.keyCode == 27) { hideAdvancedSelect(); } // esc
  });

  // Wire advanced selection
  jQuery('#ont_select_adv').click(function(event){
    event.stopPropagation();
    bp_popup_cleanup();
  });

  // Wire clear selections
  jQuery("#ont_select_clear").click(clearAllSelections);

  // Wire up the link to open dialog box
  jQuery("#ont_select_adv_href").click(function() {
    var ont_select = jQuery("#ont_select_adv");
    var chzn_select = jQuery("#"+alignToDOMId);

    ont_select.css("top", "50px");
    ont_select.css("left", chzn_select.offset().left + chzn_select.width() - 1);
    ont_select.css("width", jQuery(window).width() - (chzn_select.offset().left + chzn_select.width()) - 100 + "px");
    ont_select.css("height", jQuery(window).height() - 80);

    // Configure the chosen select list box to remove background, move z-index above the advanced select
    chzn_select.css("z-index", "4000");
    chzn_select.children("ul.chzn-choices").addClass("no_right_border");
    chzn_select.children("ul.chzn-choices").css("background", "white");
    // Chosen select list congig changes for IE
    chzn_select.children("ul.chzn-choices").css("filter", "none");
    jQuery("#<%=@select_id%>_chzn input").css("filter", "none");

    jQuery("#<%=@select_id%>_container").css("box-shadow", "0 0 10px gray");

    jQuery("#ont_list_container").height(ont_select.height() - 80);

    jQuery("#ont_select_adv").show();

    return false;
  });

  // Wire up close advanced select "X"
  jQuery("#close_adv_select").click(function(){
    hideAdvancedSelect();
  });

  // Wire up watcher for checkboxes for sync
  jQuery(".ont_select_boxes_tr input:checkbox").click(function(){
    syncFromCheckboxes();
    if (allSelected = true) {
      allSelected = false;
      jQuery("#ont_select_all").attr("checked", false);
    } else {
      // Compare total checkboxes to checked to see if they're all checked
      if (jQuery(".ont_select_boxes_tr input:checkbox").length == jQuery(".ont_select_boxes_tr input:checked").length) {
        allSelected = true;
        jQuery("#ont_select_all").attr("checked", true);
      }
    }
  });

  // Toggle all selected
  jQuery("#ont_select_all").click(function(){
    if (jQuery(this).attr("checked")) {
      allSelected = true;
    } else {
      allSelected = false;
    }
    jQuery(".ont_select_boxes_tr input:checkbox").attr("checked", allSelected);
    syncFromCheckboxes();
    refreshOntList();
  });

  // Select ontologies that are visible in the filter list
  jQuery("#ont_select_all_filtered").click(function(){
    if (jQuery(this).attr("checked")) {
      jQuery(".ont_select_boxes_tr input:checkbox:visible").attr("checked", true);
    } else {
      jQuery(".ont_select_boxes_tr input:checkbox:visible").attr("checked", false);
    }
    syncFromCheckboxes();
    refreshOntList();
  });

  // Wire up group/category select
  select_groups.init();
  select_categories.init();

  // Wire up show all filtered link
  jQuery("#show_all_filtered_ontologies").bind("click", showAllFiltered);

});

var hideAdvancedSelect = function(){
  if (jQuery("#ont_select_adv").is(":visible")) {
    jQuery("#ont_select_adv").hide();
    jQuery("#"+alignToDOMId).children("ul.chzn-choices").removeClass("no_right_border").css("background", "");
    jQuery("#<%=@select_id%>_container").css("box-shadow", "");
    jQuery("#"+alignToDOMId).css("z-index", "auto")
  }
}

// Synchronise select list to checkboxes
function syncFromList() {
  jQuery(".ont_select_boxes_tr input:checked").each(function(){
    jQuery(this).attr("checked", false);
  });

  jQuery("#<%=@select_id%> option:selected").each(function(){
    var id = jQuery(this).val();
    jQuery("#ont_select_adv_check" + id).attr("checked", true);
  });
}

var select_groups = {
  init: function() {
    jQuery("#select_groups").bind("click", function(e){bp_popup_init(e)});
    jQuery("tr.group_select_boxes_tr input").bind("click", function(e){select_groups.selectGroup(e)});
    jQuery("#group_list_container").click(function(e){e.stopPropagation()});
    this.cleanup();
  },

  cleanup: function() {
    jQuery("html").click(bp_popup_cleanup);
    jQuery(document).keyup(function(e) {
      if (e.keyCode == 27) { bp_popup_cleanup(); } // esc
    });
  },

  selectGroup: function(e) {
    e.stopPropagation();
    syncGroupsAndCategories();
    syncFromCheckboxes();
  }
}

var select_categories = {
  init: function() {
    jQuery("#select_categories").bind("click", function(e){bp_popup_init(e)});
    jQuery("tr.category_select_boxes_tr input").bind("click", function(e){select_categories.selectCategory(e)});
    jQuery("#category_list_container").click(function(e){e.stopPropagation()});
    this.cleanup();
  },

  cleanup: function() {
    jQuery("html").click(bp_popup_cleanup);
    jQuery(document).keyup(function(e) {
      if (e.keyCode == 27) { bp_popup_cleanup(); } // esc
    });
  },

  selectCategory: function(e) {
    e.stopPropagation();
    syncGroupsAndCategories();
    syncFromCheckboxes();
  }
}

// Synchronize checkboxes to select list
function syncFromCheckboxes() {
  var checkedIds = [];
  jQuery(".ont_select_boxes_tr input:checked").each(function(){
    checkedIds.push(jQuery(this).val());
  });
  jQuery("#<%=@select_id%>").val(checkedIds);
  refreshOntList();
}

function syncGroupsAndCategories() {
  jQuery("#select_all_filtered_row input").attr("checked", false);

  var groups = jQuery("#ont_select_adv tr.group_select_boxes_tr input:checked");
  var categories = jQuery("#ont_select_adv tr.category_select_boxes_tr input:checked");
  if(groups.length === 0 && categories.length === 0) {
      showAllFiltered();
  } else {
      var selected_ontologies = {};
      var group_category_names = [];
      groups.each(function(){
          jQuery(groupsMap[jQuery(this).val()]).each(function(){
              selected_ontologies[this] = 1; // this is an ontology URI (ID)
          });
          group_category_names.push(jQuery("label[for='" + jQuery(this).attr("id") + "']").html());
      });
      categories.each(function(){
          jQuery(categoriesMap[jQuery(this).val()]).each(function(){
              selected_ontologies[this] = 1; // this is an ontology URI (ID)
          });
          group_category_names.push(jQuery("label[for='" + jQuery(this).attr("id") + "']").html());
      });
      // Hide ontologies not in a selected group/category, show if in a selected group/category
      jQuery("#ont_select_adv tr.ont_select_boxes_tr input").each(function(){
          var ont_id = jQuery(this).val();
          if (!(ont_id in selected_ontologies)) {
              jQuery(this).closest("tr").hide();
          } else {
              jQuery(this).closest("tr").show();
          }
          jQuery("#select_all_filtered_row").show();
      });
      // Put group/category names on the screen
      jQuery("#groups_and_category_names").html(group_category_names.join(", "));
      jQuery("#groups_categories_names_container").show();
  }
}

// Check the selected list of ontologies against the map and replace
function ontLabelToAbbr() {
  jQuery("#<%=@select_id%>_chzn > .chzn-choices > li > span").each(function(){
    if (jQuery(this).children("span.chzn-abbr").length === 0) {
      jQuery(this).html("<span class='chzn-abbr' title='"+jQuery(this).html()+"'>"+abbreviationMap[jQuery(this).html()]+"</span>");
    }
  });
}

function refreshOntList() {
  jQuery("#<%=@select_id%>").trigger("chosen:updated");
  jQuery("#<%=@select_id%>").trigger("change");
}

function showAllFiltered() {
  jQuery("#advanced_filter_input").val("").blur();
  jQuery(".ont_select_boxes_tr").show();
  jQuery("#select_all_filtered_row").hide();
  clearGroupsAndCategories();
}

function clearGroupsAndCategories() {
  jQuery("#group_list input").attr("checked", false);
  jQuery("#category_list input").attr("checked", false);
  jQuery("#groups_categories_names_container").hide();
}

function clearAllSelections() {
  jQuery("#<%=@select_id%>").val("");
  jQuery("#<%=@select_id%>_chzn li.search-choice").remove();
  clearGroupsAndCategories();
  refreshOntList();
}

// Filters ontology list
(function (jQuery) {
  // custom css expression for a case-insensitive contains()
  jQuery.expr[':'].Contains = function(a,i,m){
      return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase())>=0;
  };


  function listFilter(input, list) { // header is any element, list is an unordered list
    jQuery(input)
      .change( function () {
        var filter = jQuery(this).val();
        if(filter) {
          // this finds all links in a list that contain the input,
          // and hide the ones not containing the input while showing the ones that do
          jQuery(list).find("td:not(:Contains(" + filter + "))").closest("tr").hide();
          jQuery(list).find("td:Contains(" + filter + ")").closest("tr").show();
          jQuery("#select_all_filtered_row").show();
        } else {
          jQuery(list).find("tr").show();
          jQuery("#select_all_filtered_row").hide();
        }

        clearGroupsAndCategories();
        jQuery("#select_all_filtered_row input").attr("checked", false);

        return false;
      })
    .keyup( function () {
        // fire the above change event after every letter
        jQuery(this).change();
    });
  }

  jQuery(document).ready(() => listFilter(jQuery("#advanced_filter_input"), jQuery("#ont_list")));
}(jQuery));
</script>

<div id="ont_select_adv" style="overflow: visible; z-index: 100; display: none; text-align: left; border: thin solid gray; position: fixed; background: white; max-width: 550px; box-shadow: 0 0 10px gray;">
  <div id="ont_select_adv_inner" style="padding: 15px 10px 3px; background: white; z-index: 5000;">
    <h2>Select Multiple Ontologies <a href="javascript:void(0);" id="close_adv_select" class="ui-dialog-titlebar-close ui-corner-all" role="button" unselectable="on" style="-moz-user-select: none; float: right;"><span class="ui-icon ui-icon-closethick" unselectable="on" style="-moz-user-select: none;">close</span></a></h2>

    <input type="text" id="advanced_filter_input" class="help_text" style="width: 300px; margin-bottom: 10px;" title="Search all ontology names">

    <span class="popup_container">
      <span class="bp_popup_link_container" style="box-shadow: none; padding-left: 25px;">
        <a href="javascript:void(0);" id="select_groups" class="bp_popup_link" style="padding: 4px 10px 6px; font-size: small; text-transform: none; display: inline-block;">Groups</a>
      </span>
      <div id="group_list_container" class="bp_popup_list" style="display: none; font-size: 9pt;">
        <table id="group_list">
          <% @groups_for_select.each do |group| %>
            <tr class="group_select_boxes_tr">
              <td valign="top"><%= check_box_tag "group_select_check", group[1], false, :id => "group_select_check#{group[1]}", :class => "group_cat_checkboxes" %></td>
              <td style="padding-left: 5px;"><%= label_tag "group_select_check#{group[1]}", group[0] %></td>
            </tr>
          <% end %>
        </table>
      </div>
    </span>

    <span class="popup_container" style="margin-left: 95px;">
      <span class="bp_popup_link_container">
        <a href="javascript:void(0);" id="select_categories" class="bp_popup_link" style="padding: 4px 10px 6px; font-size: small; text-transform: none; display: inline-block;">Categories</a>
      </span>
      <div id="category_list_container" class="bp_popup_list" style="display: none; font-size: 9pt;">
        <table id="category_list">
          <% @categories_for_select.each do |group| %>
            <tr class="category_select_boxes_tr">
              <td valign="top"><%= check_box_tag "category_select_check", group[1], false, :id => "category_select_check#{group[1]}", :class => "group_cat_checkboxes" %></td>
              <td style="padding-left: 5px;"><%= label_tag "category_select_check#{group[1]}", group[0] %></td>
            </tr>
          <% end %>
        </table>
      </div>
    </span>

    <div id="ont_list_container" style="overflow: auto; position: relative;">
      <div id="groups_categories_names_container" style="display: none; font-weight: bold; font-style: oblique; color: gray; padding: 0 1em 1em 0;">Filtered Groups and Categories: <span id="groups_and_category_names" style="font-weight: normal; font-style: none;"></div>

      <table id="ont_list">
        <!--
        <tr>
          <td style="padding-bottom: 5px;"><%= check_box_tag "ont_select_all" %></td>
          <td style="padding: 0 0 5px 5px;"><%= label_tag "ont_select_all", "All" %></td>
        </tr>
        -->

        <tr id="select_all_filtered_row" style="display: none;">
          <td style="padding-bottom: 15px;"><%= check_box_tag "ont_select_all_filtered" %></td>
          <td style="padding: 0 0 15px 5px;"><%= label_tag "ont_select_all_filtered", "Select all filtered ontologies", :style => "color: #234979; font-weight: bold;" %>&nbsp;&nbsp;(<a href="javascript:void(0);" id="show_all_filtered_ontologies">show all</a>)</td>
        </tr>

        <% @onts_for_select.each do |ont| %>
          <tr class="ont_select_boxes_tr">
            <td valign="top"><%= check_box_tag "ont_select_adv_check", ont[1], false, :id => "ont_select_adv_check#{ont[1]}" %></td>
            <td style="padding-left: 5px;"><%= label_tag "ont_select_adv_check#{ont[1]}", ont[0] %></td>
          </tr>
        <% end %>
      </table>
    </div>
  </div>
</div>