jQuery UI widget for structured queries like "Contacts where Firstname starts with A and Birthday before 1/1/2000 and State in (CA, NY, FL)"...

Overview

Structured-Filter · GitHub license npm version

Structured-Filter is a generic Web UI for building structured search or filter queries.

With it you can build structured search conditions like Firstname starts with 'A' and Birthday after 1/1/1980 and State in (CA, NY, FL)... It is a full jQuery UI widget, supporting various configurations and themes.

Structured-Filter screenshot

Check the demo for live examples.

Table of Contents

  1. Installation
  2. Usage
  3. Model
  4. Options
  5. Methods
  6. Events
  7. Theming
  8. License

Installation

You can download or fork structured-filter on GitHub.

# To get the latest stable version, use git from the command line.
git clone https://github.com/evoluteur/structured-filter

or install the npm package:

# To get the latest stable version, use npm from the command line.
npm install structured-filter

or install with Bower:

# To get the latest stable version, use Bower from the command line.
bower install structured-filter

# To get the most recent, latest committed-to-master version use:
bower install structured-filter#master

Notes:

  • If you use a version of jQuery-UI smaller than 1.12.1, you must use Structured-Filter version 1.1.0.
  • For React, use Structured-Filter-React.

Usage

First, load jQuery, jQuery UI, and the plugin:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/structured-filter.js" type="text/javascript" charset="utf-8"></script>

The widget requires a jQuery UI theme to be present, as well as its own included base CSS file (structured-filter.css). Here we use the "base" theme as an example:

<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/base/jquery-ui.css">
<link href="css/structured-filter.css" rel="stylesheet" type="text/css">

Now, let's attach it to an existing <div> tag:

<script type="text/javascript">
    $(document).ready(function() {
        $("#myFilter").structFilter({
            fields: [
                {id:"lastname", type:"text", label:"Lastname"},
                {id:"firstname", type:"text", label:"Firstname"},
                {id:"active", type:"boolean", label:"Is active"},
                {id:"age", type:"number", label:"Age"},
                {id:"bday", type:"date", label:"Birthday"},
                {id:"category", type:"list", label:"Category",
                    list:[
                        {id:"1", label:"Family"},
                        {id:"2", label:"Friends"},
                        {id:"3", label:"Business"},
                        {id:"4", label:"Acquaintances"},
                        {id:"5", label:"Other"}
                    ]
                }
            ]
        });
    });
</script>

<div id="myFilter"></div>

This will change the <div> into the widget.

Model

The widget is configured with a list of fields to use in the search conditions.

Fields

Each field must have an ID, a type, and a label.

  • id - unique identifier for the field.
  • label - displayed field name.
  • type - data type. Possible types of field: text, number, boolean, date, time, list.

Fields of type "list" must also have a "list" property for the values (array of objects with id and label).

Example:

fields = [
    {id:"lastname", type:"text", label:"Lastname"},
    {id:"firstname", type:"text", label:"Firstname"},
    {id:"active", type:"boolean", label:"Is active"},
    {id:"age", type:"number", label:"Age"},
    {id:"bday", type:"date", label:"Birthday"},
    {id:"category", type:"list", label:"Category",
        list:[
            {id:"1", label:"Family"},
            {id:"2", label:"Friends"},
            ...
        ]
    }
];

Note: To change the behavior of a "list" field, use the type "list-options" and "list-dropdown" instead of "list".

Conditions

Queries are expressed as a set of conditions.

Each condition is defined by:

  • a field
  • an operator
  • one or several values

For each field the possible operators are determined by it's type.

boolean boolean

  • Yes (1)
  • No (0)

Boolean field screenshot

date date

  • on (eq)
  • not on (ne)
  • after (gt)
  • before (lt)
  • between (bw)
  • not between (nbw)
  • is empty (null)
  • is not empty (nn)

Date field screenshot

list list

  • any of (in)
  • equal (eq)

List field screenshot

number number

  • = (eq)
  • != (ne)
  • > (gt)
  • < (lt)
  • is empty (null)
  • is not empty (nn)

Number field screenshot

text text

  • equals (eq)
  • not equal (ne)
  • starts with (sw)
  • contains (ct)
  • doesn't contain (nct)
  • finishes with (fw)
  • is empty (null)
  • is not empty (nn)

Text field screenshot

time time

  • at (eq)
  • not at (ne)
  • after (gt)
  • before (lt)
  • between (bw)
  • not between (nbw)
  • is empty (null)
  • is not empty (nn)

