在MVC中显示带有单选按钮的动态字段

时间:2017-01-09 21:24:37

标签: javascript c# html asp.net-mvc

我的MVC网站中有一个部分视图,用于特定页面的搜索参数。在这部分中,我基于特定的ID号动态显示参数。其中一些参数需要允许用户输入精确值或一系列值。这就是我到目前为止所做的:

<form id="DynamicFieldsForm">
    @{
        List<DynamicParameter> ddParams = dal.GetParameters();
        foreach (DynamicParameter dp in ddParams.OrderBy(d => d.ParameterName))
        {
            <div>
                <div class="form-group col-lg-12">
                    <div class="designerDataParamRangeSelect">
                        <input type="radio" id="@(dp.ParameterID)_RadioExact" value="exact" />Exact<br />
                        <input type="radio" id="@(dp.ParameterID)_RadioRange" value="range" />Range
                    </div>

                    <input class="form-control" type="text" id="@(dp.ParameterID)_Lower" name="@(dp.ParameterID)_Lower" placeholder="@dp.ParameterName Lower" value="" @maxLength />
                    <div id="hideThis">
                        <input class="form-control" type="text" id="@(dp.ParameterID)_Upper" name="@(dp.ParameterID)_Upper" placeholder="@dp.ParameterName Upper" value="" @maxLength />
                    </div>
                </div>
            </div>
        }
    }
</form>

从下拉列表中选择特定ID后,也会显示此部分视图。我有UI工作......这不是问题。我需要帮助的是当选择"hideThis"单选按钮时,如何在"_RadioRange" div中显示或隐藏输入字段。我将这些值从javascript函数发送到控制器,这一切都有效。我只需要帮助显示和隐藏这些字段。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

你没有提到你正在使用的JS框架(如果有的话)。在jQuery中,我有一个可重用的方法,我经常用于动态表单显示:

JS:

if ($user = User::where('email', request()->email)->where('password', request()->password)->first()) {
    Auth::login($user);
    return redirect()->to('/');
}

HTML:

var toggleChecked = function() {
        var $this       = $(this),
            $target     = $($this.data('target'))
        ;
        if ($this.is(':checked')) {
            $target.toggle($this.data('display'));
        }
    }
;
$(document).on('click','[data-action=toggleChecked]', toggleChecked);

在循环中,“hideThis”Id需要为循环的每次迭代都有唯一的Id。您可以在每个ID的末尾添加<input id='myRadio_y' name='myRadio' type='radio' value='1' data-action='toggleChecked' data-target='#hideThis' data-display='true' /> <input id='myRadio_n' name='myRadio' type='radio' value='0' data-action='toggleChecked' data-target='#hideThis' data-display='false' /> <div id='hideThis'>Dynamically Displayed Field</div> ......类似这样的内容:

@(i)

说明:

在HTML中,任何带有data-action =“toggleChecked”的复选框或单选按钮都可以切换另一个HTML标记的显示。 data-target指定要使用CSS选择器切换的标记,data-display =“(true | false)”指示该特定单选按钮/复选框是否应分别显示或隐藏。

如果有任何其他详细信息我可以帮助填写,如果这看起来像是在你的问题的正确轨道上,请告诉我。

答案 1 :(得分:0)

您的2个单选按钮需要具有name属性(两者都相同),因此它们被分组(目前您可以同时选择单选按钮,也不能取消选择)。

但是,您的实现还有其他一些问题,包括生成无效的html(重复的id属性),没有验证,并且在您的视图中包含数据库访问代码,几乎无法进行单元测试。

我建议您首先创建一个返回局部视图的[ChildActionOnly]方法,然后在布局中使用@Html.Action()进行渲染。该部分应基于允许您同时获得客户端和服务器端验证的视图模型,例如

public class ParameterVM
{
    public string Name { get; set; }
    public bool HasRange { get; set; }
    [RequiredIfFalse(ErrorMessage = "...")]
    public int? Value { get; set; }
    [RequiredIfTrue("HasRange", ErrorMessage = "...")]
    public int? LowerLimit { get; set; }
    [RequiredIfTrue("HasRange", ErrorMessage = "...")]
    public int? UpperLimit { get; set; }
}

请注意RequiredIfTrueAttributeRequiredIfFalseAttribute来自foolproof,但您会发现大量有关在SO上创建条件属性的示例。

你的控制器方法就像是

[ChildActionOnly]
public ActionResult Parameters()
{
    var model = dal.GetParameters().OrderBy(x => x.ParameterName).Select(x => new ParameterVM()
    {
        Name = x.ParameterName,
        HasRange = ... // set defaults for other properties as required
    }).ToList();
    return PartialView("_Parameters", model);
}

并且_Parameters.cstml部分视图将是

@model List<ParameterVM>
<form>
    @for(int i = 0; i < Model.Count; i++)
    {
        <div class="parameter">
            @Html.DisplayFor(m => m[i].Name)
            <label>
                @Html.RadioButtonFor(m => m[i].HasRange, false, new { id = "", @class = "radio" })
                <span>Exact</span>
            </label>
            <label>
                @Html.RadioButtonFor(m => m[i].HasRange, true, new { id = "", , @class = "radio" })
                <span>Range</span>
            </label>
            <div class="exact"@(Model.HasRange ? " hidden" ? "")>
                @Html.LabelFor(m => m[i].Value)
                @Html.TextBoxFor(m => m[i].Value)
                @Html.ValidationMessageFor(m => m[i].Value)
            </div>
            <div class="range@(Model.HasRange ? "" ? " hidden")>
                @Html.LabelFor(m => m[i].LowerLimit)
                @Html.TextBoxFor(m => m[i].LowerLimit)
                @Html.ValidationMessageFor(m => m[i].LowerLimit)
                @Html.LabelFor(m => m[i].UpperLimit)
                @Html.TextBoxFor(m => m[i].UpperLimit)
                @Html.ValidationMessageFor(m => m[i].UpperLimit)
            </div>   
        <div>
    }
</form>

在布局中,包含以下脚本以切换关联文本框的可见性

$('.radio').change(function() {
    var container = $(this).closest('.parameter');
    container.find('.exact').toggleClass('hidden');
    container.find('.range').toggleClass('hidden');
});