diff options
author | suelockwood <deathbear@apache.org> | 2014-04-17 15:20:52 -0400 |
---|---|---|
committer | suelockwood <deathbear@apache.org> | 2014-04-17 15:23:34 -0400 |
commit | 174e7596e2cabb76131bd85948aee162831706be (patch) | |
tree | 82f2e8ff6424d1d5020013b2e145be36a56d85f1 /src | |
parent | f6a1dc5f29c327712e31c9b47c47dcffd3fcefea (diff) | |
download | couchdb-174e7596e2cabb76131bd85948aee162831706be.tar.gz |
Query UI clean up. Added Validation and grouped form elements
Diffstat (limited to 'src')
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 })); |