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