RequiredFieldValidator将最后一个radiobutton聚焦在RadioButtonList上

时间:2014-01-09 17:55:36

标签: asp.net validation requiredfieldvalidator

我在asp.net中有一个单选按钮列表,如

 <asp:RadioButtonList ID="rblChoose" runat="server" RepeatDirection="Horizontal" 
 RepeatLayout="Flow">
   <asp:ListItem Text="a" Value="a" />
   <asp:ListItem Text="b" Value="b" />
</asp:RadioButtonList>
<asp:RequiredFieldValidator ID="rfvChoose" runat="server" 
ControlToValidate="rblChoose" ErrorMessage="Choose registration option." 
ForeColor="red" SetFocusOnError="true"></asp:RequiredFieldValidator>

RequiredFieldValidator显示错误的客户端消息时,它将焦点放在列表中的最后RadioButton。为什么将焦点设置在列表中的最后RadioButton上。我想关注错误的第一个RadioButton

1 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为生成的单选按钮HTML看起来与此类似。 (注意名称\ ID将被更改以适应应用程序和heirchy)。

<span id="MainContent_rblChoose"><span name="rblChoosea">
      <input id="MainContent_rblChoose_0" type="radio" name="ctl00$MainContent$rblChoose" value="a">
      <label for="MainContent_rblChoose_0">a</label></span><span name="rblChooseb">
      <input id="MainContent_rblChoose_1" type="radio" name="ctl00$MainContent$rblChoose" value="b">
      <label for="MainContent_rblChoose_1">b</label>
</span>

现在重要的是,如果你看一下name属性。名称与(对于radiobuttons)相同,因此它们可以在彼此之间正确切换。这也设置了在表单事件中发布的值。

现在,默认验证器(如果您浏览MS javascript)最终会调用以下代码段。

var inputElements = ctrl.getElementsByTagName("input");
var lastInputElement  = inputElements[inputElements.length -1];
if (lastInputElement != null) {
        ctrl = lastInputElement;
}

如果您查看上面的代码,您会注意到它实际上从与元素名称匹配的元素数组中获取lastInputElement,并且标记名称为input。因此,当代码执行以聚焦ctrl时,它会关注last元素(正如您在验证中看到的那样)。

现在我们知道这是默认行为,我们还需要知道的是我们如何克服这个问题。那就是你必须远离RequiredFieldValidator控件并使用自定义javascript函数编写自己的CustomValidator。现在这很简单,只对这种情况有效,但可以用几行代码完成。

首先,您定义CustomValidator(仅限示例)。

<asp:CustomValidator runat="server" 
                     ID="rfvChoose" 
                     ErrorMessage="Choose registration option."
                     EnableClientScript="true" 
                     ForeColor="Red" 
                     ClientValidationFunction="rfvChooseValidator" />

注意到另一个启用ClientValidationFunction的属性这是一个javascript函数,它会根据一组条件将IsValid属性设置为true \ false。然后javascript很容易实现。请注意,在我的示例中,我添加了特殊事件以在选择单选按钮后隐藏验证消息。我在javascript中放了很多评论,这样你就可以准确理解每个阶段的作用。

<script type="text/javascript">
    //function called when the rfvChoose validator is called
    function rfvChooseValidator(sender, args) {
        //set the object id for the radio button list
        var objID = '#<%= rblChoose.ClientID %>';

        //set the is valid flag by evaluating if any radio buttons in the radiobutton list are selected (using the psudo selector :checked)
        args.IsValid = $(objID + ' input[type="radio"]:checked').size() > 0;

        if (args.IsValid) {
            //if the validation is succesful remove the eventValidation custom click handler
            $(objID + ' input[type="radio"]').off('click.eventValidator');

            //hide the validation message
            $('#<%= rfvChoose.ClientID %>').css('visibility', 'hidden');
        }
        else {
            //focus the first radiobutton in the list
            $(objID + ' input[type="radio"]:first').focus();

            //if the arguments are not valid set an event handler to trigger when any of the radio buttons are selected
            // the custom click event handler uses the .eventValidator namespace so we can on\off just the click handler for event validation
            // thus leaving all other click events enabled
            $(objID + ' input[type="radio"]').off('click.eventValidator')
                .on('click.eventValidator', function () {
                    //this simply recalls the validation function with a null sender and a blank object for the args 
                    // note the blank object is set using {} as opposed to null so in the callback we can set a property
                    // of this blank object. Passing null will cause an exception when trying to set a value.
                    rfvChooseValidator(null, {});
                });
        }
    }
</script>

每次提出CustomValidator客户端验证事件时,只需将上面的javascript函数执行即可。

现在我在赏金声明中意识到你只想使用RequiredFieldValidator但是如果你想要关注第一个控件那么这是不可能的

更新

如果您想将DisplayType更改为Dynamic,则必须更改行

$('#<%= rfvChoose.ClientID %>').css('visibility', 'hidden');

$('#<%= rfvChoose.ClientID %>').css('display', 'none');

或者您可以使用以下代码替换代码以自动检测显示类型并相应地设置display \ visibility css。

//identify the display type
var displayType = $('#<%= rfvChoose.ClientID %>').data('val-display');
if (displayType === undefined || displayType == null || displayType == 'Static')
    displayType = { 'visibility': 'hidden' };
else
    displayType = { 'display': 'none' };

//hide the validation message
$('#<%= rfvChoose.ClientID %>').css(displayType);