Skip to Main Content

APEX and shuttle filter

Here is small tip how to create filter / search field for APEX shuttle item values. For this you need just place jQuery code to page JavaScript Function and Global Variable Declaration.

(function($){
$.fn.htmldbShuttlefilter=function(options){
  options=$.extend({},{"label":"Filter"},options);
  return this.each(function(i){
   var $self      = $(this)
   ,filterId      = $self.attr("id") + "_FILTER"
   ,$select       = $self.find("select")
   ,shuttleValues = $select.children("option").map(function(){
    return {text:$(this).text(),value:$(this).val(),option:this}
   })
   ,$filter = $("<input/>",{"type":"text","value":"","size":"255","autocomplete":"off","id":filterId})
   .keyup(function(){
    var filterval   = new RegExp("^"+$(this).val()+".*","i")
    ,selectedValues = $select.eq(1).children("option").map(function(){
     return $(this).val();
    });
    $select.eq(0).empty();
    $.each(shuttleValues,function(idx,obj){
     if(obj["text"].match(filterval) && $.inArray(obj["value"],selectedValues)<0){
      $select.eq(0).append(obj["option"]);
     }
    });
   })
   .width($self.width());
   $("<div/>",{"css":{"padding-bottom":"5px"}})
   .insertBefore($self)
   .append(
    $("<label/>",{"for":filterId})
    .append($("<span/>",{"css":{"font-weight":"bold"}}).text(options.label))
   )
   .append("<br/>").append($filter);
   $self.find("img[alt='Reset']").click(function(){$filter.val("")});
  });
}
})(jQuery);

Then add to page JavaScript Execute when Page Loads

$("#Px_SHUTTLE_ITEM_NAME").htmldbShuttlefilter({});

Replace Px_SHUTTLE_ITEM_NAME with your real shuttle item name.

See working example.

Shuttle with filter