Options

structured-filter provides several options to customize its behaviour:

buttonLabels (Boolean)

The labels of buttons used to manipulate filters. This options applies to the 3 buttons, "New filter", "Add filter"/"Update filter" and "Cancel" which use icons if the option is set to false.

$("#myFilter").structFilter({
    buttonLabels: true
});

Defaults to false.

dateFormat (String)

The format for parsed and displayed dates. This attribute is one of the regionalisation attributes. Common formats are: Default - "mm/dd/yy", ISO 8601 - "yy-mm-dd", Short - "d M, y", Medium - "d MM, y", Full - "DD, d MM, yy". For a full list of the possible formats see the jQuery formatDate function.

$("#myFilter").structFilter({
    dateFormat: "d M, y"
});

Defaults to "mm/dd/yy".

disableOperators (Boolean)

This option disables operators from conditions. This changes the structure of conditions from "field-operator-value" to "field-value" which simplifies the backend implementation of filtering.

$("#myFilter").structFilter({
    disableOperators: true
});

Defaults to "false".

fields (Array of Fields)

The list of fields (as an array of objects with id, label and type) to participate in the query definition. Possible types are: text, boolean, number, date, time, and list.

$("#myFilter").structFilter({
    fields: [
        {id:"lastname", type:"text", label:"Lastname"},
        {id:"firstname", type:"text", label:"Firstname"},
        {id:"active", type:"boolean", label:"Is active"},
        {id:"age", type:"number", label:"Age"},
        {id:"bday", type:"date", label:"Birthday"},
        {id:"category", type:"list", label:"Category",
            list:[
                {id:"1", label:"Family"},
                {id:"2", label:"Friends"},
                {id:"3", label:"Business"},
                {id:"4", label:"Acquaintances"},
                {id:"5", label:"Other"}
            ]
        }
    ]
});

Defaults to [ ].

highlight (Boolean)

A highlight animation performed on the last added or modified filter.

$("#myFilter").structFilter({
    highlight: false
});

Defaults to true.

submitButton (Boolean)

Shows or hides the "Submit" button.

$("#myFilter").structFilter({
    submitButton: true
});

Defaults to false.

submitReady (Boolean)

Provides hidden fields with the conditions' values to be submitted with the form (as an alternative to an AJAX call).

$("#myFilter").structFilter({
    submitReady: true
});

Defaults to false.

Methods

addCondition(data)

Adds a new filter condition.

$("#myFilter").structFilter("addCondition", {
    field:{
        label: "Lastname",
        value: "lastname"
    },
    operator:{
        label: "starts with",
        value: "sw"
    },
    value:{
        label: "\"a\"",
        value: "a"
    }
});

clear()

Removes all search filters.

$("#myFilter").structFilter("clear");

length()

Gets the number of filters.

$("#myFilter").structFilter("length");

removeCondition(index)

Removes the condition of the specified index.

$("#myFilter").structFilter("removeCondition", 0);

val([data])

Gets or sets the filter definition (as an array of filters).

$("#myFilter").structFilter("val");

$("#myFilter").structFilter("val", data);

Sample value:

[
    {
        field:{
            label: "Lastname",
            value: "Lastname"
        },
        operator:{
            label: "starts with",
            value: "sw"
        },
        value:{
            label: "\"jo\"",
            value: "jo"
        }
    }
]

valText()

Gets the filter definition (as a readable text string).

$("#myFilter").structFilter("valText");

Sample value:

Lastname starts with "jo"

valUrl()

Gets the filter definition (as a URL string).

$("#myFilter").structFilter("valUrl");

Sample value:

filters=1&field-0=Lastname&operator-0=sw&value-0=jo&label=Lastname%20starts%20with%20%22jo%22%0A

Events

change.search

This event is triggered when the list of search conditions is modified.

$("#myFilter").on("change.search", function(event){
    // do something
});

submit.search

This event is triggered when the submit button is clicked.

$("#myFilter").on("submit.search", function(event){
    // do something
});

Theming

structured-filter is as easily themeable as any jQuery UI widget, using one of the jQuery UI themes or your own custom theme made with Themeroller.

screenshot themes

CSS for themes can be accessed from Google Hosted Libraries.

Dark theme ("ui-darkness"):

<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.13.2/themes/ui-darkness/jquery-ui.css" rel="stylesheet" type="text/css">

A version of structured-filter for Bootstrap and Backbone.js is available as part of Evolutility-UI-jQuery set of generic views for CRUD (Create, Read, Update, Delete) and more.

