0

我有一个使用 jquery ui 手风琴小部件显示在几个部分中的表单。我正在尝试创建验证反馈,以便如果手风琴选项卡之一包含任何无效的输入,则该选项卡会突出显示(与输入字段一样)。这对我的大多数选项卡来说都很容易,因为每个选项卡只有一个输入字段。但是,我确实有一个选项卡,它下面有两个输入字段。这是我试图解决这个问题的方法:

//validation rules for new story form   
var storyValidator = $("form#new_story").bind("invalid-form.validate", function() {
            $("#story_create_warning").html("Your form contains " + storyValidator.numberOfInvalids() + " errors, see details below.");
        }).validate({
    ignore: [],  //so to perform validation on elements that have display:none
    errorClass: 'validationError',
    errorContainer: $("#story_create_warning"),

    highlight: function(element, errorClass) {
         $(element).addClass(errorClass);
         $(element).parents(".accord_contents").prev()
                   .addClass(errorClass);
    },

    unhighlight: function(element, errorClass) {
        $(element).removeClass(errorClass);
        //because the story_contents accordion tab has more than one input on which to validate, 
        //only remove that tabs highlighting if all elements under the tab are valid
        if ($(element).hasClass("story_contents")) {
            var contentsArray = $(".story_contents");
            var length = contentsArray.length;
            for (var i=0; i<length; i++){
                if (!storyValidator.element(contentsArray[i])) { //don't remove tab highlight if even one element in the tab doesn't validate
                    return
                }
            }
        };
        $(element).parents(".accord_contents").prev()
                            .removeClass(errorClass);
    },
    errorElement: "em",
    rules: {
        "story[title]": {
            required: true,
            minlength: 5,
            maxlength: 49
        },
        "story[posts_attributes][0][contents]": {
            required: true,
            minlength: 5,
            maxlength: 399              
        },  
        "story[posts_attributes][0][photo]": {
            accept: "jpeg|jpg|png|gif|JPEG|JPG|PNG|GIF"             
        }
    },
    messages: { [my messaging]},
    errorPlacement: function(error, element) {
            error.insertAfter( element.parent("div") );
    }
});

HTML:

<div id="new_story_form" class="removed" title="Create a New Story">
   <form action="#" method="post" id="new_story" autocomplete="off">
     <h4 id="story_create_warning" class="error" style="display:none;"></h4>

    <input type="hidden" name="story_centerpoint" id="hidden_story_location" />
    <div id='story_create_accordion'>

        <h3 class="story_accord_tab">Step 1 - Story Title</h3>
        <div class="accord_contents">
            <div class="field">
                <textarea id="story_title" class="story_title noScroll formWidthSmall" name="story[title]" placeholder="Insert a title for your story"></textarea>
            </div>
        </div>

        <h3 class="story_accord_tab">Step 2 - Story Contents</h3>
        <div class="accord_contents">
            <div class="field">
                <textarea id="contents_of_story" class="story_contents post_contents noScroll formWidthSmall" name="story[posts_attributes][0][contents]" placeholder="Insert your news"></textarea>
                <br/>
                <label>Add a photo</label>
                <input id="story_photo" class="narrowInput story_contents" type="file" name="story[posts_attributes][0][photo]"/>
            </div>
        </div>

        <h3 class="story_accord_tab">Step 3 - Additional Options</h3>
        <div class="accord_contents">
            <div class="field">
                <label>Additional info:
                    <textarea class="story_options" name="story[extra_info]"></textarea>
            </div>
        </div>
    </div>
  </form>
</div> <a href="javascript:;" id="submit">submit</a>

这适用于所有不属于story_contents该类的元素。我也可以storyValidator.element("#[enter element id]")对这些元素进行表演。

但是,属于story_contents该类的元素会分解。对于这些元素,如果我插入一个不符合我的验证规则的值,该highlight方法就会很好地触发。当我插入符合我的规则的文本时,该unhighlight方法触发,然后在几秒钟的延迟后,浏览器崩溃。for我尝试在方法内部的循环中间设置一个断点unhighlight,然后使用控制台执行storyValidator.element("#contents_of_story"). 控制台返回以下错误:RangeError: Maximum call stack size exceeded. 我遇到了某种递归问题,但我肯定无法弄清楚。

这是显示问题的小提琴:jsfiddle。运行小提琴时浏览器不会崩溃,但您可以看到延迟,并看到 unhighlight 方法没有按应有的方式删除突出显示。

有什么帮助吗?

4

2 回答 2

1

您的问题与手风琴无关。即使禁用它你仍然有问题:http: //jsfiddle.net/3Td8C/6/

但是,您的 jQuery Validate 初始化都是错误的......

var storyValidator = $("form#new_story").bind("invalid-form.validate", function() {
        $("#story_create_warning").html("Your form contains " + storyValidator.numberOfInvalids() + " errors, see details below.");
    }).validate({ ... });

.validate()只能附加到一个form元素......而不是链接到其他任何东西。

像这样正确初始化插件:

$("form#new_story").validate({ ... });

演示:http: //jsfiddle.net/3Td8C/5/

于 2013-05-08T23:37:47.100 回答
0

首先,感谢@Sparky,感谢他花时间帮助我。正如他所指出的那样,我的代码很冗长,而且很难通过它。

但是,就像我一样,在网上有很多初始化 Validate 对象的例子,比如这里这里。所以,我不认为这是我的问题。此外,API Docs展示了一个使用highlightunhighlight解决与我类似的需求的示例。所以,我认为保留我的highlight/unhighlight覆盖是要走的路。那么,我的unhighlight覆盖有什么问题?

半夜我突然意识到为什么我遇到了这个stack overflow错误。在我unhighlight的方法中,我使用了该Validate.element()方法。该方法触发了对刚刚验证的元素的新验证。该验证尝试通过,然后unhighlight在同一元素上触发,然后递归尝试再次验证该元素。此意外循环导致stack overflow错误。

解决方案是不使用该elements()方法,而是查看invalidResults由前一个验证尝试生成的对象,以查看我需要检查的两个元素中的任何一个是否仍然无效。如果这些元素中的任何一个被测试为无效,那么我知道要在父选项卡上保持突出显示。 这个小提琴显示了工作中的解决方案。

于 2013-05-09T17:59:45.530 回答