You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2014/02/20 17:04:18 UTC

[04/14] couchdb commit: updated refs/heads/paginate-api-options to 75c7077

add per page view limit and new advanced options


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c526a7a6
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c526a7a6
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c526a7a6

Branch: refs/heads/paginate-api-options
Commit: c526a7a61ac1b6eb9ea0f55218a48cf12d8adaa9
Parents: dea6cef
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Jan 28 16:30:38 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Feb 20 08:54:32 2014 +0200

----------------------------------------------------------------------
 src/fauxton/app/addons/databases/resources.js   |   2 +-
 .../addons/documents/assets/less/documents.less |   8 +
 src/fauxton/app/addons/documents/resources.js   |  30 ++-
 src/fauxton/app/addons/documents/routes.js      |  16 +-
 .../documents/templates/advanced_options.html   |   6 +-
 .../templates/advanced_options_menu.html        |  46 +++++
 .../documents/templates/all_docs_layout.html    |   2 +
 .../documents/templates/all_docs_number.html    |  22 +-
 .../addons/documents/templates/view_editor.html |   1 +
 src/fauxton/app/addons/documents/views.js       | 207 +++++++++++++------
 src/fauxton/app/addons/fauxton/components.js    |  77 ++++---
 11 files changed, 312 insertions(+), 105 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/databases/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/databases/resources.js b/src/fauxton/app/addons/databases/resources.js
