summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsuelockwood <deathbear@apache.org>2014-04-17 15:20:52 -0400
committersuelockwood <deathbear@apache.org>2014-04-17 15:23:34 -0400
commit174e7596e2cabb76131bd85948aee162831706be (patch)
tree82f2e8ff6424d1d5020013b2e145be36a56d85f1
parentf6a1dc5f29c327712e31c9b47c47dcffd3fcefea (diff)
downloadcouchdb-174e7596e2cabb76131bd85948aee162831706be.tar.gz
Query UI clean up. Added Validation and grouped form elements
-rw-r--r--src/fauxton/app/addons/documents/assets/less/documents.less27
-rw-r--r--src/fauxton/app/addons/documents/templates/advanced_options.html189
-rw-r--r--src/fauxton/app/addons/documents/views.js105
3 files changed, 205 insertions, 116 deletions
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index e49720b33..e62be3017 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -40,7 +40,8 @@ button.beautify {
#query div.controls-group.well{
- height: 150px;
+ height: 180px;
+ margin-right: 17px;
}
/** used in all_docs_list.html **/
@@ -119,16 +120,36 @@ button.beautify {
}
#keys-input {
- display: inline-block;
- width: 35%;
+ width: 100%;
}
#keys-error {
display: inline-block;
}
+
.change-sequence {
word-wrap: break-word;
}
+#dashboard-upper-content{
+ .js-query-keys-wrapper{
+ padding-top: 0;
+ }
+ /** used in advanced-options.html**/
+ .custom-inputs {
+ .row-fluid{
+ padding-top: 20px;
+ .radio, .checkbox{
+ padding-left: 0;
+ }
+ .checkbox.inline,
+ #skipRows {
+ margin-bottom: 0;
+ padding: 6px;
+ }
+ }
+ }
+}
+
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index 55c59462e..439e8648c 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -16,115 +16,144 @@ the License.
<!-- tabs for choosing Keys or Start & end -->
- <div class="btn-group toggle-btns">
- <label for="showKeys" class="drop-down btn active">
- Specific Keys
+ <div class="btn-group toggle-btns row-fluid">
+ <label for="showKeys" class="drop-down btn span6">
+ By Key(s)
</label>
- <label for="showStartEnd" class="drop-down btn">
- Bounded Queries
+ <label for="showStartEnd" class="drop-down btn span6">
+ Between Keys
</label>
</div>
- <div class="controls-group well">
+ <div class="controls-group well hide js-query-keys-wrapper">
<div class="row-fluid" id="js-showKeys">
<div class="controls controls-row">
- <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON."></textarea>
+ <label for="keys-input" class="drop-down">A key, or an array of keys.</label>
+ <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text" placeholder='Enter valid JSON; e.g., ["1234"] or ["1234","2345"]'></textarea>
<div id="keys-error" class="inline-block js-keys-error"></div>
</div>
</div>
<div class="row-fluid hide" id="js-showStartEnd">
<div class="controls controls-row">
- <input name="startkey" class="span6" type="text" placeholder="Start Key" disabled>
- <input name="endkey" class="span6" type="text" placeholder="End Key">
- </div>
- <div class="controls controls-row checkbox inline">
- <input id="check5" name="inclusive_end" type="checkbox" value="false" disabled>
- <label for="check5">Disable Inclusive End</label>
+ <div class="span6">
+ <label for="startkey" class="drop-down">Start key</label>
+ <input name="startkey" id="startkey" type="text" placeholder='e.g., "1234"' disabled>
+ </div>
+ <div class="span6">
+ <label for="endkey" class="drop-down">End key</label>
+ <input id="endkey" name="endkey" type="text" placeholder='e.g., "1234"'>
+ <div class="controls controls-row checkbox inline">
+ <input id="check5" name="inclusive_end" type="checkbox" value="true" checked disabled>
+ <label for="check5">Include End Key in results</label>
+ </div>
+ </div>
+
</div>
+
</div>
</div>
<!-- Limit and Skip are conditional -->
<div class="controls-group">
- <label class="drop-down inline">
- Limit:
- <select name="limit" class="input-small">
- <option selected="selected">None</option>
- <option>5</option>
- <option>10</option>
- <option>20</option>
- <option>30</option>
- <option>50</option>
- <option>100</option>
- <option>500</option>
- </select>
- </label>
- <label for="skipRows" class="inline drop-down">
- Skip:
- <input name="skip" class="input-large" type="text" id="skipRows" placeholder="Number of rows to skip">
- </label>
-
- <div class="checkbox inline">
- <input id="check1" type="checkbox" name="include_docs" value="true">
- <label name="include_docs" for="check1">Include Docs (show the entire doc body)</label>
- </div>
- <% if (hasReduce) { %>
- <div class="checkbox inline">
- <input id="check2" name="reduce" type="checkbox" value="true">
- <label for="check2">Reduce</label>
- </div>
- <label id="select1" class="drop-down inline">
- Group Level:
- <select id="select1" disabled name="group_level" class="input-small">
- <option value="0">None</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="999" selected="selected">exact</option>
- </select>
- </label>
+ <div class="row-fluid">
+ <div class="span6">
+ <label class="drop-down inline">
+ Limit:
+ <select name="limit" class="input-medium">
+ <option selected="selected">None</option>
+ <option>5</option>
+ <option>10</option>
+ <option>20</option>
+ <option>30</option>
+ <option>50</option>
+ <option>100</option>
+ <option>500</option>
+ </select>
+ </label>
+ </div>
+ <div class="span6">
+ <label for="skipRows" class="inline drop-down">
+ # of rows to skip
+ <input name="skip" class="input-small" type="text" id="skipRows" placeholder="0">
+ </label>
+ </div>
+ </div>
+ <div class="row-fluid">
+ <div class="span6">
+ <label id="select2" class="drop-down inline">
+ Order:
+ <select id="select2" name="descending" class="input-medium">
+ <option value="false">Ascending</option>
+ <option value="true">Descending</option>
+ </select>
+ </label>
+ </div>
+ <div class="span6">
+ <label id="select2" class="drop-down inline">
+ Docs:
+ <select id="select2" name="include_docs" class="input-medium">
+ <option value="false">Exclude</option>
+ <option value="true">Include</option>
+ </select>
+ </label>
+ </div>
+ </div>
+ <div class="row-fluid">
+ <% if (showPreview) { %>
+ <div class="span6">
+ <div class="checkbox inline">
+ <input id="check7" name="stale" type="checkbox" value="true">
+ <label for="check7">Stale</label>
+ </div>
+ </div>
<% } %>
-
- <label id="select2" class="drop-down inline">
- Order:
- <select id="select2" name="descending" class="input-large">
- <option value="false">Accending</option>
- <option value="true">Descending</option>
- </select>
- </label>
-
- <div class="checkbox inline">
- <input id="check6" name="update_seq" type="checkbox" value="true">
- <label for="check6">Update Sequence</label>
+ <div class="span6 update-seq">
+ <div class="checkbox inline">
+ <input id="check6" name="update_seq" type="checkbox" value="true">
+ <label for="check6">Update Sequence</label>
+ </div>
</div>
- <% if (showPreview) { %>
- <div class="checkbox inline">
- <input id="check7" name="stale" type="checkbox" value="true">
- <label for="check7">Stale</label>
+ </div>
+ <% if (hasReduce) { %>
+ <div class="row-fluid">
+ <div class="span6">
+ <div class="checkbox inline">
+ <input id="check2" name="reduce" type="checkbox" value="true">
+ <label for="check2">Reduce</label>
+ </div>
</div>
- <% } %>
+ <div class="span6">
+ <label id="select1" class="drop-down inline">
+ Group Level:
+ <select id="select1" disabled name="group_level" class="input-small">
+ <option value="0">None</option>
+ <option value="1">1</option>
+ <option value="2">2</option>
+ <option value="3">3</option>
+ <option value="4">4</option>
+ <option value="5">5</option>
+ <option value="6">6</option>
+ <option value="7">7</option>
+ <option value="8">8</option>
+ <option value="9">9</option>
+ <option value="999" selected="selected">Exact</option>
+ </select>
+ </label>
+ </div>
+ </div>
+ <% } %>
</div>
+
<div class="controls-group">
- <div class="row-fluid">
- <div id="button-options" class="controls controls-row">
- <button type="submit" class="btn btn-success">Query</button>
- <% if (showPreview) { %>
- <button class="btn btn-info preview">Browser Preview</button>
- <% } %>
- </div>
+ <div id="button-options" class="controls controls-row">
+ <button type="submit" class="btn btn-success">Query</button>
</div>
</div>
</form>
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index bae49c0cd..5b096bbcb 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -392,7 +392,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
this.newView = options.newView || false;
this.pagination = options.pagination;
_.bindAll(this);
-
+
this._perPage = options.perPageDefault || 20;
this.listenTo(this.collection, 'totalRows:decrement', this.render);
},
@@ -1054,21 +1054,26 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
"change form.js-view-query-update input": "updateFilters",
"change form.js-view-query-update select": "updateFilters",
"submit form.js-view-query-update": "updateView",
- "click button.preview": "previewView",
"click .toggle-btns > label": "toggleQuery"
},
toggleQuery: function(e){
e.preventDefault();
- var showFunctionName =this.$(e.currentTarget).attr("for");
- //highlight current
- this.$(".toggle-btns > label").removeClass('active');
- this.$(e.currentTarget).addClass("active");
-
- this.$("[id^='js-show']").hide();
- //show section & disable what needs to be disabled
- this[showFunctionName]();
+ if (this.$(e.currentTarget).hasClass("active")){
+ this.$('.js-query-keys-wrapper').addClass("hide");
+ this.$(".toggle-btns > label").removeClass('active');
+ this.$('.js-query-keys-wrapper').find("input,textarea").attr("disabled","true");
+ } else {
+ this.$('.js-query-keys-wrapper').removeClass("hide");
+ var showFunctionName =this.$(e.currentTarget).attr("for");
+ //highlight current
+ this.$(".toggle-btns > label").removeClass('active');
+ this.$(e.currentTarget).addClass("active");
+ this.$("[id^='js-show']").hide();
+ //show section & disable what needs to be disabled
+ this[showFunctionName]();
+ }
},
showKeys: function(){
@@ -1114,7 +1119,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
if (_.isUndefined(parsedValue)) {
errorMsg = "Keys must be valid json.";
} else if (!_.isArray(parsedValue)) {
- errorMsg = "Keys values must be in an array. E.g [1,2,3]";
+ errorMsg = "Keys values must be in an array. E.g [1,2,3]";
}
if (errorMsg) {
@@ -1123,12 +1128,30 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
type: "error",
msg: errorMsg,
clear: false,
- selector: '.js-keys-error'
+ selector: '.advanced-options .errors-container'
});
return false;
}
- return true;
+ return true;
+ },
+ validateFields: function(params){
+ var errors = false;
+ //so ghetto. Spaghetti code.
+ for (var i= 0; i <params.length; i++){
+ if (params[i].name === "skip"){
+ if (!(/^\d+$/).test(params[i].value)){
+ FauxtonAPI.addNotification({
+ msg: "Numbers only for skip",
+ type: "warn",
+ selector: ".advanced-options .errors-container",
+ clear: true
+ });
+ errors = true;
+ }
+ }
+ }
+ return errors;
},
queryParams: function () {
var $form = this.$(".js-view-query-update"),
@@ -1145,6 +1168,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
if (keysParam && !this.validateKeys(keysParam)) { return false; }
+ if (params && this.validateFields(params)){ return false; }
+
// Validate *key* params to ensure they're valid JSON
var keyParams = ["keys","startkey","endkey"];
var errorParams = _.filter(params, function(param) {
@@ -1158,6 +1183,21 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
return {params: params, errorParams: errorParams};
},
+ //these are the saaaaameeeeeeee
+ updateView: function (event) {
+ event.preventDefault();
+ var params = this.queryParams();
+ if (!params) { return;}
+ this.updateViewFn(event, params);
+ },
+
+ // previewView: function (event) {
+ // var params = this.queryParams();
+ // if (!params) { return;}
+ // this.previewFn(event, params);
+ // },
+
+
updateFilters: function(event) {
event.preventDefault();
var $ele = $(event.currentTarget);
@@ -1178,17 +1218,27 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
var notification = FauxtonAPI.addNotification({
msg: "include_docs has been disabled as you cannot include docs on a reduced view",
type: "warn",
- selector: ".view.show .all-docs-list.errors-container",
+ selector: ".advanced-options .errors-container",
clear: true
});
}
$form.find("input[name=include_docs]").prop("disabled", true);
$form.find("select[name=group_level]").prop("disabled", false);
} else {
- $form.find("select[name=group_level]").prop("disabled", true);
+ $form.find("select[name=group_level]").val("999").prop("disabled", true);
$form.find("input[name=include_docs]").prop("disabled", false);
}
break;
+ case "skip":
+ if (!(/^\d+$/).test($ele.val())){
+ FauxtonAPI.addNotification({
+ msg: "Numbers only for skip",
+ type: "warn",
+ selector: ".advanced-options .errors-container",
+ clear: true
+ });
+ }
+ break;
case "include_docs":
break;
}
@@ -1217,8 +1267,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
}
this.updateFiltersFor(key, $ele);
break;
- case "key":
- case "keys":
+ case "key":
+ case "keys":
$form.find("textarea[name='"+key+"']").val(val);
break;
default:
@@ -1228,18 +1278,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
}, this);
},
- updateView: function (event) {
- event.preventDefault();
- var params = this.queryParams();
- if (!params) { return;}
- this.updateViewFn(event, params);
- },
- previewView: function (event) {
- var params = this.queryParams();
- if (!params) { return;}
- this.previewFn(event, params);
- },
serialize: function () {
return {
@@ -1619,7 +1658,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
toggleIndexNav: function (event) {
$('#dashboard-content').scrollTop(0); //scroll up
-
+
var $targetId = this.$(event.target).attr('id'),
$previousTab = this.$(this.$('li.active a').attr('href')),
$targetTab = this.$(this.$(event.target).attr('href'));
@@ -1628,7 +1667,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
$previousTab.removeAttr('style');
}
//stop polling
- this.ddocInfoView.stopRefreshInterval();
+ this.ddocInfoView.stopRefreshInterval();
if ($targetId === 'index-nav') {
if (this.newView) { return; }
@@ -1640,8 +1679,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
} else if ($targetId === "meta-nav"){
if (!$("#ddoc-info").is(":visible")){
this.ddocInfoView.startRefreshInterval();
- }
- $targetTab.toggle('slow');
+ }
+ $targetTab.toggle('slow');
} else {
$targetTab.toggle('slow');
}
@@ -1688,7 +1727,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb,
renderDdocInfo: function(){
if(this.ddocInfoView){
this.ddocInfoView.remove();
- }
+ }
if (this.newView) { return; }
this.ddocInfoView = this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));