我的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函数发送到控制器,这一切都有效。我只需要帮助显示和隐藏这些字段。非常感谢任何帮助。
答案 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; }
}
请注意RequiredIfTrueAttribute
和RequiredIfFalseAttribute
来自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');
});