Ok, this is pretty slick so I'll share =)

I'm using this module for some larger more complicated forms, as it works very well. However, when a field error occurs on save (ie. field required, unallowed value, etc) the user is left to hunt for for the field within the tabs (if it's not on the first tab).

So this patch will apply a standard "error" css class to tabs that have errored fields so people can theme them differently, and it will switch the user to the first tab with an error.

It also has the CCK Field Access check in place from my previous feature request:

#275461: Render tabs according to CCK #access conditions

As that's only a one liner, and I'm using them together here.

Hope this gets added so that I don't have to keep patching my own version :)

Comments

nedjo’s picture

Very nice feature.

However, I wonder if we can add this to the JS file without PHP handling. It would look something like:


if ($(this).find('div.form-item .error').size()) {
  $(this).addClass('error').addClass('selected');
}

Then we would need to extend the .js file to make a .selected tab active on load.

Could you try that?

Moonshine’s picture

Ahh... I like that idea!

The problem is I am a complete jQ noob! :D It took me like 20 mins to find the correct syntax for the 1 line I added via my php code. Heh.

I did work with your code a bit here though, but I'm left stumped. I figure I must be missing something, or not finding the magic location where you were thinking to insert that code. :(

As the "error" class needs to be added to the tabs, I assume the conditional would need to be checked while looping through the tabs. However the fields with errors are not contained by the tab li's directly, they are contained by the divs with id's that the tab li's link to. So I got lost. :/

For example I was able to add error classes to the proper "ui-tabs-panel" divs with:

$(document).ready( function(){
  $('.ui-tabs-panel').each( function() {
    if ($(this).find('div.form-item .error').size()) {
      $(this).addClass('error').addClass('selected');
    }
  })
})

But how to get the classes to apply to the li's that have the links that reference the anchors on these divs in jQ I have no idea.

So that's when I figured I'm completely missing something about where your code would run. :)

Any pointers would be great... The PHP version runs solid, but if it were jQ based then you could apply it to the 5.x branch also. (no #pre_render in 5.x)

Moonshine’s picture

Ok so this became like a puzzle for me that I couldn't set down. :D I have it working entirely in jQ now with the following.. But I'm sure you'll have a more elegant way which will make me sad. :/

$(document).ready( function(){
  $('.ui-tabs-nav').children('li').each( function() {
    if ($($(this).find('a').attr('href')).find('div.form-item .error').size()) {
      $(this).addClass('error').addClass('selected');
    }
  })
  $('#tabs-fieldgroup_tabs > ul').tabs( 'select', $('.ui-tabs-nav').children('li.error:first').find('a').attr('href') );
})

BTW this also selects the first error'd tab! :D

Moonshine’s picture

Here is a new patch that implements the access and error enhancements (via jQuery)

Moonshine’s picture

After looking at this a bit more, using hook_nodeapi op=validate really isn't the ideal place to inject the jQ error handler code. In Drupal 6, it's ideal to use a #pre_render function, which I've switched to now. However, I'm not sure Drupal 5 has an equivalant place to trigger the jQ addition.

nedjo’s picture

Status: Needs review » Needs work

This looks good to me, except that the js shouldn't be in an inline js code block. It should be a behaviour in a .js file.

Moonshine’s picture

Yep.. I actually changed it to be a behavior after learning about that in #drupal a few weeks ago. I just need to clean things up a bit and I'll then post another patch for review.

nedjo’s picture

Great, this is going to be a very useful feature.

Moonshine’s picture

Status: Needs work » Needs review
StatusFileSize
new1.09 KB

This would be the patch, with the following code in "cck_fieldgroup_tabs_error.js":

// $Id$

/**
 * Attach client side error classes on tabs and select first tab in error
 */
Drupal.behaviors.cckFieldgroupTabsErrors = function (context) {
  $('.ui-tabs-nav').children('li').each( function() {
    if ($($(this).find('a').attr('href')).find('div.form-item .error').size()) {
      $(this).addClass('error').addClass('selected');
    }
  })
  $('#tabs-fieldgroup_tabs > ul').tabs('select', $('.ui-tabs-nav').children('li.error:first').find('a').attr('href'));
}

Edit: Updated patch here as I had a drupal_set_message() in there still for testing.

Moonshine’s picture

Status: Needs review » Fixed

Committed to HEAD.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.