1 /** 2 * @fileoverview Sourcemap.Editor: Main component to handle viewing and editing of Sourcemaps. 3 * @version 0.8 4 * @author sourcemap@media.mit.edu 5 * @package sourcemap 6 * @subpackage js 7 */ 8 9 10 /** 11 * Create a new Sourcemap instance. 12 * @see Sourcemap 13 */ 14 15 if (typeof(Sourcemap) == 'undefined' ) {Sourcemap = {}; } 16 17 18 /** 19 * @namespace Sourcemap Editor 20 */ 21 Sourcemap.Editor = { 22 init: function() { 23 24 /** 25 * Triggers edit mode of objects by switching fields and enabling interaction. 26 */ 27 this.processHashEvent = function(hash) { 28 if(hash == "#edit") { 29 this.initializeEditMode(); 30 if(Sourcemap.Template.usechooser) { this.showPartChooser();} 31 } 32 else if(hash == "#new") { 33 this.initializeEditMode(); 34 if(Sourcemap.Template.usechooser) { this.showPartChooser();} 35 this.initializeTooltips(); 36 } 37 }; 38 /** 39 * Intialize all the functions 40 * Make all the fields editable 41 * @see #setupPartHandlers 42 * @see #setupEndoflifeHandlers 43 * @see #setupProcessHandlers 44 */ 45 this.initializeEditMode = function() { 46 // Make Objects Editable 47 $("#object-name").html('<input class="input-object-name" value="'+$("#object-name").text()+'">'); 48 $("#object-description").html('<textarea class="input-object-description">'+$("#object-description").html()+'</textarea>'); 49 $("#object-origin").html('<input class="input-object-origin" value="'+$("#object-origin").text()+'">'); 50 $("#object-destination").html('<input class="input-object-destination" value="'+$("#object-destination").text()+'">'); 51 $("#object-via select").removeAttr("disabled"); 52 53 $( "#part-list").addClass("editmode"); 54 $("div#partlist-shell").css("height","360px"); 55 56 // Make Parts Editable 57 $(".part-name").each(function() { $(this).html('<input class="input-name" value="'+$(this).text()+'">');}); 58 $(".part-description").each(function() { $(this).html('<textarea class="input-description">'+$(this).html()+'</textarea>');}); 59 $(".part-weight").each(function() { $(this).html('<input class="input-weight" value="'+$(this).text()+'">');}); 60 $(".part-via select").removeAttr("disabled"); 61 $(".part-origin").each(function() { $(this).html('<input class="input-origin" value="'+$(this).text()+'">');}); 62 $(".part-rawemissions").each(function() { $(this).html('<input class="input-rawemissions" value="'+$(this).text()+'">');}); 63 64 /** 65 * Make Process Editable 66 */ 67 68 $(".process-text").each(function() { 69 $(this).html('<input class="input-process-text" value="'+$(this).text()+'"/>'); 70 }); 71 72 $(".process-area").each(function() { 73 if($(this).parents(".process-details").find("span.process-unit").html() != "kg") { 74 $(this).html('<input class="input-process-area" value="'+$(this).text()+'"/>'); 75 } 76 }); 77 78 $(".process-display").each(function() { 79 $(this).html('<input class="input-process-display" value="'+$(this).text()+'"/>'); 80 }); 81 82 /** 83 * Make Endoflife Editable 84 */ 85 86 $(".endoflife-display").each(function() { $(this).html('<input class="input-endoflife-display" value="'+$(this).text()+'">');}); 87 88 $(".endoflife-emissions").each(function() { $(this).html('<input class="input-endoflife-emissions" value="'+$(this).text()+'">');}); 89 90 91 /** 92 * Set handlers to Sourcemap.Object 93 * .change functions call their respective functions in objects.js 94 */ 95 96 $(".input-object-name").change(function() { 97 objectConfig.setName($(this).val()); $(this).addClass("dirty"); 98 }); 99 $(".input-object-description").change(function() { 100 objectConfig.setDescription($(this).val()); $(this).addClass("dirty"); 101 }); 102 103 $(".input-object-origin").change(function() { 104 objectConfig.setOrigin($(this).val()); $(this).addClass("dirty"); 105 }); 106 $(".input-object-destination").change(function() { 107 objectConfig.setDestination($(this).val()); $(this).addClass("dirty"); 108 }); 109 $("#object-via-select").change(function() { 110 objectConfig.setVia($("#object-via select :selected").text()); $(this).addClass("dirty"); 111 }); 112 113 Sourcemap.Editor.setupPartHandlers(""); 114 Sourcemap.Editor.setupProcessHandlers(""); 115 Sourcemap.Editor.setupEndoflifeHandlers(""); 116 Sourcemap.Editor.setupPermissions(); 117 118 /** 119 * @name onbeforeunload 120 * @function 121 */ 122 window.onbeforeunload = function() { return "You are currently editing a sourcemap and you haven't saved your changes. If you want to save your changes, click the green 'Save Sourcemap' button before you leave."; }; 123 124 $("#permission-button").removeClass("hidden"); 125 126 $("li.part-details").addClass("hover"); 127 $(".part-details .removeaction").css("display","inline"); 128 129 $('input:checkbox').removeAttr("disabled"); 130 $("#usekwh, #poweruselist, #transportlist").removeAttr("disabled"); 131 $("div#summary-statistics .checkmessage, div#summary-statistics input[type='checkbox']").css("display","inline"); 132 133 $("#editsourcemapbutton").css("display","none"); 134 $("#savesourcemapbutton").slideDown(); 135 $("#addpartbutton, #partlist-menu").slideDown(); 136 137 $(".list-expand").text("-"); 138 139 /** 140 * Auto Complete for part location 141 * keyup function sends e as the @param for filterLocate 142 */ 143 144 $(".part-origin .input-origin").unbind("keyup"); 145 $(".part-origin .input-origin").keyup(function(e) { 146 if(e.keyCode!=40 && e.keyCode != 13 && e.keyCode != 38) { 147 Sourcemap.Editor.filterLocate(e); 148 } 149 }); 150 151 }; 152 153 /** 154 * Display all the locations for the part 155 * Do an ajax call to get all the locations of a part 156 */ 157 158 $(".list").unbind("click"); 159 $(".list").click(function(e) { 160 var part_locate =""; 161 var part_location_id = parseInt($(e.target).parents(".part-details").attr("id")); 162 var part_location_name = objectConfig.parts[part_location_id].name; 163 var saveData = { part_location: part_locate, 164 name: part_location_name }; 165 166 var sendData = "data=" + JSON.stringify(saveData) + ""; 167 $.post(Sourcemap.siteurl+"parts/getPartLocations", sendData, function(response) { 168 var part_locations = eval(response); 169 $(".ac_results").remove(); 170 171 // create a div and as a child to the parent of the input field (use append) 172 var locate = $("li#"+part_location_id+".part-details .part-origin"); 173 locate.append('<div class="ac_results"><ul>'); 174 $.each(part_locations, function(i,e) { 175 // create one <li>location</li> per location inside div 176 $(".ac_results ul").append('<li>'+e.displaylocation+'</li>'); 177 178 }); 179 locate.append('</ul></div>'); 180 181 Sourcemap.Editor.hoverLocate(locate.find("input.input-origin")); 182 183 }); 184 185 }); 186 187 /** 188 * To autocomplete the location in the input field by hover over function 189 * @param target. This is a classname where the location has to be display 190 */ 191 this.hoverLocate = function(target) { 192 $(target).parent().find(".ac_results ul li").hover( 193 function(event) { 194 $(event.target).css('background', 'red'); 195 $(target).val($(event.target).html()); 196 }, 197 function(event) { 198 $(event.target).css('background', ''); 199 }); 200 }; 201 202 203 /** 204 * Do the ajax call to the server to get the locations 205 * Display them in the part-origin input field 206 * With keydown/keyup, different locations can be selected 207 * @param e, this is the target element 208 * @see #hoverLocate 209 */ 210 this.filterLocate = function(e) { 211 212 var part_locations_display = Array(); 213 var part_location_id = parseInt($(e.target).parents(".part-details").attr("id")); 214 var part_location_name = objectConfig.parts[part_location_id].name; 215 var filterPartLocate = $(e.target).val(); 216 var saveData = { part_location: filterPartLocate, 217 name: part_location_name }; 218 219 var sendData = "data=" + JSON.stringify(saveData) + ""; 220 $.post(Sourcemap.siteurl+"parts/getPartLocations", sendData, function(response) { 221 var part_locations = eval(response); 222 $(".ac_results").remove(); 223 224 // create a div and as a child to the parent of the input field (use append) 225 $(e.target).parent().append('<div class="ac_results"><ul>'); 226 $.each(part_locations, function(i,e) { 227 // create one <li>location</li> per location inside div 228 $(".ac_results ul").append('<li>'+e.displaylocation+'</li>'); 229 part_locations_display = e.displaylocation; 230 }); 231 $(e.target).parent().append('</ul></div>'); 232 Sourcemap.Editor.hoverLocate(e.target); 233 }); 234 235 var currentSelection = null; 236 237 238 239 $(e.target).unbind("keydown"); 240 $(e.target).keydown(function(event) { 241 var target = $(e.target); 242 var ac = target.parent().find('.ac_results'); 243 244 if(ac.length == 0 ) { return; } 245 if(event.keyCode==40) { 246 if(currentSelection==null) { 247 currentSelection = ac.find("li")[0]; 248 } else { 249 $(currentSelection).css('background', ''); 250 currentSelection = $(currentSelection).next(); 251 if(currentSelection.length == 0) { 252 currentSelection = ac.find("li")[0]; 253 } else { 254 currentSelection = currentSelection[0]; 255 } 256 } 257 258 $(currentSelection).css('background', 'red'); 259 260 } else if(event.keyCode==38) { 261 262 if(currentSelection==null) { 263 currentSelection = ac.find("li")[ac.find("li").length-1]; 264 } else { 265 $(currentSelection).css('background', ''); 266 currentSelection = $(currentSelection).prev(); 267 if(currentSelection.length == 0) { 268 currentSelection = ac.find("li")[ac.find("li").length-1]; 269 } else { 270 currentSelection = currentSelection[0]; 271 } 272 } 273 $(currentSelection).css('background', 'red'); 274 275 } else if(event.keyCode==13) { 276 target.val($(currentSelection).html()); 277 } 278 }); 279 280 }; 281 282 /** 283 * Enable accordion 284 */ 285 $("#summary-statistics").accordion(); 286 287 288 289 /** 290 * Stop all the functions which were enabled in edit mode. 291 * The fields are not editable and are all hidden 292 */ 293 this.stopEditMode = function() { 294 $(".qTip").remove(); 295 window.location.hash = "#"; 296 297 $( "#ajaxnote" ).text("Saving Object..."); // TODO should become notes area. 298 $( "#part-list").removeClass("editmode"); 299 300 $("#permission-button").addClass("hidden"); 301 $("#permission-panel").css("display","none"); 302 303 Sourcemap.Editor.closePartChooser(); 304 305 objectConfig.recalculateObjectValues(); 306 objectConfig.save(); 307 308 $(".list-expand").text("+"); 309 $(".list-expand").parents(".part-details").removeClass("hover"); 310 311 312 // Add input switch to unedit object 313 $(".input-object-name").each(function() { $(this).replaceWith($(this).val());}); 314 $(".input-object-description").each(function() { $(this).replaceWith(Sourcemap.Util.rhtmlspecialchars($(this).val()));}); 315 $(".input-object-permissions").each(function() { $(this).replaceWith($(this).val());}); 316 $(".input-object-origin").each(function() { $(this).replaceWith($(this).val());}); 317 $(".input-object-destination").each(function() { $(this).replaceWith($(this).val());}); 318 319 $(".input-object-via").attr("disabled", "disabled"); $(".input-object-via").removeClass("dirty"); 320 $(".input-object-lifetime").each(function() { $(this).replaceWith($(this).val());}); 321 322 // Add input switch to unedit parts 323 $(".input-name").each(function() { $(this).replaceWith($(this).val());}); 324 $(".input-description").each(function() { $(this).replaceWith(Sourcemap.Util.rhtmlspecialchars($(this).val()));}); 325 $(".input-weight").each(function() { $(this).replaceWith($(this).val());}); 326 $(".input-via").attr("disabled", "disabled"); $(".input-via").removeClass("dirty"); 327 $(".input-origin").each(function() { $(this).replaceWith($(this).val());}); 328 $(".input-rawemissions").each(function() { $(this).replaceWith($(this).val());}); 329 330 $(".part-details .removeaction").css("display","none"); 331 332 // Add input switch to unedit process 333 $(".input-process-text").each(function() { $(this).replaceWith($(this).val()); 334 }); 335 $(".input-process-area").each(function() { $(this).replaceWith($(this).val()); 336 }); 337 $(".input-process-display").each(function() { $(this).replaceWith($(this).val()); 338 }); 339 340 //Add input switch to unedit endoflife 341 $(".input-endoflife-display").each(function() { $(this).replaceWith($(this).val()); 342 }); 343 $(".input-endoflife-emissions").each(function() { $(this).replaceWith($(this).val()); 344 }); 345 346 347 // Add capability to create parts 348 $("#private-button").unbind("click"); 349 $("#editsourcemapbutton").slideDown(); 350 $("#savesourcemapbutton").css("display","none"); 351 $("#addpartbutton, #partlist-menu").css("display","none"); 352 $("div#summary-statistics .checkmessage, div#summary-statistics input[type='checkbox']").css("display","none"); 353 $("div#partlist-shell").css("height","385px"); 354 $('#partchooser-visualization').css("display","none"); 355 $("input:checkbox").attr("disabled","true"); 356 $("#usekwh, #poweruselist").attr("disabled", "true"); 357 }; 358 359 360 /** 361 * Call a function in the objects.js to add a process 362 * @param target_element, it is the location where the add process 363 * button is located. 364 * @see #getProcessesForPart 365 */ 366 this.addProcessPart = function(target_element){ 367 368 var part_id = parseInt($(target_element).parents(".part-details").attr("id")); 369 var process_id = parseInt($(target_element).parents(".part-details").find(".process-details").attr("id")); 370 Sourcemap.Editor.getProcessesForPart(part_id, process_id, target_element); 371 $("li#"+part_id+" .add-process").css("display","block"); 372 }; 373 374 375 376 /** 377 * Call a function in the objects.js to ass an endoflife for a part 378 * @param target_element, it is the location where add endoflife button 379 * is located 380 * @see #getEndoflifeForPart 381 */ 382 383 this.addEndoflifePart = function(target_element) { 384 var part_id = parseInt($(target_element).parents(".part-details").attr("id")); 385 var endoflife_id = parseInt($(target_element).parents(".part-details").find(".endoflife-details").attr("id")); 386 Sourcemap.Editor.getEndoflifeForPart(part_id, endoflife_id, target_element); 387 $("li"+part_id+" .add-endoflife").css("display", "block"); 388 }; 389 390 391 /** 392 * Setup handlers for a part 393 * @param specifier, this points to "li #id" 394 * Call the associated function in objects.js for every change function 395 * @see #intializeEditMode 396 */ 397 this.setupPartHandlers = function(specifier) { 398 // Set part handlers to Sourcemap.Object 399 400 $(specifier + ".input-name").change(function() { 401 objectConfig.setPartName(parseInt($(this).parents(".part-details").attr("id")), $(this).val()); 402 $(this).addClass("dirty"); 403 }); 404 $(specifier + ".input-description").change(function() { 405 objectConfig.setPartDescription(parseInt($(this).parents(".part-details").attr("id")), $(this).val()); 406 $(this).addClass("dirty"); 407 }); 408 $(specifier + ".input-weight").change(function() { 409 objectConfig.setPartWeight(parseInt($(this).parents(".part-details").attr("id")), $(this).val()); 410 $(this).addClass("dirty"); 411 }); 412 $(specifier + ".input-via").change(function() { 413 objectConfig.setPartVia(parseInt($(this).parents(".part-details").attr("id")), $(this).val(), $(this).children(":selected").text()); 414 $(this).addClass("dirty"); 415 }); 416 $(specifier + ".input-origin").change(function() { 417 objectConfig.setPartOrigin(parseInt($(this).parents(".part-details").attr("id")), $(this).val(), true); 418 $(this).addClass("dirty"); 419 }); 420 $(specifier + ".input-rawemissions").change(function() { 421 objectConfig.setPartRawEmissions(parseInt($(this).parents(".part-details").attr("id")), $(this).val()); 422 $(this).addClass("dirty"); 423 }); 424 $(specifier + ".removeaction").click(function() { 425 objectConfig.removePart(parseInt($(this).parents(".part-details").attr("id"))); 426 }); 427 }; 428 429 430 /** 431 * Setup handlers for process 432 * @param specifier, this points to "li .part-details #id" 433 * Call the associated function in objects.js for every change function 434 * @see #intializeEditMode 435 */ 436 this.setupProcessHandlers = function(specifier) { 437 438 $(".add-process").unbind("click"); 439 $(".add-process").click(function(e){ 440 Sourcemap.Editor.addProcessPart(e.target); 441 }); 442 443 444 $(specifier + ".input-process-area").change(function(){ 445 process_id =parseInt($(this).parents(".process-details").attr("id")); 446 var part_id = parseInt($(this).parents(".part-details").attr("id")); 447 objectConfig.setProcessFactor(part_id, process_id, $(this).val(), 1); 448 }); 449 450 $(specifier + ".input-process-text").change(function(){ 451 process_id =parseInt($(this).parents(".process-details").attr("id")); 452 var part_id = parseInt($(this).parents(".part-details").attr("id")); 453 objectConfig.addProcessEmissions(part_id, process_id, $(this).val()); 454 }); 455 456 $(specifier + ".input-process-display").change(function(){ 457 process_id =parseInt($(this).parents(".process-details").attr("id")); 458 var part_id = parseInt($(this).parents(".part-details").attr("id")); 459 objectConfig.setProcessName(part_id, process_id, $(this).val()); 460 }); 461 462 $(specifier + ".process-unit").change(function(){ 463 process_id =parseInt($(this).parents(".process-details").attr("id")); 464 var part_id = parseInt($(this).parents(".part-details").attr("id")); 465 objectConfig.addProcessUnit(part_id, process_id, $(this).val()); 466 }); 467 468 $(specifier + "span.removeprocessaction").click(function(){ 469 process_id =parseInt($(this).parents(".process-details").attr("id")); 470 var part_id = parseInt($(this).parents(".part-details").attr("id")); 471 flag = true; 472 objectConfig.removeProcess(part_id, process_id, flag); 473 }); 474 475 476 477 }; 478 479 480 /** 481 * Setup handlers for endoflife 482 * @param specifier, this points to "li .part-details #id" 483 * Call the associated function in objects.js for every change function 484 * @see #intializeEditMode 485 */ 486 487 this.setupEndoflifeHandlers = function(specifier) { 488 $(".add-endoflife").unbind("click"); 489 $(".add-endoflife").click(function(e) { 490 Sourcemap.Editor.addEndoflifePart(e.target); 491 }); 492 493 494 $(specifier + ".input-endoflife-emissions").change(function(){ 495 endoflife_id =parseInt($(this).parents(".endoflife-details").attr("id")); 496 var partId = parseInt($(this).parents(".part-details").attr("id")); 497 objectConfig.addEndoflifeEmissions(partId, endoflife_id, $(this).val()); 498 }); 499 500 $(specifier + ".input-endoflife-display").change(function(){ 501 endoflife_id =parseInt($(this).parents(".endoflife-details").attr("id")); 502 var partId = parseInt($(this).parents(".part-details").attr("id")); 503 objectConfig.setEndoflifeType(partId, endoflife_id, $(this).val()); 504 }); 505 506 $(specifier + "span.removeendoflifeaction").click(function(){ 507 var id = parseInt($(this).parents(".part-details").attr("id")); 508 var endoflife_id = parseInt($(this).parents(".endoflife-details").attr("id")); 509 flag = true; 510 511 objectConfig.removeEndoflife(id, endoflife_id, flag); 512 }); 513 514 }; 515 516 517 /** 518 * Get the value part-punch 519 * @param id, part id 520 * Calculate totalval 521 */ 522 523 this.updatePartPunch = function(id) { 524 var selectpunch = "#"+id+".part-details .part-punch-totalemissions"; 525 var embodiedpunch = "#"+id+".part-details .part-punch-emissions"; 526 var transportpunch = "#"+id+".part-details .part-punch-transportemissions"; 527 var processpunch = "#"+id+".part-details .part-punch-processemissions"; 528 var endoflifepunch = "#"+id+".part-details . part-punch-endoflifeemissions"; 529 var embodiedval = $(embodiedpunch).text(); 530 var transportval = $(transportpunch).text(); 531 var processval = $(processpunch).text(); 532 var endoflifeval = $(endoflifepunch).text(); 533 if(objectConfig.showembodied == "") { embodiedval = 0;} 534 if(objectConfig.showtransport == "") { transportval = 0;} 535 var totalval = Sourcemap.Util.roundIt(Number(embodiedval) + Number(transportval) + Number(processval),2); 536 $(selectpunch).text("" + totalval); 537 if(objectConfig.showprocess == "") { processval =0;} 538 if(objectConfig.showendoflife == "") { endoflifeval =0;} 539 }; 540 541 /** 542 * Receipt Toggle function for EmbodiedDisplay 543 * TransportDisplay, ProcessDisplay, EndoflifeDisplay 544 */ 545 this.toggleEmbodiedDisplay = function() { 546 if(objectConfig.showembodied == "on" && Sourcemap.Template.useembodied) { $(".part-rawemissions, .part-punch-emissions").css("display", "inline");} 547 else { $(".part-rawemissions, .part-punch-emissions").css("display", "none");} 548 }; 549 550 this.toggleTransportDisplay = function() { 551 if(objectConfig.showtransport == "on") { $(".part-shipping, .part-transport, .part-via, .part-punch-transportemissions").css("display", "inline");} 552 else { $(".part-shipping, .part-transport, .part-via, .part-punch-transportemissions").css("display", "none");} 553 }; 554 555 this.toggleProcessDisplay = function() { 556 if(objectConfig.showprocess =="on") { $(".add-process, .process-appearance-super, processemissions-punch-value").css("display", "inline"); } 557 else { $(".add-process, .process-appearance-super, processemissions-punch-value").css("display", "none"); } 558 }; 559 560 this.toggleEndoflifeDisplay = function () { 561 if(objectConfig.showendoflife == "on") { $(".add-endoflife, .endoflife-appearance-super, endoflifeemissions-punch-value").css("display", "inline"); } 562 else { $(".add-endoflife, .endoflife-appearance-super, endoflifeemissions-punch-value").css("display", "none"); } 563 }; 564 565 /** 566 * Currently unused 567 */ 568 this.initializeTooltips = function() { 569 $('.input-object-name').qtip({ content: '<div class="number">1</div>What is the name of your Sourcemap?', show: { when: false, ready: true }, hide: 'focus', position: { corner: { target: 'leftTop', tooltip: 'bottomLeft' } }, style: { width:540, 'font-size': 16, tip: 'bottomLeft', border: { width: 3, radius: 8, color: '#f9e98e' }, background: '#fbf7aa', 'font-weight': 'bold', color: '#000' } }); 570 571 $('.input-object-origin').qtip({ content: '<div class="number">2</div> What is the location?', show: { when: false, ready: true }, hide: 'focus', position: { corner: { target: 'rightMiddle', tooltip: 'topLeft' } }, style: { width:240, tip: 'topLeft', border: { width: 1, radius: 8, color: '#f9e98e' }, 'font-size': 12, background: '#fbf7aa', color: '#000' } }); 572 573 $('.input-object-description').qtip({ content: '<div class="number">3</div>You can add a description here, some html is ok.', show: { when: false, ready: true }, hide: 'focus', position: { corner: { target: 'bottomMiddle', tooltip: 'topMiddle' } }, style: { width:340, tip: 'topMiddle', border: { width: 1, radius: 8, color: '#f9e98e' }, 'font-size': 12, background: '#fbf7aa', color: '#000'} }); 574 }; 575 576 577 /** 578 * Partlist visualization 579 */ 580 this.partHighlight = function(id) { 581 $('#partlist-shell').scrollTo($("#"+id), 200, {offset:-10}); 582 583 $("#"+id+" .part-summary").css("background-color", "#ffffcc"); 584 $("#"+id+" .part-summary").css("border-color", "#ffaa00"); 585 $("#"+id).css("background-color", "#ffffcc"); 586 $("#"+id).css("border-color", "#ffaa00"); 587 $("#"+id+" .part-actions").css("background-color", "#ffaa00"); 588 589 $("#"+id+" .part-summary").animate({ backgroundColor: "#eeeeee", borderBottomColor: "#cccccc", borderTopColor: "#cccccc", borderLeftColor: "#cccccc", borderRightColor: "#cccccc"}, 3000 ); 590 $("#"+id+" .part-summary").animate({ backgroundColor: "#eeeeee", borderBottomColor: "#cccccc", borderTopColor: "#cccccc", borderLeftColor: "#cccccc", borderRightColor: "#cccccc"}, 3000 ); 591 $("#"+id).animate({ backgroundColor: "#eeeeee", borderBottomColor: "#cccccc", borderTopColor: "#cccccc", borderLeftColor: "#cccccc", borderRightColor: "#cccccc"}, 3000 ); 592 $("#"+id).animate({ backgroundColor: "#f5f5f5", borderBottomColor: "#cccccc", borderTopColor: "#cccccc", borderLeftColor: "#cccccc", borderRightColor: "#cccccc"}, 3000 ); 593 594 $("#"+id+" .part-actions").animate({ backgroundColor: "#cccccc"}, 3000); 595 596 $("#"+id+".part-details").addClass("hover"); 597 $("#"+id+" .list-expand").text("-"); 598 }; 599 600 /** 601 * partlist visualization 602 */ 603 604 this.showPartChooser = function() { 605 SMap.clearPopup(); 606 $('#partlist-shell, #partlist-menu').css("display","none"); 607 $("#part-shell, #part-visualization").css("width","125px"); 608 $('#partchooser-visualization').css("display", "block"); 609 $("#partchooser-visualization .visualization-close-button").click(function() {Sourcemap.Editor.closePartChooser();}); 610 $("#partlist-close-button").unbind("click"); 611 $("#partlist-close-button").click(function() { 612 Sourcemap.Editor.closePartChooser(); 613 }); 614 }; 615 616 this.closePartChooser = function() { 617 $("#part-shell, #part-visualization").css("width", "540px"), 618 $('#partlist-menu').css("display","block"); 619 $('#partlist-shell').css("display","block"); 620 $('#partchooser-visualization').css("display","none"); 621 $("#partlist-close-button").unbind("click"); 622 $("#partlist-close-button").click( function() { 623 $("#part-visualization ").css("display", "none"); 624 }); 625 }; 626 627 /** 628 * protopart definition 629 */ 630 this.protoPart = $.template('<li class="part-details hover" id="${pid}"><div class="part-actions"><span class="removeaction" style="display:inline">x</span> <span class="list-expand">-</span></div><div class="list-legend">${legend}</div><ul class="part-summary"><li class="part-name">${plinkstart}<input class="input-name" value="${pname}">${plinkfinish}</li><li class="part-origin"><input class="input-origin" value="${porigin}"></li><li class="part-weight"><input class="input-weight" value="0"></li><span class="unit"><span class="part-punch-totalemissions">0</span></span><div style="clear:both;"></div></ul><div style="clear:both;"></div><ul class="part-properties"><li class="part-rawemissions"><input class="input-rawemissions" value="${pemissions}"></li><li class="part-punch-emissions">0</li><div style="clear:both;"></div><li class="part-shipping">0</li><li class="part-via">${pvia}</li><li class="part-punch-transportemissions">0</li></ul><div style="clear:both;"></div><div class="part-description"><textarea class="input-description">${pdescription}</textarea></div><div class="add-process"><select name="Processes" class="process-selected"></select></div><div class="process-appearance-super" style="display:block"><div class="process-details"></div></div><div class="part-punch-processemissions"></div> <div class="add-endoflife"><select name="Endoflife" class="endoflife-selected"><option value=""></option></select></div><div class="endoflife-appearance-super" style="display:block"><div class="part-punch-endoflifeemissions"></div></div></li></div>'); 631 632 /** 633 * Event callbacks 634 */ 635 this.receiveDescriptionChange = function(description) { 636 $(".input-object-description").val(description); 637 }; 638 639 640 /** 641 * Display the part using protoPart definition 642 * @param part id, name, description, emissions, link 643 * Call the setup handlers for process and endoflife 644 */ 645 this.receiveAddedPart = function(id, name, description, emissions, link) { 646 $(".qtip").remove(); 647 Sourcemap.Editor.closePartChooser(); 648 var linkurl = Sourcemap.siteurl+link; 649 if(linkurl != Sourcemap.siteurl) { var linkstart = '<a href="'+linkurl+'">'; var linkfinish = '</a>'; } 650 else { var linkstart = ''; var linkfinish = '';} 651 652 $("#part-list").append( Sourcemap.Editor.protoPart , { 653 pid: id, 654 legend:id+1, 655 plinkstart:linkstart, 656 plinkfinish:linkfinish, 657 pname: name, 658 porigin: Sourcemap.Template.partlocationstubname, 659 pemissions: emissions, 660 pvia: $("#object-via").html(), 661 pdescription: description 662 }); 663 664 Sourcemap.Editor.addProcessPart($("li.#"+id+" .add-process")); 665 Sourcemap.Editor.addEndoflifePart($("li.#"+id+" .add-endoflife")); 666 Sourcemap.Editor.setupProcessHandlers("li.#"+id+" "); 667 Sourcemap.Editor.setupEndoflifeHandlers("li.#"+id+" "); 668 669 Sourcemap.Editor.setupPartHandlers("#"+id+" "); 670 if( $('#part-visualization').css("display") == "none") { 671 $('#part-visualization').css("display", "block"); 672 } 673 $('#partlist-shell').scrollTo("max"); 674 Sourcemap.Editor.partHighlight(id); 675 676 $(".list-expand").bind("click", function() { 677 $(this).parents(".part-details").toggleClass("hover"); 678 if($(this).text() == "+") { $(this).text("-"); } else { $(this).text("+"); } 679 }); 680 }; 681 682 /** 683 * remove button visualization 684 * @param id, part id 685 */ 686 this.receiveRemovedPart = function(id) { 687 if(id == 0) { $(".part-details:first").remove(); } else {$("#"+id+".part-details").remove();} 688 }; 689 690 691 /** 692 * TODO Actually only the receipt cares about this... 693 */ 694 this.receiveObjectTotals = function(emissions, embodied, transport, shipping, weight, processTotal, endoflifeTotal) { 695 $("#object-emissions").text(Sourcemap.Util.roundIt(Number(emissions),2)); 696 $("#embodiedemissions-punch-value").text(Sourcemap.Util.roundIt(Number(embodied),2)); 697 $("#transportemissions-punch-value").text(Sourcemap.Util.roundIt(Number(transport),2)); 698 $("#object-shipping").text(Sourcemap.Util.roundIt(Number(shipping),2)); 699 $("#object-weight").text(Sourcemap.Util.roundIt(Number(weight),2)); 700 $("#processemissions-punch-value").text(Sourcemap.Util.roundIt(Number(processTotal),2)); 701 $("#endoflifeemissions-punch-value").text(Sourcemap.Util.roundIt(Number(endoflifeTotal),2)); 702 703 for ( var part in objectConfig.parts ) { Sourcemap.Editor.updatePartPunch(part);} 704 }; 705 706 707 /** 708 * Callback functions 709 */ 710 this.receiveGeocodeError = function(element) { 711 $(element).parent().qtip({ content: "We couldn't find this location...", show: { when: false, ready: true }, hide: 'click', position: { corner: { target: 'topMiddle', tooltip: 'bottomMiddle' } }, style: { width:340, 'font-size': 16, tip: 'bottomMiddle', border: { width: 3, radius: 8, color: 'red' }, background: 'red', 'font-weight': 'bold', color: 'white'} }); 712 setTimeout(function(){ $(".qtip:last").fadeOut("normal", function() {$(this).remove(); }); }, 2000); 713 }; 714 715 this.receiveGeocodeMessage = function(element, address) { 716 $(element).val(address); 717 $(element).parent().qtip({ content: "We think you meant " + address + ".", show: { when: false, ready: true }, hide: 'click', position: { corner: { target: 'topMiddle', tooltip: 'bottomMiddle' } }, style: { width:340, 'font-size': 16, tip: 'bottomMiddle', border: { width: 3, radius: 8, color: '#f9e98e' }, background: '#fbf7aa', 'font-weight': 'bold', 718 color: '#000'} }); 719 setTimeout(function(){ $(".qtip:last").fadeOut("normal", function() {$(this).remove(); }); }, 2000); 720 }; 721 722 this.receiveSaveConfirmation = function(data) { 723 $( "#ajaxnote" ).text(""); 724 window.onbeforeunload = null; 725 726 if(data == "added") { 727 window.location.href = Sourcemap.siteurl+objectConfig.type+'/' + objectConfig.slug+"#edit"; 728 } 729 730 SMap.clearPopup(); 731 SMap.objectsummary = objectConfig; 732 733 SMap.refreshMap(); 734 }; 735 736 /** 737 * protoEndoflife definition 738 */ 739 this.protoEndoflife = $.template('<div class="endoflife-details" id="${id}"><input class="input-endoflife-display" value="${endoflife_type}"> <input class="input-endoflife-emissions" value="${emissions}"> <span class="endoflife-unit">${endoflife_unit}</span> <span class="process-carbon"></span> <span class="removeendoflifeaction">x</span></div>'); 740 741 742 /** 743 * Display the endoflife using protoEndoflife definition 744 * @param partId, endlifelife_id, endoflife_type, emissions, unit 745 * Call the setup handlers for endoflife 746 */ 747 this.receiveAddedEndoflife = function(partId, endoflife_id, endoflife_type, emissions, unit) { 748 var endoflifeId = endoflife_id; 749 $("#"+partId+".part-details .endoflife-appearance-super").append(Sourcemap.Editor.protoEndoflife, { 750 part_id: partId, 751 id: endoflife_id, 752 endoflife_type: endoflife_type, 753 emissions: emissions, 754 endoflife_unit: unit 755 }); 756 757 if(endoflife_type == "reuse") { 758 var children = $("#"+partId+".part-details .endoflife-appearance-super").children(); 759 $(children[children.length-1]).find(".input-endoflife-emissions").hide(); 760 $(children[children.length-2]).find(".endoflife-unit").hide(); 761 762 } 763 764 Sourcemap.Editor.setupEndoflifeHandlers("li.#"+partId+" "); 765 766 }; 767 768 /** 769 * protoProcess definition 770 */ 771 772 this.protoProcess = $.template('<div class="process-details" id="${id}"><span class="process-display"><input class="input-process-display" value="${process_name}"></span><span class="process-text"><input class="input-process-text" value="${process_emissions}"></span> <span class="process-area"><input class="input-process-area" value="${process_factor}"></span><span class="process-unit">${process_unit}</span> <span class="process-carbon"></span> <span class="removeprocessaction">x</span></div>'); 773 774 775 /** 776 * Display the endoflife using protoEndoflife definition 777 * @param partId, endlifelife_id, endoflife_type, emissions, unit 778 * Call the setup handlers for endoflife 779 */ 780 this.receiveAddedProcess = function (part_id, process_id, name, emissions, unit, flag, factor, check){ 781 var proc_id = process_id; 782 783 $("#"+part_id+".part-details .process-appearance-super").append(Sourcemap.Editor.protoProcess, { 784 part_id: part_id, 785 id: process_id, 786 process_name: name, 787 process_emissions: emissions, 788 process_unit: unit, 789 process_factor: factor 790 }); 791 792 if(unit == "kg") { 793 var children = $("#"+part_id+".part-details .process-appearance-super").children(); 794 $(children[children.length-1]).find(".input-process-area").hide(); 795 } 796 797 Sourcemap.Editor.setupProcessHandlers("li.#"+part_id+" "); 798 799 }; 800 801 802 /** 803 * process and endoflife functions to do the visualizations 804 */ 805 this.receiveEndoflifeType = function(partId, id, type) { 806 $("#"+id+".endoflife-details .input-endoflife-display").val(Sourcemap.Util.utf8decode(type)); 807 }; 808 809 this.receiveEndoflifeEmissions = function(partId, id, emissions) { 810 $("#"+id+".endoflife-details .input-endoflife-emissions").val(Sourcemap.Util.utf8decode(emissions)); 811 }; 812 813 this.receiveRemovedEndoflife = function(id, endoflife_id) { 814 if(endoflife_id == 0) { $("div.endoflife-details:first").remove(); } 815 else { $("#"+id+".part-details div#"+endoflife_id+".endoflife-details").remove();} 816 }; 817 818 this.receiveProcessNameChange = function(id, process_name) { 819 $("#"+id+".process-details .input-process-display").val(Sourcemap.Util.utf8decode(process_name)); 820 }; 821 822 this.receiveProcessEmissionsChange = function(id, emissions) { 823 $("#"+id+".process-details .input-process-text").text(Sourcemap.Util.roundIt(Number(emissions),2)); 824 }; 825 826 this.receiveProcessUnitChange = function(id, unit) { 827 $("#"+id+".process-details .process-unit").val(Sourcemap.Util.utf8decode(unit)); 828 }; 829 830 this.receiveProcessFlagChange = function(id, flag) { 831 $("#"+id+".flag").val(Sourcemap.Util.utf8decode(flag)); 832 }; 833 834 this.receiveProcessFactorChange = function(id, factor, check) { 835 if (check ==1) { 836 $("#"+id+".process-details .input-process-area").val(Sourcemap.Util.utf8decode(factor)); 837 } 838 }; 839 840 this.receiveRemovedProcess = function(id, process_id) { 841 if(process_id == 0) { $("div.process-details:first").remove(); } 842 else { $("#"+id+".part-details div#"+process_id+".process-details").remove();} 843 }; 844 845 /** 846 * part functions to do visualization 847 */ 848 this.receivePartTotalsChanged = function(id) { 849 Sourcemap.Editor.updatePartPunch(id); 850 }; 851 852 this.receivePartNameChange = function(id, name) { 853 $("#"+id+" .input-name").val(Sourcemap.Util.utf8decode(name)); 854 }; 855 856 this.receivePartDescriptionChange = function(id, description) { 857 $("#"+id+" .input-description").val(Sourcemap.Util.utf8decode(description)); 858 }; 859 860 this.receivePartWeightChange = function(id, weight) { 861 $("#"+id+" .input-weight").val(Number(weight)); 862 }; 863 this.receivePartShippingChange = function(id, shipping) { 864 $("#"+id+" .part-shipping").text(Sourcemap.Util.roundIt(Number(shipping),2)); 865 }; 866 this.receivePartEmissionsChange = function(id, emissions) { 867 $("#"+id+" .part-punch-emissions").text(Sourcemap.Util.roundIt(Number(emissions),2)); 868 }; 869 this.receievePartRawEmissionsChange = function(id, rawemissions) { 870 $( "#"+id+" .part-rawemissions").val(Sourcemap.Util.roundIt(Number(rawemissions),2)); 871 }; 872 this.receivePartTransportEmissionsChange = function(id, transportemissions) { 873 $( "#"+id+" .part-punch-transportemissions").text("" + Sourcemap.Util.roundIt(Number(objectConfig.parts[id].shipping * (objectConfig.parts[id].weight/1000) * transportemissions),2)); 874 }; 875 this.receivePartViaChange = function(id, via) { 876 $( "#"+id+" .input-via").val(via); 877 }; 878 this.receivePartOriginChange = function(id, origin) { 879 $( "#"+id+" .input-origin").val(origin); 880 SMap.refreshMap(); 881 }; 882 883 var slugToEndoflifeCache = Array(); 884 var slug_end = Array(100); 885 var defaultSelectedTextEnd = "None Selected"; 886 var endoflife_id = 0; 887 888 /** 889 * Getting the endoflife list for the parts id 890 * @param partId, endoflife_id, element 891 * Get the slug for the part and call saveEndoflifeForPart 892 */ 893 894 this.getEndoflifeForPart = function(partId, endoflife_id, element) { 895 var pslug = objectConfig.parts[partId].linkid; 896 var slug = pslug.split("/")[1]; 897 Sourcemap.Editor.saveEndoflifeForPart(slug, partId, endoflife_id, element); 898 }; 899 900 /** 901 * Display the endoflife dropdown array for the part 902 * @param slug_endoflife ,element, this is the part slug and target_element 903 */ 904 this.populateEndoflifeOptions = function(slug_endoflife, element) { 905 var options = "<option>"+defaultSelectedTextEnd+"</option>"; 906 907 $.each(slug_endoflife, function(i,e) { 908 options += '<option value="' + e.id + '">' + e.type + '</option>'; 909 endoflife_id = e.id; 910 }); 911 endoflife_id = endoflife_id+1; 912 options += '<option value="' + endoflife_id + '">' + "reuse" + '</option>'; 913 // If this element is a select element use set options. Otherwise traverse up and set children. 914 if(element.tagName == "SELECT") { 915 $(element).html(options); 916 } else { 917 $( element).parents("select").html(options); 918 } 919 }; 920 921 922 923 /** 924 * Get the JSON requet from ObjectsModel, if it already exists then cache it. 925 * @param slug_endoflife, partId, endoflife_id, element 926 */ 927 this.saveEndoflifeForPart = function(slug_endoflife, partId, endoflife_id, element) { 928 slug_end = slug_endoflife; 929 if(slugToEndoflifeCache[slug_end] != null) { 930 Sourcemap.Editor.populateEndoflifeOptions(slugToEndoflifeCache[slug_end], element); 931 } else { 932 var saveEndoflife = {parts_endoflife_slug: slug_endoflife}; 933 var sendData = "data=" + JSON.stringify(saveEndoflife) + ""; 934 $.post(Sourcemap.siteurl+"objects/getEndoflife", sendData, function(response) { 935 var objects_endoflife = eval(response); var options = ""; 936 slugToEndoflifeCache[slug_endoflife] = objects_endoflife; 937 Sourcemap.Editor.populateEndoflifeOptions(slugToEndoflifeCache[slug_endoflife], element); 938 }); 939 } 940 941 /** 942 * Select an endoflife from the list 943 * call a fuunction is objects.js to add the endoflife for the part 944 */ 945 $(".endoflife-selected").unbind("change"); 946 $(".endoflife-selected").change(function() { 947 var endoflife_type = $(this).children("option:selected").text(); 948 949 if(typeof(objectConfig.parts[partId].endoflife) == 'undefined') { 950 endoflife_id =0; 951 } else { 952 endoflife_id = $(objectConfig.parts[partId].endoflife).size(); 953 } 954 955 956 if(endoflife_type == defaultSelectedTextEnd) {return;} 957 958 var endoflifeAlreadyAdded = false; 959 $("li.#"+partId+" .endoflife-appearance-super .input-endoflife-display").each(function(i, element) { 960 if(($(element).val() == endoflife_type) || (endoflife_id != 0)) {endoflifeAlreadyAdded = true; return false;} 961 return true; 962 }); 963 if(endoflifeAlreadyAdded) {return;} 964 965 966 967 var emissions = null; 968 var unit = null; 969 var unit_flag = false; 970 var flag = false; 971 972 $.each(slugToEndoflifeCache[slug_end], function(i, e) { 973 if(e.type == endoflife_type) { 974 emissions = e.emissions; unit = e.unit; 975 if(unit != "kg") { unit_flag = true; } 976 return false; 977 } 978 return true; 979 }); 980 981 982 objectConfig.addEndoflife(partId, endoflife_id, endoflife_type, emissions, unit, flag); 983 }); 984 }; 985 986 987 988 989 var slugToProcessCache = Array(); 990 var slug = Array(100); 991 var defaultSelectText = "None Selected:"; 992 var process_id = 0; 993 var flag = false; 994 var factor = 1; 995 var check_factor = 0; 996 997 /** 998 * Getting the processes list for the parts id 999 * @param part_id, process_id, elt 1000 * call saveProcessForPart function 1001 */ 1002 1003 this.getProcessesForPart = function(part_id, process_id, elt) { 1004 var part_slug = objectConfig.parts[part_id].linkid; 1005 var slug_part =part_slug.split("/")[1]; 1006 Sourcemap.Editor.saveProcessForPart(slug_part, part_id, process_id, elt); 1007 }; 1008 1009 /** 1010 * Display the process dropdown array 1011 */ 1012 this.populateProcessOptions =function(slug_process, elt) { 1013 var options ="<option>"+defaultSelectText+"</option>"; 1014 $.each(slug_process, function(i,e) { options +='<option value="' + e.id + '">' + e.name + '</option>';}); 1015 // If this element is a select element use set options. Otherwise traverse up and set children. 1016 if(elt.tagName == "SELECT") { 1017 $(elt).html(options); 1018 } else { 1019 $(elt).parents("select").html(options); 1020 } 1021 }; 1022 1023 1024 /** 1025 * Get the JSON request from ObjectsModel, if it already exists then cache it. 1026 */ 1027 1028 this.saveProcessForPart = function(data, part_id, process_id, elt){ 1029 slug = data; 1030 if(slugToProcessCache[slug] != null) { 1031 Sourcemap.Editor.populateProcessOptions(slugToProcessCache[slug], elt); 1032 } else { 1033 var saveData = { parts_slug : data }; 1034 1035 var sendData = "data=" + JSON.stringify(saveData) + ""; 1036 $.post(Sourcemap.siteurl+"objects/getProcesses", sendData, function(response) { 1037 var objects = eval(response); 1038 var options = ""; 1039 slugToProcessCache[slug] = objects; 1040 Sourcemap.Editor.populateProcessOptions(slugToProcessCache[slug], elt); 1041 }); 1042 } 1043 1044 //Selecting a process from the list and if it exists in cache then 1045 $(".process-selected").unbind("change"); 1046 $(".process-selected").change(function() { 1047 var process_name = $(this).children("option:selected").text(); 1048 if(typeof(objectConfig.parts[part_id].process) == "undefined") { 1049 process_id = 0; 1050 } else { 1051 process_id = $(objectConfig.parts[part_id].process).size(); 1052 } 1053 1054 1055 if(process_name == defaultSelectText) { return;} 1056 1057 var processAlreadyAdded = false; 1058 $(".process-appearance-super .input-process-display").each( function(i, element) { 1059 if($(element).val() == process_name) { processAlreadyAdded = true; return false;} 1060 return true; 1061 }); 1062 if(processAlreadyAdded) {return;} 1063 1064 // Get emissions and unit from cache 1065 var emissions = null; 1066 var unit = null; 1067 var unit_flag = false; 1068 1069 $.each(slugToProcessCache[slug], function(i,e) { 1070 if(e.name == process_name) { 1071 emissions = e.emissions; 1072 unit = e.unit; 1073 if (unit != "kg"){ unit_flag = true; } 1074 return false; 1075 } 1076 return true; 1077 }); 1078 1079 if (unit_flag == true) { check_factor = 1; factor = 1; } 1080 else{ factor = 0; check_factor = 0;} 1081 1082 1083 objectConfig.addProcess(part_id, process_id, process_name, emissions, unit, flag, factor, check_factor); 1084 }); 1085 }; 1086 1087 1088 // Misc Functions TODO These functions should probably be moved somewhere else... 1089 this.calculateUsage = function() { 1090 var factorVal = $("#poweruselist").find(":selected").val(); 1091 var usage = objectConfig.usageenergy * factorVal; 1092 $("#usepunch").text(Sourcemap.Util.roundIt(Number(usage),2)); 1093 objectConfig.usageemissions = Sourcemap.Util.roundIt(Number(usage),2); 1094 }; 1095 1096 1097 /** 1098 * setting up click functions set up the permissions 1099 * call save function to save the permission settings on the server 1100 */ 1101 1102 this.setupPermissions = function() { 1103 $(".permission_user").click(function() { 1104 Sourcemap.Editor.savePermissions("useredit"); 1105 Sourcemap.Editor.removePermissions(); 1106 $(".permission_user").addClass("selected"); 1107 }); 1108 $("#groupedit").change(function() { 1109 Sourcemap.Editor.savePermissionsGroups($("#groupedit option:selected").text()); 1110 Sourcemap.Editor.removePermissions(); 1111 $(".permission_group").addClass("selected"); 1112 }); 1113 $(".permission_group").click(function() { 1114 Sourcemap.Editor.savePermissionsGroups($("#groupedit option:selected").text()); 1115 Sourcemap.Editor.removePermissions(); 1116 $(".permission_group").addClass("selected"); 1117 }); 1118 1119 $(".permission_everyone").click(function() { 1120 Sourcemap.Editor.savePermissions("everyoneedit"); 1121 Sourcemap.Editor.removePermissions(); 1122 $(".permission_everyone").addClass("selected"); 1123 $(".permission_public").addClass("selected"); 1124 $(".permission_private").removeClass("selected"); 1125 }); 1126 $(".permission_public").click(function() { 1127 objectConfig.visibility = "public"; 1128 Sourcemap.Editor.savePermissionsObjects("public"); 1129 Sourcemap.Editor.removeVisibility(); 1130 $(".permission_public").addClass("selected"); 1131 }); 1132 $(".permission_private").click(function() { 1133 if($(".permission_public").hasClass("selected") && $(".permission_everyone").hasClass("selected")){ } 1134 else { 1135 objectConfig.visibility = "private"; 1136 Sourcemap.Editor.savePermissionsObjects("private"); 1137 Sourcemap.Editor.removeVisibility(); 1138 $(".permission_private").addClass("selected"); 1139 } 1140 }); 1141 }; 1142 1143 /** 1144 * Remove function visualizations 1145 */ 1146 this.removeVisibility = function() { 1147 $(".permission_public").removeClass("selected"); 1148 $(".permission_private").removeClass("selected"); 1149 }; 1150 1151 this.removePermissions = function() { 1152 $(".permission_user").removeClass("selected"); 1153 $(".permission_group").removeClass("selected"); 1154 $(".permission_everyone").removeClass("selected"); 1155 }; 1156 1157 /** 1158 * call objects controller/model to save the settings 1159 */ 1160 this.savePermissions = function(data) { 1161 var saveData = { 1162 permission_type: data, 1163 oid: objectConfig.oid 1164 }; 1165 1166 var sendData = "data=" + JSON.stringify(saveData) + ""; 1167 $.post(Sourcemap.siteurl+"objects/setpermissions", sendData); 1168 }; 1169 1170 this.savePermissionsGroups = function(data) { 1171 var saveData = { 1172 group_name: data, 1173 permission_type: "groupedit", 1174 oid: objectConfig.oid 1175 }; 1176 1177 var sendData = "data=" + JSON.stringify(saveData) + ""; 1178 $.post(Sourcemap.siteurl+"objects/setpermissions", sendData); 1179 }; 1180 1181 this.savePermissionsObjects = function(permission) { 1182 var saveData = { 1183 visibility: permission, 1184 oid: objectConfig.oid 1185 }; 1186 1187 var sendData = "data=" + JSON.stringify(saveData) + ""; 1188 $.post(Sourcemap.siteurl+"objects/setvisibility", sendData); 1189 }; 1190 1191 /** 1192 * Listen for object events 1193 * bind event calls the respective recevie function for visualization 1194 * bind events is triggered by setDescription in objects.js 1195 * 1196 */ 1197 1198 $("body").bind('objectDescriptionUpdated', function(e, description) { 1199 Sourcemap.Editor.receiveDescriptionChange(description); 1200 }); 1201 1202 /** 1203 * bind event is triggered by setOrigin in objects.js 1204 */ 1205 $("body").bind('originGeoError', function(e, id) { 1206 if(id == "object") { Sourcemap.Editor.receiveGeocodeError(".input-object-origin"); } 1207 else { Sourcemap.Editor.receiveGeocodeError("#"+id+" .input-origin"); } 1208 }); 1209 1210 /** 1211 * bind event is triggered by setOrigin in objects.js 1212 */ 1213 $("body").bind('originGeoMessage', function(e, id, msg) { 1214 if(id == "object") { Sourcemap.Editor.receiveGeocodeMessage(".input-object-origin", msg); } 1215 else { Sourcemap.Editor.receiveGeocodeMessage("#"+id+" .input-origin", msg); } 1216 }); 1217 1218 1219 /** 1220 * bind event is triggered by recalculatedObjectValues in objects.js 1221 */ 1222 1223 $("body").bind("objectTotalsCalculated", function(e, emis, embod, trans, ship, weight, processTotal, endoflifeTotal) { 1224 Sourcemap.Editor.receiveObjectTotals(emis,embod,trans,ship,weight, processTotal, endoflifeTotal); 1225 }); 1226 1227 /** 1228 * bind event is triggered by saveConfirmation in objects.js 1229 */ 1230 $("body").bind("saveObjectConfirmation", function(e, data) { Sourcemap.Editor.receiveSaveConfirmation(data);}); 1231 1232 /** 1233 * bind event is triggered by addPart in objects.js 1234 */ 1235 $("body").bind("partAdded", function(e, id, name, description, emissions, link) { 1236 Sourcemap.Editor.receiveAddedPart(id, name, description, emissions, link); 1237 }); 1238 1239 /** 1240 * bind event is triggered by removePart in objects.js 1241 */ 1242 1243 $("body").bind("partRemoved", function(e, id) { 1244 Sourcemap.Editor.receiveRemovedPart(id); 1245 SMap.refreshMap(); 1246 }); 1247 1248 1249 1250 1251 /** 1252 * Listen for endoflife events 1253 * bind event calls the respective recieve function for visualization 1254 * bind event is triggered by addEndflife function in object.js 1255 */ 1256 1257 $("body").bind("endoflifeAdded", function(e, partId, endoflife_id, endoflife_type, emissions, unit) { 1258 Sourcemap.Editor.receiveAddedEndoflife(partId, endoflife_id, endoflife_type, emissions, unit); 1259 }); 1260 1261 /** 1262 * bind event is triggered by setEndflifeType function in object.js 1263 */ 1264 $("body"). bind("endoflifeType", function (e, partId, endoflife_id, type) { 1265 Sourcemap.Editor.receiveEndoflifeEmissions(partId, endoflife_id, type); 1266 }); 1267 1268 /** 1269 * bind event is triggered by addEndflifeEmissions function in object.js 1270 */ 1271 1272 $("body"). bind("endoflifeEmissions", function (e, partId, endoflife_id, emissions) { 1273 Sourcemap.Editor.receiveEndoflifeEmissions(partId, endoflife_id, emissions); 1274 }); 1275 1276 /** 1277 * bind event is triggered by removeEndflife function in object.js 1278 */ 1279 1280 $("body").bind("endoflifeRemoved", function(e, id, endoflife_id) { 1281 Sourcemap.Editor.receiveRemovedEndoflife(id, endoflife_id); 1282 }); 1283 1284 1285 1286 /** 1287 * Listen for endoflife events 1288 * bind event calls the respective recieve function for visualization 1289 * bind event is triggered by addEndflife function in object.js 1290 */ 1291 $("body").bind("processAdded", function(e, part_id, process_id, name, emissions, unit, flag, factor, check) { 1292 Sourcemap.Editor.receiveAddedProcess(part_id, process_id, name, emissions, unit, flag, factor,check); 1293 }); 1294 1295 1296 /** 1297 * bind event is triggered by setProcessName in objects.js 1298 */ 1299 1300 $("body").bind("addingProcessName", function(e, id, process_name){ 1301 Sourcemap.Editor.receiveProcessNameChange(id, process_name); 1302 }); 1303 1304 /** 1305 * bind event is triggered by addProcessEmissions in objects.js 1306 */ 1307 $("body").bind("addingProcessEmissions", function(e, id, emissions){ 1308 Sourcemap.Editor.receiveProcessEmissionsChange(id, emissions); 1309 }); 1310 1311 /** 1312 * bind event is triggered by setProcessUnit in objects.js 1313 */ 1314 $("body").bind("addingProcessUnit", function(e, id, unit){ 1315 Sourcemap.Editor.receiveProcessUnitChange(id, unit); 1316 }); 1317 1318 /** 1319 * bind event is triggered by setProcessFlag in objects.js 1320 */ 1321 $("body").bind("addingProcessFlag", function(e, id, flag){ 1322 Sourcemap.Editor.receiveProcessFlagChange(id, flag); 1323 }); 1324 1325 /** 1326 * bind event is triggered by setProcessFactor in objects.js 1327 */ 1328 $("body").bind("addingProcessFactor", function(e, id, factor, check){ 1329 Sourcemap.Editor.receiveProcessFactorChange(id, factor, check); 1330 }); 1331 1332 /** 1333 * bind event is triggered by removeProcess in objects.js 1334 */ 1335 $("body").bind("processRemoved", function(e, id, process_id) { 1336 Sourcemap.Editor.receiveRemovedProcess(id, process_id); 1337 }); 1338 1339 1340 1341 /** 1342 * bind event is triggered by setPartVia in objects.js 1343 */ 1344 1345 $("body").bind("partTotalsChanged", function(e, id) { 1346 Sourcemap.Editor.receivePartTotalsChanged(id); 1347 }); 1348 1349 /** 1350 * bind event is triggered by setPartName in objects.js 1351 */ 1352 $("body").bind("partNameUpdated", function(e, id, name) { 1353 Sourcemap.Editor.receivePartNameChange(id, name); 1354 }); 1355 1356 /** 1357 * bind event is triggered by setPartDescription in objects.js 1358 */ 1359 $("body").bind("partDescriptionUpdated", function(e, id, description) { 1360 Sourcemap.Editor.receivePartDescriptionChange(id, description); 1361 }); 1362 1363 1364 /** 1365 * bind event is triggered by setPartWeight in objects.js 1366 */ 1367 $("body").bind("partWeightUpdated", function(e, id, weight) { 1368 Sourcemap.Editor.receivePartWeightChange(id, weight); 1369 }); 1370 1371 /** 1372 * bind event is triggered by setPartShipping in objects.js 1373 */ 1374 $("body").bind("partShippingUpdated", function(e, id, shipping) { 1375 Sourcemap.Editor.receivePartShippingChange(id, shipping); 1376 }); 1377 1378 /** 1379 * bind event is triggered by setPartEmissions in objects.js 1380 */ 1381 $("body").bind("partEmissionsUpdated", function(e, id, emissions) { 1382 Sourcemap.Editor.receivePartEmissionsChange(id, emissions); 1383 }); 1384 1385 /** 1386 * bind event is triggered by setPartRawEmissions in objects.js 1387 */ 1388 $("body").bind("partRawEmissionsUpdated", function(e, id, rawemissions) { 1389 Sourcemap.Editor.receievePartRawEmissionsChange(id, rawemissions); 1390 }); 1391 1392 /** 1393 * bind event is triggered by setPartTransportEmissions in objects.js 1394 */ 1395 $("body").bind("partTransportEmissionsUpdated", function(e, id, transportemissions) { 1396 Sourcemap.Editor.receivePartTransportEmissionsChange(id, transportemissions); 1397 }); 1398 1399 /** 1400 * bind event is triggered by setPartVia in objects.js 1401 */ 1402 $("body").bind("partViaUpdated", function(e, id, via) { 1403 Sourcemap.Editor.receivePartViaChange(id, via); 1404 }); 1405 1406 /** 1407 * bind event is triggered by setPartOrigin in objects.js 1408 */ 1409 $("body").bind("partOriginUpdated", function(e, id, origin) { 1410 Sourcemap.Editor.receivePartOriginChange(id, origin); 1411 }); 1412 1413 1414 $("body").bind("partSelected", function(e, id) { 1415 Sourcemap.Editor.partHighlight(id-1); 1416 }); 1417 1418 $("#more-description-button").click( function() { 1419 $("body").scrollTo($("#object-story"), 500); 1420 }); 1421 1422 /** 1423 * Parts Visualization Menu 1424 */ 1425 $("#partlist-close-button").click( function() { 1426 $("#part-visualization").slideToggle("normal",function(){ 1427 SMap.fitMap($("#part-visualization").css("display")=="block"); 1428 }); 1429 }); 1430 $(".visualization-close-button").click( function() { 1431 $(".visualization").css("display", "none"); 1432 }); 1433 $(".comment-visualization-button").click( function() { 1434 $(".visualization").css("display", "none"); 1435 $("#comment-visualization").slideDown(); 1436 }); 1437 $(".charting-visualization-button").click( function() { 1438 $(".visualization").css("display", "none"); 1439 $("#charting-visualization").slideDown(); 1440 }); 1441 $(".partlist-visualization-button").click( function() { 1442 $("#part-visualization").slideToggle("normal",function(){ 1443 SMap.fitMap($("#part-visualization").css("display")=="block"); 1444 }); 1445 }); 1446 1447 /** 1448 * Edit button visualization 1449 */ 1450 1451 $("#editsourcemapbutton").click( function() { 1452 Sourcemap.Editor.initializeEditMode(); 1453 $(".add-process").show(); 1454 $(".process-appearance-super").show(); 1455 $(".part-punch-processemissions").show(); 1456 1457 $(".add-endoflife").show(); 1458 $(".endoflife-appearance-super").show(); 1459 $(".part-punch-endoflifeemissions").show(); 1460 }); 1461 1462 /** 1463 * Save button visualization 1464 */ 1465 $("#savesourcemapbutton").click( function() { 1466 Sourcemap.Editor.stopEditMode(); 1467 $(".add-process").hide(); 1468 $(".process-appearance-super").hide(); 1469 $(".part-punch-processemissions").hide(); 1470 1471 $(".add-endoflife").hide(); 1472 $(".endoflife-appearance-super").hide(); 1473 $(".part-punch-endoflifeemissions").hide(); 1474 }); 1475 1476 if(!(Sourcemap.Template.usechooser)) { $("#addpartbutton, #partlist-menu").click( function() { objectConfig.addPart(Sourcemap.Template.partstubname, '', '0', ''); });} 1477 else { $("#addpartbutton, #partlist-menu").click( function() { Sourcemap.Editor.showPartChooser(); });} 1478 1479 /** 1480 * peermissions button, shar, lastleg button visualization 1481 */ 1482 1483 $("#permission-button").click( function() { 1484 $("#delivered-panel").slideUp("fast"); $("#lastleg-button").removeClass("selected"); 1485 $("#share-panel").slideUp("fast"); $("#share-button").removeClass("selected"); 1486 $("#permission-panel").slideToggle("fast"); $("#permission-button").toggleClass("selected"); 1487 }); 1488 $("#share-button").click( function() { 1489 $("#delivered-panel").slideUp("fast"); $("#lastleg-button").removeClass("selected"); 1490 $("#permission-panel").slideUp("fast"); $("#permission-button").removeClass("selected"); 1491 $("#share-panel").slideToggle("fast"); $("#share-button").toggleClass("selected"); 1492 }); 1493 $("#lastleg-button").click( function() { 1494 $("#share-panel").slideUp("fast"); $("#share-button").removeClass("selected"); 1495 $("#permission-panel").slideUp("fast"); $("#permission-button").removeClass("selected"); 1496 $("#delivered-panel").slideToggle("fast"); $("#lastleg-button").toggleClass("selected"); 1497 1498 }); 1499 1500 var smapOptions = {}; 1501 if ($('#part-visualization').css("display") != "none") 1502 { 1503 var pv = $('#part-visualization'); 1504 smapOptions.constrain = pv[0].clientWidth + '_rc'; 1505 } 1506 1507 smapOptions.userLocation = false; 1508 smapOptions.navPosition = new OpenLayers.Pixel(2,15); 1509 1510 // Initialize Map 1511 SMap = new Sourcemap.OpenSourcemap( 'smap', objectConfig, smapOptions ); 1512 if(GBrowserIsCompatible()){ SMap.geoCoder = new GClientGeocoder(); } 1513 1514 $(".list-expand").bind("click", function() { 1515 $(this).parents(".part-details").toggleClass("hover"); 1516 if($(this).text() == "+") { $(this).text("-"); } else { $(this).text("+"); } 1517 }); 1518 1519 1520 /** 1521 * show the footprrint only if objectConfig.showfootprint is on 1522 * same for showembodied, showtransport, showendoflife, showuse 1523 */ 1524 $("#showfootprint").click(function() { 1525 if(objectConfig.showfootprint != "on") { objectConfig.showfootprint = "on";} else { objectConfig.showfootprint = "";} 1526 if(objectConfig.showfootprint == "on") { checkval = true;} else { checkval = false;} 1527 $("#showembodied").attr('checked', checkval); 1528 objectConfig.showembodied = objectConfig.showfootprint; 1529 $("#showtransport").attr('checked', checkval); 1530 objectConfig.showtransport = objectConfig.showfootprint; 1531 $("#showprocess").attr('checked', checkval); 1532 objectConfig.showprocess = objectConfig.showfootprint; 1533 $("#showendoflife").attr('checked', checkval); 1534 objectConfig.showendoflife = objectConfig.showfootprint; 1535 1536 $("#showuse").attr('checked', checkval); 1537 objectConfig.showuse = objectConfig.showfootprint; 1538 objectConfig.recalculateObjectValues(); 1539 Sourcemap.Editor.toggleEmbodiedDisplay(); 1540 Sourcemap.Editor.toggleTransportDisplay(); 1541 Sourcemap.Editor.toggleProcessDisplay(); 1542 Sourcemap.Editor.toggleEndoflifeDisplay(); 1543 }); 1544 1545 $("#showembodied").click(function() { if(objectConfig.showembodied != "on") { objectConfig.showembodied = "on";} else { objectConfig.showembodied = "";} objectConfig.recalculateObjectValues(); Sourcemap.Editor.toggleEmbodiedDisplay();}); 1546 $("#showtransport").click(function() { if(objectConfig.showtransport != "on") { objectConfig.showtransport = "on";} else { objectConfig.showtransport = "";} objectConfig.recalculateObjectValues(); Sourcemap.Editor.toggleTransportDisplay();}); 1547 $("#showprocess").click(function() { if(objectConfig.showprocess != "on") { objectConfig.showprocess = "on";} else { objectConfig.showprocess = "";} objectConfig.recalculateObjectValues(); Sourcemap.Editor.toggleProcessDisplay();}); 1548 $("#showendoflife").click(function() { if(objectConfig.showendoflife != "on") { objectConfig.showendoflife = "on";} else { objectConfig.showendoflife = "";} objectConfig.recalculateObjectValues(); Sourcemap.Editor.toggleEndoflifeDisplay();}); 1549 $("#showuse").click(function() { if(objectConfig.showuse != "on") { objectConfig.showuse = "on";} else { objectConfig.showuse = "";} objectConfig.recalculateObjectValues();}); 1550 $("#showstats").click(function() { if(objectConfig.showstats != "on") { objectConfig.showstats = "on";} else { objectConfig.showstats = "";} objectConfig.recalculateObjectValues();}); 1551 1552 $("#usekwh").change(function() { 1553 objectConfig.usageenergy = $(this).val(); 1554 Sourcemap.Editor.calculateUsage(); 1555 }); 1556 $("#poweruselist").change(function() { 1557 var selectName = $(this).parent().find(":selected").text(); 1558 objectConfig.usagetype = selectName; 1559 Sourcemap.Editor.calculateUsage(); 1560 }); 1561 1562 // Live events 1563 $(".input-name").live("click", function(){ if($(this).val() == Sourcemap.Template.partstubname) { $(this).val(""); } return false;}); 1564 $(".input-origin").live("click", function(){ if($(this).val() == Sourcemap.Template.partlocationstubname) { $(this).val(""); } return false;}); 1565 1566 // Additional UI 1567 $("#part-visualization, .visualization").draggable({ containment: '#map_container', revert: true, handle: "#part-shell-menu, .visualization-menu" }); 1568 1569 objectConfig.recalculateObjectValues(); 1570 Sourcemap.Editor.processHashEvent(window.location.hash); 1571 1572 } 1573 }; 1574 1575 var SMap = null; 1576 1577 /** 1578 * Initial call (setup for edit mode) 1579 */ 1580 $(document).ready(function() { 1581 Sourcemap.Editor.init(); 1582 }); 1583