function $L( item ) {
    if ( window.console ) window.console.log( item );
}

function parent( elem, tag ) {
    while ( elem 
            && elem.tagName 
            && elem.tagName.toLowerCase() != tag.toLowerCase() )
        elem = elem.parentNode;
    return elem;
}

function validate(myform) {
    var errors = [];
    var wordLimitProblems = 0;

    $('tr.broken').removeClass('broken');
    
    function markError( elem, messageType, formid ) {
        if (formid == elem.form.id) {
          var message = messageType && elem.getAttribute( messageType );
          if ( message ) errors.push( message );
          $(parent(elem, 'tr')).addClass( 'broken' );
        }
    }
    
    // Look for required checkboxes
    $('input[type=checkbox][required]').each(function( idx, e ) {
        if ( !e.checked ) markError( e, 'required', myform.id );
    } );
    
    // Ditto for textboxes
    $('input[type=text][required], textarea[required], input[type=file][required]').each(function( idx, e ) {
        if ( !e.value ) markError( e, 'required', myform.id );
    } );

    // And selects!
    $('select[required]').each(function( idx, e ) {
        if ( !e.selectedIndex ) markError( e, 'required', myform.id );
    } );
    
    if ( errors.length ) {
        alert( errors.join('\n') );
        return false;
    }
    
    return true;
}
