当使用Html.BeginCollectionItem时,MVC自动完成编辑器
MVC AutoComplete EditorFor while using Html.BeginCollectionItem
我试图创建一个自动完成文本框,而使用EditorTemplate
。我面临的问题是,通过使用Html.BeginCollectionItem()
扩展解决方案(https://www.nuget.org/packages/BeginCollectionItem/), EditorFor()
和TextBoxFor()
方法的Id得到动态设置,这打破了我的javascript。除此之外,我不知道这是否可能(如果可能的话,又是如何做到的)。下面你会发现我已经走了多远)。
在主视图中,我有一个循环,为集合中的每个项目生成部分视图
for (int i = 0; i < Model.VoedingCollection.Count; i++)
{
@Html.EditorFor(x => x.VoedingCollection[i], "CreateVoedingTemplate")
}
部分视图CreateVoedingTemplate.cshtml
使用Html.BeginCollectionItem()
方法
@using (Html.BeginCollectionItem("VoedingCollection"))
{
string uniqueId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('[', '_').Replace(']', '_').ToString();
string searchId = "Search_";
string standaardVoedingId = "StandaardVoeding_";
foreach (KeyValuePair<string, object> item in ViewData)
{
if (item.Key == "Count")
{
searchId = searchId + item.Value.ToString();
standaardVoedingId = standaardVoedingId + item.Value.ToString();
}
}
<div class="form-horizontal">
<div class="form-group" id=@standaardVoedingId>
@Html.LabelFor(model => model.fk_standaardVoedingId, "Voeding naam", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.HiddenFor(model => model.fk_standaardVoedingId)
<input type="text" id='@searchId' placeholder="Search for a product"/>
</div>
</div>
</div>
<script type="text/javascript">
var id = '@uniqueId' + '_fk_standaardVoedingId'.toString();
var search = '@searchId'.toString();
var url = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "AgendaApi" })';
$(document.getElementById(search)).autocomplete({
source: function (request, response) {
$.ajax({
url: url,
data: { query: request.term },
dataType: 'json',
type: 'GET',
success: function (data) {
response($.map(data, function (item) {
return {
label: item.standaardVoedingNaam,
value: item.standaardVoedingId
}
}));
}
})
},
select: function (event, ui) {
$(document.getElementById(search)).val(ui.item.label);
//$('#id').val(ui.item.value);
document.getElementById(id).value = ui.item.value;
return false;
},
minLength: 1
});
</script>
}
<link href="~/Content/SearchBox/jquery-ui.css" rel="stylesheet" />
<script src="~/Scripts/SearchBox/jquery-1.9.1.js"></script>
<script src="~/Scripts/SearchBox/jquery-ui.js"></script>
在上面的脚本中,我试图创建一个函数,用户可以在其中键入standaardVoeding
项目的名称,然后获得结果,其中,在用户选择standaardVoeding
项目后,设置standaardVoedingId
属性。然后,在提交整个表单之后,控制器接收standaardVoedingId
(以及所有其他信息)
所以我猜Javascript在某种程度上不能处理剃刀视图@
代码,其次,Html.BeginCollectionItem
做了一些可疑的事情,因为你不能在运行时通过代码设置其文本框的值。接下来,我试过做alert(document.getElementById(*html.begincollectionitemId*))
,它发现字段很好。但显然其他方法都不起作用?
是否有更好的解决方案来让这个工作?
BeginCollectionItem()
方法改变了由内置助手生成的html的id
和name
属性,在您的示例中,用于隐藏输入,而不是
<input ... name="fk_standaardVoedingId" .... />
会生成
<input ... name="VoedingCollection[xxxx].fk_standaardVoedingId" .... />
其中xxxx
为Guid
。
虽然可以使用javascript从文本框中提取Guid
值(假设使用@Html.TextBoxFor()
正确生成)并构建相关隐藏输入的id以用作选择器,但使用类名和相对选择器要容易得多。
您还需要从部分中删除脚本和css,并将其放在主视图(或其布局)中。除了内联脚本之外,您还需要为集合中的每个项目复制它。
你的部分需要是
@using (Html.BeginCollectionItem("VoedingCollection"))
{
<div class="form-horizontal">
<div class="form-group">
@Html.LabelFor(model => model.fk_standaardVoedingId, "Voeding naam", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10 item"> // add class name
@Html.HiddenFor(model => model.fk_standaardVoedingId)
<input type="text" class="search" placeholder="Search for a product"/>
</div>
</div>
</div>
}
请注意文本框及其容器的类名,其中还包括隐藏输入。然后在主视图中,脚本将是
<script type="text/javascript">
var url = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "AgendaApi" })';
// Attach the script to all textboxes
$('.search').autocomplete({
source: function (request, response) {
$.ajax({
url: url,
data: { query: request.term },
dataType: 'json',
type: 'GET',
success: function (data) {
response($.map(data, function (item) {
return {
label: item.standaardVoedingNaam,
value: item.standaardVoedingNaam, // this needs to be the name
id: item.standaardVoedingId // add property for the id
}
}));
}
})
},
select: function (event, ui) {
// Get the associated hidden input
var input = $(this).closest('.item').find('input[type="hidden"]');
// Set the value of the id property
input.val(ui.item.id);
},
minLength: 1
});
</script>
根据你的评论,你没有动态地添加或删除视图中的项目,那么在额外的开销或使用BeginCollectionItem()
方法是没有意义的。将部分的名称更改为standaardvoeding.cshtml
(假设这是类的名称)并将其移动到/Views/Shared/EditorTemplates
文件夹。
然后在主视图中,将for
循环替换为
@Html.EditorFor(m => m.VoedingCollection)
,它将为集合中的每个项生成正确的HTML。最后,从模板中删除BeginCollectionItem()
方法,使其仅为
<div class="form-horizontal">
<div class="form-group">
@Html.LabelFor(m => m.fk_standaardVoedingId, "Voeding naam", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10 item"> // add class name
@Html.HiddenFor(m => m.fk_standaardVoedingId)
<input type="text" class="search" placeholder="Search for a product"/>
</div>
</div>
</div>
- ExtJS网格单元格编辑器,防止焦点松动问题
- 可以't使用PHP使用Froala编辑器上传图像URL
- 如何在corona sdk中从CK编辑器中检索数据
- Eclipse编辑器中无法访问的代码
- 如何将拼写检查集成到密文编辑器
- 一个页面上有多个Ace编辑器,没有预先设置元素
- ACE编辑器正在删除模块,因为define是't一根绳子
- 如何从DOM中删除Aloha编辑器
- 用于用户内容的简单代码编辑器/文本格式化程序(在Rails中)
- 在plone 5中将自定义的灵活性内容类型插入到tinymce编辑器中
- 如何在tinymce编辑器中将点击事件绑定到html标签
- 扩展 ACE 编辑器,如何导入自定义文件
- 使用asp.net上的iframe mvc 3创建编辑器
- Knockout和MVC——绑定到使用模板化编辑器呈现的控件
- 如何在mvc中使用knockout js (MVVM)绑定value summernote编辑器
- 当使用Html.BeginCollectionItem时,MVC自动完成编辑器
- 如何在mvc编辑器模板中插入唯一的值
- 使用jquery-datetimepicker.js与MVC编辑器
- MVC编辑器用于动态插入
- MVC表CRUD与内联编辑器