2

Looking for a way of using the jQuery Query Builder in my angular-cli project.

First I've tried using the plugin laplasianin/angular-jqueryQueryBuilder, but I miss instructions on how to actually import this into my component. I am very novice at angular/typescript.

Then I've tried it on my own by installing the builder package: npm install jQuery-QueryBuilder

I've added it to my component, just like jQuery. This is the resulting example code, based on the following demo:

import {AfterViewInit, Component} from "@angular/core";
import * as jQuery from "jquery";
import "jQuery-QueryBuilder/dist/js/query-builder.standalone.js";
import "jQuery-QueryBuilder/dist/css/query-builder.default.css";

@Component({
    selector: 'app-query-builder',
    templateUrl: './query-builder.component.html',
    styleUrls: ['./query-builder.component.scss']
})
export class QueryBuilderComponent implements AfterViewInit{
    protected rules_basic = {
        condition: 'AND',
        rules: [{
            id: 'price',
            operator: 'less',
            value: 10.25
        }, {
            condition: 'OR',
            rules: [{
                id: 'category',
                operator: 'equal',
                value: 2
            }, {
                id: 'category',
                operator: 'equal',
                value: 1
            }]
        }]
    };

    ngAfterViewInit() {
        this.getQueryBuilder();
    }


    private getQueryBuilder() {
        // jQuery('#builder').html('appelsap');
        let queryBuilder = jQuery.fn.queryBuilder;
        jQuery('#builder').queryBuilder({
            plugins: ['bt-tooltip-errors'],

            filters: [{
                id: 'name',
                label: 'Name',
                type: 'string'
            }, {
                id: 'category',
                label: 'Category',
                type: 'integer',
                input: 'select',
                values: {
                    1: 'Books',
                    2: 'Movies',
                    3: 'Music',
                    4: 'Tools',
                    5: 'Goodies',
                    6: 'Clothes'
                },
                operators: ['equal', 'not_equal', 'in', 'not_in', 'is_null', 'is_not_null']
            }, {
                id: 'in_stock',
                label: 'In stock',
                type: 'integer',
                input: 'radio',
                values: {
                    1: 'Yes',
                    0: 'No'
                },
                operators: ['equal']
            }, {
                id: 'price',
                label: 'Price',
                type: 'double',
                validation: {
                    min: 0,
                    step: 0.01
                }
            }, {
                id: 'id',
                label: 'Identifier',
                type: 'string',
                placeholder: '____-____-____',
                operators: ['equal', 'not_equal'],
                validation: {
                    format: /^.{4}-.{4}-.{4}$/
                }
            }],

            rules: this.rules_basic
        });
    }
}

In this case the app compiles and loads, but I get the following error in return Cannot read property 'template' of undefined.

I have no clue on how to get any of this working. Would really like some help on this. Thank you.

======= EDIT As asked, this is the complete error:

ERROR TypeError: Cannot read property 'template' of undefined
    at QueryBuilder.<anonymous> (query-builder.standalone.js:415)
    at Array.forEach (<anonymous>)
    at new QueryBuilder (query-builder.standalone.js:410)
    at jQuery.fn.init.$.fn.queryBuilder (query-builder.standalone.js:3934)
    at QueryBuilderComponent.webpackJsonp.../../../../../src/app/components/application/query-builder/query-builder.component.ts.QueryBuilderComponent.getQueryBuilder (query-builder.component.ts:40)
    at QueryBuilderComponent.webpackJsonp.../../../../../src/app/components/application/query-builder/query-builder.component.ts.QueryBuilderComponent.ngAfterViewInit (query-builder.component.ts:33)
    at callProviderLifecycles (core.es5.js:11269)
    at callElementProvidersLifecycles (core.es5.js:11244)
    at callLifecycleHooksChildrenFirst (core.es5.js:11228)
    at checkAndUpdateView (core.es5.js:12325)

======= EDIT Updated the code to reflect current usage.