index ea1aed2..80cd533 100644
--- a/src/fauxton/app/addons/databases/resources.js
+++ b/src/fauxton/app/addons/databases/resources.js
@@ -22,7 +22,7 @@ define([
 function(app, FauxtonAPI, Documents) {
   var Databases = FauxtonAPI.addon();
 
-  Databases.DocLimit = 20;
+  Databases.DocLimit = 100;
 
   Databases.Model = FauxtonAPI.Model.extend({
     initialize: function(options) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 9dee85e..c30a9af 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -23,6 +23,14 @@ button.beautify {
 	margin-top: 20px;
 }
 
+#per-page {
+  float: right;
+
+  #select-per-page {
+    margin-top: 10px;
+  }
+  
+}
 
 /** used in all_docs_list.html **/
 .view {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index adfee1f..a1f43a5 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -281,7 +281,7 @@ function(app, FauxtonAPI) {
       this.database = options.database;
       this.params = options.params;
       this.skipFirstItem = false;
-
+      this.totalRowsToPaginate = 100;
       this.on("remove",this.decrementTotalRows , this);
     },
 
@@ -314,7 +314,17 @@ function(app, FauxtonAPI) {
       });
     },
 
-    urlNextPage: function (num, lastId) {
+    updateLimit: function (limit) {
+      if (this.params.startkey_docid && this.params.startkey) {
+        //we are paginating so set limit + 1
+        this.params.limit = limit + 1;
+        return;
+      }
+
+      this.params.limit = limit;
+    },
+
+    nextPage: function (num, lastId) {
       if (!lastId) {
         var doc = this.last();
 
@@ -333,7 +343,7 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
-    urlPreviousPage: function (num, params) {
+    previousPage: function (num, params) {
       if (params) { 
         this.params = params;
       } else {
@@ -430,7 +440,7 @@ function(app, FauxtonAPI) {
       return url.join("/") + query;
     },
 
-    urlNextPage: function (num, lastId) {
+    nextPage: function (num, lastId) {
       if (!lastId) {
         lastDoc = this.last();
       }
@@ -445,7 +455,7 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
-     urlPreviousPage: function (num, params) {
+     previousPage: function (num, params) {
       if (params) { 
         this.params = params;
       } else {
@@ -456,6 +466,16 @@ function(app, FauxtonAPI) {
       return this.url('app');
     },
 
+    updateLimit: function (limit) {
+      if (this.params.startkey_docid && this.params.startkey) {
+        //we are paginating so set limit + 1
+        this.params.limit = limit + 1;
+        return;
+      }
+
+      this.params.limit = limit;
+    },
+
     recordStart: function () {
       if (this.viewMeta.offset === 0) {
         return 1;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index be9ce2f..4275006 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -155,7 +155,8 @@ function(app, FauxtonAPI, Documents, Databases) {
       "route:updateAllDocs": "updateAllDocsFromView",
       "route:updatePreviewDocs": "updateAllDocsFromPreview",
       "route:reloadDesignDocs": "reloadDesignDocs",
-      "route:paginate": "paginate"
+      "route:paginate": "paginate",
+      "route:perPageChange": "perPageChange"
     },
 
     initialize: function (route, masterLayout, options) {
@@ -304,7 +305,6 @@ function(app, FauxtonAPI, Documents, Databases) {
         this.documentsView = this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
           collection: this.data.database.allDocs
         }));
-        //this.apiUrl = [this.data.database.allDocs.url("apiurl"), this.data.database.allDocs.documentation() ];
         return;
       }
 
@@ -345,13 +345,19 @@ function(app, FauxtonAPI, Documents, Databases) {
       }));
     },
 
-    paginate: function (direction) {
-      _.extend(this.documentsView.collection.params, app.getParams());
+    perPageChange: function (perPage) {
+      this.documentsView.collection.updateLimit(perPage);
       this.documentsView.forceRender();
-      if (direction === 'next') {
+    },
+
+    paginate: function (options) {
+      this.documentsView.forceRender();
+      if (options.direction === 'next') {
         this.documentsView.collection.skipFirstItem = true;
+        this.documentsView.collection.nextPage(options.perPage);
       } else {
         this.documentsView.collection.skipFirstItem = false;
+        this.documentsView.collection.previousPage(options.perPage);
       }
     },
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index bea256a..8f592f4 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -68,10 +68,12 @@ the License.
           <select name="limit" class="input-small">
             <option>5</option>
             <option>10</option>
-            <option selected="selected">20</option>
+            <option >20</option>
             <option>30</option>
             <option>50</option>
-            <option>100</option>
+            <option selected="selected">100</option>
+            <option>500</option>
+            <option>None</option>
           </select>
         </label>
         <div class="checkbox inline">  

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options_menu.html b/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
new file mode 100644
index 0000000..abc08bd
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/advanced_options_menu.html
@@ -0,0 +1,46 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<div class="row-fluid custom-inputs">
+  <div class="controls controls-row">
+    <div class="checkbox inline">  
+      <input id="include-docs-views" type="checkbox" name="include-docs" value="true">  
+      <label for="include-docs-views">
+        Include Docs</label>  
+    </div> 
+    <% if (hasReduce) { %>
+    <div class="checkbox inline">  
+      <input id="reduce" name="reduce" type="checkbox" value="true">
+      <label for="reduce">Reduce</label>  
+      <label id="group-level-label" style="display:none" class="drop-down inline">
+        Group Level:
+        <select id="group-level"  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> 
+    <% } %>
+    <a data-bypass="true" id="query-nav" class="" href="#query" data-toggle="tab">More query options</a></li>
+  </div> 
+</div> 
+

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/templates/all_docs_layout.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_layout.html b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
index 2862e16..b6428c9 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_layout.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_layout.html
@@ -11,11 +11,13 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 License for the specific language governing permissions and limitations under
 the License.
 -->
+
 <ul class="nav nav-tabs window-resizeable" id="db-views-tabs-nav">
   <li><a id="toggle-query" href="#query" data-bypass="true" data-toggle="tab">
     <i class="fonticon fonticon-plus"></i> Query Options</a></li>
 </ul>
 <div class="tab-content">
+  <div id="query-options-wrapper"></div>
   <div class="tab-pane" id="query">
   </div>
 </div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/templates/all_docs_number.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/all_docs_number.html b/src/fauxton/app/addons/documents/templates/all_docs_number.html
index df8fe07..4c9130b 100644
--- a/src/fauxton/app/addons/documents/templates/all_docs_number.html
+++ b/src/fauxton/app/addons/documents/templates/all_docs_number.html
@@ -12,12 +12,24 @@ License for the specific language governing permissions and limitations under
 the License.
 -->
 <% if (totalRows === "unknown"){ %>
-  Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
-<% } else if (showNumbers) { %>
-  Showing <%=offset%> - <%= numModels %> of <%= totalRows %> rows
+Showing 0 documents. <a href="#/database/<%=database%>/new"> Create your first document.</a>
 <% } else { %>
-  Showing <%=pageStart%> - <%= pageEnd %>
+Showing <%=pageStart%> - <%= pageEnd %>
 <%}%>
 <% if (updateSeq) { %>
-  -- Update Sequence: <%= updateSeq %>
+-- Update Sequence: <%= updateSeq %>
 <% } %>
+
+<div id="per-page">
+<label id="per-page" class="drop-down inline">
+  Per page:
+  <select id="select-per-page" name="per-page" class="input-small">
+    <option value="5">5</option>
+    <option value="10">10</option>
+    <option value="20">20</option>
+    <option value="30">30</option>
+    <option value="50">50</option>
+    <option value="100">100</option>
+  </select>
+</label>
+</div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/templates/view_editor.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/view_editor.html b/src/fauxton/app/addons/documents/templates/view_editor.html
index 6a20849..b1364df 100644
--- a/src/fauxton/app/addons/documents/templates/view_editor.html
+++ b/src/fauxton/app/addons/documents/templates/view_editor.html
@@ -23,6 +23,7 @@ the License.
   </ul>
   <div class="all-docs-list errors-container"></div>
   <div class="tab-content">
+	 <div id="query-options-wrapper"></div>
     <div class="tab-pane active" id="index">
       <div id="define-view" class="ddoc-alert well">
         <div class="errors-container"></div>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 7282ed7..ce06189 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -416,12 +416,28 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     initialize: function (options) {
       this.newView = options.newView || false;
-      this.showNumbers = options.showNumbers;
       this.pagination = options.pagination;
+      
+      this.perPage = 20;
+      
 
       this.listenTo(this.collection, 'totalRows:decrement', this.render);
     },
 
+    events: {
+      'change #select-per-page': 'updatePerPage'
+    },
+
+    updatePerPage: function (event) {
+      this.perPage = parseInt(this.$('#select-per-page :selected').val(), 10);
+      FauxtonAPI.triggerRouteEvent('perPageChange', this.perPage);
+      this.pagination.updatePerPage(this.perPage);
+    },
+
+    afterRender: function () {
+      this.$('option[value="' + this.perPage + '"]').attr('selected', "selected");
+    },
+
     serialize: function () {
        var totalRows = 0,
           recordStart = 0,
@@ -445,7 +461,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         updateSeq: updateSeq,
         offset: recordStart,
         totalRows: totalRows,
-        showNumbers: this.showNumbers,
         numModels: this.collection.models.length + recordStart - 1,
         pageStart: pageStart,
         pageEnd: pageEnd
@@ -463,29 +478,38 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     events: {
-      'click #toggle-query': "toggleQuery"
+      'click #query-nav': "toggleQuery"
     },
 
     toggleQuery: function (event) {
       $('#dashboard-content').scrollTop(0);
-      this.$('#query').toggle('fast');
+      this.$('#query').toggle('slow');
     },
 
     beforeRender: function () {
+      this.eventer = _.extend({}, Backbone.Events);
+
       this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
         updateViewFn: this.updateAllDocs,
         previewFn: this.previewView,
         hasReduce: false,
         showPreview: false,
-        database: this.database
+        database: this.database,
+        eventer: this.eventer
       }));
 
+      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+        hasReduce: false,
+        eventer:  this.eventer
+       }));
+
       this.$('#query').hide();
     },
 
     afterRender: function () {
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
+        this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
     },
@@ -576,15 +600,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     },
 
     serialize: function() {
-      var requestDuration = false;
-
-      if (this.collection.requestDurationInString) {
-        requestDuration = this.collection.requestDurationInString();
-      }
-
       return {
         viewList: this.viewList,
-        requestDuration: requestDuration,
+        requestDuration: false,
         expandDocs: this.expandDocs
       };
     },
@@ -646,53 +664,20 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
     addPagination: function () {
       var collection = this.collection;
-      var perPage = function () {
-        if (collection.params.limit && collection.skipFirstItem) {
-          return parseInt(collection.params.limit, 10) - 1;
-        } else if (collection.params.limit) {
-          return parseInt(collection.params.limit, 10);
-        }
-
-        return 20;
-      };
 
       this.pagination = new Components.IndexPagination({
         collection: this.collection,
-        scrollToSelector: '#dashboard-content',
-        previousUrlfn: function () {
-          return collection.urlPreviousPage(perPage(), this.previousParams.pop());
-        },
-        canShowPreviousfn: function () {
-          if (this.previousParams.length === 0) {
-            return false;
-          }
-
-          return true;
-        },
-        canShowNextfn: function () {
-          if (collection.length < (perPage() -1)) {
-            return false;
-          }
-
-          return true;
-        },
-
-        nextUrlfn: function () {
-          return collection.urlNextPage(perPage());
-        }
+        scrollToSelector: '#dashboard-content'
       });
     },
 
     cleanup: function () {
+      this.pagination.remove();
       this.allDocsNumber.remove();
       _.each(this.rows, function (row) {row.remove();});
-
-      if (!this.pagination) { return; }
-      this.pagination.remove();
     },
 
     beforeRender: function() {
-      var showNumbers = true;
 
       if (!this.pagination) {
         this.addPagination();
@@ -700,16 +685,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
 
       this.insertView('#documents-pagination', this.pagination);
 
-      if (this.designDocs || this.collection.idxType === '_view' || this.collection.params.startkey === '"_design"') {
-        showNumbers = false;
+      if (!this.allDocsNumber) {
+        this.allDocsNumber = new Views.AllDocsNumber({
+          collection: this.collection,
+          newView: this.newView,
+          pagination: this.pagination
+        });
       }
 
-      this.allDocsNumber = this.setView('#item-numbers', new Views.AllDocsNumber({
-        collection: this.collection,
-        newView: this.newView,
-        showNumbers: showNumbers,
-        pagination: this.pagination
-      }));
+      this.setView('#item-numbers', this.allDocsNumber);
 
       var docs = this.expandDocs ? this.collection : this.collection.simple();
 
@@ -942,9 +926,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           model = this.model;
 
       editor.editor.on("change", function (event) {
-        //if (event.data.action !== 'removeText') { return; }
-        //if (!event.data.text.match(/_id/) && !event.data.text.match(/_rev/)) { return; }
-
         var changedDoc;
         try {
           changedDoc = JSON.parse(editor.getValue());
@@ -1023,6 +1004,73 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
     }
   });
 
+  Views.AdvancedOptionsMenu = FauxtonAPI.View.extend({
+    template: 'addons/documents/templates/advanced_options_menu',
+    tagName: "div",
+    className: "controls-group advanced-options-menu",
+    events: {
+      "click input": "updateRows",
+      'change #group-level': 'updateRows',
+      'click #query-nav': 'toggleMenu'
+    },
+
+    initialize: function (options) {
+      this.hasReduce = options.hasReduce;
+      this.eventer = options.eventer;
+    },
+
+    toggleMenu: function (event) {
+      this.$('.checkbox').toggle();
+    },
+
+    updateRows: function (event) {
+      var $groupLevel = this.$('#group-level-label'),
+          params = {
+            include_docs: false,
+            reduce: false,
+            group_level: 0
+          };
+
+      if (this.$('#include-docs-views').prop('checked')) {
+        params.include_docs = true;
+      }
+
+      if (this.hasReduce && this.$('#reduce').prop('checked')) {
+        params.reduce = true;
+        params.group_level = this.$('#group-level option:selected').val();
+        $groupLevel.show();
+      } else {
+        $groupLevel.hide();
+      }
+      this.eventer.trigger('options:param_update', params);
+    },
+
+    updateFromParams: function (params) {
+      if (params.reduce) {
+        var $reduce = this.$('#reduce');
+        $reduce.prop("checked", true);
+        this.$('#group-level-label').show();
+        this.$('option[value="' + params.group_level + '"]').prop('selected', true);
+
+      } else if (params.include_docs) {
+        var $include_docs = this.$('#include-docs-views');
+        $include_docs.prop("checked", true);
+      }
+    },
+
+    serialize: function () {
+      return {
+        hasReduce: this.hasReduce
+      };
+    },
+
+    setHasReduce: function (hasReduce) {
+      this.hasReduce = hasReduce;
+    }
+
+  });
+
+
   Views.AdvancedOptions = FauxtonAPI.View.extend({
     template: "addons/documents/templates/advanced_options",
     className: "advanced-options well",
@@ -1033,7 +1081,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       this.viewName = options.viewName;
       this.updateViewFn = options.updateViewFn;
       this.previewFn = options.previewFn;
-      //this.hadReduce = options.hasReduce || true;
+      this.eventer = options.eventer;
 
       if (typeof(options.hasReduce) === 'undefined') {
         this.hasReduce = true;
@@ -1046,6 +1094,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       } else {
         this.showPreview = options.showPreview;
       }
+
+      this.eventer && this.listenTo(this.eventer, 'options:param_update', this.optionsParamsUpdate);
     },
 
     events: {
@@ -1055,6 +1105,24 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       "click button.preview": "previewView"
     },
 
+    optionsParamsUpdate: function (params) {
+       var $form = this.$el.find("form.view-query-update");
+
+       if (!params.group_level) {
+        this.$("select[name='group_level']").attr('disabled', 'disabled');
+       }
+
+       if (params.reduce && params.group_level) {
+        $form.find("select[name='group_level']").val(params.group_level).removeAttr('disabled');
+        delete params.group_level;
+       } 
+
+      _.each(params, function(val, key) {
+        $form.find("input[name='"+key+"']").prop('checked', val);
+      });
+      this.$('form.view-query-update').submit();
+    },
+
     beforeRender: function () {
       if (this.viewName && this.ddocName) {
         var buttonViews = FauxtonAPI.getExtensions('advancedOptions:ViewButton');
@@ -1136,7 +1204,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         var $ele;
         switch (key) {
           case "limit":
-            case "group_level":
+          case "group_level":
             $form.find("select[name='"+key+"']").val(val);
           break;
           case "include_docs":
@@ -1247,7 +1315,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
       "click button.preview": "previewView",
       "click #db-views-tabs-nav": 'toggleIndexNav',
       "click .beautify_map":  "beautifyCode",
-      "click .beautify_reduce":  "beautifyCode"
+      "click .beautify_reduce":  "beautifyCode",
+      "click #query-options-wrapper": 'toggleIndexNav'
     },
 
     langTemplates: {
@@ -1368,6 +1437,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
           that.mapEditor.editSaved();
           that.reduceEditor && that.reduceEditor.editSaved();
 
+
           FauxtonAPI.addNotification({
             msg: "View has been saved.",
             type: "success",
@@ -1395,6 +1465,9 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
             that.advancedOptions.renderOnUpdatehasReduce(that.hasReduce());
           }
 
+          that.advancedOptionsMenu.setHasReduce(that.hasReduce());
+          that.advancedOptionsMenu.render();
+
           FauxtonAPI.triggerRouteEvent('updateAllDocs', {ddoc: ddocName, view: viewName});
 
         }, function(xhr) {
@@ -1622,19 +1695,29 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
         database: this.database
       }));
 
+      this.eventer = _.extend({}, Backbone.Events);
+
       this.advancedOptions = this.insertView('#query', new Views.AdvancedOptions({
         updateViewFn: this.updateView,
         previewFn: this.previewView,
         database: this.database,
         viewName: this.viewName,
         ddocName: this.model.id,
-        hasReduce: this.hasReduce()
+        hasReduce: this.hasReduce(),
+        eventer: this.eventer
       }));
+
+      this.advancedOptionsMenu = this.insertView('#query-options-wrapper', new Views.AdvancedOptionsMenu({
+        hasReduce: this.hasReduce(),
+        eventer:  this.eventer
+       }));
+
     },
 
     afterRender: function() {
       if (this.params) {
         this.advancedOptions.updateFromParams(this.params);
+        this.advancedOptionsMenu.updateFromParams(this.params);
       }
 
       this.designDocSelector.updateDesignDoc();

http://git-wip-us.apache.org/repos/asf/couchdb/blob/c526a7a6/src/fauxton/app/addons/fauxton/components.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/fauxton/components.js b/src/fauxton/app/addons/fauxton/components.js
index 8b21916..eb1142c 100644
--- a/src/fauxton/app/addons/fauxton/components.js
+++ b/src/fauxton/app/addons/fauxton/components.js
@@ -69,34 +69,53 @@ function(app, FauxtonAPI, ace, spin) {
     initialize: function (options) {
       this.previousUrlfn = options.previousUrlfn;
       this.nextUrlfn = options.nextUrlfn;
-      this.canShowPreviousfn = options.canShowPreviousfn;
-      this.canShowNextfn = options.canShowNextfn;
       this.scrollToSelector = options.scrollToSelector;
       _.bindAll(this);
-      this.previousParams = [];
+      this.pageNumber = 0;
+      this._pageStart = 1;
+      this.perPage = 20;
+    },
+
+    canShowPreviousfn: function () {
+      if (this.pageNumber <= 0) {
+        return false;
+      }
+      return true;
+    },
+
+    canShowNextfn: function () {
+      if (this.collection.length < (this.perPage -1)) {
+        return false;
+      }
+      return true;
     },
 
     previousClicked: function (event) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowPreviousfn()) { return; }
-      FauxtonAPI.navigate(this.previousUrlfn(), {trigger: false});
-      FauxtonAPI.triggerRouteEvent('paginate', 'previous');
+
+      this.pageNumber = this.pageNumber -1;
+      this.decPageStart();
+
+      FauxtonAPI.triggerRouteEvent('paginate', {
+       direction: 'previous',
+       perPage: this.perPage
+      });
     },
 
     nextClicked: function (event) {
       event.preventDefault();
       event.stopPropagation();
       if (!this.canShowNextfn()) { return; }
+      
+      this.pageNumber = this.pageNumber + 1;
+      this.incPageStart();
 
-      var params = _.clone(this.collection.params);
-
-      if (params) {
-        this.previousParams.push(params);
-      }
-
-      FauxtonAPI.navigate(this.nextUrlfn(), {trigger: false});
-      FauxtonAPI.triggerRouteEvent('paginate', 'next');
+      FauxtonAPI.triggerRouteEvent('paginate', {
+       direction: 'next',
+       perPage: this.perPage
+      });
     },
 
     serialize: function () {
@@ -106,29 +125,37 @@ function(app, FauxtonAPI, ace, spin) {
       };
     },
 
-    pageLimit: function () {
-      var limit = 20;
+    updatePerPage: function (perPage) {
+      this.perPage = perPage;
+    },
 
-      if (this.collection.params.limit && this.collection.skipFirstItem) {
-        limit = parseInt(this.collection.params.limit, 10) - 1;
-      } else if (this.collection.params.limit) {
-        limit = parseInt(this.collection.params.limit, 10);
+    page: function () {
+      return this._pageStart - 1;
+    },
+
+    incPageStart: function () {
+      this._pageStart = this._pageStart + this.perPage;
+    },
+
+    decPageStart: function () {
+      var val = this._pageStart - this.perPage;
+      if (val < 1) {
+        this._pageStart = 1;
+        return;
       }
 
-      return limit;
+      this._pageStart = val;
     },
 
     pageStart: function () {
-      return (this.previousParams.length * this.pageLimit()) + 1;
-
+      return this._pageStart;
     },
 
     pageEnd: function () {
-      if (this.collection.length < this.pageLimit()) {
-        return (this.previousParams.length * this.pageLimit()) + this.collection.length;
+      if (this.collection.length < this.perPage) {
+        return this.page() + this.collection.length;
       }
 
-      return (this.previousParams.length * this.pageLimit()) + this.pageLimit();
     }
 
   });