A re-write for React in under construction at Structured-Filter-React.

License

Structured-Filter is released under the MIT license.

Copyright (c) 2022 Olivier Giulieri.

Comments
  • Restore filter from valUrl

    Restore filter from valUrl

    I get the filter url: let filterUrlFormat = $('#sonarioFilter').structFilter('valUrl');

    Then I try to set the filter, but it fails to do anything: $('#sonarioFilter').structFilter('valUrl',"filters=1&field-0=Gender&operator-0=eq&value-0=male&label=Gender%20equals%20%22male%22%20");

    Is there something I'm missing?

    opened by samcov 9
  • Run time add new fields in structFilter

    Run time add new fields in structFilter

    It's possible to add new fields object { id: "FieldID", type: "text", label: "FieldLabel" } in existing structFilter.

    $("#myFilter").structFilter({ fields: [ {type:"text", id:"lastname", label:"Lastname"}, {type:"text", id:"firstname", label:"Firstname"}, ] });

    opened by Ponvijaykumar 2
  • Can't get widget display to use the icons

    Can't get widget display to use the icons

    I'm very interested in using this package,but I am having difficulty getting the widget display right. I'm using jQuery 2.2.4, jQuery-ui 1.12.1.

    I'm following the installation instructions per the documentation. I am attempting to use this in a Flask application that uses Jinja templating and bootstrap 3.Rather than getting the nice looking display in the demo, I am getting text rather than the icons, an unappealing looking filter list, and the filter list has no way to remove a filter. In short, the icons and attractive theming is not rendering. I've even tried explicitly setting the buttonLabels option to false.

    ...

    Can you assist? Thank you

    opened by pbosavage 2
  • Collision with Bootstrap Javascript

    Collision with Bootstrap Javascript

    The css for structured-filter does not work if used with bootstrap.

    The offender is not in the css, but in the javascript. To reproduce the problem, simply add the following,

        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
    
        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    

    Then lower the jquery version to something under version 3, which bootstrap doesn't like. Then the styling will go away.

    It only occurs when the .js is there, removing the bootstrap css and leaving the js causes the problem.

    opened by samcov 2
  • Add exclusive list and select list

    Add exclusive list and select list

    I implemented a version of select and exclusive lists (based on description in the issues I opened). Works fine on my end but I don't know your code too well and since its not a particularly minor change, it is possible that I broke something in the process.

    opened by jsmccrumb 2
  • Having trouble getting the x close synble to show  up on the filters

    Having trouble getting the x close synble to show up on the filters

    After i create a filter. The little x to remove the filter will not show up. Could you point me in the direction to resolve this?

    Im including jquery base css and light theme css and jquery jquery ui and the project js missingfilterclosebutton

    Thank you for your time in advanced.

    opened by zach2825 2
  • Bump jquery from 3.4.1 to 3.5.0

    Bump jquery from 3.4.1 to 3.5.0

    Bumps jquery from 3.4.1 to 3.5.0.

    Commits
    • 7a0a850 3.5.0
    • 8570a08 Release: Update AUTHORS.txt
    • da3dd85 Ajax: Do not execute scripts for unsuccessful HTTP responses
    • 065143c Ajax: Overwrite s.contentType with content-type header value, if any
    • 1a4f10d Tests: Blacklist one focusin test in IE
    • 9e15d6b Event: Use only one focusin/out handler per matching window & document
    • 966a709 Manipulation: Skip the select wrapper for <option> outside of IE 9
    • 1d61fd9 Manipulation: Make jQuery.htmlPrefilter an identity function
    • 04bf577 Selector: Update Sizzle from 2.3.4 to 2.3.5
    • 7506c9c Build: Resolve Travis config warnings
    • Additional commits viewable in compare view
    Maintainer changes

    This version was pushed to npm by mgol, a new releaser for jquery since your current version.


    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Disable operators

    Disable operators

    In options array

     disableOperators: false
    

    In _setEditorOperator method at the begin

    if(this.options.disableOperators) {
            this._step=2;
            return this._setEditorValue();
    }
    
    opened by LborV 1
  • issue while retrieving value from structured-filter

    issue while retrieving value from structured-filter

    I am integrating this component, and after filter changed or submit i am posting those values to some link... while retrieving value from component i am getting some issue.. Please help me where i doing worng

    adding error stack (index):48 Uncaught TypeError: $(...).structFilter is not a function at updateValue ((index):48) at HTMLDivElement. ((index):95) at HTMLDivElement.dispatch (jquery.min.js:3) at HTMLDivElement.q.handle (jquery.min.js:3) at Object.trigger (jquery.min.js:4) at HTMLDivElement. (jquery.min.js:4) at Function.each (jquery.min.js:2) at r.fn.init.each (jquery.min.js:2) at r.fn.init.trigger (jquery.min.js:4) at t.(:8570/anonymous function).(anonymous function)._triggerChange (http://localhost:8570/Scripts/structured-filter.js:599:16) updateValue @ (index):48 (anonymous) @ (index):95 dispatch @ jquery.min.js:3 q.handle @ jquery.min.js:3 trigger @ jquery.min.js:4 (anonymous) @ jquery.min.js:4 each @ jquery.min.js:2 each @ jquery.min.js:2 trigger @ jquery.min.js:4 _triggerChange @ structured-filter.js:599 (anonymous) @ jquery-ui.min.js:6 addCondition @ structured-filter.js:264 (anonymous) @ jquery-ui.min.js:6 (anonymous) @ structured-filter.js:144 dispatch @ jquery.min.js:3 q.handle @ jquery.min.js:3

    image

    opened by shai1984m 1
  • can't get the remove icon to show

    can't get the remove icon to show

    hello, thanks for the nice code, but I'm having a problem showing the x icon to remove the a single filter i'm using bootstrap 3.3.7 and a custom jquery-ui theme for bootstrap

    opened by mhmd1983 1
  • Filrer as OData query

    Filrer as OData query

    Hi there, first of all thank You for such great project. I'm wondering if it is possible to create OData query from filter build with Your builder. I'd like to use Your builder to create filter that could be send to OData endpoint.

    opened by Misiu 1
  • Auto Complete for all dropdowns

    Auto Complete for all dropdowns

    Feature Request:

    It will be a very useful feature if we can provide autocomplete by typing in the dropdowns.

    So that user doesn't have to find from dropdown.

    enhancement 
    opened by hnviradiya 4
  • Dropdown select filter

    Dropdown select filter

    It would be nice to give a predefined list of values for a filter. For example, if the data that was being queried only had X options for a field, would be nice to show all of them and let the user select the one they wanted. Would use less screen space than a normal list of say 10 options, though would be limited to only one option?

    Perhaps:

    { type: "selectList", id: "myID", label: "Birthmonth", list: [
      {id: "jan", label: "January"},
      {id: "feb", label: "February"},
      {id: "mar", label: "March"},
      {id: "apr", label: "April"},
      {id: "may", label: "May"},
      {id: "jun", label: "June"},
      {id: "jul", label: "July"},
      {id: "aug", label: "August"},
      {id: "sep", label: "September"},
      {id: "oct", label: "October"},
      {id: "nov", label: "November"},
      {id: "dec", label: "December"}
    ]}
    

    and then:

    case fTypes.selectList:
      var arrayLength = this._field.list.length;
      h+='<select id="value">'+EvoUI.optNull;
      for (var i = 0; i < arrayLength; i++) {
        h+=EvoUI.inputOption(this._field.list[i].id, this._field.list[i].label);
      }
      h+='</select>';
      break;
    

    just a rough sketch of a possible way?

    enhancement 
    opened by jsmccrumb 0
  • Exclusive list

    Exclusive list

    It would be nice to have a list but with radio buttons so only one option is ever selected.

    Perhaps:

    { type: "exclusiveList", id: "myID", label: "Fancy Exclusive List", list: [
      {id: "opt1", label: "First Option"},
      {id: "opt2", label: "Second Option"},
      {id: "opt3", label: "Third Option"}
    ]}
    

    And then

    case fTypes.exculsiveList:
      var arrayLength = this._field.list.length;
      h+='<span id="value">';
      for (var i = 0; i < arrayLength; i++) {
        h+= EvoUI.inputRadio(this._field.list[i].label, this._field.list[i].id, this._field.list[i].label, v==this._field.list[i].id, 'value' + this._field.list[i].id);
      }
      h +='</span>';
      break;
    

    Haven't looked too deeply into this, I know there would need to be a few more changes to bring this in.

    enhancement 
    opened by jsmccrumb 0
  • Custom OR logic?

    Custom OR logic?

    It would be awesome if I could do filtering like this: { {Username contains 'asdf' AND Lastname contains 'foo'} OR {Username startswith 'A' and age < 13} }

    This way a lot more flexible queries could be built

    enhancement 
    opened by vladiibine 8
Releases(2.0.5)
Owner
Olivier Giulieri
Creative UI engineer with an eye for UX and a passion for model-driven UIs.
Olivier Giulieri
TikTokLive-Widget: A socket client/server program that exposes a widget with alerts (such as gifts, followers ...) for a specific user streaming on Tik Tok Live platform

TikTokLive-Widget: A socket client/server program that exposes a widget with alerts (such as gifts, followers ...) for a specific user streaming on Tik Tok Live platform

null 3 Dec 3, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
A tiny, reactive JavaScript library for structured state and tabular data.

A JavaScript library for structured state. Using plain old JavaScript objects to manage data gets old very quickly. It's error-prone, tricky to track

tinyplex 1.4k Jan 1, 2023
API dot Open Sauced is NestJS and SupaBase powered OAS3 backend designed to remove client complexity and provide a structured graph of all @open-sauced integrations

?? Open Sauced Nest Supabase API ?? The path to your next Open Source contribution ?? Prerequisites In order to run the project we need the following

TED Vortex (Teodor-Eugen Duțulescu) 13 Dec 18, 2022
Lazy minting of ERC721 NFTs using EIP712 standard for typed, structured data. ✨

ERC721 - Signature minting Lazy minting of ERC721 NFTs using EIP712 standard for typed, structured data. ✨ How it works Lazy minting or Signature mint

Sunrit Jana 21 Oct 20, 2022
Stacks Voice is a reference project that builds on the SIP018 signed structured data standard to create an accountless internet forum.

Stacks Voice Stacks Voice is a reference project that builds on the SIP018 signed structured data standard to create an accountless internet forum. Th

Clarity Innovation Lab 4 Dec 21, 2022
JqTree - Tree widget for jQuery

jqTree JqTree is a tree widget. Read more in the documentation. Features Create a tree from JSON data Drag and drop Works on ie9+, firefox, chrome and

Marco Braak 1k Dec 22, 2022
Touch enabled selectable plugin inspired by the jQuery UI widget.

Inspired by the jQuery UI Selectable plugin. Functionality and options are identical to the jQuery UI version with some additions and performance enha

Karl 135 Nov 24, 2022
jQuery UI widget for color picking (similar to the one in Microsoft Office 2010).

evol-colorpicker · evol-colorpicker is a web color picker which looks like the one in Microsoft Office 2010. It can be used inline or as a popup bound

Olivier Giulieri 285 Dec 14, 2022
A work-in-progress HTML sanitizer that strives for: performance like window.Sanitizer, readiness like DOMPurify, and ability to run in a WebWorker like neither of those.

Amuchina A work-in-progress HTML sanitizer that strives for: performance like window.Sanitizer, readiness like DOMPurify, and ability to run in a WebW

Fabio Spampinato 9 Sep 17, 2022
Fintoc.js ES Module - Use the Fintoc widget as an ES module

Fintoc.js ES Module Use the Fintoc widget as an ES module. Installation Install using npm! (or your favourite package manager) # Using npm npm install

Fintoc 6 May 13, 2022
Matrix Moderation Widget for Mjolnir

A widget for moderating with mjolnir. Highly WIP. Use at your own risk!

Marcel 7 Jun 23, 2022
A Q&A widget for your docs

Squeak! [BETA] Squeak! lets you answer user questions, right in your docs. Even better: it lets your community support itself. Top features Embeds in

PostHog 127 Jan 7, 2023
Table of contents Trilium widget for editable and readonly text notes.

Trilium-TocWidget Table of contents Trilium widget for editable and readonly text notes. Screenshot Features The ToC is live and automatically updated

Antonio Tejada 25 Dec 29, 2022
Find in note Trilium widget to replace the crappy ctrl+f search.

Trilium-FindWidget Find in note Trilium widget to replace the crappy ctrl+f search. Video sandbox.-.Trilium.Notes.2022-04-22.15-41-19_rescaled.mp4 Fea

Antonio Tejada 8 Nov 22, 2022
PoGOEvents is a Scriptable widget that displays current and upcoming Pokemon GO events.

PoGOEvents PoGOEvents is a Scriptable widget that displays current and upcoming Pokemon GO events. All event data is gathered from from ScrapedDuck, w

Anthony 33 Nov 12, 2022
Scriptable Widget which shows current news from tagesschau.de

tagesschau-widget for Scriptable Based on this reddit post of u/trbn_hck Unfortunately the Repositorie in his GitHub profile is no longer exist. Widge

Robinson 5 Sep 12, 2022