Comments

  • Jari Laine 6 Nov 2024

    Hi Shikha,

    I'm bad with CSS. Setting a static width for the search bar might not be the best option. But you might want to test if this JavaScript works better.

    (function($) {
     $.fn.htmldbShuttlefilter = function(options) {
       // Defaults
       options = $.extend({}, {
         "filterPlaceholder": "Filter"
       , "buttonTitle": "Clear filter"
       , "buttonClass": [
           "t-Button"
         , "t-Button--noLabel"
         , "padding-sm"
         ]
       , "buttonIcon": "fa-times"
       , "searchIcon": "fa-search"
       }, options);
       function getShuttleValues(elem$) {
         return elem$.children("option").map(function() {
           return {
             text: $(this).text(),
             value: $(this).val()
           };
         });
       }
       return this.each(function(i) {
         var $self = $(this),
           shuttleResetBtnId = $self.attr("id") + "_RESET"
         , $select = $self.find("select")
         , $cell   = $("<td/>", {"colspan": 3})
         , $row    = $("<tr/>").append($cell)
           // get shuttle values
         , shuttleValues = getShuttleValues($select)
           // filter reset button
         , $resetBtn = $("<button/>", {
             "type": "button",
             "title": options.buttonTitle,
             "aria-label": options.buttonTitle,
             "class": options.buttonClass.join(" ")
           }
           ).click(function() {
             // clear filter text field
             $filter.val("").keyup();
           }).append(
             $("<span/>", {
               "aria-hidden": "true",
               "class": "a-Icon fa " + options.buttonIcon,
             })
           )
           // filter icon
         , $filterIcon = $("<span/>", {
             "class": "apex-item-icon fa " + options.searchIcon
           })
           // filter text field
         , $filter = $("<input/>", {
             "type": "text",
             "value": "",
             "autocomplete": "off",
             "placeholder": options.filterPlaceholder,
             "class": "text_field apex-item-text apex-item-has-icon padding-sm padding-left-lg",
             "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(new Option(obj.text, obj.value, false, false));
               }
             });
           })
         ;
         // add needed elements to page
         $cell.append(
           $("<div/>", {"class": "t-Form-itemWrapper"})
           .append($filter)
           .append($filterIcon)
           .append(
             $("<span/>", {
               "class": "t-Form-itemText t-Form-itemText--post"
             }).append($resetBtn)
           )
         );
         $self.on("apexafterrefresh", function() {
           // initiliaze filter when shuttle is refreshed by parent item
           $filter.val("");
           shuttleValues = getShuttleValues($select);
         }).find("table").prepend($row);
         // clear also filter from shuttle reset button
         $("#" + shuttleResetBtnId).click(function() {
           $filter.val("");
         });
       });
     }
    })(apex.jQuery);
  • Shikha 6 Nov 2024

    @Jari .. one issue i am facing in this new code , search is not aligning .. i want yo decrease the wodth of search bar .. where to change that >

  • Shikha 6 Nov 2024

    Worded perfectly .. thanks a ton Jari !!!

  • Jari Laine 6 Nov 2024

    Hi Shikha,

    You might like try this JavaScript

    (function($) {
     $.fn.htmldbShuttlefilter = function(options) {
       options = $.extend({}, {
         "filterPlaceholder": "Filter",
         "buttonTitle": "Clear filter",
         "buttonClass": [
            "t-Button"
           ,"t-Button--noLabel"
           ,"padding-sm"
         ],
         "buttonIcon": "fa-times",
       }, options);
       function getShuttleValues(elem$) {
         return elem$.children("option").map(function() {
           return {
             text: $(this).text(),
             value: $(this).val()
           };
         });
       }
       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.join(" ")
           }
           ).click(function() {
             // clear filter text field
             $filter.val("").keyup();
           }).append(
             $("<span/>", {
               "aria-hidden": "true",
               "class": "a-Icon fa " + options.buttonIcon,
             })
           ),
           // filter icon
           $filterIcon = $("<span/>", {
             "class": "apex-item-icon fa fa-search"
           }),
           // filter text field
           $filter = $("<input/>", {
             "type": "text",
             "value": "",
             "autocomplete": "off",
             "placeholder": options.filterPlaceholder,
             "class": "text_field apex-item-text apex-item-has-icon padding-sm padding-left-lg",
             "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(new Option(obj.text, obj.value, false, false));
               }
             });
           })
         ;
         // add needed elements to page
         $self.prepend(
           $("<div/>", {
             "class": "t-Form-itemWrapper"
           })
           .append($filter)
           .append($filterIcon)
           .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);

    Regards, Jari

  • Shikha 5 Nov 2024

    Hi Jari, is it possible to add search icon before filterPlaceholder ? thanks in advance

  • Jari Laine 11 Mar 2021

    Hi Bil,

    Find and modify below line from JavaScript

    var filterval = new RegExp("^"+$(this).val()+".*","i")

    Change it to something like

    var filterval = new RegExp($(this).val(),"i")

    Regards,
    Jari

  • BIL 11 Mar 2021

    Dear Raf,
    That is great help.
    however, the limitation is that the filter always filters from the first character. Is there any wild letter that can be used for the search?

  • Jari Laine 9 Apr 2020

    Hi Raf,

    Modified code in this post comments may not work on APEX 5.0. Try original version from post. That version of course lack some features. I don't have possibility backport those to APEX 5.0.

  • Raf 8 Apr 2020

    Hi, I'm trying to implement this functionality, but when I run the app and open the page, I got the following error in the console:

    f?p=108:440:6758820266799::NO::::26117 Uncaught TypeError: $(...).htmldbShuttlefilter is not a function

    at HTMLDocument.<anonymous> (f?p=108:440:6758820266799::NO::::26117)

    at j (jquery-2.1.3.min.js?v=5.0.1.00.06:2)

    at Object.fireWith [as resolveWith] (jquery-2.1.3.min.js?v=5.0.1.00.06:2)

    at Function.ready (jquery-2.1.3.min.js?v=5.0.1.00.06:2)

    at HTMLDocument.I (jquery-2.1.3.min.js?v=5.0.1.00.06:2)

  • Spos 20 Feb 2020

    Jari, exactly that.

    Works perfectly.

    Thanks!