Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DS_Store
node_modules
/dist
/docs/.vuepress/dist

# local env files
.env.local
Expand Down
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ cache:
yarn: true

script:
- yarn test:unit
- yarn build
- yarn run test:unit
- yarn run build
- yarn run docs:build
58 changes: 36 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
# query-builder
[![Build Status](https://travis-ci.org/rtucek/vue-query-builder.svg?branch=master)](https://travis-ci.org/rtucek/vue-query-builder)
![npm](https://img.shields.io/npm/v/query-builder-vue)
![NPM](https://img.shields.io/npm/l/query-builder-vue)

## Project setup
```
yarn install
```
# Vue Query Builder

### Compiles and hot-reloads for development
```
yarn run serve
```
A query-builder for Vue.

### Compiles and minifies for production
```
yarn run build
```

### Run your tests
```
yarn run test
```
## Demos

### Lints and fixes files
```
yarn run lint
Plenty of samples and use cases are covered in the
[documentation](https://rtucek.github.io/vue-query-builder/demos.html).


## Features

Key features:

- Re-ordering of rules and groups with drag'n'drop.
- Emphasizing groups with configurable colors.
- Control maximum depth of nested groups.
- Easy to customize with pure CSS and slots.
- Layout can be serialized and restored.
- Vuex compatible.
- TypeScript support.


## Installation

```bash
yarn add query-builder-vue
npm install query-builder-vue
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
Follow the docs for [minimum
configuration](https://rtucek.github.io/vue-query-builder/getting-started.html#usage).


## Contribution

[Contribution guidelines](https://rtucek.github.io/vue-query-builder/contributing.html) are located
in the documentation.
13 changes: 13 additions & 0 deletions deploy-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env sh

set -e

yarn run docs:build

(
cd docs/.vuepress/dist
git init
git add -A
git commit -m 'deploy docs'
git push -f [email protected]:rtucek/vue-query-builder.git master:gh-pages
)
4 changes: 4 additions & 0 deletions dev/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,13 @@ export default class App extends Vue {
</script>

<style lang="scss">
@import url('https://fonts.googleapis.com/css?family=Roboto&display=swap');

body {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
font-size: 16px;
}

#app {
Expand Down
24 changes: 24 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
title: 'Query Builder Vue',
description: 'Query Builder Vue documentation',

base: '/vue-query-builder/',

themeConfig: {
nav: [
],

repo: 'rtucek/vue-query-builder',
docsDir: 'docs',
editLinks: true,

sidebar: [
['/', 'Introduction'],
['/demos', 'Demos'],
['/getting-started', 'Getting Started'],
['/configuration', 'Configuration'],
['/styling', 'Styling'],
['/contributing', 'Contributing'],
],
},
}
34 changes: 34 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Vue Query Builder

A Vue Query Builder library.


## About

This library got heavily inspired by [Daniel Abernathy's](https://github.com/dabernathy89) awesome
[vue-query-builder](https://github.com/dabernathy89/vue-query-builder) library, which got in turn
inspired by jQuery's [Knockout Query Builder](https://kindohm.github.io/knockout-query-builder/).

The intention behind building my own was adding some missing features such as providing TypeScript
support and re-ordering with drag'n'drop.

<iframe
src="https://codesandbox.io/embed/introduction-demo-ig55y?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.vue&theme=dark&view=preview"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="Introduction Demo"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>


## Features

The query builder has the following key features:

- Re-ordering of rules and groups with drag'n'drop.
- Emphasizing groups with configurable colors.
- Control maximum depth of nested groups.
- Easy to customize with pure CSS and slots.
- Layout can be serialized and restored.
- Vuex compatible.
- TypeScript support.
218 changes: 218 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
# Configuration

The configuration is performed by the `config` prop. A single object, which shape is defined by the
[QueryBuilderConfig interface](https://github.com/rtucek/vue-query-builder/blob/master/types/index.d.ts#L26).

Below, we'll cover every key aspect of the config object.


## Operators

The operators are used for allowing the users to choose how rules within a group should be
evaluated. For instance, you may allow the users select classic boolean operators like *AND* and
*OR* for a group. Additionally, you could also provide less common operators like *ONE OF* for
requiring at least on condition is satisfied for considering an entire group as truthy.
Along your existing operators, you may also provide the negated counterparts like *AND NOT*, *OR
NOT* and *NONE OF* operators.

Every operator is defined by an unique identifier and a visual text.


```js
{
operators: [
{
name: 'AND',
identifier: 'AND',
},
{
name: 'OR',
identifier: 'OR',
},
{
name: 'OR NOT',
identifier: 'OR_NOT',
},
{
name: 'AND NOT',
identifier: 'AND_NOT',
},
// ...
],
}
```


## Rules

Rules are individual conditions within a group and must be defined as components, adhering to the
[v-modle API](https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components).

Every must have a unique identifier, a display name, the underlying component and optionally an
individual value.

You may want to wrap an external library with a dedicated component for one of the following
reasons:
- The library doesn't support the v-model API.
- The underlying component requires addition configuration or you may want to provide additional
configuration with props.
- You want to apply custom CSS.

The `initialValue` may provide any primitive value (string, number or null), however any object or
array must be constructed by a factory function.

There are several options for assigning a component to a rule:
- JavaScript modules
- Pre-defined Vue Components
- Inline the component's definition directly (requires compiler-included build for templates or use
render functions directly)


```js
import InputSelection from './InputSelection.vue';

Vue.component('NumberSelection', {
template: `
<input
type="text"
v-model="model"
placeholder="dummy input"
>
`,
props: [
'value',
],
computed: {
model: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value);
},
},
},
});

{
rules: [
{
identifier: 'txt',
name: 'Text Selection',
component: InputSelection,
initialValue: '',
},
{
identifier: 'num',
name: 'Number Selection',
component: 'NumberSelection',
initialValue: 10,
},
{
identifier: 'other-num',
name: 'Other Number Selection',
component: {
template: `
<input
type="text"
v-model="model"
placeholder="dummy input"
>
`,
props: [
'value',
],
computed: {
model: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value);
},
},
},
},
},
],
}
```

<iframe
src="https://codesandbox.io/embed/rules-cyll8?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.vue&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="Config Rules"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>


## Colors

A complex, deep nested query can quickly become confusing. In order to keep an overview, nested
groups may be emphasized with colorful hints.

The colors property should be a string array with a minimum length of at least 2, containing any
valid CSS color definition.


```js
{
colors: [
'hsl(88, 50%, 55%)',
'hsl(187, 100%, 45%)',
'hsl(15, 100%, 55%)',
],
}
```

<iframe
src="https://codesandbox.io/embed/config-colors-gx5dh?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.vue&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="Config Colors"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>


## Sortable

Thanks to the excellent [Vue.Draggable](https://github.com/SortableJS/Vue.Draggable) library, the
query builder supports re-sorting rules and groups with drag'n'drop.

The sortable feature is disabled by default, however you may enable it simply by any [Sortable
options](https://github.com/SortableJS/Sortable#options) on the dragging property.

::: warning
There are 2 exceptions on the sortable options object:

- `groups` are ignored. The main reason is that the query builder will have set the value internally
for allowing nested dragging.

- All methods with `on` are ignored. From
[Vue.Sortable's documentation](https://github.com/SortableJS/Vue.Draggable#all-sortable-options):
> [...]
>
> This means that all sortable option are valid sortable props with the notable exception of all
> the method starting by "on" as draggable component expose the same API via events.
>
> [...]
:::

```js
{
dragging: {
animation: 300,
disabled: false,
dragClass: "sortable-drag"
}
}
```

<iframe
src="https://codesandbox.io/embed/config-dragging-uwi8o?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.vue&theme=dark"
style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;"
title="Config Dragging"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>
Loading