Normally collapseAutoAttach never gets called more than once.
However, for a component i'm developping i dynamically load a piece of HTML and insert it in an already loaded page.
There are collapsible fieldsets in there, so i have to call it!
I can imagine that other people have the same problem, so here is a solution.

The attached patch checks if the legend element already contains an "A" element, and skips the code for inserting it.

I noticed that the HEAD version of collapse.js is quite a different, so this patch is only for 4.7.3.
When the time comes for me to switch to 5.0, i'll post a new one.

Cheers, Danny

CommentFileSizeAuthor
collapse.js_2.patch1.93 KBdvdweide

Comments

killes@www.drop.org’s picture

Status: Reviewed & tested by the community » Needs review

Somebody review and advise on this, please.

agentrickard’s picture

This might be developer error. I had a similar bug report for 5.x (http://drupal.org/node/104314), which turned out to be caused by an incorrect use of drupal_add_js() which caused collapse.js to be invluded twice on the page. When this happened, the collapse function would fail in some browsers.

@dvdwelde, some questions:

1) How are you loading the collapse.js file?
2) Does collapse.js get loaded onto the finished output more than once (check source of the rendered page)?
3) How are you calling collapseAutoAttach? I don't think this needs to be called directly.

That said, the patch check might be good anyway, since it would help avoid errors.

Do you have some code (other than the patch) to review, so we can check if this is a core error of a programmer error?

dvdweide’s picture

Hi agentrickard, here are my answers:

1) How are you loading the collapse.js file?

It gets loaded by form.inc:theme_fieldset() as usual. I don't do anything special with it.

2) Does collapse.js get loaded onto the finished output more than once (check source of the rendered page)?

No, that doesn't happen, and the initial page loads just fine! The problem appears later, see question 3.

3) How are you calling collapseAutoAttach? I don't think this needs to be called directly.

I reload and replace pieces of the HTML with AJAX, and these pieces unfortunately contain collapsible fieldsets.
So, after the replacement i need to call collapseAutoAttach or they simply won't become collapsible.

If there is another way to handle this, i'd be glad to hear of it.

Danny

dvdweide’s picture

And some code, to be complete

realestate.js:

// Global killswitch
if (isJsEnabled()) {
  addLoadEvent(realestateAutoAttach);
}

/**
 * Attaches the Realestate behaviour to the Realestate form.
 */
function realestateAutoAttach() {
  var inputs = document.getElementsByTagName('input');
  for (i = 0; input = inputs[i]; i++) {
    if (input && hasClass(input, 'swlocselect')) {
      var uri = input.value;
      // Extract the button ID based on a substring of the input name: edit[foo][bar] -> foo-bar
      var selector = input.name.replace('-swlocselect', '').replace(/\]\[/g,'-').replace('[','-').replace(']','');
      var locwrapper = 'location-wrapper';
      var propwrapper = 'properties-wrapper';
      var switcher = new jsRealestateSwitch(uri, selector, locwrapper, propwrapper);
    }
    else if (input && hasClass(input, 'swlocbutton')) {
      input.style.display = 'none';
    }
  }
}

/**
 * JS Realestate object.
 */
function jsRealestateSwitch(uri, selector, locwrapper, propwrapper) {
  this.selector    = selector;
  this.locwrapper  = locwrapper;
  this.propwrapper = propwrapper;
  redirectFormChange(uri, $(selector), this);
}

/**
 * Handler for the form redirection submission.
 */
jsRealestateSwitch.prototype.onsubmit = function () {
  $(this.selector).form.submit();
}

/**
 * Handler for the form redirection completion.
 */
jsRealestateSwitch.prototype.oncomplete = function (data) {
  // Replace form and re-attach behaviour

  if (data['location']) {
    $(this.locwrapper).innerHTML = data['location'];
  }
  if (data['property']) {
    $(this.propwrapper).innerHTML = data['property'];
  }
  
  realestateAutoAttach();
  collapseAutoAttach();
}

/**
 * Handler for the form redirection error.
 */
jsRealestateSwitch.prototype.onerror = function (error) {
  alert('An error occurred:\n\n'+ error);
}

An alternative could be to call all functions passed to 'addLoadEvent()' with a parameter 'document' object on which to apply modifications.
This requires modification of all these handlers, though, that have to accept the parameter, including the drupal.js:onLoadEvent() function.

agentrickard’s picture

I don't know the solution, but my suspicion is that calling collapseAutoAttach() explicitly creates this problem. But what you're doing doesn't qualify as 'developer error' based on my original questions.

If the attached patch corrects this behavior, then I have no objection to it.

greggles’s picture

This apparently happens for some users in pathauto (see http://drupal.org/node/118539 for example) though it doesn't happen for me.

Any ideas on how/why that could happen but only intermittently?

dvdweide’s picture

Version: 4.7.3 » 4.7.x-dev

@agentrichard:
Yes, it is caused by calling collapseAutoAttach() twice. As i explained, i have to do this to make the fieldsets in the dynamically loaded part expandable.

@greggles:
No, this issue reports the exact oposite, where collapseAutoAttach() doesn't seem to be called at all
I use pathauto too, but i don't have these problems. But then, that issue applies to 5.0 while i'm using 4.7, so i can't really say too much about it.

Danny

seaneffel’s picture

I am having this problem and your advice at the top was helpful to determine that my theme was causing the problem. I switched to a standard Drupal theme and my admin page menus are again clickable and expandable. Where in my broken theme files should I look to hunt this down?

Thanks for the help.

ainigma32’s picture

Version: 4.7.x-dev » 4.7.9
Status: Needs review » Closed (won't fix)

I believe the desired behaviour was added in revision 14 see http://cvs.drupal.org/viewvc.py/drupal/drupal/misc/collapse.js?r1=1.13&r... which is in 6.x

Since I don't think anyone is backporting this to 4.x and it is not clear that this problem even applies to 5.x I'm going to set this issue to won't fix.

ainigma32’s picture

Status: Closed (won't fix) » Closed (fixed)

Housekeeping...