Skip to content

Commit 36d8db2

Browse files
committed
added EditableQuery model, held by RefineBarView
1 parent 138d6c3 commit 36d8db2

File tree

2 files changed

+85
-40
lines changed

2 files changed

+85
-40
lines changed

src/models/editable-query.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
var Model = require('ampersand-model');
2+
var EJSON = require('mongodb-extended-json');
3+
var Query = require('mongodb-language-model').Query;
4+
var _ = require('lodash');
5+
6+
// var debug = require('debug')('scout:models:editable-query');
7+
8+
/**
9+
* Editable Query, for the Refine Bar. Wrapper around a string with cleanup and validation.
10+
*/
11+
module.exports = Model.extend({
12+
props: {
13+
rawString: {
14+
type: 'string',
15+
default: '{}',
16+
required: true
17+
}
18+
},
19+
derived: {
20+
cleanString: {
21+
deps: ['rawString'],
22+
fn: function() {
23+
var output = this.rawString;
24+
// accept whitespace-only input as empty query
25+
if (_.trim(output) === '') {
26+
output = '{}';
27+
}
28+
// replace single quotes with double quotes
29+
output = output.replace(/'/g, '"');
30+
// wrap field names in double quotes
31+
output = output.replace(/([{,])\s*([^,{\s\'"]+)\s*:/g, ' $1 "$2" : ');
32+
// replace multiple whitespace with single whitespace
33+
output = output.replace(/\s+/g, ' ');
34+
return output;
35+
}
36+
},
37+
// @todo
38+
// displayString: {
39+
// deps: ['cleanString'],
40+
// fn: function() {
41+
// // return the string without key quotes for display in RefineBarView
42+
// }
43+
// },
44+
valid: {
45+
deps: ['cleanString'],
46+
fn: function() {
47+
/*eslint no-new: 0*/
48+
try {
49+
// is it valid eJSON?
50+
var queryObj = EJSON.parse(this.cleanString);
51+
// is it a valid parsable Query according to the language?
52+
new Query(queryObj, {
53+
parse: true
54+
});
55+
} catch (e) {
56+
return false;
57+
}
58+
return true;
59+
}
60+
}
61+
}
62+
});

src/refine-view/index.js

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
var AmpersandView = require('ampersand-view');
22
var EJSON = require('mongodb-extended-json');
3+
var EditableQuery = require('../models/editable-query');
34
var _ = require('lodash');
5+
var $ = require('jquery');
46
var Query = require('mongodb-language-model').Query;
5-
// var debug = require('debug')('scout:refine-view:index');
7+
var debug = require('debug')('scout:refine-view:index');
68

79
module.exports = AmpersandView.extend({
810
template: require('./index.jade'),
9-
props: {
10-
valid: {
11-
type: 'boolean',
12-
default: true
13-
}
14-
},
1511
derived: {
1612
notEmpty: {
17-
deps: ['model.queryString'],
13+
deps: ['editableQuery.queryString'],
1814
fn: function() {
19-
return this.model.queryString !== '{}';
15+
return this.editableQuery.queryString !== '{}';
2016
}
2117
}
2218
},
19+
children: {
20+
editableQuery: EditableQuery
21+
},
2322
bindings: {
24-
'model.queryString': {
23+
'editableQuery.rawString': {
2524
type: 'value',
2625
hook: 'refine-input'
2726
},
27+
// @todo, rethink these
2828
notEmpty: [{
2929
type: 'toggle',
3030
hook: 'reset-button'
@@ -34,7 +34,7 @@ module.exports = AmpersandView.extend({
3434
yes: 'btn-info',
3535
no: 'btn-default'
3636
}],
37-
valid: [
37+
'editableQuery.valid': [
3838
// red input border while query is invalid
3939
{
4040
type: 'booleanClass',
@@ -57,50 +57,33 @@ module.exports = AmpersandView.extend({
5757
'input [data-hook=refine-input]': 'inputChanged',
5858
'submit form': 'submit'
5959
},
60-
_cleanupInput: function(input) {
61-
var output = input;
62-
// accept whitespace-only input as empty query
63-
if (_.trim(output) === '') {
64-
output = '{}';
65-
}
66-
// replace single quotes with double quotes
67-
output = output.replace(/'/g, '"');
68-
// wrap field names in double quotes
69-
output = output.replace(/([{,])\s*([^,{\s\'"]+)\s*:/g, ' $1 "$2" : ');
70-
return output;
60+
initialize: function() {
61+
this.listenTo(this.model, 'change:queryString', this.onQueryChanged);
62+
},
63+
onQueryChanged: function() {
64+
this.editableQuery.rawString = this.model.queryString;
7165
},
72-
/*eslint no-new: 0*/
7366
inputChanged: function() {
74-
// validate user input on the fly
75-
var queryStr = this._cleanupInput(this.queryByHook('refine-input').value);
76-
try {
77-
// is it valid eJSON?
78-
var queryObj = EJSON.parse(queryStr);
79-
// is it a valid parsable Query according to the language?
80-
new Query(queryObj, {
81-
parse: true
82-
});
83-
} catch (e) {
84-
this.valid = false;
85-
return;
86-
}
87-
this.valid = true;
67+
this.editableQuery.rawString = this.queryByHook('refine-input').value;
8868
},
8969
resetClicked: function() {
9070
this.model.query = new Query();
71+
this.editableQuery.rawString = this.model.queryString;
9172
this.trigger('submit', this);
9273
},
9374
refineClicked: function() {
94-
var queryStr = this._cleanupInput(this.queryByHook('refine-input').value);
95-
var queryObj = new Query(EJSON.parse(queryStr), {
75+
var queryObj = new Query(EJSON.parse(this.editableQuery.cleanString), {
9676
parse: true
9777
});
9878
this.model.query = queryObj;
79+
this.editableQuery.rawString = this.model.queryString;
9980
this.trigger('submit', this);
10081
},
10182
submit: function(evt) {
10283
evt.preventDefault();
103-
if (this.valid) {
84+
// lose focus on input field first, see http://ampersandjs.com/docs#ampersand-dom-bindings-value
85+
$(evt.delegateTarget).find('input').blur();
86+
if (this.editableQuery.valid) {
10487
this.refineClicked();
10588
}
10689
}

0 commit comments

Comments
 (0)