diff --git a/_includes/recline-deps.html b/_includes/recline-deps.html index 5f4313fc..2b8cd735 100644 --- a/_includes/recline-deps.html +++ b/_includes/recline-deps.html @@ -25,7 +25,7 @@ - + diff --git a/_layouts/default.html b/_layouts/default.html index ccd3403c..9ed6a0fd 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -9,114 +9,123 @@ - + {% if page.recline-deps %} {% include recline-deps.html %} {% endif %} - + - + + diff --git a/css-site/style.css b/css-site/style.css index e08cb53e..f0a9e030 100644 --- a/css-site/style.css +++ b/css-site/style.css @@ -28,6 +28,7 @@ body, p { h1, h2, h3, h4, h5, h6 { font-family:'PT Sans',Helvetica, Arial, sans-serif; + font-weight: bold; } h2 { @@ -53,54 +54,78 @@ a:hover { Layout --------------------------------------------------- */ -.navbar .logo-icon img { - margin-top: 6px; - margin-right: 8px; +.navbar-header{ + +} + +.navbar-header .logo-icon { height: 34px; } -.navbar .brand { - font-family:'PT Sans', Helvetica, Arial, sans-serif; - font-style:italic; - font-size:18px; - font-weight:400; - letter-spacing:-1px; - line-height: 32px; +.navbar-brand { + font-family:'PT Sans', Helvetica, Arial, sans-serif; + font-style:italic; + font-size:18px; + font-weight:400; + letter-spacing:-1px; text-shadow: none !important; - color: #ffffff; + color: #FFF !important; + margin-top: -6px; } -.navbar .nav > li > a { +.navbar-nav > li > a { padding: 15px 10px; font-size: 13px; text-shadow: none !important; - color: #999999; + color: #999 !important; } -.navbar .nav > li > a:focus, -.navbar .nav > li > a:hover { - color: #ffffff; +.navbar-nav > li > a:focus, +.navbar-nav > li > a:hover { + color: #FFF !important; } .navbar .divider-vertical { height: 50px; + margin: 0 9px; + border-right: 1px solid #ffffff; } -.navbar-inner { - height:50px; - background: #303030; /* Old browsers */ - background: -moz-linear-gradient(top, #303030 0%, #2d2d2d 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#303030), color-stop(100%,#2d2d2d)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* IE10+ */ - background: linear-gradient(top, #303030 0%,#2d2d2d 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#303030', endColorstr='#2d2d2d',GradientType=0 ); /* IE6-9 */ - -webkit-box-shadow:none; +.navbar-inverse .divider-vertical { + border-right-color: #222222; +} + +@media (max-width: 767px) { + .navbar-collapse .nav > .divider-vertical { + display: none; + } +} + +.navbar { + height:50px; + background: #303030; /* Old browsers */ + background: -moz-linear-gradient(top, #303030 0%, #2d2d2d 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#303030), color-stop(100%,#2d2d2d)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #303030 0%,#2d2d2d 100%); /* IE10+ */ + background: linear-gradient(top, #303030 0%,#2d2d2d 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#303030', endColorstr='#2d2d2d',GradientType=0 ); /* IE6-9 */ + -webkit-box-shadow:none; -moz-box-shadow: none; box-shadow: none; } +.icon-white{ + color: #FFF; + margin-right: 1px; +} + +a.btn, +button.btn { + white-space: normal !important; +} + body { padding-top: 60px; } @@ -165,12 +190,12 @@ section { Footer --------------------------------------------------- */ -.footer { +.recline-footer { background-color:#040404; color:#CCC; margin-top: 30px; } -.footer:before { +.recline-footer:before { content: " "; height:14px; display:block; @@ -179,18 +204,18 @@ section { background-position: center -100px; margin-top:-34px; } -.footer:after { +.recline-footer:after { display:none; } -.footer .row { +.recline-footer .row { margin-top:15px; margin-bottom:15px; } -.footer a { +.recline-footer a { color:#CCC; } -.footer a.btn { - color:#333333; +.recline-footer a.btn { + color: #333333; } .tutorials .well { diff --git a/css/multiview.css b/css/multiview.css index 02c4b704..4b359842 100644 --- a/css/multiview.css +++ b/css/multiview.css @@ -27,22 +27,42 @@ float: right; margin-left: 5px; padding-left: 5px; - border-left: solid 2px #ddd; } -.header .recline-results-info { - line-height: 28px; +.recline-results-info { + line-height: 35px; margin-left: 20px; float: left; } +.recline-data-explorer .data-view-sidebar > div { + margin-top: 5px; + margin-bottom: 10px; +} + +.recline-data-explorer .radio, +.recline-data-explorer .checkbox { + padding-left: 20px; +} + +.recline-data-explorer .editor-update-map { + margin: 30px 0px 20px 0px; +} + +.recline-data-explorer label { + font-weight: normal; +} + /********************************************************** * Query Editor *********************************************************/ -.header .recline-query-editor { +.recline-query-editor { float: right; - height: 30px; + height: 35px; + padding-right: 5px; + margin-right: 5px; + border-right: solid 2px #ddd; } .header .input-prepend { @@ -63,40 +83,95 @@ vertical-align: top; } -.header .recline-query-editor form button { +.recline-query-editor form button { vertical-align: top; } -.header .recline-query-editor label { - display:none; +/* label for screen reader */ +.recline-query-editor .form-inline label { + position: absolute; + top:0; + left:-9999px } /********************************************************** * Pager *********************************************************/ -.header .recline-pager { +.recline-pager { float: left; margin: auto; display: block; margin-left: 20px; } -.header .recline-pager .pagination label { +.recline-pager .pagination li { + display: inline-block; +} + +.recline-pager .pagination label { display:none; } -.header .recline-pager .pagination input { - width: 30px; - height: 18px; +.recline-pager .pagination input { + width: 40px; + height: 25px; padding: 2px 4px; margin: 0; - margin-top: -4px; + margin-top: -2px; + + border: 1px solid #cccccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + transition: border linear 0.2s, box-shadow linear 0.2s; + border-radius: 4px; + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -webkit-border-radius: 4px; + + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-border-radius: 4px; + + -o-transition: border linear 0.2s, box-shadow linear 0.2s; } -.header .recline-pager .pagination a { - line-height: 26px; - padding: 0 6px; +.recline-pager .pagination a { + float: none; + margin-left: -5px; + color: #555; +} + +.recline-pager .pagination .page-range { + height: 34px; + padding: 5px 8px; + margin-left: -5px; + border: 1px solid #ddd; +} + +.recline-pager .pagination .page-range a { + padding: 0px 12px; + border: none; +} + +.recline-pager .pagination .page-range a:hover { + background-color: #ffffff; +} + +.recline-pager .pagination > li:first-child > a { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0px; + border-top-right-radius: 0px; + height: 34px; +} + +.recline-pager .pagination > li:last-child > a { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; + border-bottom-left-radius: 0px; + border-top-left-radius: 0px; + height: 34px; } /********************************************************** @@ -108,6 +183,31 @@ display: none; } +.recline-filter-editor .filters { + margin: 20px 0px; +} + +.recline-filter-editor h3 { + margin-top: 4px; +} + +.recline-filter-editor .filter { + margin-top: 20px; +} + +.recline-filter-editor .filter .form-group { + margin-bottom: 0px; +} + +.recline-filter-editor .filter input, +.recline-filter-editor .filter label { + margin: 0px; +} + +.recline-filter-editor .js-edit button { + margin: 25px 0px 0px 0px; +} + .recline-filter-editor .filter-term a { font-size: 18px; } @@ -120,6 +220,20 @@ .recline-filter-editor input { margin-top: 0.5em; + margin-bottom: 10px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border: 1px solid #cccccc; +} + +.recline-filter-editor label { + font-weight: normal; + display: block; +} + +.recline-filter-editor legend { + margin-bottom: 5px; } .recline-filter-editor .add-filter { @@ -143,22 +257,30 @@ padding: 0; } -.recline-fields-view .fields-list .accordion-heading, -.recline-fields-view .fields-list h3 -{ - margin: 3px 0 3px 5px; +.recline-fields-view .panel { + background-color: #f5f5f5; + border: 1px solid #e5e5e5; } -.recline-fields-view .fields-list .accordion-heading a, -.recline-fields-view .fields-list .accordion-heading h4 { +.recline-fields-view .panel-group h3 { + padding-left: 10px; +} + +.recline-fields-view .fields-list .panel-heading { + padding: 2px 5px; + margin: 1px 0px 1px 5px; +} + +.recline-fields-view .panel a, +.recline-fields-view .panel h4 { display: inline; } -.recline-fields-view .fields-list .accordion-heading a { +.recline-fields-view .panel a { padding: 0; } -.recline-fields-view .fields-list .accordion-heading h4 { +.recline-fields-view .panel h4 { word-wrap: break-word } diff --git a/css/slickgrid.css b/css/slickgrid.css index 5d1835a3..f70a38f1 100644 --- a/css/slickgrid.css +++ b/css/slickgrid.css @@ -29,6 +29,10 @@ classes should alter those! .recline-slickgrid .slick-header-column:hover, .slick-header-column-active { } +.recline-slickgrid .slick-header-column.ui-state-default { + height: 26px; +} + .recline-slickgrid .slick-headerrow { background: #fafafa; } @@ -167,16 +171,16 @@ classes should alter those! .recline-slickgrid .recline-row-delete { font-size: 12px; - padding: 2px; - width: 22px; - height: 14px; + padding: 3px; + width: 29px; + height: 18px; line-height: 13px; } .recline-cell-reorder { font-size: 12px; - padding: 2px; - width: 22px; + padding: 1px; + width: 31px; height: 14px; line-height: 13px; cursor: move; diff --git a/demos/images/calendar.gif b/demos/images/calendar.gif new file mode 100755 index 00000000..90fd2e17 Binary files /dev/null and b/demos/images/calendar.gif differ diff --git a/demos/index.html b/demos/index.html index 16ffa9f2..6c82024e 100644 --- a/demos/index.html +++ b/demos/index.html @@ -11,7 +11,7 @@ root: ../
-
+ - @@ -28,7 +28,7 @@ root: ../
-
+

Data Explorer

The Data Explorer is a full @@ -37,7 +37,7 @@ root: ../ was originally developed to build.

-
+
@@ -45,7 +45,7 @@ root: ../
-
+

Timeliner

Create timelines quickly and easily using the source code)

-
+
@@ -61,7 +61,7 @@ root: ../
-
+

Crime Maps

See Recline's geo filter and map view capabilities put to good use @@ -69,7 +69,7 @@ root: ../ Data Explorer pre-configured to show thefts near 9th and Mission.

-
+
@@ -77,7 +77,7 @@ root: ../
-
+

Search Demo

See how easy it is to build a responsive AJAX-based search interface @@ -85,7 +85,7 @@ root: ../ to easily customize the display of results.

-
+
diff --git a/demos/search/index.html b/demos/search/index.html index 28d3bb6a..b9cadf5f 100644 --- a/demos/search/index.html +++ b/demos/search/index.html @@ -17,7 +17,7 @@ root: ../../ } .controls .query-here { - width: 500px; + width: 510px; margin: auto; } @@ -28,30 +28,10 @@ root: ../../ } .pager-here { - width: 200px; + width: 230px; margin: auto; } -.recline-pager { - float: left; - margin: auto; - display: block; - margin-left: 20px; -} - -.recline-pager .pagination input { - width: 30px; - height: 18px; - padding: 2px 4px; - margin: 0; - margin-top: -4px; -} - -.recline-pager .pagination a { - line-height: 26px; - padding: 0 6px; -} - .body { clear: both; } @@ -71,13 +51,18 @@ root: ../../ ul.facet-items { list-style-type: none; - margin-left: 0; + margin-left: 0px; + padding: 0px; } .record ul { list-style-type: none; margin-left: 0; } + +.recline-query-editor { + border-right: none; +} + + diff --git a/docs/src/widget.facetviewer.html b/docs/src/widget.facetviewer.html index ddc3ab72..d2523dc3 100644 --- a/docs/src/widget.facetviewer.html +++ b/docs/src/widget.facetviewer.html @@ -1,83 +1,259 @@ - widget.facetviewer.js

widget.facetviewer.js

/*jshint multistr:true */
+
 
-this.recline = this.recline || {};
-this.recline.View = this.recline.View || {};
+
+
+  widget.facetviewer.js
+  
+  
+  
+
+
+  

FacetViewer

+this.recline = this.recline || {}; +this.recline.View = this.recline.View || {}; +(function($, my) { + "use strict"; + + + + +
  • +
    + +
    + +
    +

    FacetViewer

    Widget for displaying facets

    -

    Usage:

    - -
     var viewer = new FacetViewer({
    +
     var viewer = new FacetViewer({
        model: dataset
      });
    -
  • my.FacetViewer = Backbone.View.extend({
    -  className: 'recline-facet-viewer', 
    -  template: ' \
    -    <div class="facets"> \
    -      {{#facets}} \
    -      <div class="facet-summary" data-facet="{{id}}"> \
    -        <h3> \
    -          {{id}} \
    -        </h3> \
    -        <ul class="facet-items"> \
    -        {{#terms}} \
    -          <li><a class="facet-choice js-facet-filter" data-value="{{term}}" href="#{{term}}">{{term}} ({{count}})</a></li> \
    -        {{/terms}} \
    -        {{#entries}} \
    -          <li><a class="facet-choice js-facet-filter" data-value="{{time}}">{{term}} ({{count}})</a></li> \
    -        {{/entries}} \
    -        </ul> \
    -      </div> \
    -      {{/facets}} \
    -    </div> \
    -  ',
    +
    +
    + +
    my.FacetViewer = Backbone.View.extend({
    +  className: 'recline-facet-viewer', 
    +  template: ' \
    +    <div class="facets"> \
    +      {{#facets}} \
    +      <div class="facet-summary" data-facet="{{id}}"> \
    +        <h3> \
    +          {{id}} \
    +        </h3> \
    +        <ul class="facet-items"> \
    +        {{#terms}} \
    +          <li><a class="facet-choice js-facet-filter" data-value="{{term}}" href="#{{term}}">{{term}} ({{count}})</a></li> \
    +        {{/terms}} \
    +        {{#entries}} \
    +          <li><a class="facet-choice js-facet-filter" data-value="{{time}}">{{term}} ({{count}})</a></li> \
    +        {{/entries}} \
    +        </ul> \
    +      </div> \
    +      {{/facets}} \
    +    </div> \
    +  ',
     
    -  events: {
    -    'click .js-facet-filter': 'onFacetFilter'
    -  },
    -  initialize: function(model) {
    -    _.bindAll(this, 'render');
    -    this.listenTo(this.model.facets, 'all', this.render);
    -    this.listenTo(this.model.fields, 'all', this.render);
    -    this.render();
    -  },
    -  render: function() {
    -    var tmplData = {
    -      fields: this.model.fields.toJSON()
    -    };
    -    tmplData.facets = _.map(this.model.facets.toJSON(), function(facet) {
    -      if (facet._type === 'date_histogram') {
    -        facet.entries = _.map(facet.entries, function(entry) {
    -          entry.term = new Date(entry.time).toDateString();
    -          return entry;
    -        });
    -      }
    -      return facet;
    -    });
    -    var templated = Mustache.render(this.template, tmplData);
    -    this.$el.html(templated);

    are there actually any facets to show?

        if (this.model.facets.length > 0) {
    -      this.$el.show();
    -    } else {
    -      this.$el.hide();
    -    }
    -  },
    -  onHide: function(e) {
    -    e.preventDefault();
    -    this.$el.hide();
    -  },
    -  onFacetFilter: function(e) {
    -    e.preventDefault();
    -    var $target= $(e.target);
    -    var fieldId = $target.closest('.facet-summary').attr('data-facet');
    -    var value = $target.attr('data-value');
    -    this.model.queryState.addFilter({type: 'term', field: fieldId, term: value});

    have to trigger explicitly for some reason

        this.model.query();
    -  }
    -});
    +  events: {
    +    'click .js-facet-filter': 'onFacetFilter'
    +  },
    +  initialize: function(model) {
    +    _.bindAll(this, 'render');
    +    this.listenTo(this.model.facets, 'all', this.render);
    +    this.listenTo(this.model.fields, 'all', this.render);
    +    this.render();
    +  },
    +  render: function() {
    +    var tmplData = {
    +      fields: this.model.fields.toJSON()
    +    };
    +    tmplData.facets = _.map(this.model.facets.toJSON(), function(facet) {
    +      if (facet._type === 'date_histogram') {
    +        facet.entries = _.map(facet.entries, function(entry) {
    +          entry.term = new Date(entry.time).toDateString();
    +          return entry;
    +        });
    +      }
    +      return facet;
    +    });
    +    var templated = Mustache.render(this.template, tmplData);
    +    this.$el.html(templated);
    + + + + +
  • +
    + +
    + +
    +

    are there actually any facets to show?

    + +
    + +
        if (this.model.facets.length > 0) {
    +      this.$el.show();
    +    } else {
    +      this.$el.hide();
    +    }
    +  },
    +  onHide: function(e) {
    +    e.preventDefault();
    +    this.$el.hide();
    +  },
    +  onFacetFilter: function(e) {
    +    e.preventDefault();
    +    var $target= $(e.target);
    +    var fieldId = $target.closest('.facet-summary').attr('data-facet');
    +    var value = $target.attr('data-value');
    +    this.model.queryState.addFilter({type: 'term', field: fieldId, term: value});
    + +
  • + + +
  • +
    + +
    + +
    +

    have to trigger explicitly for some reason

    + +
    + +
        this.model.query();
    +  }
    +});
     
     
    -})(jQuery, recline.View);
    -
    -
  • \ No newline at end of file +})(jQuery, recline.View);
    + + + + +
    + + diff --git a/docs/src/widget.fields.html b/docs/src/widget.fields.html index d4fe2282..07b34852 100644 --- a/docs/src/widget.fields.html +++ b/docs/src/widget.fields.html @@ -1,82 +1,299 @@ - widget.fields.js

    widget.fields.js

    /*jshint multistr:true */

    Field Info

    + + + + widget.fields.js + + + + + +
    +
    + + + +
      + +
    • +
      +

      widget.fields.js

      +
      +
    • + + + +
    • +
      + +
      + +
      + +
      + +
      /*jshint multistr:true */
      + +
    • + + +
    • +
      + +
      + +
      +

      Field Info

      For each field

      +

      Id / Label / type / format

      -

      Id / Label / type / format

    Editor -- to change type (and possibly format) -Editor for show/hide ...

    Summaries of fields

    + + + + + +
  • +
    + +
    + +
    +

    Editor — to change type (and possibly format) +Editor for show/hide …

    +
    + +
  • + + +
  • +
    + +
    + +
    +

    Summaries of fields

    Top values / number empty -If number: max, min average ...

  • Box to boot transform editor ...

    this.recline = this.recline || {};
    -this.recline.View = this.recline.View || {};
    +If number: max, min average …

    -(function($, my) { - "use strict"; +
    + + + + +
  • +
    + +
    + +
    +

    Box to boot transform editor …

    + +
    + +
    +this.recline = this.recline || {};
    +this.recline.View = this.recline.View || {};
    +
    +(function($, my) {
    +  "use strict";
       
    -my.Fields = Backbone.View.extend({
    -  className: 'recline-fields-view', 
    -  template: ' \
    -    <div class="accordion fields-list well"> \
    -    <h3>Fields <a href="#" class="js-show-hide">+</a></h3> \
    -    {{#fields}} \
    -      <div class="accordion-group field"> \
    -        <div class="accordion-heading"> \
    -          <i class="icon-file"></i> \
    -          <h4> \
    -            {{label}} \
    -            <small> \
    -              {{type}} \
    -              <a class="accordion-toggle" data-toggle="collapse" href="#collapse{{id}}"> &raquo; </a> \
    -            </small> \
    -          </h4> \
    -        </div> \
    -        <div id="collapse{{id}}" class="accordion-body collapse"> \
    -          <div class="accordion-inner"> \
    -            {{#facets}} \
    -            <div class="facet-summary" data-facet="{{id}}"> \
    -              <ul class="facet-items"> \
    -              {{#terms}} \
    -                <li class="facet-item"><span class="term">{{term}}</span> <span class="count">[{{count}}]</span></li> \
    -              {{/terms}} \
    -              </ul> \
    -            </div> \
    -            {{/facets}} \
    -            <div class="clear"></div> \
    -          </div> \
    -        </div> \
    -      </div> \
    -    {{/fields}} \
    -    </div> \
    -  ',
    +my.Fields = Backbone.View.extend({
    +  className: 'recline-fields-view', 
    +  template: ' \
    +    <div class="panel-group fields-list well"> \
    +    <h3>Fields <a href="#" class="js-show-hide">+</a></h3> \
    +    {{#fields}} \
    +      <div class="panel panel-default field"> \
    +        <div class="panel-heading"> \
    +          <i class="glyphicon glyphicon-file"></i> \
    +          <h4> \
    +            {{label}} \
    +            <small> \
    +              {{type}} \
    +              <a class="accordion-toggle" data-toggle="collapse" href="#collapse{{id}}"> &raquo; </a> \
    +            </small> \
    +          </h4> \
    +        </div> \
    +        <div id="collapse{{id}}" class="panel-collapse collapse"> \
    +          <div class="panel-body"> \
    +            {{#facets}} \
    +            <div class="facet-summary" data-facet="{{id}}"> \
    +              <ul class="facet-items"> \
    +              {{#terms}} \
    +                <li class="facet-item"><span class="term">{{term}}</span> <span class="count">[{{count}}]</span></li> \
    +              {{/terms}} \
    +              </ul> \
    +            </div> \
    +            {{/facets}} \
    +            <div class="clear"></div> \
    +          </div> \
    +        </div> \
    +      </div> \
    +    {{/fields}} \
    +    </div> \
    +  ',
     
    -  initialize: function(model) {
    -    var self = this;
    -    _.bindAll(this, 'render');
  • TODO: this is quite restrictive in terms of when it is re-run + initialize: function(model) { + var self = this; + _.bindAll(this, 'render'); + + + + +

  • +
    + +
    + +
    +

    TODO: this is quite restrictive in terms of when it is re-run e.g. a change in type will not trigger a re-run atm. -being more liberal (e.g. binding to all) can lead to being called a lot (e.g. for change:width)

  •     this.listenTo(this.model.fields, 'reset', function(action) {
    -      self.model.fields.each(function(field) {
    -        field.facets.unbind('all', self.render);
    -        field.facets.bind('all', self.render);
    -      });

    fields can get reset or changed in which case we need to recalculate

          self.model.getFieldsSummary();
    -      self.render();
    -    });
    -    this.$el.find('.collapse').collapse();
    -    this.render();
    -  },
    -  render: function() {
    -    var self = this;
    -    var tmplData = {
    -      fields: []
    -    };
    -    this.model.fields.each(function(field) {
    -      var out = field.toJSON();
    -      out.facets = field.facets.toJSON();
    -      tmplData.fields.push(out);
    -    });
    -    var templated = Mustache.render(this.template, tmplData);
    -    this.$el.html(templated);
    -  }
    -});
    +being more liberal (e.g. binding to all) can lead to being called a lot (e.g. for change:width)

    -})(jQuery, recline.View); +
    + +
        this.listenTo(this.model.fields, 'reset', function(action) {
    +      self.model.fields.each(function(field) {
    +        field.facets.unbind('all', self.render);
    +        field.facets.bind('all', self.render);
    +      });
    + + + + +
  • +
    + +
    + +
    +

    fields can get reset or changed in which case we need to recalculate

    -
  • \ No newline at end of file +
    + +
          self.model.getFieldsSummary();
    +      self.render();
    +    });
    +    this.$el.find('.collapse').collapse();
    +    this.render();
    +  },
    +  render: function() {
    +    var self = this;
    +    var tmplData = {
    +      fields: []
    +    };
    +    this.model.fields.each(function(field) {
    +      var out = field.toJSON();
    +      out.facets = field.facets.toJSON();
    +      tmplData.fields.push(out);
    +    });
    +    var templated = Mustache.render(this.template, tmplData);
    +    this.$el.html(templated);
    +  }
    +});
    +
    +})(jQuery, recline.View);
    + + + + +
    + + diff --git a/docs/src/widget.filtereditor.html b/docs/src/widget.filtereditor.html index d4bf97bb..a761e3d7 100644 --- a/docs/src/widget.filtereditor.html +++ b/docs/src/widget.filtereditor.html @@ -1,168 +1,330 @@ - widget.filtereditor.js

    widget.filtereditor.js

    /*jshint multistr:true */
    +
     
    -this.recline = this.recline || {};
    -this.recline.View = this.recline.View || {};
    +
    +
    +  widget.filtereditor.js
    +  
    +  
    +  
    +
    +
    +  
    +
    + + + +
      + +
    • +
      +

      widget.filtereditor.js

      +
      +
    • + + + +
    • +
      + +
      + +
      + +
      + +
      /*jshint multistr:true */
       
      -(function($, my) {
      -  "use strict";
      +this.recline = this.recline || {};
      +this.recline.View = this.recline.View || {};
       
      -my.FilterEditor = Backbone.View.extend({
      -  className: 'recline-filter-editor well', 
      -  template: ' \
      -    <div class="filters"> \
      -      <h3>Filters</h3> \
      -      <a href="#" class="js-add-filter">Add filter</a> \
      -      <form class="form-stacked js-add" style="display: none;"> \
      -        <fieldset> \
      -          <label>Field</label> \
      -          <select class="fields"> \
      -            {{#fields}} \
      -            <option value="{{id}}">{{label}}</option> \
      -            {{/fields}} \
      -          </select> \
      -          <label>Filter type</label> \
      -          <select class="filterType"> \
      -            <option value="term">Value</option> \
      -            <option value="range">Range</option> \
      -            <option value="geo_distance">Geo distance</option> \
      -          </select> \
      -          <button type="submit" class="btn">Add</button> \
      -        </fieldset> \
      -      </form> \
      -      <form class="form-stacked js-edit"> \
      -        {{#filters}} \
      -          {{{filterRender}}} \
      -        {{/filters}} \
      -        {{#filters.length}} \
      -        <button type="submit" class="btn">Update</button> \
      -        {{/filters.length}} \
      -      </form> \
      -    </div> \
      -  ',
      -  filterTemplates: {
      -    term: ' \
      -      <div class="filter-{{type}} filter"> \
      -        <fieldset> \
      -          <legend> \
      -            {{field}} <small>{{type}}</small> \
      -            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
      -          </legend> \
      -          <input type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -        </fieldset> \
      -      </div> \
      -    ',
      -    range: ' \
      -      <div class="filter-{{type}} filter"> \
      -        <fieldset> \
      -          <legend> \
      -            {{field}} <small>{{type}}</small> \
      -            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
      -          </legend> \
      -          <label class="control-label" for="">From</label> \
      -          <input type="text" value="{{from}}" name="from" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -          <label class="control-label" for="">To</label> \
      -          <input type="text" value="{{to}}" name="to" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -        </fieldset> \
      -      </div> \
      -    ',
      -    geo_distance: ' \
      -      <div class="filter-{{type}} filter"> \
      -        <fieldset> \
      -          <legend> \
      -            {{field}} <small>{{type}}</small> \
      -            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
      -          </legend> \
      -          <label class="control-label" for="">Longitude</label> \
      -          <input type="text" value="{{point.lon}}" name="lon" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -          <label class="control-label" for="">Latitude</label> \
      -          <input type="text" value="{{point.lat}}" name="lat" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -          <label class="control-label" for="">Distance (km)</label> \
      -          <input type="text" value="{{distance}}" name="distance" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
      -        </fieldset> \
      -      </div> \
      -    '
      -  },
      -  events: {
      -    'click .js-remove-filter': 'onRemoveFilter',
      -    'click .js-add-filter': 'onAddFilterShow',
      -    'submit form.js-edit': 'onTermFiltersUpdate',
      -    'submit form.js-add': 'onAddFilter'
      -  },
      -  initialize: function() {
      -    _.bindAll(this, 'render');
      -    this.listenTo(this.model.fields, 'all', this.render);
      -    this.listenTo(this.model.queryState, 'change change:filters:new-blank', this.render);
      -    this.render();
      -  },
      -  render: function() {
      -    var self = this;
      -    var tmplData = $.extend(true, {}, this.model.queryState.toJSON());

    we will use idx in list as there id ...

        tmplData.filters = _.map(tmplData.filters, function(filter, idx) {
    -      filter.id = idx;
    -      return filter;
    -    });
    -    tmplData.fields = this.model.fields.toJSON();
    -    tmplData.filterRender = function() {
    -      return Mustache.render(self.filterTemplates[this.type], this);
    -    };
    -    var out = Mustache.render(this.template, tmplData);
    -    this.$el.html(out);
    -  },
    -  onAddFilterShow: function(e) {
    -    e.preventDefault();
    -    var $target = $(e.target);
    -    $target.hide();
    -    this.$el.find('form.js-add').show();
    -  },
    -  onAddFilter: function(e) {
    -    e.preventDefault();
    -    var $target = $(e.target);
    -    $target.hide();
    -    var filterType = $target.find('select.filterType').val();
    -    var field      = $target.find('select.fields').val();
    -    this.model.queryState.addFilter({type: filterType, field: field});
    -  },
    -  onRemoveFilter: function(e) {
    -    e.preventDefault();
    -    var $target = $(e.target);
    -    var filterId = $target.attr('data-filter-id');
    -    this.model.queryState.removeFilter(filterId);
    -  },
    -  onTermFiltersUpdate: function(e) {
    -   var self = this;
    -    e.preventDefault();
    -    var filters = self.model.queryState.get('filters');
    -    var $form = $(e.target);
    -    _.each($form.find('input'), function(input) {
    -      var $input = $(input);
    -      var filterType  = $input.attr('data-filter-type');
    -      var fieldId     = $input.attr('data-filter-field');
    -      var filterIndex = parseInt($input.attr('data-filter-id'), 10);
    -      var name        = $input.attr('name');
    -      var value       = $input.val();
    +(function($, my) {
    +  "use strict";
     
    -      switch (filterType) {
    -        case 'term':
    -          filters[filterIndex].term = value;
    -          break;
    -        case 'range':
    -          filters[filterIndex][name] = value;
    -          break;
    -        case 'geo_distance':
    -          if(name === 'distance') {
    -            filters[filterIndex].distance = parseFloat(value);
    -          }
    -          else {
    -            filters[filterIndex].point[name] = parseFloat(value);
    -          }
    -          break;
    -      }
    -    });
    -    self.model.queryState.set({filters: filters, from: 0});
    -    self.model.queryState.trigger('change');
    -  }
    -});
    +my.FilterEditor = Backbone.View.extend({
    +  className: 'recline-filter-editor well', 
    +  template: ' \
    +    <div class="filters"> \
    +      <h3>Filters</h3> \
    +      <a href="#" class="js-add-filter">Add filter</a> \
    +      <form class="form-stacked js-add" style="display: none;"> \
    +        <div class="form-group"> \
    +          <label>Field</label> \
    +          <select class="fields form-control"> \
    +            {{#fields}} \
    +            <option value="{{id}}">{{label}}</option> \
    +            {{/fields}} \
    +          </select> \
    +        </div> \
    +        <div class="form-group"> \
    +          <label>Filter type</label> \
    +          <select class="filterType form-control"> \
    +            <option value="term">Value</option> \
    +            <option value="range">Range</option> \
    +            <option value="geo_distance">Geo distance</option> \
    +          </select> \
    +        </div> \
    +        <button type="submit" class="btn btn-default">Add</button> \
    +      </form> \
    +      <form class="form-stacked js-edit"> \
    +        {{#filters}} \
    +          {{{filterRender}}} \
    +        {{/filters}} \
    +        {{#filters.length}} \
    +        <button type="submit" class="btn btn-default">Update</button> \
    +        {{/filters.length}} \
    +      </form> \
    +    </div> \
    +  ',
    +  filterTemplates: {
    +    term: ' \
    +      <div class="filter-{{type}} filter"> \
    +        <fieldset> \
    +          <legend> \
    +            {{field}} <small>{{type}}</small> \
    +            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
    +          </legend> \
    +          <input class="input-sm" type="text" value="{{term}}" name="term" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +        </fieldset> \
    +      </div> \
    +    ',
    +    range: ' \
    +      <div class="filter-{{type}} filter"> \
    +        <fieldset> \
    +          <legend> \
    +            {{field}} <small>{{type}}</small> \
    +            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
    +          </legend> \
    +          <div class="form-group"> \
    +            <label class="control-label" for="">From</label> \
    +            <input class="input-sm" type="text" value="{{from}}" name="from" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +          </div> \
    +          <div class="form-group"> \
    +            <label class="control-label" for="">To</label> \
    +            <input class="input-sm" type="text" value="{{to}}" name="to" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +          </div> \
    +        </fieldset> \
    +      </div> \
    +    ',
    +    geo_distance: ' \
    +      <div class="filter-{{type}} filter"> \
    +        <fieldset> \
    +          <legend> \
    +            {{field}} <small>{{type}}</small> \
    +            <a class="js-remove-filter" href="#" title="Remove this filter" data-filter-id="{{id}}">&times;</a> \
    +          </legend> \
    +          <div class="form-group"> \
    +            <label class="control-label" for="">Longitude</label> \
    +            <input class="input-sm" type="text" value="{{point.lon}}" name="lon" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +          </div> \
    +          <div class="form-group"> \
    +            <label class="control-label" for="">Latitude</label> \
    +            <input class="input-sm" type="text" value="{{point.lat}}" name="lat" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +          </div> \
    +          <div class="form-group"> \
    +            <label class="control-label" for="">Distance (km)</label> \
    +            <input class="input-sm" type="text" value="{{distance}}" name="distance" data-filter-field="{{field}}" data-filter-id="{{id}}" data-filter-type="{{type}}" /> \
    +          </div> \
    +        </fieldset> \
    +      </div> \
    +    '
    +  },
    +  events: {
    +    'click .js-remove-filter': 'onRemoveFilter',
    +    'click .js-add-filter': 'onAddFilterShow',
    +    'submit form.js-edit': 'onTermFiltersUpdate',
    +    'submit form.js-add': 'onAddFilter'
    +  },
    +  initialize: function() {
    +    _.bindAll(this, 'render');
    +    this.listenTo(this.model.fields, 'all', this.render);
    +    this.listenTo(this.model.queryState, 'change change:filters:new-blank', this.render);
    +    this.render();
    +  },
    +  render: function() {
    +    var self = this;
    +    var tmplData = $.extend(true, {}, this.model.queryState.toJSON());
    + + + + +
  • +
    + +
    + +
    +

    we will use idx in list as there id …

    + +
    + +
        tmplData.filters = _.map(tmplData.filters, function(filter, idx) {
    +      filter.id = idx;
    +      return filter;
    +    });
    +    tmplData.fields = this.model.fields.toJSON();
    +    tmplData.filterRender = function() {
    +      return Mustache.render(self.filterTemplates[this.type], this);
    +    };
    +    var out = Mustache.render(this.template, tmplData);
    +    this.$el.html(out);
    +  },
    +  onAddFilterShow: function(e) {
    +    e.preventDefault();
    +    var $target = $(e.target);
    +    $target.hide();
    +    this.$el.find('form.js-add').show();
    +  },
    +  onAddFilter: function(e) {
    +    e.preventDefault();
    +    var $target = $(e.target);
    +    $target.hide();
    +    var filterType = $target.find('select.filterType').val();
    +    var field      = $target.find('select.fields').val();
    +    this.model.queryState.addFilter({type: filterType, field: field});
    +  },
    +  onRemoveFilter: function(e) {
    +    e.preventDefault();
    +    var $target = $(e.target);
    +    var filterId = $target.attr('data-filter-id');
    +    this.model.queryState.removeFilter(filterId);
    +  },
    +  onTermFiltersUpdate: function(e) {
    +   var self = this;
    +    e.preventDefault();
    +    var filters = self.model.queryState.get('filters');
    +    var $form = $(e.target);
    +    _.each($form.find('input'), function(input) {
    +      var $input = $(input);
    +      var filterType  = $input.attr('data-filter-type');
    +      var fieldId     = $input.attr('data-filter-field');
    +      var filterIndex = parseInt($input.attr('data-filter-id'), 10);
    +      var name        = $input.attr('name');
    +      var value       = $input.val();
    +
    +      switch (filterType) {
    +        case 'term':
    +          filters[filterIndex].term = value;
    +          break;
    +        case 'range':
    +          filters[filterIndex][name] = value;
    +          break;
    +        case 'geo_distance':
    +          if(name === 'distance') {
    +            filters[filterIndex].distance = parseFloat(value);
    +          }
    +          else {
    +            filters[filterIndex].point[name] = parseFloat(value);
    +          }
    +          break;
    +      }
    +    });
    +    self.model.queryState.set({filters: filters, from: 0});
    +    self.model.queryState.trigger('change');
    +  }
    +});
     
     
    -})(jQuery, recline.View);
    -
    -
  • \ No newline at end of file +})(jQuery, recline.View);
    + + + + +
    + + diff --git a/docs/src/widget.pager.html b/docs/src/widget.pager.html index c03c3d98..71ab94da 100644 --- a/docs/src/widget.pager.html +++ b/docs/src/widget.pager.html @@ -1,70 +1,223 @@ - widget.pager.js

    widget.pager.js

    /*jshint multistr:true */
    +
     
    -this.recline = this.recline || {};
    -this.recline.View = this.recline.View || {};
    +
    +
    +  widget.pager.js
    +  
    +  
    +  
    +
    +
    +  
    +
    + + + +
      + +
    • +
      +

      widget.pager.js

      +
      +
    • + + + +
    • +
      + +
      + +
      + +
      + +
      /*jshint multistr:true */
       
      -(function($, my) {
      -  "use strict";
      +this.recline = this.recline || {};
      +this.recline.View = this.recline.View || {};
       
      -my.Pager = Backbone.View.extend({
      -  className: 'recline-pager', 
      -  template: ' \
      -    <div class="pagination"> \
      -      <ul> \
      -        <li class="prev action-pagination-update"><a href="">&laquo;</a></li> \
      -        <li class="active"><a><input name="from" type="text" value="{{from}}" /> &ndash; <input name="to" type="text" value="{{to}}" /> </a></li> \
      -        <li class="next action-pagination-update"><a href="">&raquo;</a></li> \
      -      </ul> \
      -    </div> \
      -  ',
      +(function($, my) {
      +  "use strict";
       
      -  events: {
      -    'click .action-pagination-update': 'onPaginationUpdate',
      -    'change input': 'onFormSubmit'
      -  },
      +my.Pager = Backbone.View.extend({
      +  className: 'recline-pager', 
      +  template: ' \
      +    <div class="pagination"> \
      +      <ul class="pagination"> \
      +        <li class="prev action-pagination-update"><a href="" class="btn btn-default">&laquo;</a></li> \
      +        <li class="page-range"><a><label for="from">From</label><input name="from" type="text" value="{{from}}" /> &ndash; <label for="to">To</label><input name="to" type="text" value="{{to}}" /> </a></li> \
      +        <li class="next action-pagination-update"><a href="" class="btn btn-default">&raquo;</a></li> \
      +      </ul> \
      +    </div> \
      +  ',
       
      -  initialize: function() {
      -    _.bindAll(this, 'render');
      -    this.listenTo(this.model.queryState, 'change', this.render);
      -    this.render();
      -  },
      -  onFormSubmit: function(e) {
      -    e.preventDefault();
      -    var newFrom = parseInt(this.$el.find('input[name="from"]').val());
      -    newFrom = Math.min(this.model.recordCount, Math.max(newFrom, 1))-1;
      -    var newSize = parseInt(this.$el.find('input[name="to"]').val()) - newFrom;
      -    newSize = Math.min(Math.max(newSize, 1), this.model.recordCount);
      -    this.model.queryState.set({size: newSize, from: newFrom});
      -  },
      -  onPaginationUpdate: function(e) {
      -    e.preventDefault();
      -    var $el = $(e.target);
      -    var newFrom = 0;
      -    var currFrom = this.model.queryState.get('from');
      -    var size = this.model.queryState.get('size');
      -    var updateQuery = false;
      -    if ($el.parent().hasClass('prev')) {
      -      newFrom = Math.max(currFrom - Math.max(0, size), 1)-1;
      -      updateQuery = newFrom != currFrom;
      -    } else {
      -      newFrom = Math.max(currFrom + size, 1);
      -      updateQuery = (newFrom < this.model.recordCount);
      -    }
      -    if (updateQuery) {
      -      this.model.queryState.set({from: newFrom});
      -    }
      -  },
      -  render: function() {
      -    var tmplData = this.model.toJSON();
      -    var from = parseInt(this.model.queryState.get('from'));
      -    tmplData.from = from+1;
      -    tmplData.to = Math.min(from+this.model.queryState.get('size'), this.model.recordCount);
      -    var templated = Mustache.render(this.template, tmplData);
      -    this.$el.html(templated);
      -    return this;
      -  }
      -});
      +  events: {
      +    'click .action-pagination-update': 'onPaginationUpdate',
      +    'change input': 'onFormSubmit'
      +  },
       
      -})(jQuery, recline.View);
      +  initialize: function() {
      +    _.bindAll(this, 'render');
      +    this.listenTo(this.model.queryState, 'change', this.render);
      +    this.render();
      +  },
      +  onFormSubmit: function(e) {
      +    e.preventDefault();
      + +
    • + + +
    • +
      + +
      + +
      +

      filter is 0-based; form is 1-based

      -
    \ No newline at end of file +
    + +
        var formFrom = parseInt(this.$el.find('input[name="from"]').val())-1; 
    +    var formTo = parseInt(this.$el.find('input[name="to"]').val())-1; 
    +    var maxRecord = this.model.recordCount-1;
    +    if (this.model.queryState.get('from') != formFrom) { // changed from; update from
    +      this.model.queryState.set({from: Math.min(maxRecord, Math.max(formFrom, 0))});
    +    } else if (this.model.queryState.get('to') != formTo) { // change to; update size
    +      var to = Math.min(maxRecord, Math.max(formTo, 0));
    +      this.model.queryState.set({size: Math.min(maxRecord+1, Math.max(to-formFrom+1, 1))});
    +    }
    +  },
    +  onPaginationUpdate: function(e) {
    +    e.preventDefault();
    +    var $el = $(e.target);
    +    var newFrom = 0;
    +    var currFrom = this.model.queryState.get('from');
    +    var size = this.model.queryState.get('size');
    +    var updateQuery = false;
    +    if ($el.parent().hasClass('prev')) {
    +      newFrom = Math.max(currFrom - Math.max(0, size), 0);
    +      updateQuery = newFrom != currFrom;
    +    } else {
    +      newFrom = Math.max(currFrom + size, 0);
    +      updateQuery = (newFrom < this.model.recordCount);
    +    }
    +    if (updateQuery) {
    +      this.model.queryState.set({from: newFrom});
    +    }
    +  },
    +  render: function() {
    +    var tmplData = this.model.toJSON();
    +    var from = parseInt(this.model.queryState.get('from'));
    +    tmplData.from = from+1;
    +    tmplData.to = Math.min(from+this.model.queryState.get('size'), this.model.recordCount);
    +    var templated = Mustache.render(this.template, tmplData);
    +    this.$el.html(templated);
    +    return this;
    +  }
    +});
    +
    +})(jQuery, recline.View);
    + + + + +
    + + diff --git a/docs/src/widget.queryeditor.html b/docs/src/widget.queryeditor.html index 79262cf0..37a42d30 100644 --- a/docs/src/widget.queryeditor.html +++ b/docs/src/widget.queryeditor.html @@ -1,44 +1,184 @@ - widget.queryeditor.js
    Jump To …

    widget.queryeditor.js

    /*jshint multistr:true */
    +
     
    -this.recline = this.recline || {};
    -this.recline.View = this.recline.View || {};
    +
    +
    +  widget.queryeditor.js
    +  
    +  
    +  
    +
    +
    +  
    +
    + + + +
      + +
    • +
      +

      widget.queryeditor.js

      +
      +
    • + + + +
    • +
      + +
      + +
      + +
      + +
      /*jshint multistr:true */
       
      -(function($, my) {
      -  "use strict";
      +this.recline = this.recline || {};
      +this.recline.View = this.recline.View || {};
       
      -my.QueryEditor = Backbone.View.extend({
      -  className: 'recline-query-editor', 
      -  template: ' \
      -    <form action="" method="GET" class="form-inline"> \
      -      <div class="input-prepend text-query"> \
      -        <span class="add-on"><i class="icon-search"></i></span> \
      -        <input type="text" name="q" value="{{q}}" class="span2" placeholder="Search data ..." class="search-query" /> \
      -      </div> \
      -      <button type="submit" class="btn">Go &raquo;</button> \
      -    </form> \
      -  ',
      +(function($, my) {
      +  "use strict";
       
      -  events: {
      -    'submit form': 'onFormSubmit'
      -  },
      +my.QueryEditor = Backbone.View.extend({
      +  className: 'recline-query-editor', 
      +  template: ' \
      +    <form action="" method="GET" class="form-inline" role="form"> \
      +      <div class="form-group"> \
      +        <div class="input-group text-query"> \
      +          <div class="input-group-addon"> \
      +            <i class="glyphicon glyphicon-search"></i> \
      +          </div> \
      +          <label>Search</label> \
      +          <input class="form-control search-query" type="text" name="q" value="{{q}}" placeholder="Search data ..."> \
      +        </div> \
      +      </div> \
      +      <button type="submit" class="btn btn-default">Go &raquo;</button> \
      +    </form> \
      +  ',
       
      -  initialize: function() {
      -    _.bindAll(this, 'render');
      -    this.listenTo(this.model, 'change', this.render);
      -    this.render();
      -  },
      -  onFormSubmit: function(e) {
      -    e.preventDefault();
      -    var query = this.$el.find('.text-query input').val();
      -    this.model.set({q: query});
      -  },
      -  render: function() {
      -    var tmplData = this.model.toJSON();
      -    var templated = Mustache.render(this.template, tmplData);
      -    this.$el.html(templated);
      -  }
      -});
      +  events: {
      +    'submit form': 'onFormSubmit'
      +  },
       
      -})(jQuery, recline.View);
      +  initialize: function() {
      +    _.bindAll(this, 'render');
      +    this.listenTo(this.model, 'change', this.render);
      +    this.render();
      +  },
      +  onFormSubmit: function(e) {
      +    e.preventDefault();
      +    var query = this.$el.find('.search-query').val();
      +    this.model.set({q: query});
      +  },
      +  render: function() {
      +    var tmplData = this.model.toJSON();
      +    var templated = Mustache.render(this.template, tmplData);
      +    this.$el.html(templated);
      +  }
      +});
       
      -
    \ No newline at end of file +})(jQuery, recline.View); + + + + + + + diff --git a/docs/src/widget.valuefilter.html b/docs/src/widget.valuefilter.html new file mode 100644 index 00000000..1f72bc0f --- /dev/null +++ b/docs/src/widget.valuefilter.html @@ -0,0 +1,264 @@ + + + + + widget.valuefilter.js + + + + + +
    +
    + + + + +
    + + diff --git a/docs/tutorial-views.markdown b/docs/tutorial-views.markdown index b44281cb..8f850c30 100644 --- a/docs/tutorial-views.markdown +++ b/docs/tutorial-views.markdown @@ -25,7 +25,7 @@ Before writing any code with Recline, you need to do the following preparation s 2. Include the relevant CSS in the head section of your document: {% highlight html %} - + {% endhighlight %} @@ -35,7 +35,7 @@ Before writing any code with Recline, you need to do the following preparation s - + diff --git a/docs/tutorials.html b/docs/tutorials.html index 8ed90f7f..6ef1e832 100644 --- a/docs/tutorials.html +++ b/docs/tutorials.html @@ -12,19 +12,19 @@ root: ../

    Basics – Using the Dataset and its Friends


    -
    +
    -
    + -
    + -
    +
    @@ -34,9 +34,9 @@ root: ../

    Backends – Loading and Storing Data from Remote Sources


    -
    +
    -
    +
    @@ -46,14 +46,14 @@ root: ../

    Views – visualize data


    -
    +
    -
    + -
    +
    diff --git a/download.markdown b/download.markdown index 056ed898..049e2e6d 100644 --- a/download.markdown +++ b/download.markdown @@ -12,22 +12,22 @@ title: Download

    Latest Code - Master

    The tutorials on this website will usually be based on the latest (master) codebase. It should also be very stable.

    -
    - + -
    - + -
    - +
    + Full package (master) »
    Everything - library, source code, unit tests, vendor libraries and documentation @@ -37,22 +37,22 @@ title: Download

    Most Recent Official Release – v0.5

    -
    - + -
    - + -
    - +
    + Full package (master) »
    Everything - library, source code, unit tests, vendor libraries and documentation @@ -89,7 +89,7 @@ Individual views have additional dependencies such as: * [Leaflet](http://leaflet.cloudmade.com/) >= 0.4.4 (required for map view) * [Leaflet.markercluster](https://github.com/danzel/Leaflet.markercluster) as of 2012-09-12 (required for marker clustering) * [Verite Timeline](https://github.com/VeriteCo/Timeline/) as of 2012-05-02 (required for the timeline view) -* [Bootstrap](http://twitter.github.com/bootstrap/) >= v2.0 (default option for CSS and UI JS but you can use your own) +* [Bootstrap](http://twitter.github.com/bootstrap/) >= v3 (default option for CSS and UI JS but you can use your own) If you grab the full zipball for Recline this will include all of the relevant dependencies in the vendor directory and you can also find them at in the @@ -105,7 +105,7 @@ Here is an example of the page setup for an app using every Recline component: - + {% include recline-deps.html %} {% endhighlight %} diff --git a/index.html b/index.html index 451ec381..aea40126 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ title: Home