1049 lines
45 KiB
HTML
1049 lines
45 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>view.multiview.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul id="jump_to">
|
||
<li>
|
||
<a class="large" href="javascript:void(0);">Jump To …</a>
|
||
<a class="small" href="javascript:void(0);">+</a>
|
||
<div id="jump_wrapper">
|
||
<div id="jump_page_wrapper">
|
||
<div id="jump_page">
|
||
|
||
|
||
<a class="source" href="backend.dataproxy.html">
|
||
backend.dataproxy.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="backend.memory.html">
|
||
backend.memory.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="ecma-fixes.html">
|
||
ecma-fixes.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="model.html">
|
||
model.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.flot.html">
|
||
view.flot.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.graph.html">
|
||
view.graph.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.grid.html">
|
||
view.grid.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.map.html">
|
||
view.map.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.multiview.html">
|
||
view.multiview.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.slickgrid.html">
|
||
view.slickgrid.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="view.timeline.html">
|
||
view.timeline.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.facetviewer.html">
|
||
widget.facetviewer.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.fields.html">
|
||
widget.fields.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.filtereditor.html">
|
||
widget.filtereditor.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.pager.html">
|
||
widget.pager.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.queryeditor.html">
|
||
widget.queryeditor.js
|
||
</a>
|
||
|
||
|
||
<a class="source" href="widget.valuefilter.html">
|
||
widget.valuefilter.js
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>view.multiview.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-1">¶</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-comment">/*jshint multistr:true */</span></pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-2">¶</a>
|
||
</div>
|
||
<p>Standard JS module setup</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">this</span>.recline = <span class="hljs-keyword">this</span>.recline || {};
|
||
<span class="hljs-keyword">this</span>.recline.View = <span class="hljs-keyword">this</span>.recline.View || {};
|
||
|
||
(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">($, my)</span> </span>{
|
||
<span class="hljs-pi"> "use strict"</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-3">¶</a>
|
||
</div>
|
||
<h2 id="multiview">MultiView</h2>
|
||
<p>Manage multiple views together along with query editor etc. Usage:</p>
|
||
<pre>
|
||
var myExplorer = new recline.View.MultiView({
|
||
model: {{recline.Model.Dataset instance}}
|
||
el: {{an existing dom element}}
|
||
views: {{dataset views}}
|
||
state: {{state configuration -- see below}}
|
||
});
|
||
</pre>
|
||
|
||
<h3 id="parameters">Parameters</h3>
|
||
<p><strong>model</strong>: (required) recline.model.Dataset instance.</p>
|
||
<p><strong>el</strong>: (required) DOM element to bind to. NB: the element already
|
||
being in the DOM is important for rendering of some subviews (e.g.
|
||
Graph).</p>
|
||
<p><strong>views</strong>: (optional) the dataset views (Grid, Graph etc) for
|
||
MultiView to show. This is an array of view hashes. If not provided
|
||
initialize with (recline.View.)Grid, Graph, and Map views (with obvious id
|
||
and labels!).</p>
|
||
<pre>
|
||
var views = [
|
||
{
|
||
id: 'grid', // used for routing
|
||
label: 'Grid', // used for view switcher
|
||
view: new recline.View.Grid({
|
||
model: dataset
|
||
})
|
||
},
|
||
{
|
||
id: 'graph',
|
||
label: 'Graph',
|
||
view: new recline.View.Graph({
|
||
model: dataset
|
||
})
|
||
}
|
||
];
|
||
</pre>
|
||
|
||
<p><strong>sidebarViews</strong>: (optional) the sidebar views (Filters, Fields) for
|
||
MultiView to show. This is an array of view hashes. If not provided
|
||
initialize with (recline.View.)FilterEditor and Fields views (with obvious
|
||
id and labels!).</p>
|
||
<pre>
|
||
var sidebarViews = [
|
||
{
|
||
id: 'filterEditor', // used for routing
|
||
label: 'Filters', // used for view switcher
|
||
view: new recline.View.FilterEditor({
|
||
model: dataset
|
||
})
|
||
},
|
||
{
|
||
id: 'fieldsView',
|
||
label: 'Fields',
|
||
view: new recline.View.Fields({
|
||
model: dataset
|
||
})
|
||
}
|
||
];
|
||
</pre>
|
||
|
||
<p><strong>state</strong>: standard state config for this view. This state is slightly
|
||
special as it includes config of many of the subviews.</p>
|
||
<pre>
|
||
var state = {
|
||
query: {dataset query state - see dataset.queryState object}
|
||
'view-{id1}': {view-state for this view}
|
||
'view-{id2}': {view-state for }
|
||
...
|
||
// Explorer
|
||
currentView: id of current view (defaults to first view if not specified)
|
||
readOnly: (default: false) run in read-only mode
|
||
}
|
||
</pre>
|
||
|
||
<p>Note that at present we do <em>not</em> serialize information about the actual set
|
||
of views in use — e.g. those specified by the views argument — but instead
|
||
expect either that the default views are fine or that the client to have
|
||
initialized the MultiView with the relevant views themselves.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.MultiView = Backbone.View.extend({
|
||
template: <span class="hljs-string">' \
|
||
<div class="recline-data-explorer"> \
|
||
<div class="alert-messages"></div> \
|
||
\
|
||
<div class="header clearfix"> \
|
||
<div class="navigation"> \
|
||
<div class="btn-group" data-toggle="buttons-radio"> \
|
||
{{#views}} \
|
||
<button href="#{{id}}" data-view="{{id}}" class="btn btn-default">{{label}}</button> \
|
||
{{/views}} \
|
||
</div> \
|
||
</div> \
|
||
<div class="recline-results-info"> \
|
||
<span class="doc-count">{{recordCount}}</span> records\
|
||
</div> \
|
||
<div class="menu-right"> \
|
||
<div class="btn-group" data-toggle="buttons-checkbox"> \
|
||
{{#sidebarViews}} \
|
||
<button href="#" data-action="{{id}}" class="btn btn-default">{{label}}</button> \
|
||
{{/sidebarViews}} \
|
||
</div> \
|
||
</div> \
|
||
<div class="query-editor-here" style="display:inline;"></div> \
|
||
</div> \
|
||
<div class="data-view-sidebar"></div> \
|
||
<div class="data-view-container"></div> \
|
||
</div> \
|
||
'</span>,
|
||
events: {
|
||
<span class="hljs-string">'click .menu-right button'</span>: <span class="hljs-string">'_onMenuClick'</span>,
|
||
<span class="hljs-string">'click .navigation button'</span>: <span class="hljs-string">'_onSwitchView'</span>
|
||
},
|
||
|
||
initialize: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(options)</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
<span class="hljs-keyword">this</span>._setupState(options.state);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-4">¶</a>
|
||
</div>
|
||
<p>Hash of ‘page’ views (i.e. those for whole page) keyed by page name</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (options.views) {
|
||
<span class="hljs-keyword">this</span>.pageViews = options.views;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.pageViews = [{
|
||
id: <span class="hljs-string">'grid'</span>,
|
||
label: <span class="hljs-string">'Grid'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.SlickGrid({
|
||
model: <span class="hljs-keyword">this</span>.model,
|
||
state: <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'view-grid'</span>)
|
||
})
|
||
}, {
|
||
id: <span class="hljs-string">'graph'</span>,
|
||
label: <span class="hljs-string">'Graph'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.Graph({
|
||
model: <span class="hljs-keyword">this</span>.model,
|
||
state: <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'view-graph'</span>)
|
||
})
|
||
}, {
|
||
id: <span class="hljs-string">'map'</span>,
|
||
label: <span class="hljs-string">'Map'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.Map({
|
||
model: <span class="hljs-keyword">this</span>.model,
|
||
state: <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'view-map'</span>)
|
||
})
|
||
}, {
|
||
id: <span class="hljs-string">'timeline'</span>,
|
||
label: <span class="hljs-string">'Timeline'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.Timeline({
|
||
model: <span class="hljs-keyword">this</span>.model,
|
||
state: <span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'view-timeline'</span>)
|
||
})
|
||
}];
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-5">¶</a>
|
||
</div>
|
||
<p>Hashes of sidebar elements</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span>(options.sidebarViews) {
|
||
<span class="hljs-keyword">this</span>.sidebarViews = options.sidebarViews;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.sidebarViews = [{
|
||
id: <span class="hljs-string">'filterEditor'</span>,
|
||
label: <span class="hljs-string">'Filters'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.FilterEditor({
|
||
model: <span class="hljs-keyword">this</span>.model
|
||
})
|
||
}, {
|
||
id: <span class="hljs-string">'fieldsView'</span>,
|
||
label: <span class="hljs-string">'Fields'</span>,
|
||
view: <span class="hljs-keyword">new</span> my.Fields({
|
||
model: <span class="hljs-keyword">this</span>.model
|
||
})
|
||
}];
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-6">¶</a>
|
||
</div>
|
||
<p>these must be called after pageViews are created</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.render();
|
||
<span class="hljs-keyword">this</span>._bindStateChanges();
|
||
<span class="hljs-keyword">this</span>._bindFlashNotifications();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-7">¶</a>
|
||
</div>
|
||
<p>now do updates based on state (need to come after render)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'readOnly'</span>)) {
|
||
<span class="hljs-keyword">this</span>.setReadOnly();
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'currentView'</span>)) {
|
||
<span class="hljs-keyword">this</span>.updateNav(<span class="hljs-keyword">this</span>.state.get(<span class="hljs-string">'currentView'</span>));
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">this</span>.updateNav(<span class="hljs-keyword">this</span>.pageViews[<span class="hljs-number">0</span>].id);
|
||
}
|
||
<span class="hljs-keyword">this</span>._showHideSidebar();
|
||
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'query:start'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self.notify({loader: <span class="hljs-literal">true</span>, persist: <span class="hljs-literal">true</span>});
|
||
});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'query:done'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self.clearNotifications();
|
||
self.$el.find(<span class="hljs-string">'.doc-count'</span>).text(self.model.recordCount || <span class="hljs-string">'Unknown'</span>);
|
||
});
|
||
<span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model, <span class="hljs-string">'query:fail'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(error)</span> </span>{
|
||
self.clearNotifications();
|
||
<span class="hljs-keyword">var</span> msg = <span class="hljs-string">''</span>;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(error) == <span class="hljs-string">'string'</span>) {
|
||
msg = error;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(error) == <span class="hljs-string">'object'</span>) {
|
||
<span class="hljs-keyword">if</span> (error.title) {
|
||
msg = error.title + <span class="hljs-string">': '</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (error.message) {
|
||
msg += error.message;
|
||
}
|
||
} <span class="hljs-keyword">else</span> {
|
||
msg = <span class="hljs-string">'There was an error querying the backend'</span>;
|
||
}
|
||
self.notify({message: msg, category: <span class="hljs-string">'error'</span>, persist: <span class="hljs-literal">true</span>});
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-8">¶</a>
|
||
</div>
|
||
<p>retrieve basic data like fields etc
|
||
note this.model and dataset returned are the same
|
||
TODO: set query state …?</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.model.queryState.set(self.state.get(<span class="hljs-string">'query'</span>), {silent: <span class="hljs-literal">true</span>});
|
||
},
|
||
|
||
setReadOnly: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">this</span>.$el.addClass(<span class="hljs-string">'recline-read-only'</span>);
|
||
},
|
||
|
||
render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> tmplData = <span class="hljs-keyword">this</span>.model.toTemplateJSON();
|
||
tmplData.views = <span class="hljs-keyword">this</span>.pageViews;
|
||
tmplData.sidebarViews = <span class="hljs-keyword">this</span>.sidebarViews;
|
||
<span class="hljs-keyword">var</span> template = Mustache.render(<span class="hljs-keyword">this</span>.template, tmplData);
|
||
<span class="hljs-keyword">this</span>.$el.html(template);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-9">¶</a>
|
||
</div>
|
||
<p>now create and append other views</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> $dataViewContainer = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.data-view-container'</span>);
|
||
<span class="hljs-keyword">var</span> $dataSidebar = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.data-view-sidebar'</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-10">¶</a>
|
||
</div>
|
||
<p>the main views</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(view, pageName)</span> </span>{
|
||
view.view.render();
|
||
<span class="hljs-keyword">if</span> (view.view.redraw) {
|
||
view.view.redraw();
|
||
}
|
||
$dataViewContainer.append(view.view.el);
|
||
<span class="hljs-keyword">if</span> (view.view.elSidebar) {
|
||
$dataSidebar.append(view.view.elSidebar);
|
||
}
|
||
});
|
||
|
||
_.each(<span class="hljs-keyword">this</span>.sidebarViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(view)</span> </span>{
|
||
<span class="hljs-keyword">this</span>[<span class="hljs-string">'$'</span>+view.id] = view.view.$el;
|
||
$dataSidebar.append(view.view.el);
|
||
}, <span class="hljs-keyword">this</span>);
|
||
|
||
<span class="hljs-keyword">this</span>.pager = <span class="hljs-keyword">new</span> recline.View.Pager({
|
||
model: <span class="hljs-keyword">this</span>.model
|
||
});
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.recline-results-info'</span>).after(<span class="hljs-keyword">this</span>.pager.el);
|
||
|
||
<span class="hljs-keyword">this</span>.queryEditor = <span class="hljs-keyword">new</span> recline.View.QueryEditor({
|
||
model: <span class="hljs-keyword">this</span>.model.queryState
|
||
});
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.query-editor-here'</span>).append(<span class="hljs-keyword">this</span>.queryEditor.el);
|
||
|
||
},
|
||
|
||
remove: <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
|
||
_.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(view)</span> </span>{
|
||
view.view.remove();
|
||
});
|
||
_.each(<span class="hljs-keyword">this</span>.sidebarViews, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(view)</span> </span>{
|
||
view.view.remove();
|
||
});
|
||
<span class="hljs-keyword">this</span>.pager.remove();
|
||
<span class="hljs-keyword">this</span>.queryEditor.remove();
|
||
Backbone.View.prototype.remove.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-11">¶</a>
|
||
</div>
|
||
<p>hide the sidebar if empty</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _showHideSidebar: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> $dataSidebar = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.data-view-sidebar'</span>);
|
||
<span class="hljs-keyword">var</span> visibleChildren = $dataSidebar.children().filter(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">return</span> $(<span class="hljs-keyword">this</span>).css(<span class="hljs-string">"display"</span>) != <span class="hljs-string">"none"</span>;
|
||
}).length;
|
||
|
||
<span class="hljs-keyword">if</span> (visibleChildren > <span class="hljs-number">0</span>) {
|
||
$dataSidebar.show();
|
||
} <span class="hljs-keyword">else</span> {
|
||
$dataSidebar.hide();
|
||
}
|
||
},
|
||
|
||
updateNav: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(pageName)</span> </span>{
|
||
<span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.navigation button'</span>).removeClass(<span class="hljs-string">'active'</span>);
|
||
<span class="hljs-keyword">var</span> $el = <span class="hljs-keyword">this</span>.$el.find(<span class="hljs-string">'.navigation button[data-view="'</span> + pageName + <span class="hljs-string">'"]'</span>);
|
||
$el.addClass(<span class="hljs-string">'active'</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-12">¶</a>
|
||
</div>
|
||
<p>add/remove sidebars and hide inactive views</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(view, idx)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (view.id === pageName) {
|
||
view.view.$el.show();
|
||
<span class="hljs-keyword">if</span> (view.view.elSidebar) {
|
||
view.view.elSidebar.show();
|
||
}
|
||
} <span class="hljs-keyword">else</span> {
|
||
view.view.$el.hide();
|
||
<span class="hljs-keyword">if</span> (view.view.elSidebar) {
|
||
view.view.elSidebar.hide();
|
||
}
|
||
<span class="hljs-keyword">if</span> (view.view.hide) {
|
||
view.view.hide();
|
||
}
|
||
}
|
||
});
|
||
|
||
<span class="hljs-keyword">this</span>._showHideSidebar();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-13">¶</a>
|
||
</div>
|
||
<p>call view.view.show after sidebar visibility has been determined so
|
||
that views can correctly calculate their maximum width</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(view, idx)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (view.id === pageName) {
|
||
<span class="hljs-keyword">if</span> (view.view.show) {
|
||
view.view.show();
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
_onMenuClick: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
|
||
e.preventDefault();
|
||
<span class="hljs-keyword">var</span> action = $(e.target).attr(<span class="hljs-string">'data-action'</span>);
|
||
<span class="hljs-keyword">this</span>[<span class="hljs-string">'$'</span>+action].toggle();
|
||
<span class="hljs-keyword">this</span>._showHideSidebar();
|
||
},
|
||
|
||
_onSwitchView: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(e)</span> </span>{
|
||
e.preventDefault();
|
||
<span class="hljs-keyword">var</span> viewName = $(e.target).attr(<span class="hljs-string">'data-view'</span>);
|
||
<span class="hljs-keyword">this</span>.updateNav(viewName);
|
||
<span class="hljs-keyword">this</span>.state.set({currentView: viewName});
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-14">¶</a>
|
||
</div>
|
||
<p>create a state object for this view and do the job of</p>
|
||
<p>a) initializing it from both data passed in and other sources (e.g. hash url)</p>
|
||
<p>b) ensure the state object is updated in responese to changes in subviews, query etc.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _setupState: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(initialState)</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-15">¶</a>
|
||
</div>
|
||
<p>get data from the query string / hash url plus some defaults</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> qs = my.parseHashQueryString();
|
||
<span class="hljs-keyword">var</span> query = qs.reclineQuery;
|
||
query = query ? <span class="hljs-built_in">JSON</span>.parse(query) : self.model.queryState.toJSON();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-16">¶</a>
|
||
</div>
|
||
<p>backwards compatability (now named view-graph but was named graph)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> graphState = qs[<span class="hljs-string">'view-graph'</span>] || qs.graph;
|
||
graphState = graphState ? <span class="hljs-built_in">JSON</span>.parse(graphState) : {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-17">¶</a>
|
||
</div>
|
||
<p>now get default data + hash url plus initial state and initial our state object with it</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> stateData = _.extend({
|
||
query: query,
|
||
<span class="hljs-string">'view-graph'</span>: graphState,
|
||
backend: <span class="hljs-keyword">this</span>.model.backend.__type__,
|
||
url: <span class="hljs-keyword">this</span>.model.get(<span class="hljs-string">'url'</span>),
|
||
dataset: <span class="hljs-keyword">this</span>.model.toJSON(),
|
||
currentView: <span class="hljs-literal">null</span>,
|
||
readOnly: <span class="hljs-literal">false</span>
|
||
},
|
||
initialState);
|
||
<span class="hljs-keyword">this</span>.state = <span class="hljs-keyword">new</span> recline.Model.ObjectState(stateData);
|
||
},
|
||
|
||
_bindStateChanges: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-18">¶</a>
|
||
</div>
|
||
<p>finally ensure we update our state object when state of sub-object changes so that state is always up to date</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">this</span>.listenTo(<span class="hljs-keyword">this</span>.model.queryState, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
self.state.set({query: self.model.queryState.toJSON()});
|
||
});
|
||
_.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(pageView)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (pageView.view.state && pageView.view.state.bind) {
|
||
<span class="hljs-keyword">var</span> update = {};
|
||
update[<span class="hljs-string">'view-'</span> + pageView.id] = pageView.view.state.toJSON();
|
||
self.state.set(update);
|
||
self.listenTo(pageView.view.state, <span class="hljs-string">'change'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> update = {};
|
||
update[<span class="hljs-string">'view-'</span> + pageView.id] = pageView.view.state.toJSON();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-19">¶</a>
|
||
</div>
|
||
<p>had problems where change not being triggered for e.g. grid view so let’s do it explicitly</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> self.state.set(update, {silent: <span class="hljs-literal">true</span>});
|
||
self.state.trigger(<span class="hljs-string">'change'</span>);
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
_bindFlashNotifications: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> self = <span class="hljs-keyword">this</span>;
|
||
_.each(<span class="hljs-keyword">this</span>.pageViews, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(pageView)</span> </span>{
|
||
self.listenTo(pageView.view, <span class="hljs-string">'recline:flash'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(flash)</span> </span>{
|
||
self.notify(flash);
|
||
});
|
||
});
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-20">¶</a>
|
||
</div>
|
||
<h3 id="notify">notify</h3>
|
||
<p>Create a notification (a div.alert in div.alert-messsages) using provided
|
||
flash object. Flash attributes (all are optional):</p>
|
||
<ul>
|
||
<li>message: message to show.</li>
|
||
<li>category: warning (default), success, error</li>
|
||
<li>persist: if true alert is persistent, o/w hidden after 3s (default = false)</li>
|
||
<li>loader: if true show loading spinner</li>
|
||
</ul>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> notify: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(flash)</span> </span>{
|
||
<span class="hljs-keyword">var</span> tmplData = _.extend({
|
||
message: <span class="hljs-string">'Loading'</span>,
|
||
category: <span class="hljs-string">'warning'</span>,
|
||
loader: <span class="hljs-literal">false</span>
|
||
},
|
||
flash
|
||
);
|
||
<span class="hljs-keyword">var</span> _template;
|
||
<span class="hljs-keyword">if</span> (tmplData.loader) {
|
||
_template = <span class="hljs-string">' \
|
||
<div class="alert alert-info alert-loader"> \
|
||
{{message}} \
|
||
<span class="notification-loader">&nbsp;</span> \
|
||
</div>'</span>;
|
||
} <span class="hljs-keyword">else</span> {
|
||
_template = <span class="hljs-string">' \
|
||
<div class="alert alert-{{category}} fade in" data-alert="alert"><a class="close" data-dismiss="alert" href="#">×</a> \
|
||
{{message}} \
|
||
</div>'</span>;
|
||
}
|
||
<span class="hljs-keyword">var</span> _templated = $(Mustache.render(_template, tmplData));
|
||
_templated = $(_templated).appendTo($(<span class="hljs-string">'.recline-data-explorer .alert-messages'</span>));
|
||
<span class="hljs-keyword">if</span> (!flash.persist) {
|
||
setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
$(_templated).fadeOut(<span class="hljs-number">1000</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
$(<span class="hljs-keyword">this</span>).remove();
|
||
});
|
||
}, <span class="hljs-number">1000</span>);
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-21">¶</a>
|
||
</div>
|
||
<h3 id="clearnotifications">clearNotifications</h3>
|
||
<p>Clear all existing notifications</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> clearNotifications: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> $notifications = $(<span class="hljs-string">'.recline-data-explorer .alert-messages .alert'</span>);
|
||
$notifications.fadeOut(<span class="hljs-number">1500</span>, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
$(<span class="hljs-keyword">this</span>).remove();
|
||
});
|
||
}
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-22">¶</a>
|
||
</div>
|
||
<h3 id="multiview-restore">MultiView.restore</h3>
|
||
<p>Restore a MultiView instance from a serialized state including the associated dataset</p>
|
||
<p>This inverts the state serialization process in Multiview</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.MultiView.restore = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(state)</span> </span>{</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-23">¶</a>
|
||
</div>
|
||
<p>hack-y - restoring a memory dataset does not mean much … (but useful for testing!)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> datasetInfo;
|
||
<span class="hljs-keyword">if</span> (state.backend === <span class="hljs-string">'memory'</span>) {
|
||
datasetInfo = {
|
||
backend: <span class="hljs-string">'memory'</span>,
|
||
records: [{stub: <span class="hljs-string">'this is a stub dataset because we do not restore memory datasets'</span>}]
|
||
};
|
||
} <span class="hljs-keyword">else</span> {
|
||
datasetInfo = _.extend({
|
||
url: state.url,
|
||
backend: state.backend
|
||
},
|
||
state.dataset
|
||
);
|
||
}
|
||
<span class="hljs-keyword">var</span> dataset = <span class="hljs-keyword">new</span> recline.Model.Dataset(datasetInfo);
|
||
<span class="hljs-keyword">var</span> explorer = <span class="hljs-keyword">new</span> my.MultiView({
|
||
model: dataset,
|
||
state: state
|
||
});
|
||
<span class="hljs-keyword">return</span> explorer;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-24">¶</a>
|
||
</div>
|
||
<h2 id="miscellaneous-utilities">Miscellaneous Utilities</h2>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre><span class="hljs-keyword">var</span> urlPathRegex = <span class="hljs-regexp">/^([^?]+)(\?.*)?/</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-25">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-25">¶</a>
|
||
</div>
|
||
<p>Parse the Hash section of a URL into path and query string</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.parseHashUrl = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(hashUrl)</span> </span>{
|
||
<span class="hljs-keyword">var</span> parsed = urlPathRegex.exec(hashUrl);
|
||
<span class="hljs-keyword">if</span> (parsed === <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-keyword">return</span> {};
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">return</span> {
|
||
path: parsed[<span class="hljs-number">1</span>],
|
||
query: parsed[<span class="hljs-number">2</span>] || <span class="hljs-string">''</span>
|
||
};
|
||
}
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-26">¶</a>
|
||
</div>
|
||
<p>Parse a URL query string (?xyz=abc…) into a dictionary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.parseQueryString = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(q)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (!q) {
|
||
<span class="hljs-keyword">return</span> {};
|
||
}
|
||
<span class="hljs-keyword">var</span> urlParams = {},
|
||
e, d = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(s)</span> </span>{
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">unescape</span>(s.replace(<span class="hljs-regexp">/\+/g</span>, <span class="hljs-string">" "</span>));
|
||
},
|
||
r = <span class="hljs-regexp">/([^&=]+)=?([^&]*)/g</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (q && q.length && q[<span class="hljs-number">0</span>] === <span class="hljs-string">'?'</span>) {
|
||
q = q.slice(<span class="hljs-number">1</span>);
|
||
}
|
||
<span class="hljs-keyword">while</span> (e = r.exec(q)) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-27">¶</a>
|
||
</div>
|
||
<p>TODO: have values be array as query string allow repetition of keys</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> urlParams[d(e[<span class="hljs-number">1</span>])] = d(e[<span class="hljs-number">2</span>]);
|
||
}
|
||
<span class="hljs-keyword">return</span> urlParams;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-28">¶</a>
|
||
</div>
|
||
<p>Parse the query string out of the URL hash</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.parseHashQueryString = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
|
||
<span class="hljs-keyword">var</span> q = my.parseHashUrl(<span class="hljs-built_in">window</span>.location.hash).query;
|
||
<span class="hljs-keyword">return</span> my.parseQueryString(q);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-29">¶</a>
|
||
</div>
|
||
<p>Compse a Query String</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>my.composeQueryString = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(queryParams)</span> </span>{
|
||
<span class="hljs-keyword">var</span> queryString = <span class="hljs-string">'?'</span>;
|
||
<span class="hljs-keyword">var</span> items = [];
|
||
$.each(queryParams, <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(key, value)</span> </span>{
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span>(value) === <span class="hljs-string">'object'</span>) {
|
||
value = <span class="hljs-built_in">JSON</span>.stringify(value);
|
||
}
|
||
items.push(key + <span class="hljs-string">'='</span> + <span class="hljs-built_in">encodeURIComponent</span>(value));
|
||
});
|
||
queryString += items.join(<span class="hljs-string">'&'</span>);
|
||
<span class="hljs-keyword">return</span> queryString;
|
||
};
|
||
|
||
my.getNewHashForQueryString = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(queryParams)</span> </span>{
|
||
<span class="hljs-keyword">var</span> queryPart = my.composeQueryString(queryParams);
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.location.hash) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="pilwrap ">
|
||
<a class="pilcrow" href="#section-30">¶</a>
|
||
</div>
|
||
<p>slice(1) to remove # at start</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-built_in">window</span>.location.hash.split(<span class="hljs-string">'?'</span>)[<span class="hljs-number">0</span>].slice(<span class="hljs-number">1</span>) + queryPart;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">return</span> queryPart;
|
||
}
|
||
};
|
||
|
||
my.setHashQueryString = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(queryParams)</span> </span>{
|
||
<span class="hljs-built_in">window</span>.location.hash = my.getNewHashForQueryString(queryParams);
|
||
};
|
||
|
||
})(jQuery, recline.View);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|