4

I am having a problem with my jquery form. If you look at this fiddle where I am creating my form, you will notice that after an input field is created, then deleted, the alert messages start popping up on the next element (below where they initially are placed).

To clarify: If the user has not entered any information yet, the alerts pop up in the correct position (floated to the right side of the input field in red text). However, if the user has inputted information, then deletes it, the ajax alert ("this field is required") pops up in the wrong place in the field below where it is supposed to. To view the problem, type in all fields correctly, then delete your name. The message "this field is required" pops up in the email field, but it belongs in the name field.

The js that controls the validation is:

$(document).ready(function() {
    $('#commentForm').validate({
        submitHandler: function(form) {
            $.ajax({
                type: 'POST',
                url: 'process.php',
                data: $(this).serialize(),
                success: function(returnedData) {
                    $('#commentForm').append(returnedData);
                }
            });         
            return false;
        },
        errorPlacement: function(error, element) {
              error.insertAfter( element).position({
                  my:'right top',
                  at:'right top',
                  of:element          
              });
         }  
    }); 
});

EDIT 1: Using Jquery NoConflict mode has not solved this issue. As it appears to be a problem with how the two plugins work together.

EDIT 2: There are actually two solutions to this problem. One is to include the jquery UI script into the head, thereby enabling its 'position' utility to align the error messages at the 'right top'.

The other solution, as noted by a few other contributors, is to modify the css to set

form p {
  position: relative;   /* This ensures error label is positioned within the p tag */
}
label.error {  
  top: 0; /* This ensures that it lines up with the top of the input */
  right:90px; 
  color: red; 
  position:absolute;
}

Thanks for all of the input.

Oleg
  • 24,465
  • 8
  • 61
  • 91
Nick B
  • 9,267
  • 17
  • 64
  • 105

5 Answers5

3

Looks like a styling issue to me (but again, everything does :) with incorrectly used position:absolute, which, btw, cancels out float:left - http://jsfiddle.net/kmJ87/17/

If you're really attached to position:absolute (more styling in the full css, like a nice box message maybe?) you could fix it by adding position:relative to the parent element (paragraph in this case) - http://jsfiddle.net/kmJ87/18/

Oleg
  • 24,465
  • 8
  • 61
  • 91
3

The problem lies partially in the CSS declarations:

/* Begin first declaration for <label class="error" /> */
label.error {
    color: red;
    position:absolute;
}
/* Begin second declaration for <label class="error" />. Nothing inherently wrong with this, but a bit odd considering the simplified fiddle.*/
label.error {
    float: left;    /* Kinda replaces previously declared absolute position as "float" and "position" are kinda, but not really, mutually exclusive properties. */
    right: 30px;    /* Useless declaration (for now) as "right" is used wih "position" not "float". */
    color: #ff714d;
    position: absolute; /* Replaces previously declared float and makes the previously assigned "right" property useful again. */
    font-family: 'subhead', helvetica, verdana;
    letter-spacing: 1px;
    text-transform: lowercase;
}

Since position: absolute; is the last declaration (in the position v. float declarations), the element is positioned absolutely.

The first part of the problem is that, since the top property was not declared and the display of the label is block, the browser positions the top on the next line down (which is where the top would be in a static flow).

The second part of the problem is that since a float was declared, the browser still tries to float the element as well (which again winds up with the browser positioning the top on the next line down).

The solution (thus far) is to remove the float declaration and declare a top of 0 in the label.error stylings.

label.error {
    color: red;
    position:absolute;
}

label.error {
    top: 0;     /* Replaces "float: left;" and fixes the display. */
    right:30px;
    color: #ff714d;
    position: absolute;
    font-family: 'subhead', helvetica, verdana;
    letter-spacing: 1px;
    text-transform: lowercase;
}

or in a single declaration:

label.error {
    color: red;
    position: absolute;
    right: 30px;
    top: 0;
    color: #ff714d;
    position: absolute;
    font-family: 'subhead', helvetica, verdana;
    letter-spacing: 1px;
    text-transform: lowercase;
}

Updating the code to this presents the final problem, which is that all error messages now appear at the very top of the document.

This is caused by the position: absolute; declaration as elements that are absolutely positioned are removed from the normal document flow and positioned (absolutely) to the closest non-statically positioned anscestor element.

In this case, there are none so the <label class="error" /> elements are absolutely positioned to the <body />. The final portion of the solution, therefore, is to make the p elements non-statically positioned (as that is where the errors should be absolutely positioned about).

Final CSS:

p {
    position: relative;
}

label.error {
    color: red;
    position: absolute;
    right: 30px;
    top: 0;
    color: #ff714d;
    position: absolute;
    font-family: 'subhead', helvetica, verdana;
    letter-spacing: 1px;
    text-transform: lowercase;
}

Updated (and working) fiddle.

pete
  • 24,141
  • 4
  • 37
  • 51
  • Yes Thank you. CSS is one solution to this problem The problem was remedied by adding form p {position: relative;} and label.error {top: 0;} – Nick B Mar 18 '12 at 21:15
  • Gave you the bounty but the other guy the answer because he was the first to point out that it was a css problem. I actually figured it out myself but I appreciate the detail you have provided. Thank you – Nick B Mar 18 '12 at 21:18
2

The jcps javascript shouldn't have any influence on the page since it only defines an object and isn't actually used anywhere (yet). When I was fiddling around with the code I also ran into problems even if the jcps javascript was commented out.

It seemed that the browser had trouble with the layout of the label within a paragraph, by changing the paragraphs to divs with position relative and adding top 0px to the error styling things got more stable. I noticed the validator still has some intermittent issues though, perhaps caused by some minor bugs.

This is the version I ended up with for now: http://jsfiddle.net/kmJ87/20/

Trax72
  • 958
  • 5
  • 12
1

We can declare document.ready method two ways

  1. $(document).ready(function() {

    // our code comes here

    }); Here $ is a global variable and refers jQuery object.

  2. jQuery(document).ready(function($) {

    // Our code comes here

    }); // Here $ is a local variable and refers jQuery object.

Check this link's 5th point : http://net.tutsplus.com/tutorials/javascript-ajax/14-helpful-jquery-tricks-notes-and-best-practices/

mukul.das
  • 21
  • 4
  • Thanks for your input. Can you show me how you would edit the jsfiddle to fix this problem? Because I dont actually use $(document).ready(function(){ in that version. – Nick B Mar 14 '12 at 01:35
  • @NickB : This is not a problem with jQuery. This is a problem with CSS. you have custom css class label.error . If you comment this class you can find every thing is working fine (Error text color may be in black, but error is displaying at the correct place). – mukul.das Mar 14 '12 at 06:54
0

Many JavaScript libraries use $ as a function or variable name, just as jQuery does. In jQuery’s case, $ is just an alias for jQuery, so all functionality is available without using $. If we need to use another JavaScript library alongside jQuery, we can return control of $ back to the other library with a call to jQuery.noConflict();

see example here :

 jQuery.noConflict();
 (function($)
  {
     // your code goes here
 })
(jQuery);

try with it

thecodedeveloper.com
  • 3,220
  • 5
  • 36
  • 67
  • Could you edit the jsfiddle to show how would use noconflict in this case? – Nick B Mar 10 '12 at 00:38
  • noConflict is not a solution for this problem as it seems to arise from the interaction of two jQuery plugins. Assigning a different value to $ does not solve this issue. Thank you. Any other ideas are very welcome – Nick B Mar 11 '12 at 22:20