Skip to content

Commit fe47d1e

Browse files
committedJul 18, 2014
First commit
0 parents  commit fe47d1e

9 files changed

+416
-0
lines changed
 

‎angular-query-builder.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
var app = angular.module('app', ['ngSanitize', 'queryBuilder']);
2+
app.controller('QueryBuilderCtrl', ['$scope', function ($scope) {
3+
var data = '{"group": {"operator": "AND","rules": []}}';
4+
5+
function computed(group) {
6+
if (!group) return "";
7+
for (var str = "(", i = 0; i < group.rules.length; i++) {
8+
i > 0 && (str += " <strong>" + group.operator + "</strong> ");
9+
str += group.rules[i].group ?
10+
computed(group.rules[i].group) :
11+
group.rules[i].field + " " + group.rules[i].condition + " " + group.rules[i].data;
12+
}
13+
14+
return str + ")";
15+
}
16+
17+
$scope.json = null;
18+
19+
$scope.filter = JSON.parse(data);
20+
21+
$scope.$watch('filter', function (newValue) {
22+
$scope.json = JSON.stringify(newValue, null, 2);
23+
$scope.output = computed(newValue.group);
24+
}, true);
25+
}]);
26+
27+
var queryBuilder = angular.module('queryBuilder', []);
28+
queryBuilder.directive('queryBuilder', ['$compile', function ($compile) {
29+
return {
30+
restrict: 'E',
31+
transclude: true,
32+
replace: true,
33+
scope: {
34+
group: '='
35+
},
36+
templateUrl: '/queryBuilderDirective.html',
37+
compile: function (element, attrs) {
38+
var content, directive;
39+
content = element.contents().remove();
40+
return function (scope, element, attrs) {
41+
scope.operators = [
42+
{ name: 'AND' },
43+
{ name: 'OR' }
44+
];
45+
46+
scope.fields = [
47+
{ name: 'Firstname' },
48+
{ name: 'Lastname' },
49+
{ name: 'Birthdate' },
50+
{ name: 'City' },
51+
{ name: 'Country' }
52+
];
53+
54+
scope.conditions = [
55+
{ name: '=' },
56+
{ name: '<>' },
57+
{ name: '<' },
58+
{ name: '<=' },
59+
{ name: '>' },
60+
{ name: '>=' }
61+
];
62+
63+
scope.addCondition = function () {
64+
scope.group.rules.push({
65+
condition: '=',
66+
field: 'Firstname',
67+
data: ''
68+
});
69+
};
70+
71+
scope.removeCondition = function (index) {
72+
scope.group.rules.splice(index, 1);
73+
};
74+
75+
scope.addGroup = function () {
76+
scope.group.rules.push({
77+
group: {
78+
operator: 'AND',
79+
rules: []
80+
}
81+
});
82+
};
83+
84+
scope.removeGroup = function () {
85+
"group" in scope.$parent && scope.$parent.group.rules.splice(scope.$parent.$index, 1);
86+
};
87+
88+
directive || (directive = $compile(content));
89+
90+
element.append(directive(scope, function ($compile) {
91+
return $compile;
92+
}));
93+
}
94+
}
95+
}
96+
}]);

‎css/bootstrap.min.css

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎css/styles.css

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.group{
2+
background-color: #fff;
3+
padding: 15px;
4+
border-radius: 5px;
5+
border: solid 1px #666;
6+
}
7+
8+
.group-conditions{
9+
margin-left: 20px;
10+
}
11+
12+
.alert-group{
13+
margin-top: 10px;
14+
margin-bottom: 10px;
15+
border-color: rgb(192, 152, 83);
16+
border-color: rgb(251, 238, 213);
17+
border-color: rgb(220, 200, 150);
18+
}
19+
20+
.condition, .group{
21+
margin-top: 15px;
22+
margin-bottom: 15px;
23+
}
19.9 KB
Binary file not shown.

‎fonts/glyphicons-halflings-regular.svg

+229
Loading
40.3 KB
Binary file not shown.
22.8 KB
Binary file not shown.

‎index.html

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<!DOCTYPE html>
2+
<html lang="en" ng-app="app">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<title>Angular.js Query Builder</title>
8+
9+
<link href="css/bootstrap.min.css" rel="stylesheet">
10+
<link href="css/styles.css" rel="stylesheet">
11+
</head>
12+
<body>
13+
<div class="container" ng-controller="QueryBuilderCtrl">
14+
<h1>Angular.js Query Builder</h1>
15+
16+
<div class="alert alert-info">
17+
<strong>Example Output</strong><br>
18+
<span ng-bind-html="output"></span>
19+
</div>
20+
21+
<query-builder group="filter.group"></query-builder>
22+
</div>
23+
24+
<script type="text/ng-template" id="/queryBuilderDirective.html">
25+
<div class="alert alert-warning alert-group">
26+
<div class="form-inline">
27+
<select ng-options="o.name as o.name for o in operators" ng-model="group.operator" class="form-control input-sm"></select>
28+
<button style="margin-left: 5px" ng-click="addCondition()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Condition</button>
29+
<button style="margin-left: 5px" ng-click="addGroup()" class="btn btn-sm btn-success"><span class="glyphicon glyphicon-plus-sign"></span> Add Group</button>
30+
<button style="margin-left: 5px" ng-click="removeGroup()" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span> Remove Group</button>
31+
</div>
32+
<div class="group-conditions">
33+
<div ng-repeat="rule in group.rules | orderBy:'index'" class="condition">
34+
<div ng-switch="rule.hasOwnProperty('group')">
35+
<div ng-switch-when="true">
36+
<query-builder group="rule.group"></query-builder>
37+
</div>
38+
<div ng-switch-default="ng-switch-default">
39+
<div class="form-inline">
40+
<select ng-options="t.name as t.name for t in fields" ng-model="rule.field" class="form-control input-sm"></select>
41+
<select style="margin-left: 5px" ng-options="c.name as c.name for c in conditions" ng-model="rule.condition" class="form-control input-sm"></select>
42+
<input style="margin-left: 5px" type="text" ng-model="rule.data" class="form-control input-sm"/>
43+
<button style="margin-left: 5px" ng-click="removeCondition($index)" class="btn btn-sm btn-danger"><span class="glyphicon glyphicon-minus-sign"></span></button>
44+
</div>
45+
</div>
46+
</div>
47+
</div>
48+
</div>
49+
</div>
50+
</script>
51+
52+
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.18/angular.min.js"></script>
53+
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.18/angular-sanitize.min.js"></script>
54+
<script src="angular-query-builder.js"></script>
55+
</body>
56+
</html>

‎readme.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Angular Query Builder
2+
======================
3+
4+
This is a sample HTML / JavaScript application that demonstrates how to use
5+
Angular.js to create a dynamic query building web UI.
6+
7+
This was inspired by https://github.com/kindohm/knockout-query-builder

0 commit comments

Comments
 (0)
Please sign in to comment.