Index: trunk/extensions/SemanticForms/libs/SemanticForms.js |
— | — | @@ -308,74 +308,102 @@ |
309 | 309 | */ |
310 | 310 | |
311 | 311 | // Display a div that would otherwise be hidden by "show on select". |
312 | | -function showDiv(div_id) { |
313 | | - jQuery('#' + div_id).find(".hiddenBySF").removeClass('hiddenBySF'); |
314 | | - jQuery('#' + div_id).show(); |
| 312 | +function showDiv(div_id, instanceWrapperDiv) { |
| 313 | + if (instanceWrapperDiv != null) { |
| 314 | + instanceWrapperDiv.find('[origID=' + div_id + ']').find(".hiddenBySF").removeClass('hiddenBySF'); |
| 315 | + instanceWrapperDiv.find('[origID=' + div_id + ']').show(); |
| 316 | + } else { |
| 317 | + jQuery('#' + div_id).find(".hiddenBySF").removeClass('hiddenBySF'); |
| 318 | + jQuery('#' + div_id).show(); |
| 319 | + } |
315 | 320 | } |
316 | 321 | |
317 | 322 | // Hide a div due to "show on select". The CSS class is there so that SF can |
318 | 323 | // ignore the div's contents when the form is submitted. |
319 | | -function hideDiv(div_id) { |
320 | | - jQuery('#' + div_id).find("span, div").addClass('hiddenBySF'); |
321 | | - jQuery('#' + div_id).hide(); |
| 324 | +function hideDiv(div_id, instanceWrapperDiv) { |
| 325 | + if (instanceWrapperDiv != null) { |
| 326 | + instanceWrapperDiv.find('[origID=' + div_id + ']').find("span, div").addClass('hiddenBySF'); |
| 327 | + instanceWrapperDiv.find('[origID=' + div_id + ']').hide(); |
| 328 | + } else { |
| 329 | + jQuery('#' + div_id).find("span, div").addClass('hiddenBySF'); |
| 330 | + jQuery('#' + div_id).hide(); |
| 331 | + } |
322 | 332 | } |
323 | 333 | |
324 | 334 | // Show this div if the current value is any of the relevant options - |
325 | 335 | // otherwise, hide it. |
326 | | -function showDivIfSelected(options, div_id, inputVal) { |
| 336 | +function showDivIfSelected(options, div_id, inputVal, instanceWrapperDiv) { |
327 | 337 | for (var j in options) { |
328 | 338 | // If it's a listbox and the user has selected more than one |
329 | 339 | // value, it'll be an array - handle either case. |
330 | 340 | if ((jQuery.isArray(inputVal) && jQuery.inArray(options[j], inputVal) >= 0) || |
331 | 341 | (!jQuery.isArray(inputVal) && (inputVal == options[j]))) { |
332 | | - showDiv(div_id); |
| 342 | + showDiv(div_id, instanceWrapperDiv); |
333 | 343 | return; |
334 | 344 | } |
335 | 345 | } |
336 | | - hideDiv(div_id); |
| 346 | + hideDiv(div_id, instanceWrapperDiv); |
337 | 347 | } |
338 | 348 | |
339 | 349 | // Used for handling 'show on select' for the 'dropdown' and 'listbox' inputs. |
340 | | -jQuery.fn.showIfSelected = function() { |
| 350 | +jQuery.fn.showIfSelected = function(partOfMultiple) { |
341 | 351 | var inputVal = this.val(); |
342 | | - var showOnSelectVals = sfgShowOnSelect[this.attr("id")]; |
| 352 | + if (partOfMultiple) { |
| 353 | + var showOnSelectVals = sfgShowOnSelect[this.attr("origID")]; |
| 354 | + var instanceWrapperDiv = this.closest(".multipleTemplateInstance"); |
| 355 | + } else { |
| 356 | + var showOnSelectVals = sfgShowOnSelect[this.attr("id")]; |
| 357 | + var instanceWrapperDiv = null; |
| 358 | + } |
343 | 359 | for (i in showOnSelectVals) { |
344 | 360 | var options = showOnSelectVals[i][0]; |
345 | 361 | var div_id = showOnSelectVals[i][1]; |
346 | | - showDivIfSelected(options, div_id, inputVal); |
| 362 | + showDivIfSelected(options, div_id, inputVal, instanceWrapperDiv); |
347 | 363 | } |
348 | 364 | } |
349 | 365 | |
350 | 366 | // Show this div if any of the relevant selections are checked - |
351 | 367 | // otherwise, hide it. |
352 | | -jQuery.fn.showDivIfChecked = function(options, div_id) { |
| 368 | +jQuery.fn.showDivIfChecked = function(options, div_id, instanceWrapperDiv) { |
353 | 369 | for (var i in options) { |
354 | 370 | if (jQuery(this).find('[value="' + options[i] + '"]').is(":checked")) { |
355 | | - showDiv(div_id); |
| 371 | + showDiv(div_id, instanceWrapperDiv); |
356 | 372 | return; |
357 | 373 | } |
358 | 374 | } |
359 | | - hideDiv(div_id); |
| 375 | + hideDiv(div_id, instanceWrapperDiv); |
360 | 376 | } |
361 | 377 | |
362 | 378 | // Used for handling 'show on select' for the 'checkboxes' and 'radiobutton' |
363 | 379 | // inputs. |
364 | | -jQuery.fn.showIfChecked = function() { |
365 | | - var showOnSelectVals = sfgShowOnSelect[this.attr("id")]; |
| 380 | +jQuery.fn.showIfChecked = function(partOfMultiple) { |
| 381 | + if (partOfMultiple) { |
| 382 | + var showOnSelectVals = sfgShowOnSelect[this.attr("origID")]; |
| 383 | + var instanceWrapperDiv = this.closest(".multipleTemplateInstance"); |
| 384 | + } else { |
| 385 | + var showOnSelectVals = sfgShowOnSelect[this.attr("id")]; |
| 386 | + var instanceWrapperDiv = null; |
| 387 | + } |
366 | 388 | for (i in showOnSelectVals) { |
367 | 389 | var options = showOnSelectVals[i][0]; |
368 | 390 | var div_id = showOnSelectVals[i][1]; |
369 | | - this.showDivIfChecked(options, div_id); |
| 391 | + this.showDivIfChecked(options, div_id, instanceWrapperDiv); |
370 | 392 | } |
371 | 393 | } |
372 | 394 | |
373 | 395 | // Used for handling 'show on select' for the 'checkbox' input. |
374 | | -jQuery.fn.showIfCheckedCheckbox = function() { |
375 | | - var div_id = sfgShowOnSelect[this.attr("id")]; |
| 396 | +jQuery.fn.showIfCheckedCheckbox = function(partOfMultiple) { |
| 397 | + if (partOfMultiple) { |
| 398 | + var div_id = sfgShowOnSelect[this.attr("origID")]; |
| 399 | + var instanceWrapperDiv = this.closest(".multipleTemplateInstance"); |
| 400 | + } else { |
| 401 | + var div_id = sfgShowOnSelect[this.attr("id")]; |
| 402 | + var instanceWrapperDiv = null; |
| 403 | + } |
376 | 404 | if (jQuery(this).is(":checked")) { |
377 | | - showDiv(div_id); |
| 405 | + showDiv(div_id, instanceWrapperDiv); |
378 | 406 | } else { |
379 | | - hideDiv(div_id); |
| 407 | + hideDiv(div_id, instanceWrapperDiv); |
380 | 408 | } |
381 | 409 | } |
382 | 410 | |
— | — | @@ -596,8 +624,16 @@ |
597 | 625 | .addClass('multipleTemplate') // backwards compatibility |
598 | 626 | .removeAttr("id") |
599 | 627 | .css("display", "block"); |
| 628 | + |
| 629 | + // Add on a new attribute, "origID", representing the ID of all |
| 630 | + // HTML elements that had an ID; and delete the actual ID attribute |
| 631 | + // of any divs and spans (presumably, these exist only for the |
| 632 | + // sake of "show on select"). We do the deletions because no two |
| 633 | + // elements on the page are allowed to have the same ID. |
| 634 | + new_div.find('[id!=""]').attr('origID', function() { return this.id; }); |
| 635 | + new_div.find('div[id!=""], span[id!=""]').removeAttr('id'); |
600 | 636 | |
601 | | - // Make internal ID unique for the relevant divs and spans, and replace |
| 637 | + // Make internal ID unique for the relevant form elements, and replace |
602 | 638 | // the [num] index in the element names with an actual unique index |
603 | 639 | new_div.find("input, select, textarea").each( |
604 | 640 | function() { |
— | — | @@ -650,9 +686,11 @@ |
651 | 687 | new_div.find('a').attr('href', function() { |
652 | 688 | return this.href.replace(/input_/g, 'input_' + num_elements + '_'); |
653 | 689 | }); |
| 690 | + /* |
654 | 691 | new_div.find('span').attr('id', function() { |
655 | 692 | return this.id.replace(/span_/g, 'span_' + num_elements + '_'); |
656 | 693 | }); |
| 694 | + */ |
657 | 695 | |
658 | 696 | // Add the new instance |
659 | 697 | this.closest(".multipleTemplateWrapper") |
— | — | @@ -678,30 +716,13 @@ |
679 | 717 | .fadeOut('fast', function() { jQuery(this).remove(); }); |
680 | 718 | }); |
681 | 719 | |
682 | | - // Enable autocompletion |
683 | | - new_div.find('.autocompleteInput').attachAutocomplete(); |
684 | | - |
685 | | - // Apply the relevant Javascript call for all FancyBox, combobox |
686 | | - // and autogrow instances in this div. |
687 | | - new_div.find('.sfFancyBox').fancybox({ |
688 | | - 'width' : '75%', |
689 | | - 'height' : '75%', |
690 | | - 'autoScale' : false, |
691 | | - 'transitionIn' : 'none', |
692 | | - 'transitionOut' : 'none', |
693 | | - 'type' : 'iframe', |
694 | | - 'overlayColor' : '#222', |
695 | | - 'overlayOpacity' : '0.8' |
696 | | - }); |
697 | 720 | // Somewhat of a hack - remove the divs that the combobox() call |
698 | 721 | // adds on, so that we can just call combobox() again without |
699 | 722 | // duplicating anything. There's probably a nicer way to do this, |
700 | 723 | // that doesn't involve removing and then recreating divs. |
701 | 724 | new_div.find('.sfComboBoxActual').remove(); |
702 | | - new_div.find('.sfComboBox').combobox(); |
703 | 725 | |
704 | | - // Handle AutoGrow as well. |
705 | | - new_div.find('.autoGrow').autoGrow(); |
| 726 | + new_div.initializeJSElements(true); |
706 | 727 | |
707 | 728 | // Initialize new inputs |
708 | 729 | new_div.find("input, select, textarea").each( |
— | — | @@ -726,40 +747,42 @@ |
727 | 748 | |
728 | 749 | } |
729 | 750 | |
730 | | -var num_elements = 0; |
731 | | - |
732 | | -// Once the document has finished loading, set up everything! |
733 | | -jQuery(document).ready(function() { |
734 | | - jQuery(".sfShowIfSelected").each( function() { |
735 | | - jQuery(this).showIfSelected(); |
| 751 | +/** |
| 752 | + * Initialize all the JS-using elements contained within this block - can be |
| 753 | + * called for either the entire HTML body, or for a div representing an |
| 754 | + * instance of a multiple-instance template. |
| 755 | + */ |
| 756 | +jQuery.fn.initializeJSElements = function(partOfMultiple) { |
| 757 | + this.find(".sfShowIfSelected").each( function() { |
| 758 | + jQuery(this).showIfSelected(partOfMultiple); |
736 | 759 | jQuery(this).change( function() { |
737 | | - jQuery(this).showIfSelected(); |
| 760 | + jQuery(this).showIfSelected(partOfMultiple); |
738 | 761 | }); |
739 | 762 | }); |
740 | 763 | |
741 | | - jQuery(".sfShowIfChecked").each( function() { |
742 | | - jQuery(this).showIfChecked(); |
| 764 | + this.find(".sfShowIfChecked").each( function() { |
| 765 | + jQuery(this).showIfChecked(partOfMultiple); |
743 | 766 | jQuery(this).click( function() { |
744 | | - jQuery(this).showIfChecked(); |
| 767 | + jQuery(this).showIfChecked(partOfMultiple); |
745 | 768 | }); |
746 | 769 | }); |
747 | 770 | |
748 | | - jQuery(".sfShowIfCheckedCheckbox").each( function() { |
749 | | - jQuery(this).showIfCheckedCheckbox(); |
| 771 | + this.find(".sfShowIfCheckedCheckbox").each( function() { |
| 772 | + jQuery(this).showIfCheckedCheckbox(partOfMultiple); |
750 | 773 | jQuery(this).click( function() { |
751 | | - jQuery(this).showIfCheckedCheckbox(); |
| 774 | + jQuery(this).showIfCheckedCheckbox(partOfMultiple); |
752 | 775 | }); |
753 | 776 | }); |
754 | 777 | |
755 | | - jQuery(".remover").click( function() { |
| 778 | + this.find(".remover").click( function() { |
756 | 779 | // Remove the encompassing div for this instance. |
757 | 780 | jQuery(this).closest(".multipleTemplateInstance") |
758 | 781 | .fadeOut('fast', function() { jQuery(this).remove(); }); |
759 | 782 | }); |
760 | | - jQuery(".autocompleteInput").attachAutocomplete(); |
761 | | - jQuery(".sfComboBox").combobox(); |
762 | | - jQuery(".autoGrow").autoGrow(); |
763 | | - jQuery(".sfFancyBox").fancybox({ |
| 783 | + this.find('.autocompleteInput').attachAutocomplete(); |
| 784 | + this.find('.sfComboBox').combobox(); |
| 785 | + this.find('.autoGrow').autoGrow(); |
| 786 | + this.find('.sfFancyBox').fancybox({ |
764 | 787 | 'width' : '75%', |
765 | 788 | 'height' : '75%', |
766 | 789 | 'autoScale' : false, |
— | — | @@ -769,7 +792,14 @@ |
770 | 793 | 'overlayColor' : '#222', |
771 | 794 | 'overlayOpacity' : '0.8' |
772 | 795 | }); |
| 796 | +} |
773 | 797 | |
| 798 | +var num_elements = 0; |
| 799 | + |
| 800 | +// Once the document has finished loading, set up everything! |
| 801 | +jQuery(document).ready(function() { |
| 802 | + jQuery('body').initializeJSElements(false); |
| 803 | + |
774 | 804 | jQuery('.multipleTemplateAdder').click( function() { jQuery(this).addInstance(); } ); |
775 | 805 | jQuery('.multipleTemplateList').sortable({ |
776 | 806 | axis: 'y', |