1//# sourceURL=data.js 2//# COPYRIGHT Kraneburg Productions 3 4$(document).on('newField', function(){ 5 console.log('NEW FIELD'); 6 7}) 8 9//console.log('data.js loading'); 10Storage.prototype.setObj = function(key, obj) { 11 return this.setItem(key, JSON.stringify(obj)) 12}; 13 14Storage.prototype.getObj = function(key) { 15 var resultObj = JSON.parse(this.getItem(key)); 16 if (resultObj == null) return undefined; 17 else return resultObj; 18} 19 20 21 22 23STATUS_UNCHANGED = 0; 24STATUS_CHANGED = 1; 25STATUS_NEW = 2; 26STATUS_CHANGING = 3; 27STATUS_DELETED = 6; 28STATUS_INVALID = 10; 29 30// Storage for Data in DOM 31// ++ ADD XML FILE SUPPORT 32XMLStorage = new Object(); 33XMLStorage.getEntity = function(view, storage) { 34 // storage is the XML element containing data 35 // view might have xmlRoot value where all its entities are stored 36 37 var entity = new Entity(); 38 entity.setView( Model.views[view.name] ); 39 entity.storage = XMLStorage; 40 entity.storageSource = storage; 41 42 entity.reload = function() { 43 if (typeof entity.storageSource === 'undefined') return; // NEw ENTITY, NOT STORED YET, DOES NOT HAVE XML TAG YET, USES DEFAULT VALUES FROM VIEW 44 for (var fieldName in view.fields) { 45 if ( isset(view.fields[fieldName].xmlStorage) ) { 46 47 var storageParams = view.fields[fieldName].xmlStorage; 48 49 if (isset(storageParams)) { 50 51 //alert(entity.fields[fieldName].status()); 52 //alert(entity.view.name); 53 54 if (isset(storageParams.selector) == false || storageParams.selector == '' || storageParams.selector == 'this') 55 var element = $(entity.storageSource); 56 else var element = $(entity.storageSource).find(storageParams.selector); 57 58 59 if (typeof storageParams.type !== 'undefined' && storageParams.type == 'tag' ) { 60 var outerHTML = element[0].outerHTML; 61 var oldTag = outerHTML.split(' ')[0]; 62 entity.data[fieldName] = convertValue( oldTag.substr(1) , 'string', view.fields[fieldName].type ); 63 } 64 else if ( isset(storageParams.attribute) ) { 65 entity.data[fieldName] = convertValue( element.attr(storageParams.attribute) , 'string', view.fields[fieldName].type ); 66 } 67 else if ( isset(storageParams.toggleAttribute) ) { 68 entity.data[fieldName] = convertValue( element.hasAttr(storageParams.toggleAttribute) , 'boolean', view.fields[fieldName].type ); 69 } 70 else if ( isset(storageParams.toggleClass) ) { 71 entity.data[fieldName] = convertValue( element.hasClass(storageParams.toggleClass) , 'boolean', view.fields[fieldName].type ); 72 } 73 else entity.data[fieldName] = convertValue( element.html() , 'string', view.fields[fieldName].type ); 74 75 } 76 } 77 } 78 79 } 80 entity.reload(); 81 82 return entity; 83} 84 85XMLStorage.store = function( entity ) { 86 if ( entity.trash() == true ) { 87 if (typeof entity.storageSource !== 'undefined') { 88 entity.storageSource.remove(); 89 } // else NEw ENTITY, NOT STORED YET, DOES NOT HAVE XML TAG YET 90 $(entity).triggerHandler('deleted'); 91 $(document).triggerHandler('entityDeleted', entity); 92// self = undefined; 93 entity.status(STATUS_DELETED); 94 delete(entity); 95 return; 96 } 97 98 if ( entity.status() == STATUS_UNCHANGED ) return true; 99 if (typeof entity.storageSource == 'undefined') { 100 // NEw ENTITY, NOT STORED YET, DOES NOT HAVE XML TAG YET 101 entity.storageSource = $('<' + entity.view.xmlEntityTag + '></' + entity.view.xmlEntityTag + '>'); 102 $(entity.view.xmlRoot).append( entity.storageSource ); 103 } 104 105 106 for (var fieldName in entity.fields) { 107 if (entity.fields[fieldName].status() != STATUS_UNCHANGED) { 108 var storageParams = entity.fields[fieldName].attribute('xmlStorage'); 109 /* 110 console.log(fieldName);
111 console.log(entity.fields[fieldName].status()); 112 console.log(storageParams); 113*/ 114 115 if (isset(storageParams)) { 116 if (isset(storageParams.selector) == false || storageParams.selector == '' || storageParams.selector == 'this') 117 var element = $(entity.storageSource); 118 else { 119 var element = $(entity.storageSource).find(storageParams.selector); 120 if (element.length == 0) { 121 // ELEMENT NOT FOUND, TRY TO CREATE 122 // selector MUST LOOK LIKE >div>ul>li 123 // ">" REQUIRED FOR CREATION 124 var parts = storageParams.selector.split('>'); 125 var element = $(entity.storageSource); 126 for (var index in parts) { 127 if ( parts[ index ] != '' ) { 128 var newElement = $('<' + parts[ index ] + '></' + parts[ index ] + '>'); 129 element.append( newElement ); 130 element = newElement; 131 } 132 } 133 } 134 } 135 136 if (typeof storageParams.type !== 'undefined' && storageParams.type == 'tag' ) { 137 var outerHTML = element[0].outerHTML; 138 var oldTag = outerHTML.split(' ')[0]; 139 outerHTML = '<' + entity.get(fieldName, 'string') + outerHTML.substr( oldTag.length, outerHTML.length - oldTag.length - oldTag.length -2) + '</' + entity.get(fieldName, 'string') +'>'; 140 element[0].outerHTML = outerHTML; 141 } 142 else if (isset(storageParams.attribute)) { 143 if (entity.get(fieldName, 'string') == '' ) { 144 if ( storageParams.keep != true ) element.removeAttr( storageParams.attribute ); 145 else element.attr( storageParams.attribute, ''); 146 } 147 else if (entity.fields[fieldName].type == 'boolean' && entity.get(fieldName) == false) element.removeAttr( storageParams.attribute ); 148 else element.attr( storageParams.attribute, entity.get(fieldName, 'string')); 149 } 150 else if (isset(storageParams.toggleAttribute)) { 151 if (entity.get(fieldName) == 0) element.removeAttr(storageParams.toggleAttribute); 152 else element.attr(storageParams.toggleAttribute, ''); 153 } 154 else if (isset(storageParams.toggleClass)){ 155 if (entity.get(fieldName) == 0) element.removeClass(storageParams.toggleClass); 156 else element.addClass(storageParams.toggleClass); 157 } 158 else // SET VALUE 159 { 160 // REMOVE EMPTY FIELD 161 if ( entity.get(fieldName) == '' ) { 162 element.remove(); 163 } 164 // OR SET VALUE 165 else element.html( entity.get(fieldName, 'string') ); 166 } 167 168 169 170 } 171 172 } 173 } 174 entity.status(STATUS_UNCHANGED); 175 $(entity).trigger( 'stored' ); 176 return true; 177 178} 179 180 181 182 183// Storage for Data in Object 184ObjectStorage = new Object(); 185 186 187 188ObjectStorage.store = function( entity ) { 189 if ( entity.trash() == true ) { 190 if (typeof entity.storageSource !== 'undefined') { 191 entity.storageSource.remove(); 192 } // else NEw ENTITY, NOT STORED YET, DOES NOT HAVE XML TAG YET 193 $(entity).triggerHandler('deleted'); 194 $(document).triggerHandler('entityDeleted', entity); 195// self = undefined; 196 entity.status(STATUS_DELETED); 197 delete(entity); 198 return; 199 } 200 201 if ( entity.status() == STATUS_UNCHANGED ) return true; 202 if (typeof entity.storageSource == 'undefined') { 203 // NEw ENTITY, NOT STORED YET, DOES NOT HAVE XML TAG YET 204 entity.storageSource = $('<' + entity.view.xmlEntityTag + '></' + entity.view.xmlEntityTag + '>'); 205 $(entity.view.xmlRoot).append( entity.storageSource ); 206 } 207 208 209 for (var fieldName in entity.fields) { 210 if (entity.fields[fieldName].status() != STATUS_UNCHANGED) { 211 var storageParams = entity.fields[fieldName].attribute('xmlStorage'); 212 /* 213 console.log(fieldName);
214 console.log(entity.fields[fieldName].status()); 215 console.log(storageParams); 216*/ 217 218 if (isset(storageParams)) { 219 if (isset(storageParams.selector) == false || storageParams.selector == '' || storageParams.selector == 'this') 220 var element = $(entity.storageSource); 221 else { 222 var element = $(entity.storageSource).find(storageParams.selector); 223 if (element.length == 0) { 224 // ELEMENT NOT FOUND, TRY TO CREATE 225 // selector MUST LOOK LIKE >div>ul>li 226 // ">" REQUIRED FOR CREATION 227 var parts = storageParams.selector.split('>'); 228 var element = $(entity.storageSource); 229 for (var index in parts) { 230 if ( parts[ index ] != '' ) { 231 var newElement = $('<' + parts[ index ] + '></' + parts[ index ] + '>'); 232 element.append( newElement ); 233 element = newElement; 234 } 235 } 236 } 237 } 238 239 if (typeof storageParams.type !== 'undefined' && storageParams.type == 'tag' ) { 240 var outerHTML = element[0].outerHTML; 241 var oldTag = outerHTML.split(' ')[0]; 242 outerHTML = '<' + entity.get(fieldName, 'string') + outerHTML.substr( oldTag.length, outerHTML.length - oldTag.length - oldTag.length -2) + '</' + entity.get(fieldName, 'string') +'>'; 243 element[0].outerHTML = outerHTML; 244 } 245 else if (isset(storageParams.attribute)) { 246 if (entity.get(fieldName, 'string') == '' ) { 247 if ( storageParams.keep != true ) element.removeAttr( storageParams.attribute ); 248 else element.attr( storageParams.attribute, ''); 249 } 250 else if (entity.fields[fieldName].type == 'boolean' && entity.get(fieldName) == false) element.removeAttr( storageParams.attribute ); 251 else element.attr( storageParams.attribute, entity.get(fieldName, 'string')); 252 } 253 else if (isset(storageParams.toggleAttribute)) { 254 if (entity.get(fieldName) == 0) element.removeAttr(storageParams.toggleAttribute); 255 else element.attr(storageParams.toggleAttribute, ''); 256 } 257 else if (isset(storageParams.toggleClass)){ 258 if (entity.get(fieldName) == 0) element.removeClass(storageParams.toggleClass); 259 else element.addClass(storageParams.toggleClass); 260 } 261 else // SET VALUE 262 { 263 // REMOVE EMPTY FIELD 264 if ( entity.get(fieldName) == '' ) { 265 element.remove(); 266 } 267 // OR SET VALUE 268 else element.html( entity.get(fieldName, 'string') ); 269 } 270 271 272 273 } 274 275 } 276 } 277 entity.status(STATUS_UNCHANGED); 278 $(entity).trigger( 'stored' ); 279 return true; 280 281} 282 283 284 285 286 287 288FileCache = new Object(); 289FileCache.load = function(params) 290{ 291 try { 292 var fileStorageName = 'File::' + params.url; 293 if (isset('APP_NAME')) fileStorageName = 'File::' + APP_NAME + '_' + APP_VERSION + '_' + params.url; 294 var tempDataType = params.dataType; 295 var localFileData = window.localStorage.getItem(fileStorageName); 296 297 if (isset(localFileData) && localFileData != null) 298 { 299 //console.log('RESTORING'); 300 if (tempDataType == 'xml') localFileData = $.parseXML( localFileData ); 301 //console.log(localFileData); 302 params.done(localFileData); 303 return; 304 } 305 306 307 params.dataType = 'text'; 308 $.ajax( params ).done( function(data) { 309 window.localStorage.setItem(fileStorageName, data); 310 params.dataType = tempDataType; 311 if (tempDataType == 'xml') data = $.parseXML( data ); 312 else if (tempDataType == 'json') data = $.parseJSON( data ); 313 if (typeof params.done == 'function' ) params.done(data); 314 }); 315 } catch ( e ) { 316 317 console.log('Error - loading file :' + params.url); 318 throw e; 319// alert(params.url); 320// if (typeof params.fail == 'function' ) params.fail(); 321 } 322 323 324} 325 326function Query (queryString) { 327 // ### 328 329 this.view = undefined; 330 331 this.host = undefined; // retrieve data from different server, keeping filter and string provider/data/view/... 332 this.path = undefined; // becomes "'provider/plugins/data/view/VIEWNAME/' if empty 333 334 this.filters = []; 335 this.sorters = []; 336 this.limiters = []; 337 this.relations = []; 338 339 /* 340 this.toXML = function() { 341 var xml = ''; 342 foreach (index in this.filters) { 343 var filter = this.filters[filter]; 344 xml += filter.key + ' ' + filter.operator + ' "' + filter.value + '"'; 345 } 346 return xml; 347 }; 348 */ 349 this.toURL = function() { 350 351 352 var hostURL = 'provider/plugins/data/'; 353 if (typeof this.path !== 'undefined' && this.path != '') { 354 hostURL = this.path; 355 }; 356 357 if (typeof this.host !== 'undefined' && this.host != '') hostURL = this.host + hostURL; 358 if (typeof this.relationString !== 'undefined') return (hostURL + '?query=' + this.relationString); 359 360 if (typeof this.path === 'undefined' || this.path == '') { 361 hostURL = hostURL + 'view/' + this.view + '/'; 362 }; 363 364 365 var url = ''; 366 367 for (var index in this.filters) { 368 var filter = this.filters[index]; 369 if (url != '') url += ' ' + filter.connector + ' '; 370 url += filter.toURL(); 371 } 372 var first = true; 373 if (this.sorters.length > 0) 374 { 375 if (url != '') url += ' '; 376 url += 'ORDER BY '; 377 for (var index in this.sorters) { 378 var sorter = this.sorters[index]; 379 if (!first) url += ' ORDER BY '; 380 first = false; 381 url += sorter.field + ' ' + sorter.direction; 382 } 383 384 //url += filter.field + ' ' + filter.comparator + ' "' + filter.value + '"'; 385 386 } 387 388 if (this.limiters.length > 0) 389 { 390 if (url != '') url += ' '; 391 url += 'LIMIT '; 392 // BUT ONLY ONE LIMIT MAKES SENSE 393 for (var index in this.limiters) { 394 var limiter = this.limiters[index]; 395// if (!first) url += ', '; 396 first = false; 397 url += limiter.from + ', ' + limiter.amount; 398 } 399 400 //url += filter.field + ' ' + filter.comparator + ' "' + filter.value + '"'; 401 402 } 403 404 if (this.relations.length > 0) 405 { 406 if (url != '') url += ' RELATIONS '; 407 url += this.relations.join(', '); 408 } 409 410 url = hostURL + '?list[filters]=' + url; 411 if (typeof DATA_URL != 'undefined') url = DATA_URL + url; 412 return url; 413 }; 414 415 this.toString = function() { 416 if (typeof this.relationString !== 'undefined') { 417 return this.relationString; 418 } 419 420 var url = 'VIEW ' + this.view; 421 422 var first = true; 423 for (var index in this.filters) { 424 var filter = this.filters[index]; 425 if ( first ) { 426 url += ' WHERE '; 427 first = false; 428 } else url += ' ' + filter.connector + ' '; 429 url += filter.toURL(); 430 } 431 first = true; 432 if (this.sorters.length > 0) 433 { 434 if (url != '') url += ' '; 435 url += 'ORDER BY '; 436 for (var index in this.sorters) { 437 var sorter = this.sorters[index]; 438 if (!first) url += ' ORDER BY '; 439 first = false; 440 url += sorter.field + ' ' + sorter.direction; 441 } 442 443 //url += filter.field + ' ' + filter.comparator + ' "' + filter.value + '"'; 444 445 } 446 447 if (this.limiters.length > 0) 448 { 449 if (url != '') url += ' '; 450 url += 'LIMIT '; 451 // BUT ONLY ONE LIMIT MAKES SENSE 452 for (var index in this.limiters) { 453 var limiter = this.limiters[index]; 454// if (!first) url += ', '; 455 first = false; 456 url += limiter.from + ', ' + limiter.amount; 457 } 458 459 //url += filter.field + ' ' + filter.comparator + ' "' + filter.value + '"'; 460 461 } 462 return url; 463 }; 464 465 this.parseString = function(queryString) { 466 467 if (queryString.substring(0,8) == "RELATION") { 468 // SEARCH FOR LAST RELATION, WHICH IS VIEW NAME 469 var parts = queryString.split('RELATION '); 470 var words = parts[parts.length-1].split(' '); 471 this.view = words[0]; 472 this.relationString = queryString; 473 return; 474 }; 475 476 477 var words = queryString.split(' '); 478 var pos = 0; 479 480 if (words.length == 1) this.view = words[0]; 481 if (words.length <= 1) return; 482 483 //console.log(words.length); 484 485 while (words.length > pos) { 486 var action = words[pos].toUpperCase(); 487 488 if (action == 'VIEW') { 489 this.view = words[pos + 1]; 490 pos += 2; 491 } 492 493 494 else if (action == 'RELATIONS' ) { 495 pos ++; 496// if ( typeof this.relations === 'undefined' ) this.relations = []; 497 do { 498 var field = words[pos]; 499 if (field.charAt(field.length - 1) == ',') field = field.slice(0, field.length-1); 500 this.relations.push(field); 501 pos++; 502 } while (words[pos - 1].charAt(words[pos - 1].length - 1) == ','); 503 } 504 505 506 else if (action == 'ORDER' && words[pos + 1].toUpperCase() == 'BY') { 507 pos += 2; 508 509 do { 510 511 var field = words[pos]; 512 if (field.charAt(field.length - 1) == ',') field = field.slice(0, field.length-1); 513 pos++; 514 515 var direction = 'ASC'; 516 if (words.length > pos) { 517 var tmpDirection = words[pos].toUpperCase(); 518 if (tmpDirection.charAt(tmpDirection.length - 1) == ',') tmpDirection = tmpDirection.slice(0, field.length-1); 519 if (tmpDirection == 'ASC' || tmpDirection == 'ASC,') { pos++; } 520 if (tmpDirection == 'DESC' || tmpDirection == 'DESC,') { direction = 'DESC'; pos++; } 521 } 522 523 524 var sorter = new Sorter({'field': field, 'direction': direction }); 525 this.sorters.push(sorter); 526 } while (words[pos - 1].charAt(words[pos - 1].length - 1) == ','); 527 528 } 529 530 else if (action == 'LIMIT' ) { 531 pos++; 532 533 var from = words[pos]; 534 if (from.charAt(from.length - 1) == ',') from = from.slice(0, from.length-1); 535 from = parseInt(from); 536 pos++; 537
538 var amount = parseInt( words[pos] ); 539 pos++; 540 541 var limiter = new Limiter({'from': from, 'amount': amount }); 542 this.limiters.push(limiter); 543 544 } 545 546 else { 547 548 if (action == 'WHERE') pos++; 549 550 var continueWhereParsing = true; 551 552 do { 553 var connector = 'AND'; 554 555 if (pos > 0 && words[pos-1].toUpperCase() == 'OR') connector = 'OR'; 556 557 var field = words[pos]; 558 pos++; 559 var comparator = words[pos]; 560 pos++; 561 562 var value = ''; 563 564 if (comparator.toUpperCase() == 'IS') { 565 566 if (words[pos].toUpperCase() == 'NOT') { 567 comparator = 'IS NOT'; 568 pos++; 569 } else if (words[pos].toUpperCase() == 'IN') { 570 comparator = 'IS IN'; 571 pos++; 572 } 573 574 value = words[pos]; // NULL 575 pos++; 576 // NOT SUPPORTED: IS IN, IS NOT, ... 577 578 } else { 579 do { // SEARCH END OF STRING IN " 580 if (words.length == pos) { 581 alert('Error in Query String. WHERE value must be enclosed by "..."'); 582 console.log('ERROR - UNEXPECTED PARSE END'); 583 debugger; 584 return; 585 } 586 value += ' ' + words[pos]; 587 pos++; 588 589 } while (value.charAt(value.length - 1) != '"'); 590 value = value.slice(2, value.length-1); // CLEAN " CHARS 591 592 593 //console.log (value); 594 } 595 596 var filter = new Filter({'field': field, 'comparator': comparator, 'value': value, 'connector': connector}); 597 this.filters.push(filter); 598 599 if (words.length <= pos) continueWhereParsing = false; 600 else { 601 var tmpConnector = words[pos].toUpperCase(); 602 if (tmpConnector == 'AND' || tmpConnector == 'OR') pos++; 603 else continueWhereParsing = false; 604 } 605 } while (continueWhereParsing); 606 } 607 608 609 610/* 611 else { 612 console.log ('ERROR - UNABLE TO PARSE: '+ words[pos]); 613 pos++; 614 } 615*/ 616 } 617 618 } 619 620 this.merge = function(query) { 621 if ( $.isArray(query) ) { 622 // query is Array of Queries 623 // merge each query 624 for ( var index in query) this.merge(query[index]); 625 } else 626 { 627 console.log(query); 628 this.filters = this.filters.concat(query.filters); 629 this.sorters = this.sorters.concat(query.sorters); 630 if (isset(this.view) == false) this.view = query.view; 631 } 632 } 633 634 if (isset(queryString) == false) return this 635 else if (typeof queryString == 'string') this.parseString(queryString); 636 else return this.merge(queryString); 637 638} 639 640 641 642function Filter(iniParams) { 643 this.field; 644 this.value; 645 this.comparator = '='; 646 this.connector = 'AND'; 647 648 $.extend( this, iniParams ); 649 650 this.getField = function() { 651 // Can be overwritten 652 return this.field; 653 }; 654 this.getValue = function() { 655 // Can be overwritten 656 return this.value; 657 }; 658 659 this.set = function(field, value) { 660 this.field = field; 661 this.value = value; 662 $(this).triggerHandler('changed'); 663 } 664 665 this.toURL = function() { 666 if ( this.comparator.toUpperCase() == 'IS') return this.getField() + ' ' + this.comparator + ' ' + this.getValue(); 667 else if ( this.comparator.toUpperCase() == 'IS NOT') return this.getField() + ' ' + this.comparator + ' ' + this.getValue(); 668 else if ( this.comparator.toUpperCase() == 'IS IN') return this.getField() + ' ' + this.comparator + ' ' + this.getValue(); 669 else return this.getField() + ' ' + this.comparator + ' "' + this.getValue() + '"'; 670 }; 671 672 this.validate = function ( entity ) { 673 674 675 // check if entity data corresponds to filter 676 // Filter Value is STRING! 677 // und wird umgewandelt: FILTER TYPE von STRING nach ENTITY TYPE um 678// console.log(this); 679// console.log(entity); 680// console.log(this.getField()); 681 682 var field = entity.fields[ this.getField() ]; 683 if (typeof field === 'undefined') return false;
683 // FIELD DOES NOT EXIST, RETURN FALSE; 684 685 var entityValue = field.get(); 686 var filterValue = convertValue( this.getValue(), 'string', field.type ); 687 688 if ( isTypeLikeString (field.type) ) { 689 if (typeof entityValue === 'undefined') entityValue = ''; 690 entityValue = entityValue.toUpperCase(); 691 filterValue = filterValue.toUpperCase(); 692 } 693 694 695 696 if (isset(this.comparator) == false || this.comparator == '=') 697 { 698 /* 699 alert(typeof this.getValue()); 700 alert(typeof this.value); 701 alert(typeof entity.get(this.getField())); 702 alert(typeof convertValue(this.getValue(), 'string', 'binary')); 703 */ 704 705 return entityValue == filterValue; 706 } 707 else if (this.comparator == "!=" || this.comparator == "<>") 708 { 709 return entityValue != filterValue; 710 } 711 712 else if (this.comparator == "<") 713 { 714 return entityValue < filterValue; 715 } 716 717 else if (this.comparator == ">") 718 { 719 if (isTypeLikeString (field.type)) filterValue += '_'; 720 return entityValue > filterValue; 721 } 722 723 else if (this.comparator == "<=") 724 { 725 if (isTypeLikeString (field.type)) filterValue += '_'; 726 return entityValue <= filterValue; 727 } 728 else if (this.comparator == ">=") 729 { 730 return entityValue >= filterValue; 731 } 732 else if (this.comparator == "*") // LIKE 733 { 734 return entity.get( this.getField(), 'string' ).toLowerCase().indexOf( this.getValue().toLowerCase() ) !== -1; 735 } 736 737 738/* 739 if ($filter["comparator"] == "LIKE") 740 { 741 // ENTFERNE % AM ENDE UND AM ANFANG 742 $needle = substr($filter["field2"], 1, -1); 743 if (stripos($entity->get($filter["field1"]), $needle) !== false) $result = true; 744 } 745 746 */ 747 } 748 749} 750 751 752Sorter = function(iniParams) { 753 this.direction = 'ASC'; 754 $.extend( this, iniParams ); 755} 756 757Limiter = function(iniParams) { 758 this.from = 0; 759 this.amount = 0; 760 $.extend( this, iniParams ); 761} 762 763 764 765 766 767View = function(url) { 768 this.name = 'undefined'; 769 this.fields = new Object(); 770 this.resolutions = new Object(); 771 772 773 this.getBlankEntity = function( forcedFilters ) 774 { 775 var entity; 776 777 if ( typeof this.xmlRoot !== 'undefined' ) entity = XMLStorage.getEntity( this ); 778 else if ( typeof this.data !== 'undefined' ) entity = ObjectStorage.getEntity( this ); 779 else entity = new Entity(); 780 entity.isNew = true; 781 entity.setView(this); 782 783 for (var index in this.fields) 784 { 785 //console.log(this.fields[index]); 786 if (isset(this.fields[index]['default'])) { 787 entity.data[index] = entity.fields[index].getDefault(); 788 entity.fields[index].dataStatus = STATUS_CHANGED; 789// entity.data[index] = convertValue(this.fields[index]['default'], 'string', this.fields[index]['type']); 790 791 } 792 else if (this.fields[index]['type'] == 'boolean' ) entity.data[index] = false; 793 else if (this.fields[index]['type'] == 'string' || this.fields[index]['type'] == 'html' || this.fields[index]['type'] == 'varchar') entity.data[index] = ''; 794 } 795 796 entity.forceFilters( forcedFilters ); 797 //entity.dataStatus = STATUS_NEW; 798 entity.getPrimaryField().set(Model.nextBlankId()); 799 800 801 //console.log('NEW ENTITY'); 802 //console.log(entity); 803 804 //?? 805 entity.status(STATUS_NEW); 806 // $(document).trigger('entityDisplayReady', entity); 807 $(document).triggerHandler('entityReady_' + entity.viewName, entity); 808 $(document).triggerHandler('entityReady', entity); 809 810 $(document).triggerHandler('blankEntity_' + entity.viewName, entity); 811 $(document).triggerHandler('blankEntity', entity); 812 return entity; 813 } 814 815 this.getTitle = function() { 816 if ( typeof this.title == 'string') return this.title; 817 else return this.name; 818 } 819 820 this.getFieldTitle = function( fieldName ) { 821 if ( typeof this.fields[ fieldName ].title === 'string') return this.fields[ fieldName ].title; 822 else return this.fields[ fieldName ].name.toLowerCase().replace(/(^| )(\w)/g, function(x) { return x.toUpperCase() }).replace('_', ' '); 823 824 825 826 827 } 828 829 830 831 this.getPrimaryField = function getPrimaryField() { 832 for (var index in this.fields) { 833 if (isset(this.fields[index]['index']) && this.fields[index]['index'].toUpperCase() == 'PRIMARY') return this.fields[index]; 834 } 835 } 836 837 this.getPrimaryEntity = function( id, callback, type, async) { 838 //console.log('GET'); 839 //console.log(this); 840 if (typeof async === 'undefined') async = true; 841 842 var primaryField = this.getPrimaryField(); 843 if (isset( type )) id = convertValue(id, type, 'string'); 844// var set = 845 new EntitySet({query: new Query('VIEW ' + this.name + ' WHERE '+ primaryField['name'] +' = "' + id + '"'), callback: function( set ){ 846// alert('AS'); 847 for (var index in set.entities) { 848 EntityCache.add(set.entities[index]); 849 if (isset(callback)) callback(set.entities[index]); 850 } 851 }}, async); 852// console.log(set); 853 854// $(set).on('ready', function() { 855// 856// for (var index in set.entities) { 857// EntityCache.add(set.entities[index]); 858// if (isset(callback)) callback(set.entities[index]); 859// 860// 861// } 862// }); 863 864 } 865 866 /* 867 this.getData = function(additionalFilters) 868 { 869 // LOCAL ONLY 870 } 871 */ 872
873 874 875 this.loadXML = function(url, callback, async) 876 { 877 if (typeof async === 'undefined') async = true; 878 879 var view = this; 880 881 882 FileCache.load({ 883 async: async, 884 url: url, 885 context: this, 886 dataType: 'xml', 887 888 done: function(data){ 889 890 // parse XML 891 892 var xml = $(data); 893 894 xml.find('>view').children().each(function() { 895 896 // Parse View Params 897 898 var xmlTag = $(this); 899 var viewPropertyName = xmlTag.prop("tagName"); 900 901 if (viewPropertyName != 'fields' && viewPropertyName != 'resolutions') 902 { 903 /* 904 console.log('yyyy'); 905 console.log(viewPropertyName); 906 console.log(xmlTag.text()); 907 //console.log(xmlTag[0].innerHTML); 908 //console.log(xmlTag.html()); 909 console.log('yyyy2'); 910 */ 911 912 913// var viewPropertyValue = xmlTag.html(); // VERKACKT IM IE! 914 var viewPropertyValue = xmlTag.text(); 915 view[viewPropertyName] = viewPropertyValue; 916 917 918 } 919 920 }); 921 922 923 xml.find('field').each(function(){ 924 925 // Parse Field Params 926 927 var field = new Object(); 928 var xmlField = $(this); 929 930 xmlField.children().each(function(e1, e2) { 931 var xmlTag = $(this); 932 var fieldPropertyName = xmlTag.prop("tagName"); 933 //var fieldPropertyValue = xmlTag.html(); 934 var fieldPropertyValue = xmlTag.text(); 935 936 field[fieldPropertyName] = fieldPropertyValue; 937 }); 938 view.fields[field['name']] = field; 939 940 941// field.getTitle = function( ) { 942// if ( typeof field.title === 'string') return field.title; 943// else return field.name; 944// } 945 946 }); 947 948 xml.find('resolution').each(function(){ 949 950 // Parse resolution Params 951 952 var resolution = new Object(); 953 var xmlField = $(this); 954 955 xmlField.children().each(function(e1, e2) { 956 var xmlTag = $(this); 957 var fieldPropertyName = xmlTag.prop("tagName"); 958 //var fieldPropertyValue = xmlTag.html(); 959 var fieldPropertyValue = xmlTag.text(); 960 961 if ( fieldPropertyName == 'width' ) fieldPropertyValue = parseInt( fieldPropertyValue ); 962 963 resolution[fieldPropertyName] = fieldPropertyValue; 964 }); 965 view.resolutions[resolution['name']] = resolution; 966 }); 967 968 969 970 $(view).trigger('ready'); 971 $(document).triggerHandler('viewReady', view); 972 if (typeof callback == 'function') callback(); 973 974 }}) 975 }; 976 977 if (isset(url)) this.loadXML(url); 978} 979 980function Relation() { 981 this.viewName; 982 this.relationViewName; 983 var fieldName = '## PRIMARY ##'; 984 var relationFieldName = '## PRIMARY ##'; 985 this.fieldName = function(name) { 986 if (isset( name )) fieldName = name; 987 else { 988 if (fieldName == '## PRIMARY ##') return Model.views[this.viewName].getPrimaryField().name; 989 else return fieldName; 990 } 991 } 992 993 this.relationFieldName = function(name) { 994 if (isset( name )) relationFieldName = name; 995 else { 996 997 // if ( typeof Model.views[this.relationViewName] === 'undefined' ) throw('Relation: VIEW NOT LOADED ' + this.relationViewName); 998 if ( typeof Model.views[ this.relationViewName ] === 'undefined' ) Model.loadView( this.relationViewName , undefined, false ); 999 1000 if (relationFieldName == '## PRIMARY ##') return Model.views[this.relationViewName].getPrimaryField().name; 1001 else return relationFieldName; 1002 } 1003 } 1004} 1005 1006 1007Model = new Object(); 1008Model.lastBlankId = 0; 1009Model.nextBlankId = function() 1010{ 1011 Model.lastBlankId -= 1; 1012 return Model.lastBlankId; 1013} 1014Model.views = {}; 1015Model.views_loading = {}; 1016Model.loadView = function(url, callback, async ) { 1017 // READ XML FROM URL OR VIEWNAME 1018 1019 1020 1021 var job = new Job(); 1022 job.info = 'loadView'; 1023 1024// job.hire( () => { 1025// new EntitySet().loadFromURL( 'provider/plugins/data/view/' + viewName + '/?list[filters]=*PRIMARY* = "' + idAsString + '"', function( set ){ 1026// for (var index in set.entities) { 1027// EntityCache.add(set.entities[index]); 1028// if ( typeof callback === 'function') callback(set.entities[index]); 1029// console.log( set.entities[index] ); 1030// 1031// job.doSuccess( set.entities[index] ); 1032// return; 1033//// return ( set.entities[index] ); 1034// } 1035// job.failed( new Error('Primary Entity "'+ idAsString +'"not found.') ); 1036// return; 1037// 1038// }, async); 1039// }); 1040// 1041// job.do();
1042 1043 1044 1045 1046 1047 1048 1049 1050 if (typeof Model.views[ url ] !== 'undefined') { 1051 if (typeof callback === 'function') callback(); 1052 job.doSuccess(); 1053 return Model.views[ url ]; 1054 } 1055 1056 if (typeof Model.views_loading[ url ] === 'undefined') { 1057 Model.views_loading[ url ] = []; 1058 if (typeof callback === 'function') Model.views_loading[ url ].push( callback ); 1059 1060 if (url.substr(url.lastIndexOf('.') + 1).toLowerCase() == 'xml'){ 1061 var newView = new View(); 1062 $(newView).on('ready', function(){Model.views[newView.name] = newView}); 1063 newView.loadXML(url, callback); 1064 return newView; 1065 }; 1066 1067 var viewLoader = new EntitySet(); 1068 viewLoader.loadFromURL( 'provider/plugins/data/view/' + url + '/?list[filters]=false', function(){ 1069 // callback(); 1070 for (var index in Model.views_loading[ url ]){ 1071 Model.views_loading[ url ][ index ](); 1072 } 1073 1074 delete Model.views_loading[ url ]; 1075 job.doSuccess(); 1076 }, async); 1077 return job; 1078 } 1079 if (typeof callback === 'function') Model.views_loading[ url ].push( callback ); 1080 1081 1082 1083 return job; 1084 1085} 1086 1087Model.addView = function( view ){ 1088 // TRIGGERS READY 1089 // NEEDED IF CHANGES TO FIELDS ARE MADE BEFORE ENTITIES ARE CREATED 1090 $(view).trigger('beforeReady'); 1091 $(Model).trigger('beforeViewReady', view); 1092 $(Model).trigger('beforeViewReady_' + view.name, view); 1093 $(document).triggerHandler('beforeViewReady', view); // LEGACY 1094 Model.views[view.name] = view; 1095 $(view).trigger('ready'); 1096 $(Model).trigger('viewReady', view); 1097 $(Model).trigger('viewReady_' + view.name, view); 1098 $(document).triggerHandler('viewReady', view); // LEGACY 1099} 1100 1101 1102 1103Model.getPrimaryEntity = function( viewName, idAsString, callback, async){ 1104 // WORKS WITHOUT LOADING VIEW FIRST 1105 // ID MUST BE STRING 1106 if (typeof async === 'undefined') async = true; 1107 1108 var job = new Job(); 1109// console.clear(); 1110// console.log( job ); 1111// job.success.hire(function(){alert('test')}); 1112 job.info = 'getPrimaryEntity'; 1113 1114// job.hire( () => { 1115 new EntitySet().loadFromURL( 'provider/plugins/data/view/' + viewName + '/?list[filters]=*PRIMARY* = "' + idAsString + '"', function( set ){ 1116 for (var index in set.entities) { 1117 EntityCache.add(set.entities[index]); 1118 if ( typeof callback === 'function') callback(set.entities[index]); 1119 console.log( set.entities[index] ); 1120 job.result = set.entities[index]; 1121 job.doSuccess( job.result ); 1122 return; 1123// return ( set.entities[index] ); 1124 } 1125 job.result = new Error('Primary Entity "'+ idAsString +'"not found.'); 1126 job.doFail( job.result ); 1127 return; 1128 1129 }, async); 1130// }); 1131// job.do(); 1132 return job; 1133} 1134 1135 1136Model.relations = {}; 1137$(document).on('viewReady', function(event, view) { 1138 if (isset(Model.relations[view.name]) == false) Model.relations[view.name] = {}; 1139 1140 for (var index in view.fields) { 1141 if (isset(view.fields[index].foreign)) { 1142 // create relation 1143 var relation = new Relation(); 1144 relation.viewName = view.name; 1145 relation.fieldName( index ); 1146 relation.relationViewName = view.fields[index].foreign; 1147 relation.relationFieldName( '## PRIMARY ##' ); 1148 if (isset( view.fields[index].foreign_name )) relation.name = view.fields[index].foreign_name; 1149 else relation.name = view.fields[index].foreign; 1150 Model.relations[view.name][relation.name] = relation; 1151 1152 var invertedRelation = new Relation(); 1153 1154 invertedRelation.name = view.name; 1155/* if (isset( view.fields[index].foreign_name )) invertedRelation.name = view.fields[index].foreign_name; 1156 else invertedRelation.name = view.name; 1157// else invertedRelation.name = view.fields[index].foreign; 1158*/ 1159 1160 invertedRelation.relationViewName = view.name; 1161 invertedRelation.relationFieldName( index ); 1162 invertedRelation.viewName = view.fields[index].foreign; 1163 invertedRelation.fieldName('## PRIMARY ##'); 1164 1165 if (isset(Model.relations[invertedRelation.viewName]) == false) Model.relations[invertedRelation.viewName] = {}; 1166 Model.relations[invertedRelation.viewName][invertedRelation.name] = invertedRelation; 1167 1168 1169 } 1170 } 1171 1172}); 1173 1174 1175 1176 1177EntityStorage = new Object(); 1178 1179//EntityStorage.sets = new Object(); 1180EntityStorage.sets = undefined; 1181 1182EntityStorage.baseName = 'Entity::'; 1183if (isset('APP_NAME')) EntityStorage.baseName = 'Entity::' + APP_NAME + '_'; 1184 1185 1186 1187EntityStorage.store = function (entity) 1188{ 1189 console.log('Store Entity'); 1190 localStorage.setObj(this.baseName + ':::' + entity.viewName +':::'+ '_'+ entity.getPrimary('string'), entity.data); 1191 if (isset(EntityStorage.sets[entity.viewName]) == false) EntityStorage.sets[entity.viewName] = new EntitySet(); 1192 EntityStorage.sets[entity.viewName].add(entity); 1193 1194} 1195 1196EntityStorage.load = function() 1197{ 1198 var sets = {}; 1199 for (var key in localStorage){
1200 if (key.substring(0, EntityStorage.baseName.length) == EntityStorage.baseName) 1201 { 1202 var viewName = key.split(":::")[1]; 1203 1204 if (isset(sets[viewName]) == false) sets[viewName] = new EntitySet(); 1205 1206 console.log(key); 1207 var entity = Model.views[viewName].getBlankEntity(); 1208 //var entity = new Entity(); 1209 entity.data = localStorage.getObj(key); 1210 console.log(entity); 1211 sets[viewName].add(entity); 1212 } 1213 } 1214 EntityStorage.sets = sets; 1215// return sets; 1216} 1217 1218EntityCache = new Object(); 1219EntityCache.entityCache = {}; 1220EntityCache.setCache = {}; 1221 1222EntityCache.add = function ( entity ) 1223{ 1224 if ( isset( entity.viewName) == false) entity.viewName = 'unknown'; 1225 if ( isset( EntityCache.entityCache[ entity.viewName ]) == false ) 1226 { 1227 EntityCache.entityCache[entity.viewName] = new EntitySet(); 1228 EntityCache.entityCache[entity.viewName].name = entity.viewName; 1229 1230 $(EntityCache).trigger('setAdded', EntityCache.entityCache[entity.viewName]); 1231 } 1232// console.log('ADDED ENTITY ' + entity.getPrimary()); 1233 1234 // CHECK IF CACHE ALREADY CONTAINS ENTITY 1235 if (typeof EntityCache.entityCache[ entity.viewName ].entities[entity.getPrimary()] === 'undefined') { 1236 EntityCache.entityCache[ entity.viewName ].add( entity ); 1237 } 1238} 1239 1240EntityCache.restore = function() 1241{ 1242 console.log('restoreAll'); 1243 for (var index in EntityCache.entityCache) 1244 EntityCache.entityCache[index].restore(); 1245} 1246 1247EntityCache.store = function( ) 1248{ 1249 // params.callback 1250 // params.progress 1251 1252 console.log('storeAll'); 1253 console.log( EntityCache.entityCache); 1254 var counterEntities = 0; 1255 var counterCompleted = 0; 1256 var counterDeleted = 0; 1257 var counterChanged = 0; 1258 var fails = 0; 1259 1260 var arrStore = []; 1261 var arrDelete = []; 1262 1263 1264 var saveJob = new Job(); 1265 saveJob.info = 'EntityCache.store'; 1266 1267 1268/* 1269 1270 for (var index in EntityCache.entityCache) { 1271 for (var id in EntityCache.entityCache[index].trash) { 1272// saveJob.hire( EntityCache.entityCache[index].trash[id].store() ); 1273// saveJob.hire( EntityCache.entityCache[index].entities[id].jobs('store') ); 1274 saveJob.hire( EntityCache.entityCache[index].trash[id].store, true ); 1275 } 1276 for (var id in EntityCache.entityCache[index].entities) { 1277 if (EntityCache.entityCache[index].entities[id].status() != STATUS_UNCHANGED) { 1278 1279 // liefert storeBefore Job! 1280 // saveJob.hire( EntityCache.entityCache[index].entities[id].store() ); 1281 // saveJob.hire( EntityCache.entityCache[index].entities[id].jobs('store') ); 1282 saveJob.hire( EntityCache.entityCache[index].entities[id].store, true ); 1283 1284 1285 1286 1287 1288// EntityCache.entityCache[index].entities[id].store() ; 1289// saveJob.hire( EntityCache.entityCache[index].entities[id].events.get('store') ); 1290 1291 } 1292 } 1293 } 1294*/ 1295 1296 var changes = EntityCache.getChanges(); 1297 for (var index in changes ){ 1298 saveJob.hire( changes[index].store, true ); 1299 } 1300 1301 saveJob.doSuccess(); 1302 console.log( saveJob ); 1303 1304 return saveJob; 1305 1306 /* OLD 1307 1308 var callbackOfEntities = function( result ) { 1309 counterCompleted++; 1310 console.log( 'result' ); 1311 console.log( counterCompleted +' - ' + counterEntities ); 1312 console.log( result ); 1313 if ( result.success == false ) { 1314 fails++; 1315 } else { 1316 if (result.action == 'store') counterChanged++; 1317 else if (result.action == 'delete') counterDeleted++; 1318 } 1319 if (typeof params.progress === "function") params.progress ( { 'fails': fails, 'completed': counterCompleted, 'changed': counterChanged, 'deleted': counterDeleted, 'amount': counterEntities} ); 1320 1321 if ( counterEntities == counterCompleted ) { 1322 if (typeof params.callback === "function") params.callback( { 'fails': fails, 'completed': counterCompleted, 'changed': counterChanged, 'deleted': counterDeleted, 'amount': counterEntities} ); 1323 } 1324 1325 }; 1326 1327 // CHECK HOW MANY ENTITIES HAVE BEEN CHANGED 1328 for (var index in EntityCache.entityCache) { 1329// counterEntities += EntityCache.entityCache[index].countTrash;
1330 for (var id in EntityCache.entityCache[index].trash) { 1331 counterEntities++; 1332 arrStore.push( EntityCache.entityCache[index].trash[id] ); 1333 } 1334 for (var id in EntityCache.entityCache[index].entities) { 1335 if (EntityCache.entityCache[index].entities[id].status() != STATUS_UNCHANGED) { 1336 counterEntities++; 1337 arrStore.push( EntityCache.entityCache[index].entities[id] ); 1338 } 1339 } 1340 } 1341 1342 if (counterEntities == 0 && typeof params.callback === "function") params.callback( { 'fails': fails, 'completed': counterCompleted, 'changed': counterChanged, 'deleted': counterDeleted, 'amount': counterEntities} ); 1343 1344 console.log(arrStore); 1345// alert('sotre'); 1346 1347 for (var index in arrStore) { 1348 arrStore[index].store( { callback: callbackOfEntities }); 1349 } 1350 */ 1351 1352 1353} 1354 1355 1356 1357 1358EntityCache.getChanges = function( ) { 1359 var result = []; 1360 for (var index in EntityCache.entityCache) { 1361 for (var id in EntityCache.entityCache[index].trash) { 1362 result.push( EntityCache.entityCache[index].trash[id] ); 1363 } 1364 for (var id in EntityCache.entityCache[index].entities) { 1365 if (EntityCache.entityCache[index].entities[id].status() != STATUS_UNCHANGED) { 1366 result.push( EntityCache.entityCache[index].entities[id] ); 1367 } 1368 } 1369 } 1370 return result; 1371} 1372 1373 1374 1375 1376 1377 1378$(document).on('readyOnce', function() { 1379 1380 if (typeof READY_FLAG_DATA != 'undefined') return; READY_FLAG_DATA = 1; 1381 1382 // PARSING PAGES ITEMS ONLY! 1383 // OTHER FIELDS AND ENTITIES DISABLED 1384 1385 1386 console.log('scanning html'); 1387 $('[data-structure="field"][data-view="pages_items"]').each(function(){ 1388// $('[data-structure="field"]').each(function(){ 1389 1390// var entity = Model.views['pages_items'].getBlankEntity(); 1391 1392 1393 var id; 1394 var view; 1395 var fieldName; 1396 var entity; 1397 var type; 1398 var value; 1399 var format = ''; 1400 1401 //console.log('display'); 1402 //console.log($(this).html() + ' ' + $(this).attr('data-field')); 1403 1404//console.log(this); 1405 1406 if (isset($(this).attr('data-raw'))) value = $(this).attr('data-raw'); 1407 else value =$(this).html(); 1408 1409 1410 if (isset($(this).attr('data-id'))) id = $(this).attr('data-id'); 1411 else view = $(this).parent().attr('data-id'); 1412 1413 if (isset($(this).attr('data-view'))) view = $(this).attr('data-view'); 1414 else view = $(this).parent().attr('data-view'); 1415 1416 if (isset($(this).attr('data-field'))) fieldName = $(this).attr('data-field'); 1417 else view = $(this).parent().attr('data-field'); 1418 1419 if (isset($(this).attr('data-type'))) type = $(this).attr('data-type'); 1420 else type = $(this).parent().attr('data-type'); 1421 1422 if (isset($(this).attr('data-format'))) format = $(this).attr('data-format'); 1423 else if (isset($(this).parent().attr('data-format'))) format = $(this).parent().attr('data-format'); 1424 1425 if (isset(EntityCache.entityCache[view]) && isset(EntityCache.entityCache[view].entities[id])) entity = EntityCache.entityCache[view].entities[id]; 1426 else { 1427 entity = new Entity(id); 1428 entity.addField('id', id, 'string'); 1429 entity.viewName = $(this).attr('data-view'); 1430 EntityCache.add(entity); 1431 } 1432 1433 var field = entity.addField(fieldName, convertValue(value, 'html', type), type); 1434 //field.attribute('format', format); 1435 field.format = format; 1436 1437 var display = $(this); 1438 1439 display.data('entity', entity); 1440 display.data('field', field); 1441 1442 $(field).on('changed', display, field.defaultOnChangeHandler); 1443 1444 1445 if (field.format != '') display.html(field.getForWeb()); 1446 1447 1448 $(document).trigger('fieldDisplayReady', display); 1449 1450 }); 1451 1452 1453 $(EntityCache).trigger('parseCompleted'); 1454 1455 1456 /* 1457 $('[data-structure="entity"]').each(function(){ 1458 var display = $(this); 1459 1460 var viewName = display.attr('data-view'); 1461 1462 if (isset( EntityCache.entityCache[viewName] && isset( EntityCache.entityCache[viewName].entities[display.attr('data-id')])) ) 1463 { 1464 display.data('entity', EntityCache.entityCache[viewName].entities[display.attr('data-id')]); 1465 1466 //$(DataCache).triggerHandler('entityReady', DataCache.sets[set].entities[id]); 1467 1468 $(EntityCache.entityCache[viewName]).triggerHandler('entityAdded', EntityCache.entityCache[viewName].entities[display.attr('data-id')]); 1469 1470 if (isset(display.data('entity').view)) $(document).trigger('entityDisplayReady_' + display.data('entity').view.name, display); 1471 $(document).trigger('entityDisplayReady', display); 1472 1473 } 1474 1475 1476 }); 1477 */ 1478 1479}); 1480 1481 1482 1483 1484 1485EntityField = function(entity, name) { 1486 this.entity = entity; 1487 this.name = name; 1488 this.format = ''; 1489 1490 this.dataStatus = STATUS_UNCHANGED; 1491 1492 this.syncFields = []; 1493 1494 this.status = function(newStatus) 1495 { 1496 if (isset(newStatus) == false) return this.dataStatus; 1497 this.dataStatus = newStatus; 1498 } 1499 1500 1501 1502 this.get = function(outputType, format) 1503 { 1504 /* 1505 if (this.name == 'text') { 1506 console.log('FIELD: ');
1507 console.log(this); 1508 alert(this.attribute('type')+ ' - ' + this.entity.data[this.name]); 1509 } 1510 */ 1511 var value = convertValue(this.entity.data[this.name], this.attribute('type'), outputType, format); 1512// if ( isNaN(value) ) { 1513// value = this.getDefault(); 1514// } 1515 return value; 1516 }; 1517 1518 this.getForWeb = function(format) 1519 { 1520 1521 if (isset(format) == false) 1522 { 1523 format = this.attribute('format'); 1524 } 1525 1526 //console.log('FORMAT:'); 1527 //console.log(this.attribute('format')); 1528 //console.log(format); 1529//alert(this.get('html', format)); 1530 return this.get('html', format); 1531 }; 1532 1533 1534 1535 this.set = function(value, inputType, inputFormat, silent) 1536 { 1537 // IF value = Entity - set Primary to field value 1538 if (value instanceof Entity ) { 1539 inputType = this.attribute('type'); 1540 value = value.getPrimary( this.attribute('type') ); 1541 } 1542 1543 1544 if ( (inputFormat == 'HH:mm' || inputFormat == 'HH:mm:ss') && this.attribute('type') == 'datetime' ) { 1545 // SPECIAL CASE 1546 // SETTING TIME TO DATETIME KEEPS OLD DATE 1547 var dateString = this.get('string', 'YYYY-MM-DD'); 1548 value = dateString + ' ' + value; 1549 inputFormat = 'YYYY-MM-DD ' + inputFormat; 1550 console.log( value ); 1551 value = convertValue(value, inputType, this.attribute('type'), null, inputFormat); 1552 if (value == 'Invalid Date') value = convertValue(dateString, inputType, this.attribute('type'), null, 'YYYY-MM-DD'); 1553 console.log( value ); 1554 } 1555 1556 value = convertValue(value, inputType, this.attribute('type'), null, inputFormat); 1557 1558 // CHECK IF INVALID NUMBER (NaN) 1559 // !!! IMPORTANT NaN === NaN; // false !!! 1560 // In that case use default value 1561 if ( value !== value) { 1562 if (typeof this.attribute('default') !== 'undefined') value = this.getDefault(); 1563 } 1564 1565 var oldValue = this.entity.data[this.name]; 1566 1567 // LEAVE AND DO NOT TRIGGER CHANGE IF VALUE UNCHANGED. CANNOT DETERMINE CHANGES ON DATE OBJECT 1568 if ( oldValue == value && value instanceof Date == false ) return; 1569 1570 1571 if (this.dataStatus == STATUS_CHANGING) return; // PREVENT EVENT CIRCUITS 1572 1573 if (isset(silent) == false) silent = false; 1574 1575 var oldStatus = this.status(); 1576 this.status(STATUS_CHANGING); 1577 1578 var params = { field: this, oldValue: oldValue, newValue: value }; 1579 1580 if (silent == false) $(this.entity).trigger( "beforeChanged", this.name ); 1581 if (silent == false) { 1582 $(this).trigger("beforeChanged", params ); 1583 if ( value != params.newValue) { 1584 value = params.newValue; 1585 if (value == oldValue) { 1586 this.status( oldStatus ); 1587 return; 1588 } 1589 } 1590 1591 1592 } 1593 1594 1595 //this.dataStatus = STATUS_CHANGING; 1596 1597 //console.log('TRIGGER'); 1598 //console.log(silent); 1599 1600 1601 if (isset(this.entity.dataArchive[this.name]) == false) 1602 { 1603 this.entity.dataArchive[this.name] = []; 1604 } 1605 this.entity.dataArchive[this.name].push(this.entity.data[this.name]); 1606 1607 1608 //console.log(this.entity.dataArchive); 1609 1610 this.entity.data[this.name] = value; 1611 1612 // ENTITY STATUS MUST BE CHANGED TO STATUS_CHANGED 1613 // OTHERWISE ENTIY STATUS IS NOT SET CORRECTLY IN TRIGGERED FIELD CHANGED METHODS 1614 // THEREFORE STORE CURRENT ENTITY STATUS. SET QUIET. RESET. UPDATE WITH TRIGGER 1615 1616 var oldEntityStatus = this.entity.status();
1617 this.entity.dataStatus = STATUS_CHANGED; //SET QUIET 1618 1619 if (silent == false) $(this).trigger("changed", { field: this, oldValue: oldValue, newValue: value } ); 1620 1621 if (silent == false) $(this.entity).trigger( "changed", this.name ); 1622 if (silent == false) $(document).trigger( "entityChanged", { entity: this.entity, field: this.name, oldValue: oldValue, newValue: value } ); 1623 1624 this.status(STATUS_CHANGED); // ENTIY STATUS WAS SET TO CHANGED QUIETLY BEFORE 1625 1626 this.entity.dataStatus = oldEntityStatus; // RESET 1627 this.entity.status(STATUS_CHANGED); // UPDATE WITH TRIGGER 1628 1629 }; 1630 1631 this.getDefault = function() { 1632 if (typeof this.attribute('default') !== 'undefined') return convertValue(this.attribute('default'), 'string', this.attribute('type')); 1633 return; 1634 } 1635 1636 1637 this.attribute = function(attributeName, value) 1638 { 1639 var view; 1640 if (typeof this.entity.view !== 'undefined') view = this.entity.view; 1641 else if (typeof this.entity.viewName !== 'undefined') view = Model.views[ this.entity.viewName ]; 1642 1643 if (typeof view == 'undefined') 1644 { 1645// console.log('No VIEW'); 1646 // console.log(attributeName); 1647 // console.log(this[attributeName]); 1648 return this[attributeName]; 1649 } 1650 1651 //console.log(this.entity.view.fields[this.name][attributeName]); 1652 //console.log(attributeName); 1653 //console.log(this.entity.view.fields); 1654 /* 1655 console.log('--- VIEW'); 1656 console.log(this.entity.view); 1657 console.log(value); 1658 console.log(attributeName); 1659 console.log(this.entity.view.fields[name][attributeName]); 1660 */ 1661 1662 if (typeof(value) !== 'undefined') view.fields[name][attributeName] = value; 1663 else return view.fields[name][attributeName]; 1664 1665 } 1666 1667 this.getRelationViewName = function(){ 1668 1669 if (typeof this.attribute('foreign') === 'undefined') return false; 1670 return this.attribute('foreign'); 1671 } 1672 1673 this.getRelationView = function(){ 1674 1675 if (typeof this.attribute('foreign') === 'undefined') return false; 1676 // VIEW MUST BE LOADED BEFORE RETURN 1677// alert( this.attribute('foreign') ); 1678 if (typeof Model.views[ this.attribute('foreign') ] === 'undefined') { 1679 Model.loadView( this.attribute('foreign'), null, false); 1680 } 1681 return Model.views[ this.attribute('foreign') ]; 1682 } 1683 1684 this.getForeignView = function(){ 1685 // LEGACY 1686 return this.getRelationView(); 1687 } 1688 1689 1690 this.toAttribute = function( element, attributeName, ){ 1691 var field = this; 1692 if ( typeof attributeName === 'undefined' ) attributeName = 'data-field-' + field.name; 1693 $(this).on('changed', function( event ){ 1694 $(element).attr( attributeName, field.get('string' )); 1695 }); 1696 $(element).attr( attributeName, field.get('string' )); 1697 } 1698 1699 1700 this.toDisplay = function( options ) 1701 { 1702 var display = null; 1703 var tagName; 1704 var label; 1705 var format; 1706 var type; 1707 var field = this; 1708 1709 if (typeof (options) == 'undefined') tagName = 'div'; 1710 else { 1711 if (typeof options == 'object') { 1712 if (options instanceof jQuery) display = options; // options = element = display 1713 else { 1714 tagName = options.tagName; 1715 format = options.format; 1716 label = options.label; 1717 type = options.type; 1718 } 1719 } else tagName = options; 1720 } 1721 1722 if ( label === true ) label = this.getLabel(); 1723 1724 1725 if (typeof (tagName) == 'undefined') tagName = 'div'; 1726 1727 if (typeof (type) == 'undefined') { 1728 if ( typeof display !== 'undefined' && display != null && display.hasAttr('data-type') ) type = display.attr('data-type');
1729 else type = this.attribute('type'); 1730 } 1731 1732 if (typeof (format) == 'undefined') { 1733 if (typeof display !== 'undefined' && display != null && display.hasAttr('data-format') ) format = display.attr('data-format'); 1734 else format = this.attribute('format'); 1735 } 1736 1737 if (display == null) { 1738 var displayString = '<' + tagName + '></' + tagName + '>'; 1739// alert(displayString); 1740 display = $(jQuery.parseHTML(displayString)); 1741 } 1742 1743 display.attr('data-structure', 'field'); 1744 1745 display.attr('data-type', type); 1746 1747 display.attr('data-field', this.name); 1748 1749 display.attr('data-format', format); 1750 1751 1752 1753 1754 1755 // Get FORMAT from Attribute 1756 // Use FORMAT presets for special types 1757 // element type might differ from entity field type 1758 if (typeof format === 'undefined') { 1759 var attrType = display.attr('data-type'); 1760 if ( attrType == 'date') format = 'L'; 1761 else if ( attrType == 'datetime') format = 'L LT'; 1762 else if ( attrType == 'time') format = 'HH:mm'; 1763 } 1764 1765// if ( field.type == 'datetime' ) display.attr('data-value', field.get('string', 'YYYY-MM-DD HH:mm:ss')); 1766// else if ( field.type == 'time' ) display.attr('data-value', field.get('string', 'HH:mm:ss')); 1767// else display.attr('data-value', field.getForWeb()); 1768 1769// display.html(field.getForWeb( format )); 1770 1771// alert( format + ' ' + value ); 1772 1773 1774 1775 var value; // CONTENT THAT IS DISPLAYED 1776 if ( type == 'boolean') { 1777 if (this.get() == 1) value = '<span data-icon="1"></span>'; 1778 else value = '<span data-icon="0"></span>'; 1779 } 1780 else if ( type == 'password') { 1781 value = ''; 1782 for (var i=0; i<field.get('string').length; i++) value += '•' 1783 } 1784 1785 else if ( type == 'link' ) { 1786 var linkContent = options.content || this.getForWeb(); 1787 var url = this.get('string').trim(); 1788 if ( isEmail(url) ) url = 'mailto:' + url; 1789 else { 1790 if (url.substring(0, 4).toLowerCase() == 'www.') url = 'http://' + url; 1791 } 1792 var target = ''; 1793 if (typeof options.target !== 'undefined') target = ' target="'+options.target +'"'; 1794 value = '<a href="'+ url + '"'+target+'>' + linkContent + '</a>'; 1795 if (url == '') value = ''; 1796 } 1797 else value = this.getForWeb( format ); 1798 1799 1800 if( display.prop("tagName") == 'INPUT' ) display.val( value ); 1801 else display.html( value ); 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 display.attr('data-label', label || this.attribute('label')); 1812 display.attr('data-id', this.entity.getPrimary('string')); 1813 display.attr('data-view', this.entity.viewName); 1814// console.log(this.name); 1815// console.log(this); 1816 1817 // Get Additional Field Attributes from VIEW 1818 for (var index in Model.views[this.entity.viewName].fields[name] ){ 1819 var fieldAttribute = Model.views[this.entity.viewName].fields[ name ][ index ]; 1820 if (index != 'name' && index != 'type' && index != 'title' && index != 'size' && typeof fieldAttribute != 'function' && typeof fieldAttribute != 'object' && display.hasAttr('data-' + index) == false) { 1821 // console.log('data-' + index); 1822 // console.log(fieldAttribute); 1823 display.attr('data-' + index , fieldAttribute); 1824 } 1825 1826 1827 } 1828 1829 1830 display.attr('data-value', this.getForWeb('plain')); 1831 1832 display.data('entity', this.entity); 1833 display.data('field', this); 1834
1835 if( display.prop('tagName') == 'SELECT') { 1836 display.find('[value]:not([value="' + field.getForWeb() + '"])').removeAttr('selected'); 1837 display.find('[value="' + field.getForWeb() + '"]').attr('selected', 'selected'); 1838 } 1839 1840 1841 1842 this.defaultOnChangeHandler = function(event){ 1843// var display = $(event.data[0]); 1844// var field = this; 1845 1846 console.log('refresh'); 1847 //console.log(event); 1848 //console.log(display); 1849 1850 var autoRefresh = display.triggerHandler('needRefresh', event); 1851 if (isset(autoRefresh) == false) autoRefresh = true; 1852 1853 if (autoRefresh) 1854 { 1855 // Get FORMAT from Attribute 1856 // Use FORMAT presets for special types 1857 // element type might differ from entity field type 1858 format = display.attr('data-format'); 1859// alert(format); 1860 if (typeof format === 'undefined') { 1861 var attrType = display.attr('data-type'); 1862 if ( attrType == 'date') format = 'L'; 1863 else if ( attrType == 'datetime') format = 'L LT'; 1864 else if ( attrType == 'time') format = 'HH:mm'; 1865 } 1866 1867// if ( field.type == 'datetime' ) display.attr('data-value', field.get('string', 'YYYY-MM-DD HH:mm:ss')); 1868// else if ( field.type == 'time' ) display.attr('data-value', field.get('string', 'HH:mm:ss')); 1869// else 1870// 1871 display.attr('data-value', field.getForWeb('plain')); 1872 1873 1874 if ( display.attr('data-type') == 'link') { 1875 var linkContent = field.getForWeb(); 1876 var url = field.get().trim(); 1877 if ( isEmail(url) ) url = 'mailto:' + url;
1878 var link = display.find('>a'); 1879 link.attr('href', url); 1880 link.html( field.getForWeb() ); 1881 } 1882 else 1883 if ( display.attr('data-type') == 'boolean') { 1884 if (field.get() == 1) display.html('<span data-icon="1"></span>'); 1885 else display.html('<span data-icon="0"></span>'); 1886 } else if ( type == 'password') { 1887 var text = ''; 1888 for (var i=0; i<field.get('string').length; i++) text += '•' 1889 display.html( text ); 1890 } 1891 else if( display.prop('tagName') == 'SELECT') { 1892 display.find('[value]:not([value="' + field.getForWeb() + '"])').removeAttr('selected'); 1893 display.find('[value="' + field.getForWeb() + '"]').attr('selected', 'selected'); 1894 } 1895 else { 1896 display.html(field.getForWeb( format )); 1897 } 1898 1899 1900 1901 } 1902 display.triggerHandler('doneRefresh', event); 1903 1904 }; 1905 1906 1907 if ( type == 'picture') { 1908// return; 1909// console.log(this); 1910// console.log(this.get()); 1911// alert(this.attribute('foreign') ); 1912// alert(this.get('string')); 1913 1914 display.html(''); 1915 1916 var path = ''; 1917 1918 if (typeof this.attribute('foreign') != 'undefined') { 1919 console.log(this); 1920 console.log(this.attribute('foreign')); 1921// if (typeof Model.views[ this.attribute('foreign') ] == 'undefined') console.log('ERROR: Picture - foreign view not loaded - ' + this.attribute('foreign') ); 1922// path = Model.views[ this.attribute('foreign') ].path; 1923 } 1924 1925 // Timeout required for CSS to apply 1926 setTimeout(function(){var module = PictureModule( { element: display, field: field } );}, 1); 1927 1928 1929 } 1930 1931 1932 1933 else if ( type == 'file') { 1934 1935 var path = ''; 1936 if (typeof this.attribute('foreign') != 'undefined') { 1937// console.log(this); 1938 path = Model.views[ this.attribute('foreign') ].path; 1939 } 1940 1941 var module = FileModule( { element: display, fileView: Model.views[ this.attribute('foreign') ], presentation: 'filename' } ); 1942 if ( this.get() != '' ) { 1943// ignoreTrigger = true; 1944 module.setFile( path + this.get() ); 1945// console.log(this); 1946 } 1947// console.log (module); 1948 1949 $(module).on('pictureSelected', function( event, url ) { 1950// console.log( 'SELECTED'); 1951// console.log( url.substring( path.length ) ); 1952// console.log( url ); 1953// console.log( module.pictureEntity.get('id')); 1954// console.log( module.pictureEntity.get('filename')); 1955 1956 field.set( url.substring( path.length ) ); // remove path from url; 1957 1958 } ); 1959 1960 $(this).on('changed', display, function( event ){ 1961 if ( this.get() != '' ) module.setPicture
1961( path + this.get() ); 1962 }); 1963 1964 } 1965 1966 else $(this).on('changed', display, this.defaultOnChangeHandler); 1967 1968 1969 //console.log('FIELD'); 1970 //console.log(display); 1971 1972 1973 1974 1975 1976 $(document).trigger('fieldDisplayReady', display); 1977 1978 return display; 1979 } 1980 1981 this.restore = function() 1982 { 1983 if (isset(this.entity.dataArchive[this.name])) 1984 { 1985 console.log('restore'); 1986 console.log(this.entity.dataArchive[this.name]); 1987 1988 this.set(this.entity.dataArchive[this.name][0]); 1989 $(this).trigger('restored', this); 1990 } 1991 1992 }; 1993 1994 1995 1996 1997 this.getLabel = function() { 1998// console.log(this); 1999// return this.entity.view.fields[this.name].getTitle(); 2000 return this.entity.view.getFieldTitle( this.name ); 2001 } 2002 2003 2004 this.isPrimary = function(){ 2005 return this.name == this.entity.getPrimaryFieldName(); 2006 } 2007 2008 2009 this.desyncWithField = function( fieldOrOptions ) { 2010 // REMOVES SYNC CONNECTION BETWEEN TWO FIELDS 2011 var field; 2012 if (typeof fieldOrOptions.field !== 'undefined') { 2013 field = fieldOrOptions.field; 2014 } else field = fieldOrOptions; 2015 2016 var thisField = this; 2017 var syncData; 2018 for (var index = this.syncFields.length-1; index >= 0; index--) { 2019 if ( this.syncFields[index].sourceField == field ) { 2020 syncData = this.syncFields[index]; 2021 // remove all events 2022 for (var eventIndex = 0; eventIndex < this.syncFields[index].eventList.length; eventIndex++) { 2023 this.syncFields[index].eventList[eventIndex].off(); 2024 } 2025 // remove syncField; 2026 this.syncFields.splice(index, 1); 2027 } 2028 } 2029 return syncData; 2030 } 2031 2032 this.syncWithField = function( fieldOrOptions ) { 2033 // Connects the fields of two different entities 2034 // Changing one field value also triggers a change of the other 2035 // If bidirectional = false or field values are different, THIS field value is changed 2036 // PRIMARY FIELDS ARE NEVER CHANGED BY SYNC!!! 2037 2038 var syncData = {}; 2039 2040 var bidirectional = true; 2041 var field; 2042 if (typeof fieldOrOptions.field !== 'undefined') { 2043 field = fieldOrOptions.field; 2044 if (typeof fieldOrOptions.bidirectional !== 'undefined') { 2045 bidirectional = fieldOrOptions.bidirectional; 2046 } 2047 2048 } else field = fieldOrOptions; 2049 2050 var thisField = this; 2051 2052 // PREVENT MULTIPLE SYNCS WITH THE SAME ENTITY.FIELD 2053 for (var index = 0; index < this.syncFields.length; index++) { 2054 if ( this.syncFields[index].sourceField == field ) return this.syncFields[index]; 2055 } 2056 2057 syncData.sourceField = field; 2058 syncData.bidirectional = bidirectional; 2059 syncData.eventList = []; // eventList used to unbind events later 2060 this.syncFields.push(syncData); 2061 // Make equal 2062 if ( thisField.get() != field.get() ) 2063 thisField.set( field.get() ); 2064 2065 2066 // trigger store if parent field was stored 2067 2068 // field.entity.store.onSuccess( () => { 2069 // thisField.entity.store( ); 2070 // }); 2071 2072/* 2073 syncData.eventList.push( $(field.entity).onEvent('stored', function(event, data) { 2074 if (thisField.entity.status() == STATUS_CHANGED) thisField.entity.store( ); 2075 }) ); 2076*/ 2077 2078 2079 // IF PARENT FIELD IS PRIMARY WAIT FOR IT TO BE STORED BEFORE STORING SELF 2080 // REQUIRED FOR PRIMARY TO BE SET BY DATABASE 2081// if ( field.entity.getPrimaryFieldName() == field.name ) { 2082 if ( field.isPrimary() ) { 2083 thisField.entity.store.onBefore.hire( () => { 2084 if ( field.entity.status() == STATUS_CHANGED || field.entity.status() == STATUS_NEW || field.entity.trash( ) ) return field.entity.store; 2085 else return true; 2086 }); 2087 2088/* 2089 syncData.eventList.push( $(thisField.entity).onEvent('beforeStored', function(event, data) { 2090// alert(field.name + ' ' + field.get() + ' ' + field.entity.status()); 2091 data.preventStore = (field.entity.status() == STATUS_CHANGED || field.entity.status() == STATUS_NEW ); 2092 }) ); 2093*/ 2094 }; 2095 2096 2097 syncData.eventList.push( $(field).onEvent('changed', function(event){ 2098 thisField.set(field.get()); 2099 }) ); 2100 2101 2102 if (bidirectional) { 2103 syncData.eventList.push( $(thisField).onEvent('changed', function(event){ 2104 if (field.isPrimary() == false) field.set(thisField.get()); 2105 }) ); 2106 } 2107 2108 return syncData; 2109 } 2110}; 2111 2112 2113function Entity(initialId) { 2114 var self = this; 2115 this.class = 'Entity'; 2116 this.data = {}; 2117 this.dataArchive = {}; 2118 this.fields = {}; 2119 this.dataStatus = STATUS_UNCHANGED; 2120 this.view = undefined; 2121 this.viewName = 'unknown'; 2122 this.entitySet = undefined; 2123 this.isNew = false; 2124 2125// var privateId = initialId; 2126 var privateTrash = false; 2127 /* 2128 this.id = function(newId) 2129 { 2130 if (isset(newId)) privateId = newId; 2131 else return privateId; 2132 } 2133 */ 2134 this.status = function(newStatus) 2135 { 2136 if (isset(newStatus) == false) return this.dataStatus; 2137 if (this.dataStatus != newStatus) { 2138 this.dataStatus = newStatus; 2139 $(this).trigger('statusChange', newStatus); 2140 } 2141 } 2142 2143 this.trash = function(trashStatus) 2144 { 2145 if (isset(trashStatus) == false) return privateTrash;
2146// console.log('TRASH'); 2147 if (privateTrash == trashStatus) return; 2148 privateTrash = trashStatus; 2149 2150 $(this).trigger("trashStatus", this); 2151 $(this).trigger("changed", this); 2152 } 2153 2154 this.set = function (fieldName, value, type, format, silent) 2155 { 2156// console.log(fieldName); 2157 if (typeof fieldName != 'string') { 2158 // FIRST VALUE IS OBJECT 2159 value = fieldName.value; 2160 type = fieldName.type; 2161 format = fieldName.format; 2162 silent = fieldName.silent; 2163 fieldName = fieldName.field; 2164 } 2165 2166 // check if fieldName is in other view - then search for Relation 2167 var parts = fieldName.split('.'); 2168 if ( parts.length > 1 ){ 2169 if (typeof Model.relations[ this.view.name ] != 'undefined' && typeof Model.relations[ this.view.name ][ parts[0] ] != 'undefined' ) { 2170 fieldName = Model.relations[ this.view.name ][ parts[0] ].fieldName(); 2171 } else console.log ('ERROR: VIEW "' + this.viewName + '" does not have FIELD OR RELATION "' + fieldName + '"', this, value); 2172 } 2173 2174 if (isset(this.fields[fieldName]) == false) console.log ('ERROR: VIEW "' + this.viewName + '" does not have FIELD "' + fieldName + '"', value); 2175 this.fields[fieldName].set(value, type, format, silent); 2176 }; 2177 2178 this.get = function (fieldName, type, format) 2179 { 2180 //console.log(fieldName); 2181 //console.log(this); 2182 if (isset(this.fields[fieldName]) == false) console.log ('ERROR: VIEW "' + this.viewName + '" does not have FIELD "' + fieldName + '"'); 2183 return this.fields[fieldName].get(type, format); 2184 }; 2185 2186 this.getForWeb = function (fieldName, format) 2187 { 2188 if (isset(this.fields[fieldName]) == false) console.log ('ERROR: VIEW "' + this.viewName + '" does not have FIELD "' + fieldName + '"'); 2189 return this.fields[fieldName].getForWeb(format); 2190 }; 2191 2192 this.getPrimary = function(type) 2193 { 2194 if ( this.getPrimaryFieldName() == false ) return false;
2195 return this.get(this.getPrimaryFieldName() , type); 2196 } 2197 2198 this.getPrimaryField = function( ) 2199 { 2200// console.log(this); 2201 2202 if (typeof this.view == 'undefined' ) return this.fields[ 'id' ]; 2203 var primaryField = this.view.getPrimaryField(); 2204 if (typeof primaryField == 'undefined' ) return this.fields[ 'id' ]; 2205 return this.fields[ primaryField.name ]; 2206// return this.fields['id']; 2207 } 2208 2209 2210 this.getPrimaryFieldName = function() 2211 { 2212 var field = this.getPrimaryField(); 2213 if (typeof field === 'undefined' ) return false; 2214 return field.name; 2215 } 2216 2217 this.getTitle = function() { 2218 var titleField = this.getTitleField(); 2219 if (titleField == false) return ''; 2220 return titleField.get('string'); 2221 } 2222 2223 this.getTitleField = function( ) 2224 { 2225 if (typeof this.view === 'undefined') false; 2226 if (typeof this.view.displayField !== 'undefined' && this.view.displayField != '' ) return this.fields[ this.view.displayField ]; 2227 return false; 2228 } 2229 2230// 2231 2232 this.validate = function( filterOrArrayOrQuery ) { 2233 2234 if (typeof filterOrArrayOrQuery === 'undefined' ) return true; 2235 if (typeof filterOrArrayOrQuery === 'function' ) return filterOrArrayOrQuery( this ); 2236 2237 2238 // check if entity data corresponds to all filters 2239 var filters; 2240 var thisEntity = this; 2241 if (filterOrArrayOrQuery instanceof Query) filters = filterOrArrayOrQuery.filters; 2242 else if ( typeof filterOrArrayOrQuery.comparator !== 'undefined') filters = [ filterOrArrayOrQuery ]; 2243 else if ( Array.isArray( filterOrArrayOrQuery ) ) filters = filterOrArrayOrQuery; 2244 if (isset( filters ) == false) alert('ERROR setting entity filters. Filter object not given.\nTYPE: '+ typeof filterOrArrayOrQuery); 2245 2246 var valid = true; 2247 $.each(filters, function( index, filter ) { 2248 if ( filter.validate( thisEntity ) == false ) { 2249 valid = false; 2250 } 2251 }); 2252 return valid; 2253 } 2254 2255 2256 this.forceFilters = function ( filters ) 2257 { 2258 // Sets entity values according to filter 2259 // ++ parameter filters can be filterArray OR query 2260 2261 console.log('FORCE FILTERS'); 2262 2263 if (isset(filters) == false) return; 2264// console.log(filters.constructor.name); 2265// console.log(filters); 2266 var filterArr = []; 2267// if (isset(filters.getValue)) filterArr.push(filters); // SINGLE FILTER 2268 if (filters.constructor.name == 'Filter') filterArr.push(filters); // SINGLE FILTER 2269 else filterArr = filters.filters; 2270 2271// console.log(filterArr); 2272 2273 2274 for (var index in filterArr) { 2275 var filter = filterArr[index]; 2276 if (filter.comparator == '=') this.set(filter.getField(), filter.getValue(), 'string'); 2277 } 2278 } 2279 2280 this.getRelationSet = function( options ) 2281 { 2282 // ONLY SUPPORTS NEXT RELATION, NO DEEPER RELATIONS 2283 // SYNCHRONIZES PARENT FIELD 2284 2285 var parentEntity = this; 2286 2287 var params; 2288 if (typeof options === 'string' || options instanceof String || options.constructor.name == 'Query') params = { query: options }; 2289 else params = options; 2290 2291 var query = this.getRelationQuery(params.query); 2292 2293 var relation = Model.relations[this.viewName][query.relation]; 2294// var relation = Model.relations[this.viewName][query.view]; 2295 2296 var relationCacheName; 2297 2298 if (typeof params.cacheName !== 'undefined' ) relationCacheName = this.viewName + '_' + this.getPrimary('string') + '_' + params.cacheName; 2299 else relationCacheName = relationCacheName = this.viewName + '_' + this.getPrimary('string') + '_' + relation.relationViewName; 2300// if ( isset( this.relationCachePrefix ) == false ) this.relationCachePrefix = this.viewName + '_' + this.getPrimary('string') + '_'; 2301// if (isset (params.cacheName) ) relationCacheName = this.relationCachePrefix + params.cacheName; 2302// 2303 2304 2305// $(parentEntity.getPrimaryField()).on('changed', function() { 2306// alert('new relation anem needed' + parentEntity.data[parentEntity.getPrimaryFieldName()]); 2307// relationCacheName =''; 2308// if ( isset( parentEntity.relationCachePrefix ) == false ) parentEntity.relationCachePrefix = parentEntity.viewName + '_' + parentEntity.data[parentEntity.getPrimaryFieldName()] + '_'; 2309// if (isset (params.cacheName) ) relationCacheName = parentEntity.relationCachePrefix + params.cacheName; 2310// alert(relationCacheName); 2311// 2312// }); 2313 2314// alert( params.cacheName ); 2315// alert( 'cacheName: ' + relationCacheName ); 2316// 2317 2318/* 2319 if (false) { 2320 var entitySet = new EntitySet({ 'cacheName': relationCacheName }); 2321 entitySet.hookFilters(query); 2322 entitySet.view = Model.views[query.view]; 2323 } 2324 else entitySet = new EntitySet({ 'cacheName': relationCacheName, 'query': query }); 2325*/ 2326 if (this.isNew) { 2327 var entitySet; 2328 // CHECK IF RELATIONSET ALREADY CACHED 2329 if ( typeof EntityCache.setCache[relationCacheName] !== 'undefined' ) { 2330 // alert(relationCacheName); 2331 // ASSIGN CACHED SET 2332 entitySet = new EntitySet( { 'cacheName': relationCacheName }); 2333 } else { 2334 // APPLY QUERY ON ENTITY CACHE THEN CACHE RELATIONSET 2335// console.log(query);
2336// console.log(options); 2337 if (typeof EntityCache.entityCache[ query.view ] !== 'undefined') { 2338 entitySet = EntityCache.entityCache[ query.view ].applyQuery( query ); 2339 EntityCache.setCache[ relationCacheName ] = entitySet; 2340 // console.log(entitySet); 2341 // alert('NEW'); 2342 } else entitySet = new EntitySet({ 'cacheName': relationCacheName, 'query': query }); 2343 } 2344 2345 2346 setTimeout( function( ){ 2347 entitySet.status('ready'); 2348 $(entitySet).trigger( 'ready' ); 2349 if (typeof options.callback !== 'undefined') options.callback( entitySet ); 2350 }, 100); 2351 2352 2353 } else { 2354 entitySet = new EntitySet({ 'cacheName': relationCacheName, 'query': query, 'callback': options.callback}, options.async ); 2355 } 2356 entitySet.view = Model.views[query.view]; 2357 entitySet.query = query; 2358 2359 2360// console.log(query); 2361// console.log(entitySet); 2362 2363 2364 // STORE PARENTENTITY BEFORE ENTITY 2365 // TO DETERMINE PRIMARY 2366 $(entitySet).on('entityAdded', function(event, entity){ 2367/* 2368 if (entity.isNew) { 2369 entity.set(relation.relationFieldName(), parentEntity.get(relation.fieldName())); 2370 } 2371 2372 $(parentEntity).on('stored', function(event, data) { 2373 console.log('STATUS'); 2374 console.log(entity.status()); 2375 console.log(entity.status() == STATUS_CHANGED); 2376 if (entity.status() == STATUS_CHANGED) entity.store(); 2377 }); 2378 2379 $(entity).on('beforeStored', function(event, data) { 2380 data.preventStore = (parentEntity.status() == STATUS_CHANGED); 2381 }); 2382 2383 */ 2384 2385 entity.fields[relation.relationFieldName()].syncWithField( parentEntity.fields[relation.fieldName()] ); 2386 2387 2388 2389/* 2390 $(parentEntity.getPrimaryField()).on('changed', function(event){ 2391 entity.set(relation.relationFieldName(), parentEntity.get(relation.fieldName())); 2392 }); 2393*/ 2394 2395 2396 }); 2397 2398 2399 return entitySet; 2400 2401 2402 } 2403 2404 2405 this.getRelationQuery = function( params1 ) { 2406 2407 // DOES NOT LINK RELATED FIELDS, USE getRelationSet instead! 2408 2409 var query = new Query(params1); 2410 var thisEntity = this; 2411 if (typeof Model.relations[this.viewName][query.view] === 'undefined') console.log('ERROR: View '+ this.viewName + ' does not have a relation to View ' + query.view); 2412 var relation = Model.relations[this.viewName][query.view]; 2413 2414 // query.view is NAME of relation! 2415 // therefore overwrite query.view by relation.relationViewName 2416 query.view = relation.relationViewName; 2417 query.relation = relation.name; 2418 2419 2420 var filter = new Filter(); 2421 filter.set(relation.relationFieldName(), thisEntity.get(relation.fieldName())) ; 2422 2423// $(thisEntity.fields[relation.fieldName()]).on('changed', function() { 2424// filter.set(relation.relationFieldName(), thisEntity.get(relation.fieldName())) ; 2425// }); 2426 query.filters.push(filter); 2427 return query; 2428 } 2429 2430 this.loadRelations = function(relationString, callback, async) { 2431 //STRING EXAMPLE: 'RELATION invoice id = "xy" RELATION invoice_items amount > 2 RELATION products'); 2432 var es = new EntitySet(); 2433 es.loadRelations('RELATION ' + this.view.name + ' ' + this.view.getPrimaryField().name + ' = "'+ this.getPrimary('string') + '" ' + relationString, callback, async); 2434// es.loadRelations('RELATION ' + this.view.name + ' ' + this.view.getPrimaryField().name + ' = "'+ this.getPrimary('string') + '" RELATION ordered_webinars RELATION orders RELATION users', callback, async); 2435 return es; 2436 } 2437 2438 2439 this.setView = function(view) 2440 { 2441 2442 this.viewName = view.name; 2443 this.view = view; 2444 2445 for (var fieldName in view.fields) 2446 { 2447 2448 this.addField(fieldName, this.data[ fieldName ], view.fields[ fieldName ].t
2448ype, view.fields[ fieldName ].format); 2449 2450 /* 2451 var field = new EntityField(this, fieldName); 2452 //field.entity = this; 2453 field.type = view.fields[fieldName].type; 2454 field.format = view.fields[fieldName].format; 2455 this.fields[fieldName] = field; 2456// $(document).trigger('newField', field); 2457 */ 2458 } 2459 } 2460 2461 2462 /* 2463 this.getHTML = function(fieldNames, tagName) { 2464 2465 if (isset(fieldNames) == false) 2466 { 2467 fieldNames = Object.keys(this.fields); 2468 } 2469 if (isset(tagName) == false) tagName = 'div'; 2470 2471 var result = '<li data-structure="entity" data-id="' + this.id() + '">'; 2472 2473 for (var index in fieldNames) { 2474 var fieldName = fieldNames[index]; 2475 result += '<' + tagName + ' data-structure="field" data-type="' + this.fields[fieldName].type + '" data-field="' + fieldName + '" data-id="' + this.id() + '" data-view="' + this.viewName + '">' + this.getForWeb(fieldName) + '</' + tagName + '>'; 2476 } 2477 2478 result += '</li>'; 2479 2480 return result; 2481 }; 2482 */ 2483 2484 this.toDisplay = function(options) { 2485 if (typeof options == 'string') alert('ERROR: toDisplay Function outdated, use OPTION object'); 2486 // OPTIONS { fieldNames, tagName, additionalFunction, display } 2487 2488 if (isset(options) == false) options = {}; 2489 if (isset(options.fieldNames) == false) 2490 { 2491 //fieldNames = []; 2492 //for(var k in this.fields){console.log(k); fieldNames.push(k)}; 2493 options.fieldNames = Object.keys(this.fields); 2494 } 2495 2496 if (isset(options.tagName) == false) options.tagName = 'div'; 2497 2498 //console.log(this.fields); 2499 //console.log(fieldNames); 2500 //var obj = $(jQuery.parseHTML(this.getHTML(fieldNames, tagName))); 2501 if (isset(options.display)) 2502 var obj = options.display.element || options.display; 2503 else var obj = $(jQuery.parseHTML('<' + options.tagName + ' data-structure="entity" data-view="'+ this.viewName +'" data-id="' + this.getPrimary('string') + '"></' + options.tagName + '>')); 2504 2505 for (var index in options.fieldNames) { 2506 //if (isset(this.fields[fieldNames[index]].attribute('function')) == false) 2507 obj.append(this.fields[options.fieldNames[index]].toDisplay( )); 2508 } 2509 2510 2511 if (isset(options.additionalFunction)) options.additionalFunction(obj); 2512 2513 obj.data('entity', this); 2514 obj.find('[data-structure="field"]').data('entity', this); 2515 /* 2516 obj.find('[data-structure="field"]').on('changed', function(event, fieldName) { 2517 display.html(this.get(fieldName)) 2518 .css('color', 'blue'); 2519 }); 2520 */ 2521 /* 2522 $(obj.entity).on('changed', function(e, fieldName){ 2523 console.log('changed'); 2524 console.log(obj); 2525 obj.css('color', 'red'); 2526 }) 2527 */ 2528 2529 2530 // ++ REMOVE entityDisplayReady EVENT IF POSSIBLE 2531 // ++ USE displayInserted EVENT INSTEAD 2532 2533 if (isset(obj.data('entity').view)) $(document).trigger('entityDisplayReady_' + obj.data('entity').view.name, obj); 2534 $(document).trigger('entityDisplayReady', obj); 2535 2536 return obj; 2537 }; 2538 2539 2540 this.clone = function() { 2541 var newEntity = this.view.getBlankEntity(); 2542 var primaryFieldName = this.getPrimaryFieldName(); 2543 for (var fieldName in this.fields) { 2544 if (fieldName != primaryFieldName) { 2545 newEntity.set({field: fieldName, value: this.get(fieldName), silent: true}); 2546 } 2547 } 2548 EntityCache.add(newEntity); 2549 return newEntity; 2550 } 2551 2552 this.cloneWithChildren = function( fullDepth ) { 2553 2554 if ( typeof fullDepth === 'undefined' ) fullDepth = true; 2555 2556 var originalEntity = this; 2557 var newEntity = this.clone(); 2558 var primaryFieldName = this.getPrimaryFieldName(); 2559 console.log('clone'); 2560 console.log(newEntity); 2561 $.each(Model.relations[this.view.name], function() { 2562// console.log(Model.relations[this.view.name][index]); 2563// console.log(Model.relations[this.view.name][index].relationFieldName()); 2564// console.log(Model.relations[this.view.name][index].fieldName()); 2565 2566 2567 console.log(this); 2568 console.log(this.viewName); 2569 2570 var relationFieldName = this.relationFieldName(); 2571 console.log(relationFieldName); 2572 if ( primaryFieldName == this.fieldName() ) { 2573 var relatedSet = originalEntity.getRelationSet( { query: 'VIEW ' + this.relationViewName, callback: function(entitySet) { 2574 console.log(newEntity.getPrimary() ); 2575 console.log(entitySet); 2576 $.each(entitySet.entities, function() { 2577 var clonedChild;
2578 if ( fullDepth) clonedChild = this.cloneWithChildren(); 2579 else clonedChild = this.clone(); 2580 clonedChild.fields[relationFieldName].syncWithField( newEntity.getPrimaryField() ); 2581 2582// clonedChild.set( relationFieldName, newEntity.getPrimary() ); 2583 console.log(clonedChild); 2584 }); 2585 } }); 2586 2587 } 2588 }); 2589 2590 return newEntity; 2591 2592 } 2593 2594 this.toArrayOfStrings = function( changesOnly ){ 2595 // NOT REALLY ARRAY, IS OBJECT OF KEY / VALUES, CAN BE STRINGIFIED 2596 if ( typeof changesOnly === 'undefined' ) changesOnly = false; 2597 2598 var dataArr = {}; 2599 for (fieldName in this.fields) 2600 if (changesOnly == false || this.fields[fieldName].status() != STATUS_UNCHANGED) { 2601 if (this.fields[fieldName].attribute('type') == 'html') 2602 dataArr[fieldName] = this.get(fieldName, 'html'); 2603 else if (this.fields[fieldName].attribute('type') == 'currency') // PROBLEMS WITH , and . OTHERWISE 2604 dataArr[fieldName] = this.get(fieldName).toString(); 2605 else dataArr[fieldName] = this.get(fieldName, 'string'); 2606 } 2607 var entityArr = {'type': 'entity', 'view' : this.viewName, 'id' : this.getPrimary('string'), 'new' : this.isNew, 'status' : this.status(), 'data' : dataArr}; 2608 return entityArr; 2609 }; 2610 2611 2612 this.select = function() 2613 { 2614 $(this).trigger('selected'); 2615 } 2616 2617 this.delete = function() { 2618 this.trash(true); 2619 this.store(); 2620 } 2621 2622 2623 2624 2625 EventMaker( this, 'store'); 2626 2627 2628 this.onStore( (options) => { 2629 2630// console.log ('store', options, this); 2631 2632 2633 // returns job 2634 // otherJob.hire( entity.store() ) executes store() once and immediately 2635 // otherJob.hire( entity.store ) hires the "store" function and executes each time on otherJob.do() 2636 2637 2638 $(this).triggerHandler('storeRequested'); // triggert even if no STORE needed. Required for other entities depending on this one 2639 2640 if (isset( this.storage )) { 2641 return this.storage.store(this); 2642 } 2643 2644 if (options == EntityStorage) 2645 { 2646 return EntityStorage.store(this); 2647 } 2648 2649 var storeJob = new Job(); 2650 storeJob.isDoing; 2651// storeJob.isDoing = true; 2652// setTimeout( function(){ 2653// storeJob.doFail( ); 2654// 2655// }, 2000); 2656// return storeJob; 2657 2658 2659 storeJob.info = 'store entity - ' + this.viewName; 2660 2661// alert( storeJob.stateSelf); 2662 2663 2664 var dataStore; 2665 var thisEntity = this; 2666 2667 if (isset(options) == false) { 2668 options = {}; 2669 } 2670 if (isset(options.dataStore) == false) { 2671 dataStore = 'provider/plugins/data/' + this.viewName + '/'; 2672 if (typeof DATA_URL != 'undefined') dataStore = DATA_URL + dataStore; 2673 } else if (isString(options)) { 2674 dataStore = options; 2675 } 2676 2677 var url = dataStore; 2678 2679 2680 2681 if (this.trash()) 2682 { 2683 if (this.isNew) { 2684 $(self).triggerHandler('deleted'); 2685 $(document).triggerHandler('entityDeleted', self); 2686// self = undefined; 2687 self.status(STATUS_DELETED); 2688 2689 if (typeof options.success === "function") options.success( { entity: this, success: true, action: 'delete' } ); 2690 if (typeof options.callback === "function") options.callback( { entity: this, success: true, action: 'delete' }); 2691 2692 delete(self); 2693// console.log(self); 2694// console.log(this); 2695 return storeJob.doSuccess(); 2696 } 2697 2698 $.ajax({ 2699 url: url, 2700 type: 'POST', 2701 context: this, 2702 data: {'items':[{'type': 'entity', 'view' : this.viewName, 'id' : this.getPrimary('string'), 'delete' : true, 'status' : this.status()}]}, 2703 //data: JSON.stringify(dataArr, null, 2), 2704 //dataType: 'json', 2705 }).done(function(data) { 2706 2707 console.log('DELETED'); 2708 $(self).triggerHandler('deleted'); 2709 $(document).triggerHandler('entityDeleted', self); 2710 self.status(STATUS_DELETED); 2711 2712 if (typeof options.success === "function") options.success( { entity: self, success: true, action: 'delete' } ); 2713 if (typeof options.callback === "function") options.callback( { entity: self, success: true, action: 'delete' }); 2714 2715 2716 self = undefined; 2717 console.log(self); 2718 2719 storeJob.doSuccess(); 2720 2721 //$(this).trigger( "stored" ); 2722 }); 2723 2724 return storeJob; 2725 } 2726 2727 if (this.status() == STATUS_UNCHANGED) { 2728 if (typeof options.success === "function") options.success( { entity: this, success: true, action: 'none' } ); 2729 if (typeof options.callback === "function") options.callback( { entity: this, success: true, action: 'none' }); 2730 2731 return storeJob.doSuccess(); 2732 } 2733 2734// console.log(this); 2735// alert('x ' + this.get('id')); 2736 2737 var dataArr = this.toArrayOfStrings( true ); 2738 2739 var eventData = { 2740 preventStore : false, 2741 storeJob: storeJob 2742 }; 2743 2744 2745 2746 2747 2748 2749 2750 $(this).triggerHandler('beforeStored', eventData); 2751 if (eventData.preventStore) { 2752 //alert('prevented'); 2753 // storeJob.doFail(); 2754 console.log('store prevented ' + this.getPrimary('string')); 2755 $(this).triggerHandler('storePrevented'); 2756 2757 if (typeof options.callback === "function") options.callback( { entity: this, success: false, action: 'store', error: 'prevented' }); 2758 2759 return storeJob.doFail(); 2760 return storeJob; 2761 } 2762 2763 //console.log(JSON.stringify(dataArr, null, 2)); 2764 //console.log(dataArr); 2765 $.ajax({
2766 url: url, 2767 type: 'POST', 2768 context: this, 2769 data: {'items':[ dataArr ]}, 2770 //data: JSON.stringify(dataArr, null, 2), 2771 dataType: 'json', 2772 }).done(function(data) { 2773 2774 // Confirm entity was stored 2775 // Retrieve id of new entity 2776 // ++ check changes of other fields by server 2777 2778 if (isset(data['data'][0])) { 2779 console.log(thisEntity.getPrimary('string')); 2780 2781 // COMPAIR FIELDS (id and others) 2782 for (var fieldName in data['data'][0]) { 2783 2784 if (isset(thisEntity.fields[fieldName]) && thisEntity.fields[fieldName].attribute('type') == 'html' ) 2785 { 2786 if (thisEntity.data[fieldName] != data['data'][0][fieldName]) { 2787 thisEntity.set(fieldName, data['data'][0][fieldName], 'string'); 2788// alert('DIF - field: ' + fieldName + ' Value: '+data['data'][0][fieldName]); 2789 } 2790 } else if (isset(thisEntity.fields[fieldName]) && thisEntity.get(fieldName, 'string') != data['data'][0][fieldName]) { 2791 thisEntity.set(fieldName, data['data'][0][fieldName], 'string'); 2792// alert('DIF - field: ' + fieldName + ' Value: '+data['data'][0][fieldName]); 2793 } 2794 2795 } 2796 2797 2798 if (thisEntity.isNew) { 2799// thisEntity.set(thisEntity.getPrimaryFieldName(), data['data'][0][thisEntity.getPrimaryFieldName()], 'string'); 2800 2801 //thisEntity.privateId = thisEntity.getPrimary(); 2802 //thisEntity.id(thisEntity.getPrimary()); 2803 //console.log(thisEntity.getPrimary()); 2804 //console.log(thisEntity.id()); 2805 thisEntity.isNew = false; 2806 } 2807 2808 } 2809 2810 thisEntity.status(STATUS_UNCHANGED); 2811 for (var fieldName in thisEntity.fields) 2812 { 2813 thisEntity.fields[fieldName].status( STATUS_UNCHANGED ); 2814 } 2815 2816 2817 console.log('STORED ENTITY'); 2818 console.log(thisEntity); 2819 if (typeof options.success === "function") options.success( { entity: this, success: true, action: 'store' } ); 2820 if (typeof options.callback === "function") options.callback( { entity: this, success: true, action: 'store' }); 2821 $(thisEntity).trigger( "stored" ); 2822 2823 storeJob.doSuccess(); 2824 2825 }).error(function(data, textStatus, errorThrown ) { 2826 console.log('Error storing entity!'); 2827 console.log(data); 2828 console.log(textStatus); 2829 console.log(errorThrown); 2830// alert('Error storing entity!'); 2831 if (typeof options.error === "function") options.error( { entity: this, success: false, action: 'store', error: textStatus + ' - ' + errorThrown } ); 2832 if (typeof options.callback === "function") options.callback( { entity: this, success: false, action: 'store', error: textStatus + ' - ' + errorThrown } ); 2833 console.log( storeJob ); 2834 storeJob.doFail( { error: textStatus } ); 2835 }); 2836 2837 return storeJob; 2838 2839 2840 /* 2841 var ns= $.initNamespaceStorage('ns_nameXX' + this.data['id']); // Namespace in localStorage 2842 var storage = ns.localStorage; 2843 storage.set('xxx', this.data ); 2844 */ 2845 }); 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 this.restore = function() { 2861 2862 for (var index in this.fields) 2863 { 2864 this.fields[index].restore(); 2865 } 2866 this.status( STATUS_UNCHANGED ); 2867 2868 /* 2869 var ns= $.initNamespaceStorage('ns_nameXX' + this.data['id']); // Namespace in localStorage 2870 var storage = ns.localStorage; 2871 storage.set('xxx', this.data ); 2872 */ 2873 }; 2874 2875 2876 this.addField = function(fieldName, value, type, format) 2877 { 2878 if (typeof value !== 'undefined') this.data[fieldName] = value; 2879 var field = new EntityField(this, fieldName); 2880 field.entity = this; 2881 if (typeof type !== 'undefined') field.type = type; 2882 if (typeof format !== 'undefined') field.format = format; 2883 this.fields[fieldName] = field; 2884// $(document).trigger('newField', field); 2885 2886 2887 // DEFINE GETTER AND SETTER 2888 // DO NOT CREATE IF OTHER PROPERY WITH THAT NAME EXISTS ALREADY
2889// if (typeof this[fieldName] === 'undefined') => typeof result, does not show if property is defined 2890 if ( Object.getOwnPropertyDescriptor(this, fieldName) === undefined ) 2891 Object.defineProperty( this, [ fieldName ], { 2892 set: function( value ) { 2893 this.set( fieldName, value ); 2894 }, 2895 get: function() { 2896 return this.get( fieldName ); 2897 } 2898 }); 2899 2900 return field; 2901 } 2902 2903 2904}; 2905 2906 2907 2908 2909function EntitySet( options, async ) { 2910 var thisEntitySet = this; 2911 2912 if (isString(options)) options = { query: new Query( options )}; 2913 2914 if (isset( options ) == false ) options = {}; 2915 2916 if (options.constructor.name == 'Query') options.query = options; 2917 2918 this.query = options.query || undefined; 2919 2920 var status = 'new'; 2921 2922 this.entities = {}; 2923 this.trash = {}; 2924 this.name = options.name || 'unknown'; 2925 this.cacheName = options.cacheName; 2926 this.fields = {}; 2927 this.async = true; 2928 if (typeof async !== 'undefined') this.async = async; 2929 2930 this.count = 0; 2931 this.countTrash = 0; 2932 this.countUnlimited = 0; 2933 this.streaming = false; 2934 this.forceStreaming = options.forceStreaming || false; 2935 this.keys = []; 2936 this.streamingOrder = {}; 2937 2938 if (isset( this.cacheName) ) { 2939// if (false ) { 2940 2941// this.cacheName += 'xx'; 2942// alert( this.cacheName); 2943 if (isset (EntityCache.setCache[ this.cacheName ])) { 2944// if (typeof options.callback === "function") setTimeout( function() { options.callback() }, 10); 2945//alert(this.cacheName); 2946 var cachedSet = EntityCache.setCache[ this.cacheName ]; 2947 cachedSet.status('ready'); 2948 setTimeout( function( ){ 2949 2950// Ready Trigger Deactivated on EntitySet from Cache. Use status check! 2951// $(cachedSet).trigger( "ready" ); 2952 if (typeof options.callback === 'function') options.callback( cachedSet ); 2953 }, 100); 2954 2955 return cachedSet; 2956// return EntityCache.setCache[ this.cacheName ]; 2957 } 2958// EntityCache.setCache[ this.cacheName ] = this; 2959 } 2960 2961 2962 2963 /* 2964 if (isset(url)) { 2965 this.loadFromURL(url); 2966 }*/ 2967 2968 2969 2970// if (isset(options)) { 2971// } 2972 2973 2974 this.status = function(newStatus) { 2975 if (typeof newStatus !== 'undefined' && newStatus != status) { 2976 status = newStatus; 2977 $(this).trigger( status ); // for example "ready" 2978 } 2979 return status; 2980// if (isset(newStatus)) status = newStatus; 2981// else return status; 2982 } 2983 2984 this.remove = function( entity ) { 2985 // REMOVE DOES NOT MEAN DELETE! 2986 // ONLY REMOVES ENTIY FROM SET AND TRIGGERS REMOVE EVENT 2987 var entityId = entity.getPrimary(); 2988 2989 if ( this.entities[entityId] == entity) { 2990// if (entity.trash()) ??? 2991 if (typeof this.streamingOrder !== 'undefined') delete this.streamingOrder[ entity.getPrimary('string') ]; 2992 this.count--; 2993 delete this.entities[entityId]; 2994 $(this).triggerHandler('entityRemoved', entity); 2995 return true; 2996 } else { 2997// alert('error'); 2998 return false 2999 } 3000 } 3001 3002 this.removeAll = function() { 3003 // REMOVE DOES NOT MEAN DELETE! 3004 // ONLY REMOVES ENTIY FROM SET AND TRIGGERS REMOVE EVENT 3005 $.each(this.entities, function( key, entity ) { 3006 thisEntitySet.remove( entity ); 3007// var entityId = entity.getPrimary();
3008// delete thisEntitySet.entities[entityId]; 3009// $(thisEntitySet).triggerHandler('entityRemoved', entity); 3010 }); 3011 } 3012 3013 3014 this.getEntity = function( index ) { 3015 if (typeof index === 'undefined') index = 0; 3016 return this.entities[ Object.keys(this.entities)[index]]; 3017 } 3018 3019 this.getEntitiesByField = function( fieldName, valueOrEntity, type ) { 3020 // RETURNS ARRAY OF entities WITH fieldName = fieldValue 3021 // CREATES KEY LISTS FOR LOOKUP 3022 3023 if (typeof this.view.fields[ fieldName ] === 'undefined') { 3024 alert('ERROR: View ' + this.view.name + ' does not have field ' + fieldName ); 3025 return result; 3026 } 3027 3028 if (typeof type === 'undefined') type = this.view.fields[ fieldName ].type; 3029 var result = []; 3030 if (valueOrEntity instanceof Entity) { 3031 var fieldValue = valueOrEntity.getPrimary( type ); 3032 } else var fieldValue = valueOrEntity; 3033 fieldValue = convertValue( fieldValue, type, this.view.fields[ fieldName ].type) 3034 // Now fieldValue is of the same type as this 3035 3036 3037 // IF PRIMARY FIELD DO NOT GO THROUGH ALL ENTITIES, USE INDEX INSTEAD, FASTER 3038 if (fieldName == this.view.getPrimaryField().name) { 3039 if ( typeof this.entities[ fieldValue ] === 'undefined' ) return []; 3040 else return [ this.entities[ fieldValue ] ]; 3041 } 3042 3043 3044 3045 for (var index in this.entities) { 3046 var entity = this.entities[index]; 3047 if (entity.get(fieldName) == fieldValue) result.push( entity ); 3048 // INCLUDES TRASHED ENTITIES 3049// if (entity.trash() == false && entity.get(fieldName) == fieldValue) result.push( entity ); 3050 } 3051 3052 return result; 3053 3054 3055 3056 3057 // OLD VERSION WITH LOOK OF ARRAY "KEYS" 3058 // FASTER BUT NOT USED ANYMORE BECAUSE IT DOES NOT UPDATE ON CHANGES 3059 3060 /* 3061 // RETURN PRIMARY VALUE WITHOUT EXTRA KEY LIST 3062 3063 if (fieldName == this.view.getPrimaryField().name) { 3064 if ( typeof this.entities[ fieldValue ] === 'undefined' ) return []; 3065 else return [ this.entities[ fieldValue ] ]; 3066 } 3067 3068 3069 var result = []; 3070 3071 if (typeof this.view.fields[ fieldName ] === 'undefined') { 3072 alert('ERROR: View ' + this.view.name + ' does not have field ' + fieldName ); 3073 return result; 3074 } 3075 3076 if ( typeof this.keys[ fieldName ] === 'undefined' ){ 3077 // CREATE KEY 3078 this.keys[ fieldName ] = {} ; 3079 for (var index in this.entities) { 3080 var entity = this.entities[index]; 3081 console.log(entity.get(fieldName, 'string')); 3082 if ( typeof thisEntitySet.keys[ fieldName ][ entity.get(fieldName, 'string')] === 'undefined' ) thisEntitySet.keys[ fieldName ][ entity.get(fieldName, 'string')] = []; 3083 thisEntitySet.keys[ fieldName ][ entity.get(fieldName, 'string')].push( entity ); 3084 } 3085 } 3086 3087 // RETURN KEY 3088 if (typeof this.keys[ fieldName ][ fieldValue ] === 'undefined') return []; 3089 return this.keys[ fieldName ][ fieldValue ]; 3090 3091 */ 3092 } 3093 3094 this.getEntityByField = function( fieldName, valueOrEntity, type ){ 3095 // RETURNS FIRST MATCHING ENTITY OR FALSE; 3096 var result = this.getEntitiesByField(fieldName, valueOrEntity, type ) 3097 if ( result.length == 0 ) return false; 3098 else return result[0]; 3099 } 3100 3101 this.getPrimaryEntity = function( primary ){ 3102 // RETURNS ONLY EXISTING ENTITIES, DOES NOT LOAD FROM SERVER! 3103 return this.getEntityByField(this.view.getPrimaryField().name, primary ); 3104 } 3105 3106 3107 3108 3109 3110 this.add = function(entity, index) 3111 { 3112 if (isset(index) == false) index = entity.getPrimary();
3113 else entity.getPrimaryField().set(index); 3114 entity.entitySet = this; 3115 3116 3117 var entityId = entity.getPrimary(); 3118 3119 3120 if ( typeof this.entities[entityId] !== 'undefined' ){ 3121 return false; 3122 } 3123 3124 this.entities[entityId] = entity; 3125 3126 //console.log('ADDED _ ' + entity.id()); 3127 3128 var set = this; 3129 3130 EntityCache.add(entity); 3131 3132 3133/* 3134 if (entity.isNew) { 3135 alert('NEW ENTITY'); 3136 entity.forceFilters(this.) 3137 3138 } 3139 */ 3140 3141 $(entity).on('selected', function(event){$(set).trigger('selected', entity)}); 3142 3143 $(entity).on('statusChange', function(event, status){ 3144 $(set).triggerHandler('entityStatusChange', {entity: entity, status: status}); 3145 }); 3146 3147 $(entity).on('changed', function(event){$(set).trigger('entityChanged', entity ) }); 3148 3149 3150 $(entity).on('deleted', function(event){ 3151// alert('DLETED ' + entity.status() + ' - ' + entity.getPrimary()); 3152 if (entity.trash()) { 3153 delete set.trash[entity.getPrimary()]; 3154 $(set).triggerHandler('countChanged'); 3155 set.countTrash -= 1; 3156 } else { 3157 delete set.entities[entity.getPrimary()]; 3158 $(set).triggerHandler('countChanged'); 3159 set.count -= 1; 3160 } 3161 }); 3162 3163 3164 $(entity.getPrimaryField()).on('changed', function(event){ 3165 // PRIMARY HAS CHANGED -> CHANGE ITS KEY IN EntitySet 3166 if (entity.trash()) 3167 { 3168 set.trash[entity.getPrimary()] = entity; 3169 delete set.trash[entityId]; 3170 } 3171 else 3172 { 3173 set.entities[entity.getPrimary()] = entity; 3174 delete set.entities[entityId]; 3175 } 3176// alert('FIELD CHANGED ' + entity.status() + ' - ' + entity.getPrimary() + ' - ' + entityId); 3177 }); 3178 3179 3180 3181 $(entity).on('trashStatus', function(event){ 3182 if (entity.trash()) 3183 { 3184 // REMOVE ENTIY FROM KEYS 3185 for (var key in set.keys ){ 3186 var index = set.keys[ key ][ entity.get( key )].indexOf( entity ); 3187 if (index > -1) { 3188 set.keys[ key ][ entity.get( key )].splice( index, 1 ); 3189 } 3190 } 3191 3192 // INSERT ENTITY TO TRASH 3193 set.trash[entity.getPrimary()] = entity; 3194 // REMOVE ENTITY FROM ENTITIES 3195 delete set.entities[entity.getPrimary()]; 3196 3197 $(set).triggerHandler('countChanged'); 3198 set.count -= 1; 3199 set.countTrash += 1; 3200 3201 3202 } 3203 else 3204 { 3205 // INSERT ENTIY FROM KEYS 3206 for (var key in set.keys ){ 3207 if ( typeof set.keys[ key ][ entity.get(key, 'string')] === 'undefined' ) thisEntitySet.keys[ key ][ entity.get(key, 'string')] = []; 3208 set.keys[ key ][ entity.get(key, 'string')].push( entity ); 3209 } 3210 3211 // INSERT ENTITY TO ENTITIES 3212 set.entities[entity.getPrimary()] = entity; 3213 // REMOVE ENTITY FROM TRASH 3214 delete set.trash[entity.getPrimary()]; 3215 3216 set.count += 1; 3217 set.countTrash -= 1; 3218 $(set).triggerHandler('countChanged'); 3219 3220 } 3221 }); 3222 3223 3224 3225 for (var key in set.keys ){ 3226 if ( typeof set.keys[ key ][ entity.get(key, 'string')] === 'undefined' ) thisEntitySet.keys[ key ][ entity.get(key, 'string')] = [];
3227 set.keys[ key ][ entity.get(key, 'string')].push( entity ); 3228 } 3229 3230 3231 3232 3233 3234 this.count += 1; 3235 $(this).triggerHandler('countChanged'); 3236 $(this).trigger('entityAdded', entity); 3237 return true; 3238 } 3239 3240 /* 3241 this.getBlankEntity = function() 3242 { 3243 var entity = new Entity(); 3244 entity.dataStatus = STATUS_NEW; 3245 3246 console.log('NEW ENTITY'); 3247 console.log(entity); 3248 this.add(entity); 3249 3250 return entity; 3251 } 3252 */ 3253 3254 3255 this.hookFilters = function(objectWithFilters) { 3256 3257 if (objectWithFilters.constructor.name == 'Query') for (var index in objectWithFilters.filters) { 3258 $(objectWithFilters.filters[index]).on('changed', function() { 3259 thisEntitySet.forceFilters(objectWithFilters.filters[index]); 3260 }); 3261 } else if ($.isArray(objectWithFilters)) for (var index in objectWithFilters) { 3262 $(objectWithFilters[index]).on('changed', function() { 3263 thisEntitySet.forceFilters(objectWithFilters[index]); 3264 }); 3265 } else if (objectWithFilters.constructor.name == 'Filter') { 3266 $(objectWithFilters).on('changed', function() { 3267 thisEntitySet.forceFilters(objectWithFilters); 3268 }); 3269 } else { 3270 console.log('ERROR: NO FILTER GIVEN'); 3271 console.log(objectWithFilters); 3272 } 3273 3274 } 3275 3276 this.loadFromQuery = function(query, callback, async) { 3277 3278 // ++ REPLACE DATA EXCHANGE CODE 3279 if ( typeof Model.views[ query.view ]!== 'undefined' && typeof Model.views[ query.view ].xmlRoot !== 'undefined') 3280 this.loadFromXML( query, callback, async ); 3281 else if ( typeof Model.views[ query.view ]!== 'undefined' && typeof Model.views[ query.view ].data !== 'undefined') this.loadFromObject( query, callback, async ); 3282 else this.loadFromURL( query.toURL(), callback, async ); 3283 this.query = query; 3284 if (this.name == 'unknown') this.name = query.view; 3285 this.hookFilters(query); 3286 } 3287 3288 this.loadRelations = function(string, callback, async) { 3289 //STRING EXAMPLE: 'RELATION invoice id = "xy" RELATION invoice_items amount > 2 RELATION products'); 3290 this.query = new Query(string); 3291 this.loadFromURL( 'provider/plugins/data/?query=' + string, callback, async ); 3292 } 3293 3294 3295 this.loadFromXML = function( query, callback, async) { 3296 var entitySet = this; 3297 var query = new Query(query); 3298 var view = Model.views[ query.view ]; 3299 var element = view.xmlRoot; 3300 3301 entitySet.streaming = false; 3302 3303// console.log( view ); 3304 3305 if (typeof this.view == 'undefined' ) this.view = view; 3306 3307// alert( view.xmlRoot ); 3308// for (var index in element){ 3309 $( element ).find('>' + view.xmlEntityTag ).each( function(){ 3310// alert( this ); 3311 var entity = XMLStorage.getEntity(view, this); 3312// console.log( entity ); 3313 entitySet.add( entity ); 3314 }); 3315 entitySet.status('ready'); 3316 3317 console.log(query); 3318 if (typeof callback == 'function') setTimeout( function(){ callback() }, 1); 3319 3320 } 3321 3322 3323 this.loadFromObject = ( query, callback, async) => { 3324 var entitySet = this; 3325 var query = new Query(query); 3326 var view = Model.views[ query.view ]; 3327 console.log( view.data ); 3328 3329 entitySet.streaming = false; 3330 3331 if (typeof this.view == 'undefined' ) this.view = view; 3332 3333 for (var index in view.data ) { 3334 console.log( index ); 3335 var entity = new Entity(); 3336 entity.data[ 'key' ] = index; 3337 entity.data[ 'value' ] = view.data[ index ]; 3338 entity.setView( view ); 3339 entity.storage = ObjectStorage; 3340 entitySet.add( entity ); 3341 }; 3342// entitySet.applyQuery( query ); 3343 entitySet.status('ready'); 3344 3345 console.log(query); 3346 if (typeof callback == 'function') setTimeout( function(){ callback( entitySet.applyQuery( query ) ) }, 1); 3347 3348 } 3349 3350 3351 3352 3353 this.loadFromJSON = function( data ){
3354 3355 if (typeof data['data'] == 'undefined'){ 3356 // No entityset data given, perhaps data contains multiple EntitySets 3357 if ( typeof data[ this.name ] !== 'undefined' ) data = data[ this.name ]; // found EntitySet with this name, choose this data 3358 } 3359 3360 3361 var viewName; 3362 this.status('loading'); 3363// console.log(this); 3364// console.log(data); 3365 if( typeof( data['_view'] ) !== 'undefined' ) { 3366 // ENTITY DATA ONLY, NO ADDITIONAL INFORMATION 3367 data = { viewName: data['_view'], data: [ data ] }; 3368 3369 } 3370 3371 3372 if ( typeof data['viewName'] !== 'undefined') { 3373 viewName = data['viewName']; 3374 if (typeof Model.views[ viewName ] == 'undefined') { 3375 var thisEntitySet = this; 3376 Model.loadView( viewName, function(){ }, false ); 3377 } 3378 this.view = Model.views[ viewName ]; 3379 } 3380 else if ( typeof data['view'] === 'undefined' || data['view'] === null || typeof data['view']['name'] === 'undefined' ) 3381 { 3382 console.log('ERROR: No view data returned.'); 3383 console.log(data); 3384 return; 3385 } 3386 else { 3387 viewName = data['view']['name']; 3388 } 3389 3390 if (typeof Model.views[ viewName ] == 'undefined') { 3391 3392 var newView = new View(); 3393 3394 newView.name = viewName; 3395 newView.title = data['view']['title']; 3396 newView.displayField = data['view']['displayField']; 3397 if (typeof data['view']['arrangeField'] !== 'undefined' && data['view']['arrangeField'] != null )newView.arrangeField = data['view']['arrangeField']; 3398 newView.fields = data['view']['fields']; 3399 newView.resolutions = data['view']['resolutions']; 3400 newView.type = data['view']['type']; 3401 if (typeof data['view']['path'] !== 'undefined'){ 3402 newView.path = data['view']['path']; 3403 } 3404 3405 3406 3407 $.each(newView.fields, function( key, field ) { 3408 field.getTitle = function( ) { 3409 if ( typeof field.title === 'string') return field.title; 3410 else return field.name; 3411 } 3412 }); 3413 3414 Model.addView( newView ); 3415 3416 } else { 3417// console.log(data); 3418// console.log(this.view); 3419// alert(data); 3420 } 3421 3422 if (isset(this.view) == false) this.view = Model.views[ viewName ]; 3423// 3424 if ( typeof data['unlimited'] !== 'undefined' ) { 3425 this.countUnlimited = parseInt(data['unlimited']); 3426 if ( data['data'].length != this.countUnlimited || this.forceStreaming == true) this.streaming = true; 3427 } 3428 else { 3429 this.countUnlimited = data['data'].length; 3430 } 3431 3432 if ( typeof data['from'] !== 'undefined' ) this.from = parseInt( data['from'] ); else this.from = 0; 3433 3434 // TRIGGER WHEN VIEW AND STREAMING SIZE DONE 3435 // AND BEFORE ADDING ENTITIES 3436 // NEEDED FOR DISPLAYSET PLACEHOLDER PREPARATION 3437 $(this).trigger('addingEntities'); 3438 3439 var counter = 0; 3440 for (var index in data['data']){ 3441 3442 var entity = new Entity();
3443 3444 3445 if (isset(viewName)) 3446 { 3447 entity.viewName = viewName; 3448 if (isset(Model.views[entity.viewName])) { 3449 entity.view = Model.views[entity.viewName]; 3450 } 3451 } 3452 3453 if (typeof this.view === "undefined" ) console.log('ERROR: VIEW NOT LOADED'); 3454 for (var fieldName in this.view.fields) 3455 { 3456 // TYPE HTML IS STORED AS STRING IN ENTITY DATA 3457// console.log(this.view); 3458 3459 if (this.view.fields[fieldName].type == 'html') 3460 entity.addField(fieldName, data['data'][index][fieldName]); 3461 else 3462 entity.addField(fieldName, convertValue(data['data'][index][fieldName], 'string', entity.view.fields[fieldName].type), entity.view.fields[fieldName].type); 3463 3464// entity.addField(fieldName, convertValue(data['data'][index][fieldName], 'string', entity.view.fields[fieldName].type), entity.view.fields[fieldName].type); 3465 } 3466 3467 //if (isset(data['view']['fields']['id'])) entity.id(data['data'][index]['id']); 3468// alert('xxx ' + data['view']['name'] + ' - ' + entity.getPrimary()); 3469 3470 if (isset(EntityCache.entityCache[viewName]) && isset(EntityCache.entityCache[viewName].entities[entity.getPrimary()])) { 3471 // ENTITY ALREADY EXISTS IN ENTITYCACHE 3472 // USE ENTITY IN ENTITYCACHE 3473 // AND UPDATE ! 3474 // PREVIOUS CHANGES ARE NOT OVERWRITTEN 3475 3476 3477 var cacheEntity = EntityCache.entityCache[viewName].entities[entity.getPrimary()]; 3478 3479 3480 // COMPARE FIELDS (id and others) 3481 3482 var hasChangedFields = false; // determine if fields were changed locally. do not overwrite these fields 3483 3484 for (var fieldName in cacheEntity.fields) { 3485 // Compare strings, not objects 3486 if (typeof cacheEntity.fields[fieldName] != 'undefined' && cacheEntity.fields[fieldName].status() == STATUS_UNCHANGED && cacheEntity.get(fieldName, 'string') != entity.get(fieldName, 'string') ){ 3487//console.log(cacheEntity); 3488// console.log(fieldName); 3489// console.log(cacheEntity.fields[fieldName].status()); 3490// 3491// console.log(cacheEntity.data[fieldName]); 3492// console.log(entity.data[fieldName]); 3493 3494 cacheEntity.set(fieldName, entity.data[fieldName]); 3495// cacheEntity.set(fieldName, entity.data[fieldName], null, null, true); 3496 cacheEntity.fields[fieldName].status( STATUS_UNCHANGED ); 3497 3498 } else if (typeof cacheEntity.fields[fieldName] != 'undefined' && cacheEntity.fields[fieldName].status() == STATUS_CHANGED){ 3499 hasChangedFields = true; 3500 } 3501 3502 } 3503 3504 3505 if (cacheEntity.isNew) { 3506 // cacheEntity.set(cacheEntity.getPrimaryFieldName(), data['data'][0][cacheEntity.getPrimaryFieldName()], 'string'); 3507 3508 //cacheEntity.privateId = cacheEntity.getPrimary(); 3509 //cacheEntity.id(cacheEntity.getPrimary()); 3510 //console.log(cacheEntity.getPrimary()); 3511 //console.log(cacheEntity.id()); 3512 cacheEntity.isNew = false; 3513 } 3514 3515 if ( hasChangedFields == false ) cacheEntity.status(STATUS_UNCHANGED); 3516 3517 entity = cacheEntity; 3518 3519 3520 3521 3522 } else { 3523 $(document).triggerHandler('entityReady_' + entity.viewName, entity); 3524 $(document).triggerHandler('entityReady', entity); 3525 } 3526 3527 3528 if (this.streaming) { 3529// entity.stream = counter + this.from; 3530 this.streamingOrder[ entity.getPrimary('string') ] = counter + this.from; 3531 } 3532 counter++ 3533 3534 this.add(entity); 3535 } 3536 3537 if ( this.streaming == false && typeof this.cacheName !== 'undefined') EntityCache.setCache[ this.cacheName ] = this; 3538 3539 this.status('ready'); 3540 }, 3541 3542 this.loadFromURL = function( url, callback, async ) { 3543 if (typeof async === 'undefined') async = true; 3544 $.ajax({
3545 async: async, 3546 url: url, 3547 type: 'POST', 3548 dataType: 'json', 3549 context: this, 3550 error: function( data ) { 3551 this.ajaxResult = data; 3552 if (typeof callback === "function") callback( false ); 3553 } 3554 }).done(function(data) { 3555 3556 this.ajaxResult = data; 3557 3558 this.loadFromJSON( data ); 3559 3560 if (typeof callback === "function") callback( this ); 3561 3562 }); 3563 3564 3565 }; 3566 3567 this.loadStream = function( from, amount, callback ){ 3568 3569 var streamQuery = new Query( this.query.toString() ); 3570 3571 streamQuery.limiters = new Array( new Limiter( {from: from, amount: amount }) ); 3572 3573 var streamEntitySet = new EntitySet( { query: streamQuery, forceStreaming: true, callback: function(){ 3574 console.log( streamEntitySet); 3575// var i = 0; 3576// for ( var entityIndex in streamEntitySet.entities) { 3577// 3578// var entity = streamEntitySet.entities[entityIndex] ; 3579// 3580// 3581// entity.stream = from + i; 3582// thisEntitySet.add( entity ); 3583// 3584// console.log('### ' + i + ' -- ' + entityIndex); 3585//console.log( entity.get('title') ); 3586//console.log( streamEntitySet.entities ); 3587// 3588// 3589// i++; 3590// 3591// } 3592// 3593 } 3594 } ); 3595 3596 var i = 0; 3597 3598 $(streamEntitySet).on('entityAdded', function(event, entity){ 3599// entity.stream = from + i; 3600//console.log(entity); 3601 i++; 3602 var id = entity.getPrimary('string'); 3603 thisEntitySet.streamingOrder[ id ] = streamEntitySet.streamingOrder[ id ]; 3604 thisEntitySet.add( entity ); 3605 3606 }); 3607 3608 3609 }; 3610 3611 3612 3613 3614 this.downloadExcel = function(){ 3615 if (typeof this.query === 'undefined') return false; 3616 var excelQuery = new Query( this.query.toString() ); 3617// console.log( this.query); 3618// console.log( this.query.toString() ); 3619// console.log( excelQuery ); 3620 excelQuery.limiters = []; 3621 var url = excelQuery.toURL() +'&format=xls'; 3622 window.open(url, '_blank'); 3623 } 3624 3625 3626 this.getHTML = function(fields) { 3627 var result = '<ul data-structure="set">'; 3628 for (var index in this.entities) result += this.entities[index].getHTML(); 3629 result += '</ul>'; 3630 return result; 3631 }; 3632 3633 this.applyQuery = function (variableQuery, returnCopy) { 3634 // Filter Entities in this EntitySet 3635 // Return a copy or this without filtered Entities 3636 3637 3638 var query = new Query( variableQuery ); 3639 var result = this; 3640 3641 if (isset( returnCopy ) == false) returnCopy = true; 3642 if ( returnCopy ) result = new EntitySet(); 3643 3644 $.each(this.entities, function( key, entity ) {
3645 if (entity.validate( query )) { 3646 if ( returnCopy ) result.add( entity ); 3647 } else { 3648 if ( returnCopy == false ) delete result.entities[key]; 3649 } 3650 }); 3651 return result; 3652 } 3653 3654 3655 this.getBlankEntity = function ( additionalQuery ) { 3656 var filters = []; 3657 console.log(this); 3658 console.log('________________ FILTER'); 3659 console.log(additionalQuery); 3660 3661 if (isset( additionalQuery ) && typeof additionalQuery == 'string') additionalQuery = new Query(additionalQuery); 3662 3663 console.log(additionalQuery); 3664 3665 if (isset( additionalQuery )) filters = filters.concat(additionalQuery.filters); 3666 if (isset( this.query )) filters = filters.concat(this.query.filters); 3667 console.log(this); 3668 console.log(filters); 3669 3670 var entity = this.view.getBlankEntity( {'filters': filters} ); 3671 3672// for (var index in this.query.filters) { 3673// this.query.filters[index].hook(entity); 3674// } 3675 3676 $(this).triggerHandler('blankEntity', entity); 3677 3678 this.add( entity ); 3679 3680 return entity; 3681 } 3682 3683 this.forceFilters = function( filters ) { 3684 for (var index in this.entities) { 3685 this.entities[index].forceFilters(filters); 3686 } 3687 for (var index in this.trash) { 3688 this.trash[index].forceFilters(filters); 3689 } 3690 } 3691 3692 this.store = function(dataStore) { 3693 for (var index in this.trash) { 3694 this.trash[index].store(dataStore); 3695 } 3696 for (var index in this.entities) { 3697 this.entities[index].store(dataStore); 3698 } 3699 }; 3700 3701 this.restore = function() 3702 { 3703 for (var index in this.entities) 3704 { 3705 this.entities[index].restore(); 3706 } 3707 3708 } 3709 3710 this.treatAllEntities = function(handlerFunction) { 3711 // handlerFunction is triggered for all Entities 3712 // ON entityAdded 3713 // AND for all existing entities (from cache) 3714 3715 for (var index in this.entities) { 3716 handlerFunction( null, this.entities[index] ); 3717 } 3718 3719 for (var index in this.trash) { 3720 handlerFunction( null, this.trash[index] ); 3721 } 3722 3723 $(this).on('entityAdded', function(event, entity){ handlerFunction(event, entity) }); 3724 3725 } 3726 3727// this.treatAllEntities( function(event, entity){ EntityCache.add(entity) }); 3728 3729 if (isset( this.query )) this.loadFromQuery(this.query, options.callback, this.async); 3730// if (isset( this.query )) this.loadFromURL(this.query.toURL()); 3731 3732 3733 3734}; 3735 3736 3737 3738ObjectView = function( viewName, data ){ 3739 // CREATES AND RETURNS A NEW VIEW BASED ON A KEY VALUE OBJECT 3740 var view = new View(); 3741 view.name = viewName; 3742 3743 view.fields['key'] = {'name': 'key', 'type': 'string', 'objectStorage': { 'type': 'key' }, 'index': 'primary' }; 3744 view.fields['value'] = {'name': 'value', 'type': 'string', 'objectStorage': { 'type': 'value' } }; 3745 3746 view.displayField = 'key'; 3747 view.data = data; 3748 3749 Model.addView( view ); 3750 viewToEditor ( { 'viewName': view.name, 'navigation': false } ); 3751}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.