Forum Discussion

Astroraf's avatar
Astroraf
Data Pipeline
08-07-2025

Custom Filtering to allow users to filter for specific zip codes

Hi DRay​  and friends,

I am trying to allow my users to filter for multiple different zip codes, and specific zip codes to their use cases. Right now in Sisense a user would have to search and click the ones they want, I know with custom code filtering then can give the codes they want to filter for. Is there any easier way, maybe BloX, where a user can search/filter for multiple zip codes without looking them up/without using the custom code filter option?

example:

 

{
  "explicit": true,
  "multiSelection": true,
  "members": [
    33825,
    34420,
    33834,
    33525,
    34432,
    32134,
    33843,
    34690,
    34691,
    33852,
    33810,
    34638,
    34639,
    33549,
    33559,
    33558,
    34652,
    34470,
    34471,
    34472,
    34473,
    34474,
    34475,
    34476,
    34479,
    34480,
    34481,
    34482,
    33556,
    32179,
    34683,
    34684,
    33576,
    33870,
    33872,
    33875,
    33584,
    34488,
    34491,
    33604,
    33605,
    33610,
    33612,
    33613,
    33614,
    33617,
    33618,
    33619,
    33624,
    33625,
    33637,
    33647,
    33603,
    33607,
    33609,
    33615,
    33626,
    33634,
    33635,
    34689,
    33592,
    33873,
    33543,
    33545,
    33544,
    33540,
    33541,
    33542,
    33823,
    33827,
    33830,
    34714,
    33523,
    33837,
    33896,
    33897,
    33838,
    33839,
    33841,
    33844,
    33847,
    33855,
    33849,
    34759,
    33850,
    33851,
    33853,
    33859,
    33898,
    33801,
    33803,
    33805,
    33809,
    33811,
    33812,
    33813,
    33815,
    33854,
    33860,
    33856,
    33868,
    33867,
    33877,
    34787,
    33880,
    33881,
    33884
  ]
}

