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 11-MAR-21 04.57.17.589522 AM

    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-21 04.41.40.532667 AM

    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 09-APR-20 03.56.16.000000 AM

    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 08-APR-20 09.13.55.000000 PM

    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-20 08.17.50.000000 AM

    Jari, exactly that.

    Works perfectly.

    Thanks!

  • Jari Laine 19-FEB-20 06.03.19.000000 PM

    Hi Spos,

    You mean get filter working when shuttle is refreshed by cascading parent item?
    If so, try below code

    (function($){
     $.fn.htmldbShuttlefilter=function(options){
      options=$.extend({},{"filterPlaceholder":"Filter","buttonTitle":"Clear filter","buttonClass":"fa-times"},options);
       return this.each(function(i){
        var $self      = $(this)
        ,filterId      = $self.attr("id") + "_FILTER"
        ,$select       = $self.find("select")
        ,$resetBtn     = $("<button/>",{
          "type"       : "button"
         ,"class"      : "t-Button t-Button--noLabel t-Button--icon t-Button--small"
         ,"title"      : options.buttonTitle
         ,"aria-label" : options.buttonTitle
         }).append(
          $("<span/>",{
            "aria-hidden" : "true"
           ,"class"       : "t-Icon fa " + options.buttonClass
           ,
          })
        )  
       ,shuttleValues = $select.children("option").map(function(){
        return {text:$(this).text(),value:$(this).val(),option:this}
       })
       ,$filter = $("<input/>",{"css":{"width":"100%"},"type":"text","placeholder":options.filterPlaceholder,"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"]);
         }
        });
       });
       $resetBtn.click(function(){$filter.val("").keyup()});
    
       $self.prepend(
        $("<div/>",{"css":{"padding-bottom":"5px","width":"90%"}})
        .append(
         $("<div/>",{"css":{"white-space":"nowrap"}})
         .append($filter)
         .append($resetBtn)
        )
       );
       $self.find("button[title='Reset']").click(function(){$filter.val("")});
    
       // Bind to apexafterrefresh event to initiliaze filter
       $self.on("apexafterrefresh", function(){
         shuttleValues = $select.children("option").map(function(){
           return {text:$(this).text(),value:$(this).val(),option:this}
         });  
       });
    
      });
     }
    })(apex.jQuery);

    Changes I made are in rows 49 - 53

  • Spos 19-FEB-20 12.05.14.000000 PM

    Has anyone find solution for Shuttle Item with Cascading LOV Parent Item(s) defined?

  • Rafal 10-OCT-19 01.24.37.000000 PM

    Hi Jari,

    Works pefectly. Thanks a lot.

    Rafal

  • Jari Laine 10-OCT-19 01.10.39.000000 PM

    Hi Rafal,

    See if this JavaScript works better on APEX 19.1

    (function($){
     $.fn.htmldbShuttlefilter=function(options){
      options=$.extend({},{"filterPlaceholder":"Filter","buttonTitle":"Clear filter","buttonClass":"fa-times"},options);
       return this.each(function(i){
        var $self      = $(this)
        ,filterId      = $self.attr("id") + "_FILTER"
        ,$select       = $self.find("select")
        ,$resetBtn     = $("<button/>",{
          "type"       : "button"
         ,"class"      : "t-Button t-Button--noLabel t-Button--icon t-Button--small"
         ,"title"      : options.buttonTitle
         ,"aria-label" : options.buttonTitle
         }).append(
          $("<span/>",{
            "aria-hidden" : "true"
           ,"class"       : "t-Icon fa " + options.buttonClass
           ,
          })
        )  
       ,shuttleValues = $select.children("option").map(function(){
        return {text:$(this).text(),value:$(this).val(),option:this}
       })
       ,$filter = $("<input/>",{"css":{"width":"100%"},"type":"text","placeholder":options.filterPlaceholder,"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"]);
         }
        });
       });
       $resetBtn.click(function(){$filter.val("").keyup()});
       
       $self.prepend(
        $("<div/>",{"css":{"padding-bottom":"5px","width":"90%"}})
        .append(
         $("<div/>",{"css":{"white-space":"nowrap"}})
         .append($filter)
         .append($resetBtn)
        )
       );
       $self.find("button[title='Reset']").click(function(){$filter.val("")});
      });
     }
    })(apex.jQuery);

    Regards,
    Jari

  • Rafal 10-OCT-19 12.54.09.000000 PM

    Hi Jari,

    I'm trying to use your code with the 'clear' buttow in Apex 19.1. Filtering of shuttle values works really nice, but I have a problem with the page layout - the shuttle appears just next to the 'clear' button, and not below. Could you please advise, what should be added to the code to make the components correctly displayed on the page? I don't have too much experience with javascript and css.

    Thank you in advance.

    Rafal