Mercurial > hg > audiodb
comparison examples/browser/web/js/jOWL_UI.js @ 640:901803e1305f
First instance of audioDB browser code.
author | mas01mj |
---|---|
date | Thu, 08 Oct 2009 11:19:11 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
639:2eaea1afd6b3 | 640:901803e1305f |
---|---|
1 /* | |
2 * jOWL_UI, User Interface Elements for jOWL, semantic javascript library | |
3 * Creator - David Decraene | |
4 * Version 1.0 | |
5 * Website: http://Ontologyonline.org | |
6 * Licensed under the MIT license | |
7 * Verified with JSLint http://www.jslint.com/ | |
8 */ | |
9 (function($){ | |
10 | |
11 jOWL.UI = { | |
12 broadcaster : function(){ | |
13 var listeners = []; | |
14 this.addListener = function(obj){ | |
15 function add(obj){if(obj.propertyChange) { listeners.push(obj); } } | |
16 if(obj.constructor == Array){for(var i=0;i<obj.length;i++){ add(obj[i]); } } | |
17 else { add(obj); } | |
18 return this; | |
19 }; | |
20 this.broadcast = function(item){ for(var i=0;i<listeners.length;i++){ listeners[i].propertyChange.call(item, item); } }; | |
21 if(!this.propertyChange){ this.propertyChange = function(item){}; } | |
22 }, | |
23 asBroadcaster : function(ui_elem){ ui_elem.broadcaster = jOWL.UI.broadcaster; ui_elem.broadcaster(); }, | |
24 defaults : { | |
25 contentClass: "jowl-content", | |
26 focusClass: "ui-state-hover", | |
27 wrapperClass : "ui-widget-content" | |
28 } | |
29 }; | |
30 | |
31 /** | |
32 WIDGETS | |
33 all widgets: | |
34 addListener : add an object with a propertyChange function, will be triggered on select | |
35 propertyChange: update the widget with a new jowl object | |
36 Events: | |
37 onSelect: (look into propertylens click), return false to suppress the event, this = jquery element, first argument = jOWL object | |
38 CSS: | |
39 wrapperClass: css class(es) for main element, the el itself | |
40 contentClass: css class(es) for main content element, accessible by el.content | |
41 focusClass: css class(es) for element in focus, | |
42 */ | |
43 $.fn.extend({ | |
44 /* | |
45 owl_navbar | |
46 options: | |
47 onSelect : this element refers to jquery node, first argument = jOWL object | |
48 */ | |
49 owl_navbar: function(options){ | |
50 options = $.extend({ | |
51 contentClass : jOWL.UI.defaults.contentClass, | |
52 focusClass : jOWL.UI.defaults.focusClass, | |
53 onSelect : function(item){}, | |
54 onPropertyChange : function(item){} | |
55 }, options); | |
56 var self = this; | |
57 this.addClass("jowl-navbar"); | |
58 this.content = $("."+options.contentClass, this).empty(); | |
59 if(!this.content.length) { this.content = $("<div/>").addClass(options.contentClass).appendTo(this); } | |
60 this.parents = $('<div/>').appendTo(this.content); | |
61 this.focus = $('<div/>').addClass(options.focusClass).appendTo(this.content); | |
62 this.children = $('<div/>').appendTo(this.content); | |
63 var listnode = $('<span/>').click(function(){ | |
64 var node = $(this); | |
65 var res = jOWL(node.attr('title')); | |
66 if(options.onSelect.call(node, res) === false) { return; } | |
67 if(res && res.isClass) { self.propertyChange.call(res, res); self.broadcast(res); } | |
68 }); | |
69 | |
70 jOWL.UI.asBroadcaster(this); | |
71 | |
72 this.propertyChange = function(item){ | |
73 if(options.onPropertyChange.call(this, item) === false) { return; } | |
74 if(item.isClass){ | |
75 item.bind(self.focus); | |
76 if(jOWL.options.reason) { item.hierarchy();} | |
77 self.parents.empty().append(item.parents().bind(listnode)); | |
78 self.children.empty().append(item.children().bind(listnode)); | |
79 } | |
80 }; | |
81 return this; | |
82 }, | |
83 /** | |
84 autocomplete field. | |
85 */ | |
86 owl_autocomplete : function(options){ | |
87 options = $.extend({ | |
88 time:500, //responsetime to check for new keystrokes, default 500 | |
89 chars:3, //number of characters needed before autocomplete starts searching | |
90 focus:false, //put cursor on the input field when loading | |
91 limit:10, //limit size of result list to given amount | |
92 contentClass : "ui-widget-content", | |
93 focusClass : jOWL.UI.defaults.focusClass, | |
94 hintClass : "ui-autocomplete-hint", | |
95 hint: false, //Message (if any) to show when unfocused. | |
96 onSelect : function(item){}, //function that can be overridden | |
97 formatListItem : function(listitem, type, identifier, termarray){ //formatting of results, can be overridden | |
98 if(type){ listitem.append($('<div class="type"/>').text(type)); } | |
99 listitem.append($('<div class="name"/>').text(identifier)); | |
100 if(termarray.length) { listitem.append($('<div class="terms"/>').text(termarray.join(', ')) | |
101 .prepend($('<span/>').addClass('termlabel').text("Terms: "))); | |
102 } | |
103 }}, options); | |
104 jOWL.UI.asBroadcaster(this); | |
105 | |
106 this.showHint = function(){ | |
107 this.hinted = true; | |
108 if(options.hint){ | |
109 this.addClass(options.hintClass).val(options.hint); | |
110 } | |
111 else {this.val(''); } | |
112 }; | |
113 this.showHint(); | |
114 | |
115 var self = this; var old = ''; var open = false; self.val(''); | |
116 var results = $('<ul/>').addClass(options.contentClass).addClass("jowl_autocomplete_results"); | |
117 var div = $("<div/>").addClass(options.wrapperClass).append(results); this.after(div); | |
118 results.cache = {}; | |
119 results.isEmpty = function(){ for(x in results.cache) { return false; } return true; }; | |
120 results.close = function(){this.hide();}; | |
121 results.open = function(q, cache){ | |
122 this.show(); | |
123 if(q){ | |
124 if(!cache || results.isEmpty()) { results.cache = jOWL.query(q, options); } | |
125 else { | |
126 var newcache = {}; | |
127 for(x in results.cache){ | |
128 var entry = results.cache[x]; | |
129 var found = false; | |
130 var newentries = []; | |
131 if(x.searchMatch(q) > -1) { found = true; } | |
132 for(var i = 0;i<entry.length;i++){ | |
133 if(entry[i].term.searchMatch(q) > -1) { found = true; newentries.push(entry[i]); } | |
134 } | |
135 if(found) { newcache[x] = newentries; } | |
136 } | |
137 results.cache = newcache; | |
138 } | |
139 this.populate(results.cache); | |
140 } | |
141 }; | |
142 | |
143 results.populate = function(data){ | |
144 var res = this; this.empty(); var count =0; | |
145 var clickFunction = function(){ | |
146 var node = $(this), res = jOWL(node.data("jowltype")); | |
147 if(options.onSelect.call(node, res) === false) { return; } | |
148 self.broadcast(res); | |
149 }; | |
150 | |
151 var onHover = function(){ $(this).addClass(options.focusClass); }; | |
152 var offHover = function(){$(this).removeClass(options.focusClass);}; | |
153 | |
154 for(x in data){ | |
155 if(count < options.limit){ | |
156 var item = data[x]; | |
157 var v = jOWL.isExternal(x); | |
158 v = v ? v[1] : x; | |
159 var list = $('<li/>').data("jowltype", x) | |
160 .click(clickFunction).hover(onHover, offHover) | |
161 .appendTo(res); | |
162 var terms = []; | |
163 for(var l = 0;l<item.length;l++){ | |
164 var found = false; var newterm = item[l].term; | |
165 for(var y=0; y < terms.length;y++){ if(terms[y].toLowerCase() == newterm.toLowerCase()) { found = true; } } | |
166 if(!found) { terms.push(newterm); } | |
167 } | |
168 options.formatListItem.call(list, list, item[0].type, v, terms); | |
169 | |
170 } | |
171 count++; | |
172 } | |
173 }; | |
174 | |
175 setInterval(function(){ | |
176 var newvalue = self.val(); | |
177 var cache = true; | |
178 if(old != newvalue){ | |
179 var longervalue = newvalue.length > old.length && newvalue.indexOf(old) === 0; | |
180 if(!old) { cache = false; } | |
181 old = newvalue; | |
182 if(newvalue.length < options.chars && open){ results.close();open = false;} | |
183 else if(newvalue.length >=options.chars && newvalue.length > 0){ | |
184 if(cache) { cache = longervalue && newvalue.length > options.chars; } | |
185 results.open(newvalue, cache); | |
186 open = true; | |
187 } | |
188 | |
189 } | |
190 }, options.time); | |
191 | |
192 self.bind('keyup', function(){ if(!this.value.length){ results.close(); open = false; } }); | |
193 self.bind('blur', function(){ | |
194 if(open){setTimeout(function(){results.close();}, 200);open = false;} | |
195 if(!self.val().length){self.showHint();} | |
196 }); | |
197 //timeout for registering clicks on results. | |
198 self.bind('focus', function(){ | |
199 if(self.hinted){ | |
200 self.hinted = false; | |
201 $(this).removeClass(options.hintClass).val(''); | |
202 } | |
203 if(self.val().length && !open){results.open('', open);open = true;}}); | |
204 //reopen, but do not get results | |
205 return this; | |
206 }, | |
207 /** | |
208 Tree View | |
209 */ | |
210 owl_treeview : function(options){ | |
211 options = $.extend({ | |
212 contentClass : jOWL.UI.defaults.contentClass, | |
213 focusClass: "focus", | |
214 nameClass: "name", | |
215 treeClass: "jowl-treeview", | |
216 rootClass: "root", | |
217 onSelect : function(item){}, //function that can be overwritten to specfy behavior when something is selected | |
218 rootThing : false, //if true then topnode is (owl) 'Thing' | |
219 isStatic : false, // if static then selections will refresh the entire tree | |
220 addChildren : false //add a given objects children to the treeview as well | |
221 }, options); | |
222 | |
223 /** construct the hierarchy & make a tree of it */ | |
224 function TreeModel(owlobject){ | |
225 | |
226 function clear(el){ //reset invParents, for later use. | |
227 if(el.parents) { el.parents().each(function(){ | |
228 this.invParents = null; clear(this); | |
229 }); } | |
230 } | |
231 | |
232 function leaf(node){ | |
233 node.jnode.addClass(options.focusClass); | |
234 if(options.addChildren){ | |
235 var entry = jOWL(node.$name.attr('title')); | |
236 if(entry && entry.children){ entry.children().each(function(){ node.add(this); }); } } | |
237 } | |
238 | |
239 function traverse(itemarray, appendto){ | |
240 if(!itemarray) { return; } | |
241 itemarray.each(function(){ | |
242 var node = appendto.add(this); | |
243 if(this.invParents){ traverse(this.invParents, node); } | |
244 else { leaf(node); } | |
245 }); | |
246 | |
247 } | |
248 | |
249 var h = owlobject.hierarchy(true); | |
250 if(options.rootThing) { traverse(h, tree.root(jOWL("Thing"))); } | |
251 else { | |
252 var root = tree.root(h); | |
253 for(var i=0;i<root.length;i++){ | |
254 traverse(root[i].invParents, root[i]); | |
255 if(!root[i].invParents) { leaf(root[i]); } | |
256 } | |
257 | |
258 } | |
259 clear(owlobject); | |
260 | |
261 } | |
262 | |
263 /** | |
264 var tree = $(selector).owl_treeview(); | |
265 var root = tree.root("node"); | |
266 root.add("node2").add("child"); | |
267 */ | |
268 function Tree(node, treemodel, options){ | |
269 var rack = $('<ul/>').addClass(options.treeClass).appendTo(node); | |
270 var tree = this; | |
271 /**item can be text, a jOWL object, or a jOWL array */ | |
272 this.root = function(item){ | |
273 var rt = null; //root | |
274 rack.empty(); | |
275 if(item && item.each) { | |
276 rt = []; | |
277 item.each(function(it){ | |
278 var x = new fn.node(it, true); | |
279 x.wrapper.addClass("tv"); | |
280 x.jnode.appendTo(rack); | |
281 x.invParents = it.invParents; it.invParents = null; //reset for later use | |
282 rt.push(x); | |
283 }); | |
284 return rt; | |
285 } | |
286 rt = new fn.node(item, true); | |
287 rt.wrapper.addClass("tv"); | |
288 rt.jnode.appendTo(rack); | |
289 return rt; | |
290 }; | |
291 | |
292 var fn = {}; | |
293 fn.node = function(text, isRoot){ //creates a new node | |
294 this.jnode = isRoot ? $('<li/>').addClass(options.rootClass) : $('<li class="tvi"/>'); | |
295 this.$name = null; | |
296 if(text){ | |
297 this.$name = $('<span/>').addClass(options.nameClass); | |
298 if(typeof text == "string") { this.$name.html(text); } | |
299 else if(text.bind) { text.bind(this.$name); } | |
300 var n = this.$name; | |
301 this.$name.appendTo(this.jnode).click(function(){ | |
302 var entry = jOWL(n.attr('title')); | |
303 if(entry && options.onSelect.call(n, entry) === false) { return; } | |
304 tree.broadcast(entry); | |
305 if(options.isStatic) { tree.propertyChange(entry); } | |
306 return false;}); | |
307 } | |
308 | |
309 this.wrapper = $('<ul/>').appendTo(this.jnode); | |
310 var self = this; | |
311 self.jnode.click(function(){toggle(); return false;}); | |
312 | |
313 this.add = function(text){ | |
314 var nn = new fn.node(text); | |
315 if(!self.wrapper.children().length) { toNode(); } | |
316 else { | |
317 var lastchild = self.wrapper.children(':last'); | |
318 lastchild.swapClass("tvilc", "tvic"); | |
319 lastchild.swapClass("tvile", "tvie"); | |
320 lastchild.swapClass("tvil", "tvi"); | |
321 | |
322 }//children - change end of list | |
323 self.wrapper.append(nn.jnode.swapClass('tvi', 'tvil')); | |
324 return nn; | |
325 }; | |
326 | |
327 function toggle(){ | |
328 var t = self.jnode.hasClass("tvic") || self.jnode.hasClass("tvie") || self.jnode.hasClass("tvilc") || self.jnode.hasClass("tvile"); | |
329 if(!t) { return; } | |
330 self.jnode.swapClass('tvic', 'tvie'); self.jnode.swapClass('tvilc', 'tvile'); | |
331 self.wrapper.slideToggle(); | |
332 } | |
333 | |
334 function toNode(){ | |
335 self.jnode.swapClass('tvil', 'tvilc'); | |
336 self.jnode.swapClass('tvi', 'tvic'); | |
337 } | |
338 }; | |
339 return this; | |
340 }// end Tree | |
341 | |
342 this.addClass("jowl-tree"); | |
343 this.content = $("."+options.contentClass, this).empty(); | |
344 if(!this.content.length){ this.content = $('<div/>').addClass(options.contentClass).appendTo(this); } | |
345 var tree = new Tree(this.content, null, options); | |
346 jOWL.UI.asBroadcaster(tree); | |
347 tree.propertyChange = function(item){ if(item.isClass) { var m = new TreeModel(item); } }; | |
348 return tree; | |
349 }, | |
350 /** Uses templating | |
351 options: | |
352 onChange: owl:Class, owl:Thing, etc..., tell the widget what to do with the different kinds of Ontology Objects. | |
353 "data-jowl" : {split: ", ", "somevariable" : function_triggered_for_each_result } | |
354 example: "rdfs:label" : {split: ", ", "rdfs:label" : function(){ //'this' keyword refers to HTML element}} ) | |
355 example: "sparql-dl:PropertyValue(owl:Class, ?p, ?x)" : {"?p": function(){ //'this' keyword refers to HTML element }} | |
356 //prefil: for sparql-dl queries | |
357 //onComplete: function to trigger when the specific propertybox query is completed, this refers to the HTML element for propertybox | |
358 //sort: sort results on specified parameter, for sparql-dl results. | |
359 onUpdate: called when the widget updates itself | |
360 */ | |
361 owl_propertyLens : function(options){ | |
362 var self = this; | |
363 self.options = $.extend({ | |
364 backlinkClass : "backlink", | |
365 split: {}, | |
366 disable : {}, | |
367 click : {}}, | |
368 options); | |
369 self.resourcetype = this.attr('data-jowl') || "owl:Class"; | |
370 var propertyboxes = []; | |
371 $('.propertybox', this).each(function(){ | |
372 var node = new jOWL.UI.PropertyBox($(this), self); | |
373 propertyboxes.push(node); | |
374 node.el.hide(); | |
375 }); | |
376 var backlink = $('.backlink', this).hide(); | |
377 if(!backlink.length) { backlink = $('<div class="jowl_link"/>').addClass(self.options.backlinkClass).text("Back").hide().appendTo(this); } | |
378 jOWL.UI.asBroadcaster(this); | |
379 | |
380 /** fn: optional function to execute*/ | |
381 this.link = function(source, target, htmlel, fn){ | |
382 htmlel.addClass("jowl_link").click(function(){ | |
383 if(fn) { fn(); } | |
384 self.broadcast(target); | |
385 self.propertyChange(target); | |
386 backlink.source = source.name; | |
387 backlink.show().unbind('click').click(function(){ | |
388 self.broadcast(source); self.propertyChange(source); backlink.hide(); | |
389 }); | |
390 | |
391 }); | |
392 | |
393 }; | |
394 | |
395 var action = { | |
396 "rdfs:label": function(item){ return [{"rdfs:label": item.label() }]; }, | |
397 "rdf:ID" : function(item){ return [{"rdf:ID": [item.name, item] }]; }, | |
398 "rdfs:comment" : function(item){ | |
399 return $.map(item.description(), function(n){return {"rdfs:comment":n }; }); | |
400 }, | |
401 "rdf:type" : function(item){ | |
402 if(item.owlClass) { return [{"rdf:type": item.owlClass() }]; } | |
403 return [{"rdf:type": item.type }]; | |
404 }, | |
405 "term" : function(item){ | |
406 return $.map(item.terms(), function(n, i){ return { "term" : n[0] }; }); | |
407 }, | |
408 "rdfs:range": function(item){if(item.range) { return [{"rdfs:range": item.range }]; } }, | |
409 "rdfs:domain": function(item){if(item.domain) { return [{"rdfs:domain": item.domain }]; } }, | |
410 "permalink": function(item){ | |
411 var href = jOWL.permalink(item); | |
412 return [{"permalink": "<a href='"+href+"'>Permalink</a>" }]; | |
413 }, | |
414 "owl:disjointWith": function(item){ | |
415 if(!(item.isClass)) { return; } | |
416 return $.map( | |
417 jOWL.Xpath('*', item.jnode) | |
418 .filter(function(){return this.nodeName == "owl:disjointWith"; }), | |
419 function(n, i){ return {"owl:disjointWith": jOWL($(n).RDF_Resource())}; | |
420 }); | |
421 }, | |
422 "default" : function(item){ | |
423 var type = this.attr("data-jowl"); | |
424 return $.map( | |
425 jOWL.Xpath('*', item.jnode).filter(function(){return this.nodeName == type; }), | |
426 function(n, i){ var x = {}; x[type] = $(n).text(); return x; } | |
427 ); | |
428 } | |
429 }; | |
430 | |
431 this.propertyChange = function(item){ | |
432 if(!item) { return; } | |
433 self.property = item; | |
434 if(backlink.source != item.name) { backlink.hide(); } else { backlink.source = false; } | |
435 | |
436 if(item.type != self.resourcetype){ | |
437 if(item.isDatatypeProperty && self.resourcetype == "rdf:Property") {} | |
438 else if(item.isObjectProperty && self.resourcetype == "rdf:Property"){} | |
439 else { return; } | |
440 } | |
441 | |
442 for(var i = 0;i<propertyboxes.length;i++){ | |
443 var pbox = propertyboxes[i]; | |
444 pbox.clear(); | |
445 if(!pbox.actiontype){return; } | |
446 var actiontype = pbox.actiontype; | |
447 if(self.options.disable[actiontype]) { return; } | |
448 | |
449 if(!self.options[actiontype]) { self.options[actiontype] = {}; } | |
450 | |
451 if(actiontype.indexOf("sparql-dl:") === 0){ | |
452 var query = actiontype.split("sparql-dl:", 2)[1]; | |
453 var fill = {}; fill[self.resourcetype] = item; | |
454 if(self.options[actiontype].prefill) { $.extend(fill, self.options[actiontype].prefill); } | |
455 var qr = new jOWL.SPARQL_DL(query, fill).execute({onComplete : function(r){ | |
456 if(self.options[actiontype].sort) { r.sort(self.options[actiontype].sort); } | |
457 pbox.setResults(r.results, item); | |
458 }}); | |
459 } | |
460 else { | |
461 var choice = (action[actiontype]) ? actiontype : "default"; | |
462 var results = action[choice].call(pbox.valuebox, item); | |
463 pbox.setResults(results, item); | |
464 } | |
465 } | |
466 | |
467 if(self.options.onUpdate) { self.options.onUpdate.call(this, item); } | |
468 }; //end property change | |
469 | |
470 if(self.options.tooltip){ | |
471 var lens = this.remove(); | |
472 this.display = function(element, htmlel){ | |
473 htmlel.tooltip({ | |
474 title: element.label(), | |
475 html: function(){ lens.propertyChange(element); backlink.hide(); return lens.get(0); } | |
476 }); | |
477 }; | |
478 } | |
479 return this; | |
480 }, | |
481 | |
482 /** | |
483 Use propertyChange to set the class | |
484 Use addField to add property refinements | |
485 Use serialize to serialize input | |
486 */ | |
487 owl_datafield: function(options){ | |
488 options = $.extend({ | |
489 selectorClass : "jowl-datafield-selector", | |
490 messageClass : "jowl-datafield-message", | |
491 labelClass : "jowl-datafield-property-label" | |
492 }, options); | |
493 var self = this; | |
494 var pArray = {}; //associative array for properties. | |
495 this.messages = {}; | |
496 this.messages[jOWL.NS.xsd()+"positiveInteger"] = "Allowed values: positive numbers or comparisons like '>5 && <15' "; | |
497 | |
498 this.addClass("owl_UI"); | |
499 jOWL.UI.asBroadcaster(this); | |
500 | |
501 this.property = null; | |
502 | |
503 this.propertyChange = function(item){ | |
504 if(item.isClass){ | |
505 this.property = item; | |
506 for(x in pArray){//reset all properties | |
507 if(pArray[x].remove){ pArray[x].remove(); delete pArray[x]; } | |
508 } | |
509 } | |
510 }; | |
511 | |
512 /** Sets up a new field */ | |
513 this.addField = function(property){ | |
514 if(pArray[property.URI]){ | |
515 //allow for multiple fields? | |
516 return; | |
517 } | |
518 | |
519 var $content = $("<div/>"); | |
520 pArray[property.URI] = $content; | |
521 | |
522 var $title = property.bind($("<div/>")).addClass(options.labelClass).appendTo($content).click(function(){ $content.remove(); delete pArray[property.URI]; }); | |
523 | |
524 if(property.isObjectProperty){ | |
525 | |
526 var sp = new jOWL.SPARQL_DL("Type(?t, ?c),PropertyValue(concept, property, ?c)", {concept : self.property, property : property }).execute({ | |
527 onComplete : function(obj){ | |
528 if(!obj.results.length){ return; } //modify to deal with non value results | |
529 obj.sort("?t"); | |
530 | |
531 $select = $("<select class='"+options.selectorClass+"'/>").appendTo($content); | |
532 | |
533 for(var i=0;i<obj.results.length;i++){ | |
534 obj.results[i]['?t'].bind($("<option/>")).appendTo($select); | |
535 } | |
536 | |
537 $content.appendTo(self); | |
538 }}); | |
539 | |
540 } | |
541 else if(property.isDatatypeProperty){ | |
542 var msg =""; | |
543 if(self.messages[property.range]){ msg = self.messages[property.range]; } | |
544 | |
545 var $input = $('<div/>').addClass(options.selectorClass).attr("title", property.range).append($('<input type="text" style="font-size:11px;width:100px;"/>')); | |
546 var $message = $('<div/>').addClass(options.messageClass).text(msg).appendTo($input); | |
547 | |
548 $content.append($input).appendTo(self); | |
549 $('input', $content).focus(function(){ | |
550 $message.animate({opacity: 1.0}, 1500).fadeOut(); | |
551 }); | |
552 | |
553 | |
554 } | |
555 | |
556 }; | |
557 | |
558 this.serialize = function(){ | |
559 var q = { "Type": self.property, "PropertyValue" : [] }; | |
560 | |
561 $('.'+options.selectorClass, self).each(function(){ | |
562 var $this = $(this); | |
563 var $prop = $this.siblings('.'+options.labelClass); | |
564 var prop = $prop.attr('title'); | |
565 if( $this.is("select")){ | |
566 var s = $this.get(0); | |
567 var thing = $(s[s.selectedIndex]).attr('title'); | |
568 q.PropertyValue.push([prop, thing]); | |
569 } | |
570 else { | |
571 var $input = $this.find("input"); | |
572 var datatype = $this.attr('title'); | |
573 var entry = $input.get(0).value; | |
574 if(entry) { q.PropertyValue.push([prop, '"'+entry+'"']); } | |
575 } | |
576 }); | |
577 return q; | |
578 }; | |
579 | |
580 return this; | |
581 } | |
582 }); | |
583 | |
584 /** Used by owl_PropertyLens */ | |
585 jOWL.UI.PropertyBox = function($el, resourcebox){ | |
586 var v = $('[data-jowl]', $el); | |
587 if(v.length){ this.descendant = true;} | |
588 | |
589 this.el = $el; | |
590 this.resourcebox = resourcebox; | |
591 this.valuebox = v.length ? v : $el; | |
592 this.actiontype = this.valuebox.attr('data-jowl'); | |
593 }; | |
594 | |
595 jOWL.UI.PropertyBox.prototype = { | |
596 setResults : function(results, item){ | |
597 var nodes = jOWL.UI.Template(results, this.valuebox, this.resourcebox.options[this.actiontype].split); | |
598 this.complete(nodes, item); | |
599 if(nodes && nodes.length && this.descendant) { this.el.show(); this.valuebox.hide(); } | |
600 if(this.resourcebox.options[this.actiontype].onComplete) { this.resourcebox.options[this.actiontype].onComplete.call(this.el.get(0)); } | |
601 }, | |
602 complete : function(nodes, item){ | |
603 var res = this.resourcebox; | |
604 if(!nodes || !nodes.length) { return; } | |
605 var v = $.data(nodes, "parameters"); | |
606 for(x in v){ | |
607 if(v[x].length && typeof res.options[this.actiontype][x] == "function") { | |
608 v[x].each(res.options[this.actiontype][x]); | |
609 }} | |
610 for(x in res.options.onChange){ | |
611 var data = $('[typeof='+x+']', nodes).add(nodes.filter('[typeof='+x+']')); | |
612 if(x.charAt(0) == "." || x.charAt(0) == "#"){ data = data.add($(x, nodes));} | |
613 data.each(function(){ | |
614 var node = $(this); | |
615 $.data(node, 'data-jowl', x); | |
616 var id = node.attr('title'); | |
617 if(id != "anonymousOntologyObject") { res.options.onChange[$.data(node, 'data-jowl')].call(node, item, jOWL(id), res); } | |
618 }); | |
619 } | |
620 }, | |
621 clear : function(){ | |
622 var prev = this.valuebox.prev('.jowl-template-result'); | |
623 if(!prev.length){ prev = this.valuebox.prev('.jowl-template-splitter');} | |
624 if(prev.length) { prev.remove(); this.clear(this.valuebox); } | |
625 } | |
626 }; | |
627 | |
628 /**arr: associative array of variablrd, jqel: node for which variables need to be substituted, */ | |
629 jOWL.UI.Template = function(arr, jqel, splitter){ | |
630 var options = { | |
631 resultClass : "jowl-template-result", | |
632 splitterClass : "jowl-template-splitter" | |
633 }; | |
634 if(!arr) { return; } | |
635 | |
636 function bindObject(value, jnode){ | |
637 var bound = false; | |
638 if(!value) { return false; } | |
639 if(typeof value == 'string') { jnode.html(value); bound = true;} | |
640 else if(value.constructor == Array){ | |
641 if(value.length == 2) { value[1].bind(jnode).text(value[0]); bound = true; } | |
642 } | |
643 else if(value.bind){ value.bind(jnode); bound = true; } | |
644 return bound; | |
645 } | |
646 var count = 0, a = [], b = {}; | |
647 var remnantFn = function(){ | |
648 var txt = $(this).text(); | |
649 if(txt.indexOf('${') === 0 && txt.lastIndexOf('}') == txt.length-1 ) { $(this).hide(); } | |
650 }; | |
651 for(var i=0;i<arr.length;i++){ | |
652 var x = jqel.clone(true).wrapInner("<"+jqel.get(0).nodeName+" class='"+options.resultClass+"'/>").children(); | |
653 /** copy style settings */ | |
654 x.addClass(jqel.attr('class')).removeClass('propertybox'); | |
655 /** accepted obj types= string, array["string", "jowlobject"], jowlobject*/ | |
656 for(obj in arr[i]){ | |
657 if(!b[obj]) { b[obj] = []; } | |
658 var occurrences = $(':contains(${'+obj+'})', x); | |
659 if(!occurrences.length){ | |
660 if(x.text() == "${"+obj+"}") { if(bindObject(arr[i][obj], x)) { | |
661 count++; b[obj].push(x.get(0)); | |
662 }} | |
663 } | |
664 else { | |
665 occurrences.each(function(){ | |
666 if(this.innerHTML == "${"+obj+"}") { var node = $(this); if(bindObject(arr[i][obj], node)) { count++; b[obj].push(this); } } | |
667 }); | |
668 } | |
669 } | |
670 var remnants = $(':contains(${)', x); //hide parameters that weren't substituted | |
671 remnants.each(remnantFn); | |
672 if(count){ | |
673 x.insertBefore(jqel); | |
674 a.push(x.get(0)); | |
675 if(count > 1 && splitter) { | |
676 $splitter = (splitter.indexOf('<') === 0) ? $(splitter) : $("<span/>").text(splitter); | |
677 $splitter.addClass(options.splitterClass).insertBefore(x); | |
678 } | |
679 } | |
680 } | |
681 for(x in b){ if(b[x].length) { b[x] = $(b[x]); } } | |
682 var nodes = $(a); | |
683 $.data(nodes, "parameters", b); | |
684 return nodes; | |
685 }; | |
686 | |
687 /** | |
688 Supporting functionality | |
689 */ | |
690 | |
691 $.fn.swapClass = function(c1,c2) { | |
692 return this.each(function() { | |
693 if ($(this).hasClass(c1)) { $(this).removeClass(c1); $(this).addClass(c2);} | |
694 else if ($(this).hasClass(c2)) {$(this).removeClass(c2);$(this).addClass(c1);} | |
695 }); | |
696 }; | |
697 | |
698 })(jQuery); |