Single Article

APEX and shuttle filter - Revisited

Category APEX and jQuery

Previously I did write post about APEX and shuttle filter. I received comments that filtering does not work when shuttle have parent cascading item. Issue was that JavaScript code stores shuttle values to variable for filtering only on page load.

I did receive also proposal to add button for clearing filter item. This is also included to new JavaScript code along with some style changes for APEX 19.2.

Here is modified code for page JavaScript Function and Global Variable Declaration:

(function($) {
  $.fn.htmldbShuttlefilter = function(options) {

    options = $.extend({}, {
      "filterPlaceholder": "Filter",
      "buttonTitle": "Clear filter",
      "buttonClass": "a-Button a-Button--noLabel a-Button--withIcon a-Button--small a-Button--noUI a-Button--shuttle margin-top-none",
      "buttonIcon": "fa-times"
    }, options);

    function getShuttleValues(elem$) {
      return elem$.children("option").map(function() {
        return {
          text: $(this).text(),
          value: $(this).val(),
          option: this
        };
      });
    }

    return this.each(function(i) {
      
      var $self = $(this),
        shuttleResetBtnId = $self.attr("id") + "_RESET",
        $select = $self.find("select"),
        // get shuttle values
        shuttleValues = getShuttleValues($select),
        // filter reset button
        $resetBtn = $("<button/>", {
          "type": "button",
          "title": options.buttonTitle,
          "aria-label": options.buttonTitle,
          "class": options.buttonClass,
          "css": {"padding": "4px"}
        }).append(
          $("<span/>", {
            "aria-hidden": "true",
            "class": "a-Icon fa " + options.buttonIcon,
          })
        ).click(function() {
          // clear filter text field
          $filter.val("").keyup();
        }),
        // filter text field
        $filter = $("<input/>", {
          "type": "text",
          "value": "",
          "autocomplete": "off",
          "placeholder": options.filterPlaceholder,
          "class": "text_field apex-item-text",
          "css": {"width": "100%"}
        }).keyup(function() {
          // filter shuttle when typing to text field
          var filterval = new RegExp("^" + $(this).val() + ".*", "i"),
          selectedValues = $select.eq(1).children("option").map(function() {
            return $(this).val();
          });

        // empty shuttle available values
        $select.eq(0).empty();
        // add values that match filter criteria
        $.each(shuttleValues, function(idx, obj) {
          if (obj["text"].match(filterval) && $.inArray(obj["value"], selectedValues) < 0) {
            $select.eq(0).append(obj["option"]);
          }
        });
      });
      // add needed elements to page
      $self.prepend(
        $("<div/>", {
          "class": "t-Form-itemWrapper"
        }).append($filter).append(
          $("<span/>", {
            "class": "t-Form-itemText t-Form-itemText--post"
          }).append($resetBtn)
        )
      ).on("apexafterrefresh", function() {
        // initiliaze filter when shuttle is refreshed by parent item
        $filter.val("");
        shuttleValues = getShuttleValues($select);
      });
      // clear also filter from shuttle reset button
      $("#" + shuttleResetBtnId).click(function() {
        $filter.val("");
      });

    });
  }
})(apex.jQuery);

If you like add filter to all shuttles in page, then add to page JavaScript Execute when Page Loads:

$(".apex-item-group--shuttle").htmldbShuttlefilter();

Depending on your need, change jQuery selector.

See working example where Dept shuttle is parent for Emp.

Comments

No comments yet on this article.

Global Right Column

Search

Archives

Subscribe in a Reader