| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 2 /** 3 * @file 4 * Add JavaScript behaviors for the "options" form element type. 5 */ 6 7 (function($) { 8 9 Drupal.optionElements = Drupal.optionElements || {}; 10 11 Drupal.behaviors.optionsElement = function(context) { 12 $('div.form-options:not(.options-element-processed)', context).each(function() { 13 $(this).addClass('options-element-processed'); 14 var optionsElement = new Drupal.optionsElement(this); 15 Drupal.optionElements[optionsElement.identifier] = optionsElement; 16 }); 17 }; 18 19 /** 20 * Constructor for an options element. 21 */ 22 Drupal.optionsElement = function(element) { 23 var self = this; 24 25 // Find the original "manual" fields. 26 this.element = element; 27 this.manualElement = $(element).find('fieldset.options, div.fieldset.options').get(0); 28 this.manualOptionsElement = $(element).find('textarea').get(0); 29 this.manualDefaultValueElement = $(element).find('input.form-text').get(0); 30 this.keyTypeToggle = $(element).find('input.key-type-toggle').get(0); 31 this.multipleToggle = $(element).find('input.multiple-toggle').get(0); 32 33 // Setup variables containing the current status of the widget. 34 this.optgroups = $(element).is('.options-optgroups'); 35 this.multiple = $(element).is('.options-multiple'); 36 this.keyType = element.className.replace(/^.*?options-key-type-([a-z]+).*?$/, '$1'); 37 this.customKeys = Boolean(element.className.match(/options-key-custom/)); 38 this.identifier = this.manualOptionsElement.id + '-widget'; 39 this.enabled = $(this.manualOptionsElement).attr('readonly') == ''; 40 this.defaultValuePattern = $(element).find('input.default-value-pattern').val(); 41 42 if (this.defaultValuePattern) { 43 this.defaultValuePattern = new RegExp(this.defaultValuePattern); 44 } 45 46 // Warning messages. 47 this.keyChangeWarning = Drupal.t('Custom keys have been specified in this list. Removing these custom keys may change way data is stored. Are you sure you wish to remove these custom keys?'); 48 49 // Setup new DOM elements containing the actual options widget. 50 this.optionsElement = $('<div></div>').get(0); // Temporary DOM object. 51 this.optionsToggleElement = $(Drupal.theme('optionsElementToggle')).get(0); 52 this.optionAddElement = $(Drupal.theme('optionsElementAdd')).get(0); 53 54 // Add the options widget and toggle elements to the page. 55 $(this.manualElement).css('display', 'none').before(this.optionsElement).after(this.optionsToggleElement).after(this.optionAddElement); 56 57 // Enable add item link. 58 $(this.optionAddElement).find('a').click(function() { 59 var newOption = self.addOption($('table tr:last', self.optionsElement).get(0)); 60 $(newOption).find('input[type=text]:visible:first').focus(); 61 return false; 62 }); 63 64 // Enable the toggle action for manual entry of options. 65 $(this.optionsToggleElement).find('a').click(function() { 66 self.toggleMode(); 67 return false; 68 }); 69 70 // Add a handler for key type changes. 71 if (this.keyTypeToggle) { 72 $(this.keyTypeToggle).click(function() { 73 var checked = $(this).attr('checked'); 74 // Before switching the key type, ensure we're not destroying user keys. 75 if (!checked) { 76 var options = self.optionsFromText(); 77 var confirm = false; 78 if (self.keyType == 'associative') { 79 for (var n = 0; n < options.length; n++) { 80 if (options[n].key != options[n].value) { 81 confirm = true; 82 break; 83 } 84 } 85 } 86 if (confirm) { 87 if (window.confirm(self.keyChangeWarning)) { 88 self.setCustomKeys(false); 89 } 90 } 91 else { 92 self.setCustomKeys(false); 93 } 94 } 95 else { 96 self.setCustomKeys(true); 97 } 98 }); 99 } 100 101 // Add a handler for multiple value changes. 102 if (this.multipleToggle) { 103 $(this.multipleToggle).click(function(){ 104 self.setMultiple($(this).attr('checked')); 105 }); 106 } 107 108 // Be sure to show the custom keys if we have any errors. 109 if (Drupal.settings.optionsElement && Drupal.settings.optionsElement.errors) { 110 this.customKeys = true; 111 } 112 113 // Update the options widget with the current state of the textarea. 114 this.updateWidgetElements(); 115 116 // Highlight errors that may have occurred during Drupal validation. 117 if (Drupal.settings.optionsElement && Drupal.settings.optionsElement.errors) { 118 this.checkKeys(Drupal.settings.optionsElement.errors, 'error'); 119 } 120 } 121 122 /** 123 * Update the widget element based on the current values of the manual elements. 124 */ 125 Drupal.optionsElement.prototype.updateWidgetElements = function() { 126 var self = this; 127 128 // Create a new options element and replace the existing one. 129 var newElement = $(Drupal.theme('optionsElement', this)).get(0); 130 if ($(this.optionsElement).css('display') == 'none') { 131 $(newElement).css('display', 'none'); 132 } 133 $(this.optionsElement).replaceWith(newElement); 134 this.optionsElement = newElement; 135 136 // Manually set up table drag for the created table. 137 Drupal.settings.tableDrag = Drupal.settings.tableDrag || {}; 138 Drupal.settings.tableDrag[this.identifier] = { 139 'option-depth': { 140 0: { 141 action: 'depth', 142 hidden: false, 143 limit: 0, 144 relationship: 'self', 145 source: 'option-depth', 146 target: 'option-depth' 147 } 148 } 149 }; 150 151 // Allow indentation of elements if optgroups are supported. 152 if (this.optgroups) { 153 Drupal.settings.tableDrag[this.identifier]['option-parent'] = { 154 0: { 155 action: 'match', 156 hidden: false, 157 limit: 1, 158 relationship: 'parent', 159 source: 'option-value', 160 target: 'option-parent' 161 } 162 }; 163 } 164 165 // Enable button for adding options. 166 $('a.add', this.optionsElement).click(function() { 167 var newOption = self.addOption($(this).parents('tr:first').get(0)); 168 $(newOption).find('input[type=text]:visible:first').focus(); 169 return false; 170 }); 171 172 // Enable button for removing options. 173 $('a.remove', this.optionsElement).click(function() { 174 self.removeOption($(this).parents('tr:first').get(0)); 175 return false; 176 }); 177 178 // Add the same update action to all textfields and radios. 179 $('input', this.optionsElement).change(function() { 180 self.updateOptionElements(); 181 self.updateManualElements(); 182 }); 183 184 // Add a delayed update to textfields. 185 $('input.option-value', this.optionsElement).keyup(function(e) { 186 self.pendingUpdate(e); 187 }); 188 189 // Attach behaviors as normal to the new widget. 190 Drupal.attachBehaviors(this.optionsElement); 191 192 // Add an onDrop action to the table drag instance. 193 Drupal.tableDrag[this.identifier].onDrop = function() { 194 // Update the checkbox/radio buttons for selecting default values. 195 if (self.optgroups) { 196 self.updateOptionElements(); 197 } 198 // Update the options within the hidden text area. 199 self.updateManualElements(); 200 }; 201 202 // Add an onIndent action to the table drag row instances. 203 Drupal.tableDrag[this.identifier].row.prototype.onIndent = function() { 204 if (this.indents) { 205 $(this.element).addClass('indented'); 206 } 207 else { 208 $(this.element).removeClass('indented'); 209 } 210 }; 211 212 // Update the default value and optgroups. 213 this.updateOptionElements(); 214 } 215 216 /** 217 * Update the original form element based on the current state of the widget. 218 */ 219 Drupal.optionsElement.prototype.updateManualElements = function() { 220 var options = {}; 221 222 // Build a list of current options. 223 var previousOption = false; 224 $(this.optionsElement).find('input.option-value').each(function() { 225 var $row = $(this).is('tr') ? $(this) : $(this).parents('tr:first'); 226 var depth = $row.find('input.option-depth').val(); 227 if (depth == 1 && previousOption) { 228 if (typeof(options[previousOption]) != 'object') { 229 options[previousOption] = {}; 230 } 231 options[previousOption][this.value] = this.value; 232 } 233 else { 234 options[this.value] = this.value; 235 previousOption = this.value; 236 } 237 }); 238 this.options = options; 239 240 // Update the default value. 241 var defaultValue = this.multiple ? [] : ''; 242 var multiple = this.multiple; 243 $(this.optionsElement).find('input.option-default').each(function() { 244 if (this.checked && this.value) { 245 if (multiple) { 246 defaultValue.push(this.value); 247 } 248 else { 249 defaultValue = this.value; 250 } 251 } 252 }); 253 this.defaultValue = defaultValue; 254 255 // Update with the new text and trigger the change action on the field. 256 this.optionsToText(); 257 258 if (this.manualDefaultValueElement) { 259 // Don't wipe out custom pattern-matched default values. 260 defaultValue = multiple ? defaultValue.join(', ') : defaultValue; 261 if (defaultValue || !(this.defaultValuePattern && this.defaultValuePattern.test(this.manualDefaultValueElement.value))) { 262 this.manualDefaultValueElement.value = defaultValue; 263 $('.default-value-pattern-match', this.element).remove(); 264 } 265 } 266 267 $(this.manualOptionsElement).change(); 268 } 269 270 /** 271 * Several maintenance routines to update all rows of the options element. 272 * 273 * - Disable options for optgroups if indented. 274 * - Disable add and delete links if indented. 275 * - Match the default value radio button value to the key of the text element. 276 */ 277 Drupal.optionsElement.prototype.updateOptionElements = function() { 278 var self = this; 279 var previousRow = false; 280 var previousElement = false; 281 var $rows = $(this.optionsElement).find('tbody tr'); 282 283 $rows.each(function(index) { 284 var optionValue = $(this).find('input.option-value').val(); 285 var optionKey = $(this).find('input.option-key').val(); 286 287 // Update the elements key if matching the key and value. 288 if (self.keyType == 'associative') { 289 $(this).find('input.option-key').val(optionValue); 290 } 291 292 // Match the default value checkbox/radio button to the option's key. 293 $(this).find('input.option-default').val(optionKey ? optionKey : optionValue); 294 295 // Hide the add/remove links the row if indented. 296 var depth = $(this).find('input.option-depth').val(); 297 var defaultInput = $(this).find('input.option-default').get(0); 298 299 if (depth == 1) { 300 // Affect the parent row, adjusting properties for optgroup items. 301 $(previousElement).attr('disabled', true).attr('checked', false); 302 $(previousRow).addClass('optgroup').find('a.add, a.remove').css('display', 'none'); 303 $(this).find('a.add, a.remove').css('display', ''); 304 $(defaultInput).attr('disabled', false); 305 306 // Hide the key column for the optgroup. It would be nice if hiding 307 // columns worked in IE7, but for now this only works in IE8 and other 308 // standards-compliant browsers. 309 if (self.customKeys && (!$.browser.msie || $.browser.version >= 8)) { 310 $(previousRow).find('td.option-key-cell').css('display', 'none'); 311 $(previousRow).find('td.option-value-cell').attr('colspan', 2); 312 } 313 } 314 else { 315 // Set properties for normal options that are not optgroups. 316 $(defaultInput).attr('disabled', false); 317 $(this).removeClass('optgroup').find('a.add, a.remove').css('display', ''); 318 319 // Hide the key column. See note above for compatibility concerns. 320 if (self.customKeys && (!$.browser.msie || $.browser.version >= 8)) { 321 $(this).find('td.option-key-cell').css('display', ''); 322 $(this).find('td.option-value-cell').attr('colspan', ''); 323 } 324 previousElement = defaultInput; 325 previousRow = this; 326 } 327 }); 328 329 // Do not allow the last item to be removed. 330 if ($rows.size() == 1) { 331 $rows.find('a.remove').css('display', 'none') 332 } 333 334 // Disable items if needed. 335 if (this.enabled == false) { 336 this.disable(); 337 } 338 } 339 340 /** 341 * Add a new option below the current row. 342 */ 343 Drupal.optionsElement.prototype.addOption = function(currentOption) { 344 var self = this; 345 var windowHieght = $(document).height(); 346 var newOption = $(currentOption).clone() 347 .find('input.option-key').val(self.keyType == 'numeric' ? self.nextNumericKey() : '').end() 348 .find('input.option-value').val('').end() 349 .find('input.option-default').attr('checked', false).end() 350 .find('a.tabledrag-handle').remove().end() 351 .removeClass('drag-previous') 352 .insertAfter(currentOption) 353 .get(0); 354 355 // Scroll down to accomidate the new option. 356 $(window).scrollTop($(window).scrollTop() + $(document).height() - windowHieght); 357 358 // Make the new option draggable. 359 Drupal.tableDrag[this.identifier].makeDraggable(newOption); 360 361 // Enable button for adding options. 362 $('a.add', newOption).click(function() { 363 var newOption = self.addOption($(this).parents('tr:first').get(0)); 364 $(newOption).find('input[type=text]:visible:first').focus(); 365 return false; 366 }); 367 368 // Enable buttons for removing options. 369 $('a.remove', newOption).click(function() { 370 self.removeOption(newOption); 371 return false; 372 }); 373 374 // Add the update action to all textfields and radios. 375 $('input', newOption).change(function() { 376 self.updateOptionElements(); 377 self.updateManualElements(); 378 }); 379 380 // Add a delayed update to textfields. 381 $('input.option-value', newOption).keyup(function(e) { 382 self.pendingUpdate(e); 383 }); 384 385 this.updateOptionElements(); 386 this.updateManualElements(); 387 388 return newOption; 389 } 390 391 /** 392 * Remove the current row. 393 */ 394 Drupal.optionsElement.prototype.removeOption = function(currentOption) { 395 $(currentOption).remove(); 396 397 this.updateOptionElements(); 398 this.updateManualElements(); 399 } 400 401 /** 402 * Toggle link for switching between the JavaScript and manual entry. 403 */ 404 Drupal.optionsElement.prototype.toggleMode = function() { 405 if ($(this.optionsElement).is(':visible')) { 406 var height = $(this.optionsElement).height(); 407 $(this.optionsElement).css('display', 'none'); 408 $(this.optionAddElement).css('display', 'none'); 409 $(this.manualElement).css('display', '').find('textarea').height(height); 410 $(this.optionsToggleElement).find('a').text(Drupal.t('Normal entry')); 411 } 412 else { 413 this.updateWidgetElements(); 414 $(this.optionsElement).css('display', ''); 415 $(this.optionAddElement).css('display', ''); 416 $(this.manualElement).css('display', 'none'); 417 $(this.optionsToggleElement).find('a').text(Drupal.t('Manual entry')); 418 } 419 } 420 421 /** 422 * Enable the changing of options. 423 */ 424 Drupal.optionsElement.prototype.enable = function() { 425 this.enabled = true; 426 $(this.manualOptionsElement).attr('readonly', ''); 427 $(this.element).removeClass('options-disabled'); 428 429 $('a.add, a.remove, a.tabledrag-handle, div.form-option-add a', this.element).css('display', ''); 430 $('input.form-text', this.optionsElement).attr('disabled', ''); 431 }; 432 433 /** 434 * Disable the changing of options. 435 */ 436 Drupal.optionsElement.prototype.disable = function() { 437 this.enabled = false; 438 $(this.manualOptionsElement).attr('readonly', true); 439 $(this.element).addClass('options-disabled'); 440 441 $('a.add, a.remove, a.tabledrag-handle, div.form-option-add a', this.element).css('display', 'none'); 442 $('input.form-text', this.optionsElement).attr('disabled', 'disabled'); 443 }; 444 445 /** 446 * Enable entering of custom key values. 447 */ 448 Drupal.optionsElement.prototype.setCustomKeys = function(enabled) { 449 if (enabled) { 450 $(this.element).addClass('options-key-custom'); 451 } 452 else { 453 $(this.element).removeClass('options-key-custom'); 454 } 455 456 this.customKeys = enabled; 457 // Rebuild the options widget. 458 this.updateManualElements(); 459 this.updateWidgetElements(); 460 } 461 462 /** 463 * Change the current key type (associative, custom, numeric, none). 464 */ 465 Drupal.optionsElement.prototype.setKeyType = function(type) { 466 $(this.element) 467 .removeClass('options-key-type-' + this.keyType) 468 .addClass('options-key-type-' + type); 469 this.keyType = type; 470 // Rebuild the options widget. 471 this.updateManualElements(); 472 this.updateWidgetElements(); 473 } 474 475 /** 476 * Set the element's #multiple property. Boolean TRUE or FALSE. 477 */ 478 Drupal.optionsElement.prototype.setMultiple = function(multiple) { 479 if (multiple) { 480 $(this.element).addClass('options-multiple'); 481 } 482 else { 483 // Unselect all default options except the first. 484 $(this.optionsElement).find('input.option-default:checked:not(:first)').attr('checked', false); 485 this.updateManualElements(); 486 $(this.element).removeClass('options-multiple'); 487 } 488 this.multiple = multiple; 489 // Rebuild the options widget. 490 this.updateWidgetElements(); 491 }; 492 493 /** 494 * Highlight duplicate keys. 495 */ 496 Drupal.optionsElement.prototype.checkKeys = function(duplicateKeys, cssClass){ 497 $(this.optionsElement).find('input.option-key').each(function() { 498 if (duplicateKeys[this.value]) { 499 $(this).addClass(cssClass); 500 } 501 }); 502 }; 503 504 /** 505 * Update a field after a delay. 506 * 507 * Similar to immediately changing a field, this field as pending changes that 508 * will be updated after a delay. This includes textareas and textfields in 509 * which updating continuously would be a strain the server and actually slow 510 * down responsiveness. 511 */ 512 Drupal.optionsElement.prototype.pendingUpdate = function(e) { 513 var self = this; 514 515 // Only operate on "normal" keys, excluding special function keys. 516 // http://protocolsofmatrix.blogspot.com/2007/09/javascript-keycode-reference-table-for.html 517 if (!( 518 e.keyCode >= 48 && e.keyCode <= 90 || // 0-9, A-Z. 519 e.keyCode >= 93 && e.keyCode <= 111 || // Number pad. 520 e.keyCode >= 186 && e.keyCode <= 222 || // Symbols. 521 e.keyCode == 8) // Backspace. 522 ) { 523 return; 524 } 525 526 if (this.updateDelay) { 527 clearTimeout(this.updateDelay); 528 } 529 530 this.updateDelay = setTimeout(function(){ 531 self.updateOptionElements(); 532 self.updateManualElements(); 533 }, 500); 534 }; 535 536 /** 537 * Given an object of options, convert it to a text string. 538 */ 539 Drupal.optionsElement.prototype.optionsToText = function() { 540 var $rows = $('tbody tr', this.optionsElement); 541 var output = ''; 542 var inGroup = false; 543 var rowCount = $rows.size(); 544 var defaultValues = []; 545 546 for (var rowIndex = 0; rowIndex < rowCount; rowIndex++) { 547 var isOptgroup = $rows.eq(rowIndex).is('.optgroup'); 548 var isChild = $rows.eq(rowIndex).is('.indented'); 549 var key = $rows.eq(rowIndex).find('input.option-key').val(); 550 var value = $rows.eq(rowIndex).find('input.option-value').val(); 551 552 // Handle groups. 553 if (this.optgroups && value !== '' && isOptgroup) { 554 output += '<' + ((key !== '') ? (key + '|') : '') + value + '>' + "\n"; 555 inGroup = true; 556 } 557 // Typical key|value pairs. 558 else { 559 // Exit out of any groups. 560 if (this.optgroups && inGroup && !isChild) { 561 output += "<>\n"; 562 inGroup = false; 563 } 564 565 // Add the row for the option. 566 if (this.keyType == 'none' || this.keyType == 'associative') { 567 output += value + "\n"; 568 } 569 else if (value == '') { 570 output += "\n"; 571 } 572 else { 573 output += ((key !== '') ? (key + '|') : '') + value + "\n"; 574 } 575 } 576 } 577 578 this.manualOptionsElement.value = output; 579 }; 580 581 /** 582 * Given a text string, convert it to an object. 583 */ 584 Drupal.optionsElement.prototype.optionsFromText = function() { 585 // Use jQuery val() instead of value because it fixes Windows line breaks. 586 var rows = $(this.manualOptionsElement).val().match(/^.*$/mg); 587 var parent = ''; 588 var options = []; 589 var defaultValues = {}; 590 591 // Drop the last row if empty. 592 if (rows.length && rows[rows.length - 1] == '') { 593 rows.pop(); 594 } 595 596 if (this.manualDefaultValueElement) { 597 if (this.multiple) { 598 var defaults = this.manualDefaultValueElement.value.split(','); 599 for (var n = 0; n < defaults.length; n++) { 600 var defaultValue = defaults[n].replace(/^[ ]*(.*?)[ ]*$/, '$1'); // trim(). 601 defaultValues[defaultValue] = defaultValue; 602 } 603 } 604 else { 605 var defaultValue = this.manualDefaultValueElement.value.replace(/^[ ]*(.*?)[ ]*$/, '$1'); // trim(). 606 defaultValues[defaultValue] = defaultValue; 607 } 608 } 609 610 for (var n = 0; n < rows.length; n++) { 611 var row = rows[n].replace(/^[ \r\n]*(.*?)[ \r\n]*$/, '$1'); // trim(). 612 var key = ''; 613 var value = ''; 614 var checked = false; 615 var hasChildren = false; 616 var groupClear = false; 617 618 var matches = {}; 619 // Row is a group. 620 if (this.optgroups && (matches = row.match(/^\<((([^>|]*)\|)?([^>]*))\>$/))) { 621 if (matches[0] == '<>') { 622 parent = ''; 623 groupClear = true; 624 } 625 else { 626 key = matches[3] ? matches[3] : ''; 627 parent = value = matches[4]; 628 hasChildren = true; 629 } 630 } 631 // Check if this row is a key|value pair. 632 else if ((this.keyType == 'mixed' || this.keyType == 'numeric' || this.keyType == 'custom') && (matches = row.match(/^([^|]+)\|(.*)$/))) { 633 key = matches[1]; 634 value = matches[2]; 635 checked = defaultValues[key]; 636 } 637 // Row is a straight value. 638 else { 639 key = (this.keyType == 'mixed' || this.keyType == 'numeric') ? '' : row; 640 value = row; 641 if (!key && this.keyType == 'mixed') { 642 checked = defaultValues[value]; 643 } 644 else { 645 checked = defaultValues[key]; 646 } 647 } 648 649 if (!groupClear) { 650 options.push({ 651 key: key, 652 value: value, 653 parent: (value !== parent ? parent : ''), 654 hasChildren: hasChildren, 655 checked: (checked ? 'checked' : false) 656 }); 657 } 658 } 659 660 // Convert options to numeric if no key is specified. 661 if (this.keyType == 'numeric') { 662 var nextKey = this.nextNumericKey(); 663 for (var n = 0; n < options.length; n++) { 664 if (options[n].key == '') { 665 options[n].key = nextKey; 666 nextKey++; 667 } 668 } 669 } 670 671 return options; 672 }; 673 674 /** 675 * Utility method to get the next numeric option in a list of options. 676 */ 677 Drupal.optionsElement.prototype.nextNumericKey = function(options) { 678 this.keyType = 'custom'; 679 options = this.optionsFromText(); 680 this.keyType = 'numeric'; 681 682 var maxKey = -1; 683 for (var n = 0; n < options.length; n++) { 684 if (options[n].key.match(/^[0-9]+$/)) { 685 maxKey = Math.max(maxKey, options[n].key); 686 } 687 } 688 return maxKey + 1; 689 }; 690 691 /** 692 * Theme function for creating a new options element. 693 * 694 * @param optionsElement 695 * An options element object. 696 */ 697 Drupal.theme.prototype.optionsElement = function(optionsElement) { 698 var output = ''; 699 var options = optionsElement.optionsFromText(); 700 var hasDefault = optionsElement.manualDefaultValueElement; 701 var defaultType = optionsElement.multiple ? 'checkbox' : 'radio'; 702 var keyType = optionsElement.customKeys ? 'textfield' : 'hidden'; 703 704 // Helper function to print out a single draggable option row. 705 function tableDragRow(key, value, parent, indent, status) { 706 var output = ''; 707 output += '<tr class="draggable' + (indent > 0 ? ' indented' : '') + '">' 708 output += '<td class="' + (hasDefault ? 'option-default-cell' : 'option-order-cell') + '">'; 709 for (var n = 0; n < indent; n++) { 710 output += Drupal.theme('tableDragIndentation'); 711 } 712 output += '<input type="hidden" class="option-parent" value="' + parent.replace(/"/g, '"') + '" />'; 713 output += '<input type="hidden" class="option-depth" value="' + indent + '" />'; 714 if (hasDefault) { 715 output += '<input type="' + defaultType + '" name="' + optionsElement.identifier + '-default" class="form-radio option-default" value="' + key.replace(/"/g, '"') + '"' + (status == 'checked' ? ' checked="checked"' : '') + (status == 'disabled' ? ' disabled="disabled"' : '') + ' />'; 716 } 717 output += '</td><td class="' + (keyType == 'textfield' ? 'option-key-cell' : 'option-value-cell') +'">'; 718 output += '<input type="' + keyType + '" class="' + (keyType == 'textfield' ? 'form-text ' : '') + 'option-key" value="' + key.replace(/"/g, '"') + '" />'; 719 output += keyType == 'textfield' ? '</td><td class="option-value-cell">' : ''; 720 output += '<input class="form-text option-value" type="text" value="' + value.replace(/"/g, '"') + '" />'; 721 output += '</td><td class="option-actions-cell">' 722 output += '<a class="add" title="' + Drupal.t('Add new option') + '" href="#"' + (status == 'disabled' ? ' style="display: none"' : '') + '><span class="add">' + Drupal.t('Add') + '</span></a>'; 723 output += '<a class="remove" title="' + Drupal.t('Remove option') + '" href="#"' + (status == 'disabled' ? ' style="display: none"' : '') + '><span class="remove">' + Drupal.t('Remove') + '</span></a>'; 724 output += '</td>'; 725 output += '</tr>'; 726 return output; 727 } 728 729 output += '<div class="options-widget">'; 730 output += '<table id="' + optionsElement.identifier + '">'; 731 732 output += '<thead><tr>'; 733 output += '<th>' + (hasDefault ? Drupal.t('Default') : ' ') + '</th>'; 734 output += keyType == 'textfield' ? '<th>' + Drupal.t('Key') + '</th>' : ''; 735 output += '<th>' + Drupal.t('Value') + '</th>'; 736 output += '<th> </th>'; 737 output += '</tr></thead>'; 738 739 output += '<tbody>'; 740 741 // Make sure that at least a few options exist if empty. 742 if (!options.length) { 743 var newOption = { 744 key: '', 745 value: '', 746 parent: '', 747 hasChildren: false, 748 checked: false 749 } 750 options.push(newOption); 751 options.push(newOption); 752 options.push(newOption); 753 } 754 755 for (var n = 0; n < options.length; n++) { 756 var option = options[n]; 757 var depth = option.parent === '' ? 0 : 1; 758 var checked = !option.hasChildren && option.checked; 759 output += tableDragRow(option.key, option.value, option.parent, depth, checked); 760 } 761 762 output += '</tbody>'; 763 output += '</table>'; 764 765 if (optionsElement.defaultValuePattern && optionsElement.manualDefaultValueElement && optionsElement.defaultValuePattern.test(optionsElement.manualDefaultValueElement.value)) { 766 output += Drupal.theme('optionsElementPatternMatch', optionsElement.manualDefaultValueElement.value); 767 } 768 769 output += '</div>'; 770 771 return output; 772 }; 773 774 Drupal.theme.prototype.optionsElementPatternMatch = function(matchedValue) { 775 return '<div class="default-value-pattern-match"><span>' + Drupal.t('Manual default value') + '</span>: ' + matchedValue + '</div>'; 776 }; 777 778 Drupal.theme.prototype.optionsElementAdd = function() { 779 return '<div class="form-option-add"><a href="#">' + Drupal.t('Add item') + '</a></div>'; 780 }; 781 782 Drupal.theme.prototype.optionsElementToggle = function() { 783 return '<div class="form-options-manual"><a href="#">' + Drupal.t('Manual entry') + '</a></div>'; 784 }; 785 786 Drupal.theme.tableDragChangedMarker = function () { 787 return ' '; 788 }; 789 790 Drupal.theme.tableDragChangedWarning = function() { 791 return ' '; 792 }; 793 794 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |