all-in-one mkwsResults, then the redesigned application needs to
specify the locations where the termlists should appear in both
cases. In this case, wrap the wide-screen `mkwsTermlists` element in a
-`mkwsTermlistContainer1` element; and provide an
-`mkwsTermlistContainer2` element in the place where the narrow-screen
+`mkwsTermlists-Container-wide` element; and provide an
+`mkwsTermlists-Container-narrow` element in the place where the narrow-screen
termlists should appear.
<script type="text/javascript" src="tools/htdocs/mkws.js"></script>
<style type="text/css">
- #mkwsTermlists div.facet {
+ .mkwsTermlists div.facet {
float:left;
width: 30%;
margin: 0.3em;
}
- #mkwsStat {
+ .mkwsStat {
text-align: right;
}
</style>
<script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
<script type="text/javascript" src="tools/htdocs/mkws.js"></script>
<style type="text/css">
- #mkwsTermlists div.facet {
+ .mkwsTermlists div.facet {
float:left;
width: 30%;
margin: 0.3em;
}
- #mkwsStat {
+ .mkwsStat {
text-align: right;
}
</style>
<script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
<script class="mkwsTemplate_Summary" type="text/x-handlebars-template">
<a href="#" id="{{_id}}" onclick="{{_onclick}}">
- {{#first md-thumburl}}
+ {{#mkws-first md-thumburl}}
<img src="{{this}}" alt="{{../md-title}}"/>
- {{/first}}
+ {{/mkws-first}}
<br/>
</a>
</script>
<link rel="stylesheet" type="text/css" href="http://x.mkws.indexdata.com/mkws.css" />
<link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />
<script type="text/javascript">
- var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth" };
+ var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth",
+ responsive_design_width: 800 };
</script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="http://x.mkws.indexdata.com/jquery.json-2.4.js"></script>
<body>
<div class="mkwsSwitch"></div>
<div class="mkwsLang"></div>
- <div class="mkwsSearch"></div>
+ <div class="mkwsSearch-Container-wide"><div class="mkwsSearch"></div></div>
<div class="mkwsResults"></div>
<div class="mkwsTargets"></div>
<div class="mkwsStat"></div>
<div class="mkwsBuilder"></div>
+ <div class="mkwsSearch-Container-narrow"></div>
</body>
</html>
<i>{{md-title-responsibility}}</i>\
{{/if}}\
<p>\
- {{{paragraphs md-description}}}\
+ {{{mkws-paragraphs md-description}}}\
</p>\
');
});
</td>
</tr>
{{/if}}
- {{#if-any location having="md-subject"}}
+ {{#mkws-if-any location having="md-subject"}}
<tr>
<th>Subject</th>
<td>
- {{#first location having="md-subject"}}
+ {{#mkws-first location having="md-subject"}}
{{#if md-subject}}
{{md-subject}}
{{/if}}
- {{/first}}
+ {{/mkws-first}}
</td>
</tr>
- {{/if-any}}
+ {{/mkws-if-any}}
<tr>
<th>Locations</th>
<td>
- {{#commaList location}}
- {{attr "@name"}}{{/commaList}}
+ {{#mkws-commaList location}}
+ {{mkws-attr "@name"}}{{/mkws-commaList}}
</td>
</tr>
</table>
have not yet been extensively battle-tested.
0.9.2 [IN PROGRESS]
- - Full-record template invokes {{translate}} on fieldnames.
+ - Full-record template invokes {{mkws-translate}} on fieldnames.
Fixes MKWS-84 Translate fieldnames in full-record popup.
0.9.1 Thu Dec 19 15:33:13 GMT 2013
};
+// Translation function.
+mkws.M = function (word) {
+ var lang = mkws.config.lang;
+
+ if (!lang || !mkws.locale_lang[lang])
+ return word;
+
+ return mkws.locale_lang[lang][word] || word;
+};
+
+
// This function is taken from a StackOverflow answer
// http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript/901144#901144
mkws.getParameterByName = function(name) {
return '\
<table>\
<tr>\
- <th>{{translate "Title"}}</th>\
+ <th>{{mkws-translate "Title"}}</th>\
<td>\
{{md-title}}\
{{#if md-title-remainder}}\
</tr>\
{{#if md-date}}\
<tr>\
- <th>{{translate "Date"}}</th>\
+ <th>{{mkws-translate "Date"}}</th>\
<td>{{md-date}}</td>\
</tr>\
{{/if}}\
{{#if md-author}}\
<tr>\
- <th>{{translate "Author"}}</th>\
+ <th>{{mkws-translate "Author"}}</th>\
<td>{{md-author}}</td>\
</tr>\
{{/if}}\
{{#if md-electronic-url}}\
<tr>\
- <th>{{translate "Links"}}</th>\
+ <th>{{mkws-translate "Links"}}</th>\
<td>\
{{#each md-electronic-url}}\
- <a href="{{this}}">Link{{index1}}</a>\
+ <a href="{{this}}">Link{{mkws-index1}}</a>\
{{/each}}\
</td>\
</tr>\
{{/if}}\
- {{#if-any location having="md-subject"}}\
+ {{#mkws-if-any location having="md-subject"}}\
<tr>\
- <th>{{translate "Subject"}}</th>\
+ <th>{{mkws-translate "Subject"}}</th>\
<td>\
- {{#first location having="md-subject"}}\
+ {{#mkws-first location having="md-subject"}}\
{{#if md-subject}}\
- {{#commaList md-subject}}\
- {{this}}{{/commaList}}\
+ {{#mkws-commaList md-subject}}\
+ {{this}}{{/mkws-commaList}}\
{{/if}}\
- {{/first}}\
+ {{/mkws-first}}\
</td>\
</tr>\
- {{/if-any}}\
+ {{/mkws-if-any}}\
<tr>\
- <th>{{translate "Locations"}}</th>\
+ <th>{{mkws-translate "Locations"}}</th>\
<td>\
- {{#commaList location}}\
- {{attr "@name"}}{{/commaList}}\
+ {{#mkws-commaList location}}\
+ {{mkws-attr "@name"}}{{/mkws-commaList}}\
</td>\
</tr>\
</table>\
} else if (name === "Image") {
return '\
<a href="#" id="{{_id}}" onclick="{{_onclick}}">\
- {{#first md-thumburl}}\
+ {{#mkws-first md-thumburl}}\
<img src="{{this}}" alt="{{../md-title}}"/>\
- {{/first}}\
+ {{/mkws-first}}\
<br/>\
</a>\
';
function resizePage() {
- var list = ["mkwsSwitch", "mkwsLang"];
-
- var width = mkws.config.responsive_design_width;
- var parent = $(".mkwsTermlists").parent();
-
- if ($(window).width() <= width &&
- parent.hasClass("mkwsTermlistContainer1")) {
- log("changing from wide to narrow: " + $(window).width());
- $(".mkwsTermlistContainer1").hide();
- $(".mkwsTermlistContainer2").show();
+ var threshhold = mkws.config.responsive_design_width;
+ var width = $(window).width();
+ var from, to, method;
+
+ if ((mkws.width === undefined || mkws.width > threshhold) &&
+ width <= threshhold) {
+ from = "wide"; to = "narrow"; method = "hide";
+ } else if ((mkws.width === undefined || mkws.width <= threshhold) &&
+ width > threshhold) {
+ from = "narrow"; to = "wide"; method = "show";
+ }
+ mkws.width = width;
+
+ if (from) {
+ log("changing from " + from + " to " + to + ": " + width);
for (var tname in mkws.teams) {
- $(".mkwsTermlists.mkwsTeam_" + tname).appendTo($(".mkwsTermlistContainer2.mkwsTeam_" + tname));
- for(var i = 0; i < list.length; i++) {
- $("." + list[i] + ".mkwsTeam_" + tname).hide();
- }
- }
- } else if ($(window).width() > width &&
- parent.hasClass("mkwsTermlistContainer2")) {
- log("changing from narrow to wide: " + $(window).width());
- $(".mkwsTermlistContainer1").show();
- $(".mkwsTermlistContainer2").hide();
- for (var tname in mkws.teams) {
- $(".mkwsTermlists.mkwsTeam_" + tname).appendTo($(".mkwsTermlistContainer1.mkwsTeam_" + tname));
- for(var i = 0; i < list.length; i++) {
- $("." + list[i] + ".mkwsTeam_" + tname).show();
- }
+ var team = mkws.teams[tname];
+ team.visitWidgets(function (t, w) {
+ var w1 = team.widget(t + "-Container-" + from);
+ var w2 = team.widget(t + "-Container-" + to);
+ if (w1) {
+ $(w1.node).hide();
+ }
+ if (w2) {
+ $(w2.node).show();
+ $(w.node).appendTo($(w2.node));
+ }
+ });
+ team.queue("resize-" + to).publish();
}
}
};
myTeam.addWidget(myWidget);
var newHTML = this.innerHTML;
if (newHTML !== oldHTML) {
- log("widget " + tname + ":" + type + " HTML changed from '" + oldHTML + "' to '" + newHTML + "': reparse!");
+ log("widget " + tname + ":" + type + " HTML changed: reparsing");
makeWidgetsWithin(level+1, $(this));
}
});
}
}
+ var lang = mkws.getParameterByName("lang") || mkws.config.lang;
+ if (!lang || !mkws.locale_lang[lang]) {
+ mkws.config.lang = ""
+ } else {
+ mkws.config.lang = lang;
+ }
+
+ log("Locale language: " + (mkws.config.lang ? mkws.config.lang : "none"));
+
if (mkws.config.query_width < 5 || mkws.config.query_width > 150) {
log("Reset query width: " + mkws.config.query_width);
mkws.config.query_width = 50;
var now = $.now();
log("Walking MKWS nodes took " + (now-then) + " ms");
-// for (var tName in mkws.teams) {
-// var myTeam = mkws.teams[tName]
-// var types = myTeam.widgetTypes();
-// log("TEAM '" + tName + "' = " + myTeam + " has widget types " + types);
-// for (var i = 0; i < types.length; i++) {
-// var type = types[i];
-// log(" has widget of type '" + type + "': " + myTeam.widget(type));
-// }
-// }
+ /*
+ for (var tName in mkws.teams) {
+ var myTeam = mkws.teams[tName]
+ log("TEAM '" + tName + "' = " + myTeam + " ...");
+ myTeam.visitWidgets(function(t, w) {
+ log(" has widget of type '" + t + "': " + w);
+ });
+ }
+ */
if (mkws.config.use_service_proxy) {
authenticateSession(mkws.config.service_proxy_auth,
// Handlebars helpers
-Handlebars.registerHelper('json', function(obj) {
+Handlebars.registerHelper('mkws-json', function(obj) {
return $.toJSON(obj);
});
-Handlebars.registerHelper('paragraphs', function(obj) {
+Handlebars.registerHelper('mkws-paragraphs', function(obj) {
var acc = [];
for (var i = 0; i < obj.length; i++) {
acc.push('<p>', obj[i], '</p>');
});
-Handlebars.registerHelper('translate', function(s) {
+Handlebars.registerHelper('mkws-translate', function(s) {
return mkws.M(s);
});
-// We need {{attr '@name'}} because Handlebars can't parse {{@name}}
-Handlebars.registerHelper('attr', function(attrName) {
+// We need {{mkws-attr '@name'}} because Handlebars can't parse {{@name}}
+Handlebars.registerHelper('mkws-attr', function(attrName) {
return this[attrName];
});
/*
- * Use as follows: {{#if-any NAME1 having="NAME2"}}
+ * Use as follows: {{#mkws-if-any NAME1 having="NAME2"}}
* Applicable when NAME1 is the name of an array
* The guarded code runs only if at least one element of the NAME1
* array has a subelement called NAME2.
*/
-Handlebars.registerHelper('if-any', function(items, options) {
+Handlebars.registerHelper('mkws-if-any', function(items, options) {
var having = options.hash.having;
for (var i in items) {
var item = items[i]
});
-Handlebars.registerHelper('first', function(items, options) {
+Handlebars.registerHelper('mkws-first', function(items, options) {
var having = options.hash.having;
for (var i in items) {
var item = items[i]
});
-Handlebars.registerHelper('commaList', function(items, options) {
+Handlebars.registerHelper('mkws-commaList', function(items, options) {
var out = "";
for (var i in items) {
});
-Handlebars.registerHelper('index1', function(obj) {
+Handlebars.registerHelper('mkws-index1', function(obj) {
return obj.data.index + 1;
});
var m_tempateText = {}; // widgets can register tempates to be compiled
var m_template = {}; // compiled templates, from any source
var m_config = mkws.objectInheritingFrom(mkws.config);
- var m_widgets = {}; // Maps widget-type to object
+ var m_widgets = {}; // Maps widget-type to array of widget objects
that.toString = function() { return '[Team ' + teamName + ']'; };
switch(view) {
case 'targets':
- if (targets) targets.css('display', 'block');
- if (results) results.css('display', 'none');
- if (blanket) blanket.css('display', 'none');
- if (motd) motd.css('display', 'none');
+ if (targets) $(targets).show();
+ if (results) $(results).hide();
+ if (blanket) $(blanket).hide();
+ if (motd) $(motd).hide();
break;
case 'records':
- if (targets) targets.css('display', 'none');
- if (results) results.css('display', 'block');
- if (blanket) blanket.css('display', 'block');
- if (motd) motd.css('display', 'none');
+ if (targets) $(targets).hide();
+ if (results) $(results).show();
+ if (blanket) $(blanket).show();
+ if (motd) $(motd).hide();
break;
default:
alert("Unknown view '" + view + "'");
};
- // Translation function. At present, this is properly a
- // global-level function (hence the assignment to mkws.M) but we
- // want to make it per-team so different teams can operate in
- // different languages.
- //
- function M(word) {
- var lang = m_config.lang;
-
- if (!lang || !mkws.locale_lang[lang])
- return word;
-
- return mkws.locale_lang[lang][word] || word;
- }
- mkws.M = M; // so the Handlebars helper can use it
-
-
// Finds the node of the specified class within the current team
function findnode(selector, teamName) {
teamName = teamName || m_teamName;
//log('findnode(' + selector + ') found ' + node.length + ' nodes');
return node;
}
- that.findnode = findnode;
- // This much simpler and more efficient function should be usable
- // in place of most uses of findnode.
function widgetNode(type) {
var w = that.widget(type);
return w ? $(w.node) : undefined;
that.addWidget = function(w) {
- if (!m_widgets[w.type]) {
- m_widgets[w.type] = w;
- log("Registered '" + w.type + "' widget in team '" + m_teamName + "'");
- } else if (typeof(m_widgets[w.type]) !== 'number') {
- m_widgets[w.type] = 2;
- log("Registered duplicate '" + w.type + "' widget in team '" + m_teamName + "'");
+ if (m_widgets[w.type] === undefined) {
+ m_widgets[w.type] = [ w ];
+ log("Added '" + w.type + "' widget to team '" + m_teamName + "'");
} else {
- m_widgets[w.type] += 1;
- log("Registered '" + w.type + "' widget #" + m_widgets[w.type] + "' in team '" + m_teamName + "'");
+ m_widgets[w.type].push(w);
+ log("Added '" + w.type + "' widget #" + m_widgets[w.type].length + "' to team '" + m_teamName + "'");
}
}
- that.widgetTypes = function() {
- var keys = [];
- for (var k in m_widgets) keys.push(k);
- return keys.sort();
- }
-
that.widget = function(type) {
- return m_widgets[type];
- }
+ var list = m_widgets[type];
+ if (!list)
+ return undefined;
+ if (list.length > 1) {
+ alert("widget('" + type + "') finds " + list.length + " widgets: using first");
+ }
+ return list[0];
+ }
- var lang = mkws.getParameterByName("lang") || m_config.lang;
- if (!lang || !mkws.locale_lang[lang]) {
- m_config.lang = ""
- } else {
- m_config.lang = lang;
+ that.visitWidgets = function(callback) {
+ for (var type in m_widgets) {
+ var list = m_widgets[type];
+ for (var i = 0; i < list.length; i++) {
+ var res = callback(type, list[i]);
+ if (res !== undefined) {
+ return res;
+ }
+ }
+ }
+ return undefined;
}
- log("Locale language: " + (m_config.lang ? m_config.lang : "none"));
return that;
};
});
-mkws.registerWidgetType('Results', function() {
- // Nothing to do apart from act as an autosearch trigger
- // Contained elements do all the real work
- widget.autosearch(this);
-});
-
-
mkws.registerWidgetType('Records', function() {
var that = this;
var team = this.team;
<a href="#" onclick="mkws.switchView(\'' + tname + '\', \'records\')">Records</a><span> \
| \
</span><a href="#" onclick="mkws.switchView(\'' + tname + '\', \'targets\')">Targets</a>');
+ widget.hideWhenNarrow(this);
});
$(this.node).html('\
<table width="100%" border="0" cellpadding="6" cellspacing="0">\
<tr>\
- <td class="mkwsTermlistContainer1 mkwsTeam_' + tname + '" width="250" valign="top">\
+ <td class="mkwsTermlists-Container-wide mkwsTeam_' + tname + '" width="250" valign="top">\
<div class="mkwsTermlists mkwsTeam_' + tname + '"></div>\
</td>\
<td class="mkwsMOTDContainer mkwsTeam_' + tname + '" valign="top">\
</tr>\
<tr>\
<td colspan="2">\
- <div class="mkwsTermlistContainer2 mkwsTeam_' + tname + '"></div>\
+ <div class="mkwsTermlists-Container-narrow mkwsTeam_' + tname + '"></div>\
</td>\
</tr>\
</table>');
+
+ widget.autosearch(this);
});
}
$(this.node).html(data);
+ widget.hideWhenNarrow(this);
// set or re-set "lang" URL parameter
});
+// Some elements have mkws* classes that makes them appear as widgets
+// -- for example, because we want to style them using CSS -- but have
+// no actual functionality. We register these to prevent ignorable
+// warnings when they occur.
+
+mkws.registerWidgetType('Query', function() {});
+mkws.registerWidgetType('MOTDContainer', function() {});
+mkws.registerWidgetType('Button', function() {});
+mkws.registerWidgetType('Popup', function() {});
+
+// Not sure whether the following should have functionality:
+// Select HTMLFormElement
+// *-Container-wide HTMLTableCellElement
+// *-Container-narrow HTMLDivElement
+// Bytarget HTMLDivElement
var max = ref[1];
var pzIndex = ref[2] ? name : null;
+ that.toString = function() {
+ return '[Widget ' + that.team.name() + ':' + that.type + '(' + name + ')]';
+ };
+
that.team.queue("termlists").subscribe(function(data) {
data = data[name];
};
+// Utility function for all widgets that want to hide in narrow windows
+widget.hideWhenNarrow = function(widget) {
+ widget.team.queue("resize-narrow").subscribe(function(n) {
+ $(widget.node).hide();
+ });
+ widget.team.queue("resize-wide").subscribe(function(n) {
+ $(widget.node).show();
+ });
+};
+
+