Los mensajes de validación de Ajax de conflicto de JQuery devuelven la ubicación

I am having a problem with my jquery form. If you look at this violín 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.

preguntado el 09 de marzo de 12 a las 17:03

5 Respuestas

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/

respondido 15 mar '12, 01:03

Just to clarify there's no conflict between the plugins jsfiddle.net/AstDerek/kmJ87/19 - ast derek

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;
}

Como 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 en el objeto label.error estilismos.

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.

Esto es causado por el 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).

CSS final:

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.

respondido 17 mar '12, 00:03

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.

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.

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/

respondido 16 mar '12, 23:03

Podemos declarar documento.listo 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 objeto.

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

respondido 13 mar '12, 12:03

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.

@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

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();

ver ejemplo aquí:

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

prueba con eso

respondido 09 mar '12, 18:03

Could you edit the jsfiddle to show how would use noconflict in this case? - Nick B.

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.

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.