Skip to content

Commit

Permalink
add "sortable" options with HTML5 drag&drop
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed May 25, 2014
1 parent 527fd15 commit 7046b9f
Show file tree
Hide file tree
Showing 6 changed files with 310 additions and 39 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bower_components
node_modules
32 changes: 25 additions & 7 deletions bower.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
{
"name": "jQuery-QueryBuilder",
"version": "1.0.0-SNAPSHOT",
"homepage": "https://github.com/mistic100/jQuery-QueryBuilder",
"authors": [
"mistic100"
],
"description": "jQuery-QueryBuilder",
"version": "1.0.0",
"authors": [{
"name": "Damien \"Mistic\" Sorel",
"homepage": "http://www.strangeplanet.fr"
}],
"description": "jQuery plugin for user friendly query/filter creator",
"main": [
"./query-builder.js",
"./query-builder.css"
],
"dependencies" : {
"bootstrap": "3.x.x"
},
"license": "MIT"
"keywords": [
"jquery",
"query",
"builder",
"filter"
],
"license": "MIT",
"homepage": "https://github.com/mistic100/jQuery-QueryBuilder",
"repository": {
"type": "git",
"url": "git://github.com/mistic100/jQuery-QueryBuilder.git"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
28 changes: 19 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
{
"name": "jQuery-QueryBuilder",
"version": "1.0.0-SNAPSHOT",,
"homepage": "https://github.com/mistic100/jQuery-QueryBuilder",
"author": "mistic100",
"version": "1.0.0",
"author": {
"name": "Damien \"Mistic\" Sorel",
"homepage": "http://www.strangeplanet.fr"
},
"description": "jQuery plugin for user friendly query/filter creator",
"main": [
"./query-builder.js",
"./query-builder.css"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"dependencies" : {
"bootstrap": "3.x.x"
},
"keywords": [
"jquery",
"query",
"builder",
"filter"
],
"license": "MIT",
"homepage": "https://github.com/mistic100/jQuery-QueryBuilder",
"repository": {
"type": "git",
"url": "git://github.com/mistic100/jQuery-QueryBuilder.git"
},
"dependencies" : {
"bootstrap": "3.x.x"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/mistic100/jQuery-QueryBuilder/issues"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}
54 changes: 37 additions & 17 deletions query-builder.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@
* Licensed under MIT (http://opensource.org/licenses/MIT)
*/

.rule-container,
.rules-group-container,
.rule-placeholder {
margin:4px 0;
border-radius:5px;
padding:5px;
border:1px solid #eee;
background:#fff;
background:rgba(255, 255, 255, 0.9);
}

/* GROUPS */
.rules-group-container {
padding:10px;
margin:4px 0;
padding:10px 10px 5px 10px;
border:1px solid #DCC896;
background:#FCF9ED;
background:rgba(250, 240, 210, 0.5);
border-radius:5px;
}
.rules-group-header {
margin-bottom:10px;
Expand All @@ -20,25 +29,13 @@
display:none;
}

/* hide first delete button */
.query-builder>.rules-group-container>.rules-group-header [data-delete] {
display:none;
}

/* RULES */
.rules-list {
list-style:none;
padding:0 0 0 20px;
margin:0;
}
.rule-container {
margin:4px 0;
padding:5px;
border:1px solid #eee;
background:#fff;
background:rgba(255, 255, 255, 0.9);
border-radius:5px;
}
.rule-container {}
.rule-container.has-error {
background:#fdd;
border-color:#f99;
Expand Down Expand Up @@ -97,4 +94,27 @@
}
.rules-list>*:last-child:after {
display:none;
}
}

/* DRAG & DROP */
.rule-container .drag-handle,
.rules-group-container .drag-handle {
cursor:move;
display:inline-block;
}

.rule-container .dragged,
.rules-group-container .dragged {
opacity:0.5;
}

.rule-placeholder {
border:1px dashed #bbb;
opacity:0.7;
}

/* hide first delete button and drag handle */
.query-builder>.rules-group-container>.rules-group-header [data-delete],
.query-builder>.rules-group-container>.rules-group-header .drag-handle {
display:none;
}
105 changes: 99 additions & 6 deletions query-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@
});

// INIT
if (this.settings.sortable) {
this.initSortable();
}

this.$el.addClass('query-builder');
this.addGroup(this.$el);
};
Expand All @@ -127,6 +131,7 @@
onAfterAddGroup: null,
onAfterAddRule: null,

sortable: false,
filters: [],

lang: {
Expand Down Expand Up @@ -725,6 +730,92 @@
this.$el.trigger(e);
};

/**
* Init HTML5 drag and drop
*/
QueryBuilder.prototype.initSortable = function() {
$.event.props.push('dataTransfer');

var placeholder, isHandle = false;

this.$el.on('mousedown', '.drag-handle', function(e) {
isHandle = true;
});
this.$el.on('mouseup', '.drag-handle', function(e) {
isHandle = false;
});

this.$el.on('dragstart', '[draggable]', function(e) {
e.stopPropagation();

if (isHandle) {
e.dataTransfer.setData('id', e.target.id);

placeholder = $('<div class="rule-placeholder">&nbsp;</div>');
placeholder.height($(e.target).height());
placeholder.insertAfter(e.target);

$(e.target).hide();

isHandle = false;
}
else {
e.preventDefault();
}
});

this.$el.on('dragenter', '[draggable]', function(e) {
e.stopPropagation();

var target = $(e.target), parent;

parent = target.closest('.rule-container');
if (parent.length) {
placeholder.detach().insertAfter(parent);
return;
}

parent = target.closest('.rules-group-container');
if (parent.length) {
placeholder.detach().appendTo(parent.find('.rules-list').eq(0));
return;
}
});

this.$el.on('dragover', '[draggable]', function(e) {
e.preventDefault();
e.stopPropagation();
});

this.$el.on('drop', function(e) {
e.stopPropagation();

var src = $('#'+ e.dataTransfer.getData('id')),
target = $(e.target), parent;

parent = target.closest('.rule-container');
if (parent.length) {
src.detach().insertAfter(parent);
return;
}

parent = target.closest('.rules-group-container');
if (parent.length) {
src.detach().appendTo(parent.find('.rules-list').eq(0));
return;
}
});

this.$el.on('dragend', '[draggable]', function(e) {
e.stopPropagation();

var src = $('#'+ e.dataTransfer.getData('id'));

src.show();
placeholder.remove();
});
};


// DATA ACCESS
// ===============================
Expand Down Expand Up @@ -881,17 +972,18 @@
*/
QueryBuilder.prototype.getGroupTemplate = function(group_id) {
return '\
<dl id='+ group_id +' class="rules-group-container"> \
<dl id='+ group_id +' class="rules-group-container" '+ (this.settings.sortable ? 'draggable="true"' : '') +'> \
<dt class="rules-group-header"> \
<div class="btn-group"> \
<label class="btn btn-xs btn-primary active"><input type="radio" name="'+ group_id +'_cond" value="AND" checked> '+ this.lang.and_condition +'</label> \
<label class="btn btn-xs btn-primary"><input type="radio" name="'+ group_id +'_cond" value="OR"> '+ this.lang.or_condition +'</label> \
</div> \
<div class="btn-group pull-right"> \
<button type="button" class="btn btn-xs btn-success" data-add="rule"><i class="glyphicon glyphicon-plus"></i> '+ this.lang.add_rule +'</button> \
<button type="button" class="btn btn-xs btn-success" data-add="group"><i class="glyphicon glyphicon-plus-sign"></i> '+ this.lang.add_group +'</button> \
<button type="button" class="btn btn-xs btn-danger" data-delete="group"><i class="glyphicon glyphicon-remove"></i> '+ this.lang.delete_group +'</button> \
</div> \
<div class="btn-group"> \
<label class="btn btn-xs btn-primary active"><input type="radio" name="'+ group_id +'_cond" value="AND" checked> '+ this.lang.and_condition +'</label> \
<label class="btn btn-xs btn-primary"><input type="radio" name="'+ group_id +'_cond" value="OR"> '+ this.lang.or_condition +'</label> \
</div> \
'+ (this.settings.sortable ? '<div class="drag-handle"><i class="glyphicon glyphicon-sort"></i></div>' : '') +' \
</dt> \
<dd class=rules-group-body> \
<ul class=rules-list></ul> \
Expand All @@ -906,12 +998,13 @@
*/
QueryBuilder.prototype.getRuleTemplate = function(rule_id) {
return '\
<li id='+ rule_id +' class="rule-container"> \
<li id='+ rule_id +' class="rule-container" '+ (this.settings.sortable ? 'draggable="true"' : '') +'> \
<div class="rule-header"> \
<div class="btn-group pull-right"> \
<button type="button" class="btn btn-xs btn-danger" data-delete="rule"><i class="glyphicon glyphicon-remove"></i> '+ this.lang.delete_rule +'</button> \
</div> \
</div> \
'+ (this.settings.sortable ? '<div class="drag-handle"><i class="glyphicon glyphicon-sort"></i></div>' : '') +' \
<div class="rule-filter-container">'+ this.getRuleFilterSelect(rule_id) +'</div> \
<div class="rule-operator-container"></div> \
<div class="rule-value-container"></div> \
Expand Down
Loading

0 comments on commit 7046b9f

Please sign in to comment.