Roberto
  • 199
  • 1
  • 6
  • 16
  • Could you post the whole error code ? It says something about template, but you have absolutely no `template` in the code you provided. –  Jun 29 '17 at 09:10
  • jquery only works after view init. Hence run the code under ngAfterViewInit(){} function – thangavel .R Jun 29 '17 at 09:18
  • I've updated the code above to reflect my current class. This includes using `ngAfterViewInit` where the template error also occurs. – Roberto Jun 29 '17 at 09:22
  • Trying several different hooks and the error still occurs. I've looked into what templates should hold, and it seems that it should be the contents from template.js from the src directory of the package, but this feels wrong. – Roberto Jun 29 '17 at 09:32

1 Answers1

5

Firstly, laplasianin/angular-jqueryQueryBuilder is an AngularJs (1) library.

Secondly, if you set this lines in your anglar-cli.json you will be able to make it works:

  "styles": [
    "../node_modules/bootstrap/dist/css/bootstrap.css",
    "../node_modules/jQuery-QueryBuilder/dist/css/query-builder.default.css",
    "styles.css"
  ],
  "scripts": [
    "../node_modules/jquery/dist/jquery.min.js",
    "../node_modules/bootstrap/dist/js/bootstrap.min.js",
    "../node_modules/jQuery-QueryBuilder/dist/js/query-builder.standalone.min.js"        
  ],

Your component:

import { Component, AfterViewInit } from '@angular/core';

declare var $: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {

 protected rules_basic = {
        condition: 'AND',
        rules: [{
            id: 'price',
            operator: 'less',
            value: 10.25
        }, {
            condition: 'OR',
            rules: [{
                id: 'category',
                operator: 'equal',
                value: 2
            }, {
                id: 'category',
                operator: 'equal',
                value: 1
            }]
        }]
    };

    ngAfterViewInit() {
        this.getQueryBuilder();
    }

    private getQueryBuilder() {
        $('#builder').queryBuilder({
            plugins: ['bt-tooltip-errors'],

            filters: [{
                id: 'name',
                label: 'Name',
                type: 'string'
            }, {
                id: 'category',
                label: 'Category',
                type: 'integer',
                input: 'select',
                values: {
                    1: 'Books',
                    2: 'Movies',
                    3: 'Music',
                    4: 'Tools',
                    5: 'Goodies',
                    6: 'Clothes'
                },
                operators: ['equal', 'not_equal', 'in', 'not_in', 'is_null', 'is_not_null']
            }, {
                id: 'in_stock',
                label: 'In stock',
                type: 'integer',
                input: 'radio',
                values: {
                    1: 'Yes',
                    0: 'No'
                },
                operators: ['equal']
            }, {
                id: 'price',
                label: 'Price',
                type: 'double',
                validation: {
                    min: 0,
                    step: 0.01
                }
            }, {
                id: 'id',
                label: 'Identifier',
                type: 'string',
                placeholder: '____-____-____',
                operators: ['equal', 'not_equal'],
                validation: {
                    format: /^.{4}-.{4}-.{4}$/
                }
            }],

            rules: this.rules_basic
        });
    }

}

Don't forget:

  • npm install bootstrap --save
  • npm install jquery --save
  • npm install jQuery-QueryBuilder --save

Unfortunately, you will not have any autocompletion but it works.

Gilsdav
  • 1,147
  • 7
  • 10
  • I currently went with referencing jquery from `window` and instantiating the plugin there. I will try your code as well as I feel it is much cleaner. Will respond back with any outcome. Thank you! – Roberto Jul 03 '17 at 09:32
  • Hi, I was looking to do the same ting in ang 6 or Ang 7 any pointers please – Transformer Nov 04 '18 at 03:31
  • 1
    Hello @transformer , my answer normally works with Angular 6/7. You can also find `scripts` and `styles` parts in `angular.json`. But If you are looking for form building without specifically need jqueryBuild I think it's better to use Formly : https://alligator.io/angular/formly/ – Gilsdav Nov 06 '18 at 18:19
  • For people who have in case added import * as $ from "jquery"; on the top then you need to replace it with declare var $: any; For me replacing the line worked. – Sagar Khatri Jul 05 '20 at 11:44