8 Replies

  • Vicki786's avatar
    Vicki786
    Data Pipeline

    Hi Astroraf​ ,

    please try the following code.  I put something together per your requirement as an example:


    The JSON body is as follows:

    {
        "title": "ZIP Filter",
        "body": [
            {
                "type": "TextBlock",
                "text": "Paste ZIPs (comma/space/newline), then Apply or Clear",
                "wrap": true,
                "style": {
                    "margin-bottom": "8px"
                }
            },
            {
                "type": "Input.Text",
                "id": "zipbox",
                "isMultiline": true,
                "placeholder": "e.g. 90001, 90002 …",
                "style": {
                    "height": "120px",
                    "border": "1px solid #cbd5e1",
                    "background": "#fff",
                    "padding": "8px",
                    "border-radius": "8px"
                }
            }
        ],
        "actions": [
            {
                "type": "echoZip",
                "title": "Debug: Echo"
            },
            {
                "type": "applyZipFilter",
                "title": "Apply ZIP Filter",
                "opts": {
                    "title": "ZIP Code",
                    "dim": "[Address.ZipCode]",
                    "datatype": "text",
                    "save": false
                }
            },
            {
                "type": "applyZipFilter",
                "title": "Clear",
                "opts": {
                    "title": "ZIP Code",
                    "dim": "[Address.ZipCode]",
                    "datatype": "text",
                    "clear": true,
                    "save": false
                }
            }
        ]
    }



    There are two Actions for this Blox Dashboard as well:


    echoZip is for testing the code:

    (function (payload) {
      var ID = "zipbox";
    
      function getRoot(p) {
        try {
          var w = p && p.widget;
          var cand = [
            p && p.element,
            w && w.element && (w.element.nodeType ? w.element : (w.element[0] || null)),
            w && w.$el && w.$el[0],
            w && w.el && w.el[0]
          ];
          for (var i = 0; i < cand.length; i++) {
            if (cand[i] && cand[i].querySelector) return cand[i];
          }
        } catch (e) {}
        return document;
      }
    
      function readZip(p) {
        if (p && p.inputs && p.inputs[ID] != null) return String(p.inputs[ID]);
        var st = p && p.widget && p.widget.scope && p.widget.scope.state;
        if (st && st[ID] != null) return String(st[ID]);
        var root = getRoot(p);
        var el = root.querySelector("#" + ID) || document.querySelector("#" + ID);
        return el ? (typeof el.value === "string" ? el.value : (el.textContent || "")) : "";
      }
    
      var root = getRoot(payload);
      var v = readZip(payload);
    
      alert("inputs/state/DOM resolved value:\n" + JSON.stringify(v) +
            "\n\nroot used: " + (root === document ? "document" : "widget DOM"));
    })(payload);
    

    and applyZipFilter to take the action:

    (function (payload) {
      var opts = (payload && payload.opts) || {};
      var dash = prism.activeDashboard;
      var ID = "zipbox";
    
      function getRoot(p) {
        try {
          var w = p && p.widget;
          var cand = [
            p && p.element,
            w && w.element && (w.element.nodeType ? w.element : (w.element[0] || null)),
            w && w.$el && w.$el[0],
            w && w.el && w.el[0]
          ];
          for (var i = 0; i < cand.length; i++) {
            if (cand[i] && cand[i].querySelector) return cand[i];
          }
        } catch (e) {}
        return document;
      }
    
      function readZip(p) {
        if (p && p.inputs && p.inputs[ID] != null) return String(p.inputs[ID]);
        var st = p && p.widget && p.widget.scope && p.widget.scope.state;
        if (st && st[ID] != null) return String(st[ID]);
        var root = getRoot(p);
        var el = root.querySelector("#" + ID) || document.querySelector("#" + ID);
        return el ? (typeof el.value === "string" ? el.value : (el.textContent || "")) : "";
      }
    
      var raw = readZip(payload);
    
      // Clear path (explicit or empty)
      if (opts.clear || !String(raw).trim()) {
        try {
          var items = (dash.filters && (dash.filters.$$items || dash.filters.items)) || [];
          var existing = items && items.find(function (f) { return f && f.jaql && f.jaql.dim === opts.dim; });
          if (existing) (dash.filters || dash.$$model.filters).remove(existing);
          dash.refresh();
        } catch (e) { console.error("ZIP clear failed", e); }
        return;
      }
    
      // Parse & de-dupe
      var asNumeric = String(opts.datatype || "text").toLowerCase() === "numeric";
      var parts = String(raw).split(/[\s,;|]+/g).filter(Boolean);
      var seen = Object.create(null), members = [];
      for (var i = 0; i < parts.length; i++) {
        var v = parts[i].trim();
        if (!v) continue;
        if (asNumeric) { if (!/^\d+$/.test(v)) continue; v = Number(v); }
        if (!seen[v]) { seen[v] = 1; members.push(v); }
      }
      if (!members.length) { alert("No valid ZIPs parsed."); return; }
    
      var filterObj = {
        jaql: {
          dim: opts.dim,                         // paste the exact dim from Filter ▸ ⋮ ▸ Advanced
          title: opts.title || "ZIP Code",
          datatype: asNumeric ? "numeric" : "text",
          filter: { explicit: true, multiSelection: true, members: members }
        }
      };
    
      try { (dash.filters || dash.$$model.filters).update(filterObj, { refresh: true, save: !!opts.save }); }
      catch (e1) { (dash.filters || dash.$$model.filters).update([filterObj], { refresh: true, save: !!opts.save }); }
    })(payload);
    

    How to test this script:

    1) type zip code example: 90001, 90002,
    2) click Debug: Echo (you should see the value),
    3) then Apply ZIP Filter (pill should appear),
    4) and Clear (pill removed).

  • DRay's avatar
    DRay
    Sisense Employee

    Hi Astroraf​,

    Thank you for reaching out. I see your question hasn't gotten a response yet, so I'm asking internally to try and get you an answer. 

  • DRay's avatar
    DRay
    Sisense Employee

    Hi Astroraf​ ,

    I’m following up to see if the solution offered by Vicki786​ worked for you.

    If so, please click the 'Accept as Solution' button on their post. That way others with the same questions can find the answer. If not, please let us know so that we can continue to help.

    Thank you.

    • DRay's avatar
      DRay
      Sisense Employee

      Thank you for the update. Would you be willing to share your solution? I think others would be interested in seeing how you solved this.