annotate examples/browser/web/js/jOWL_UI.js @ 770:c54bc2ffbf92 tip

update tags
author convert-repo
date Fri, 16 Dec 2011 11:34:01 +0000
parents 901803e1305f
children
rev   line source
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);