Jquery asp.net mvc-实现一个;“自动完成”;博客的标签选择?
我正在开发一个博客系统供我自己使用,我想实现一个自动完成标记选择(类似于stackoverflow),我将如何实现这样的功能?任何示例或教程链接都将不胜感激Jquery asp.net mvc-实现一个;“自动完成”;博客的标签选择?,jquery,asp.net-mvc,autocomplete,tags,tagging,Jquery,Asp.net Mvc,Autocomplete,Tags,Tagging,我正在开发一个博客系统供我自己使用,我想实现一个自动完成标记选择(类似于stackoverflow),我将如何实现这样的功能?任何示例或教程链接都将不胜感激 谢谢。您可以调用一个操作方法,该方法将获取他们当前输入的文本,并返回一个包含可能标记的填充列表的视图 您的操作方法可能如下所示: public ActionResult GetTags(string tag) { List<string> tags = // get AutoComplete data from some
谢谢。您可以调用一个操作方法,该方法将获取他们当前输入的文本,并返回一个包含可能标记的填充列表的视图 您的操作方法可能如下所示:
public ActionResult GetTags(string tag)
{
List<string> tags = // get AutoComplete data from somewhere
return View(tags);
}
看到我的问题了吗
实际上,我们“借用”(读取副本并粘贴)了SO的自动完成javascript,然后对其进行了轻微的调整——比如重命名它,这样它就不会干扰e
这两个系统实际上非常相似,但我们特别希望有这样一个标签系统
你可以把我用过的密码拔掉
下面是我们用于标记的示例操作
public ActionResult ProfileTags(string prefix, int? limit)
{
if (!limit.HasValue)
limit = ConfigurationHelper.Paging.TagList;
if (String.IsNullOrEmpty(prefix))
prefix = String.Empty;
ProfileTagModel model = new ProfileTagModel()
{
Tags = profileTagRepository.GetList(new ProfileTagsByPrefixQuery(prefix)).OrderBy(x => x.Name).Take<ProfileTag>(limit.Value)
};
return View(model);
}
这样做时,不需要视图。自动完成程序接收json数据,并神奇地完成所有操作。末尾的.Result函数允许您设置在进行选择时发生的事件。在本例中,它实际上是将用户发送到另一个页面,但我们使用它在隐藏字段中设置了一个值
编辑
我忘记了这个代码的内置CSS类。下面是一个CSS示例
.ac_results{
padding:0;
border:1px solid #4c4c4c;
background-color:#ffffff;
overflow:hidden;
z-index:99999;
text-align:left;
font-size: 14px; line-height:14px;
color: #333333;
}
.ac_highlight{
font-weight:bold;
text-decoration:underline;
background-color: #ff6600;
color: #ffffff;
}
.ac_results ul{
width:100%;
list-style-position:outside;
list-style:none;
padding:0;
margin:0;
}
.ac_results li{
margin:0;
padding:3px 6px 3px 6px;
cursor:default;
display:block;
line-height:14px;
overflow:hidden;
}
.ac_loading{
background:#fff url(/Content/images/loading.gif) right center no-repeat;
}
.ac_over{
background-color:#ff6600;
color:#ffffff;
}
我决定尝试一下jQuery UI Autocomplete,这似乎很简单:)下面是javascript代码:
$(document).ready(function () {
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
$("#TagsString")
// don't navigate away from the field on tab when selecting an item
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
source: function (request, response) {
$.get("/Blog/GetTags", { term: extractLast(request.term) }, function (data) {
response($.map(data.tags, function (item) {
return {
label: item.Name,
value: item.Id
}
}))
}, "json");
},
minLength: 2,
dataType: 'json',
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.label);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
以下是HTML:
<p>
@Html.TextBoxFor(Model => Model.TagsString, new { @tabindex = "2", @size = "22", @value = "", @class = "text_input" })
<label for="TagsString">
<strong class="leftSpace">Tags</strong></label></p>
<style>
.ui-autocomplete-loading
{
background: white url('/Content/Images/ui-anim_basic_16x16.gif') right center no-repeat;
}
</style>
@Html.TextBoxFor(Model=>Model.TagsString,新的{@tabindex=“2”、@size=“22”、@value=”、@class=“text\u input”})
标记
.ui自动完成加载
{
背景:白色url('/Content/Images/ui-anim_basic_16x16.gif')右中心不重复;
}
以下是行动:
[HttpGet]
public virtual JsonResult GetTags(string term)
{
var getTags = _tag.All().Where(t => t.Name.ToLower().Contains(term.ToLower())).OrderBy(t => t.Name).ToList();
TagViewModel model = new TagViewModel()
{
Tags = Mapper.Map<List<Tag>, List<TagModel>>(getTags)
};
return Json(new
{
tags = model.Tags
}, JsonRequestBehavior.AllowGet);
}
[HttpGet]
公共虚拟JsonResult GetTags(字符串术语)
{
var getTags=_tag.All().Where(t=>t.Name.ToLower().Contains(term.ToLower()).OrderBy(t=>t.Name.ToList();
TagViewModel模型=新的TagViewModel()
{
Tags=Mapper.Map(getTags)
};
返回Json(新的
{
tags=model.tags
},JsonRequestBehavior.AllowGet);
}
工作非常好:)我使用jQueryUI的自动完成功能,但我事先加载了数据 视图:
@Html.TextBoxFor(Model => Model.Tags, new { @class = "txtbox-long" })
@Html.Resource(@<link href="@Url.Content("~/Content/CSS/flick/jquery-ui-1.8.11.css")" rel="stylesheet" type="text/css" />, "css")
@Html.Resource(@<script src="@Url.Content("~/Content/JS/jquery-ui-1.8.11.min.js")" type="text/javascript" language="javascript"></script>, "js")
@Html.Resource(
@<script type="text/javascript" language="javascript">
$(document).ready(function () {
var tags; $.getJSON("/Thread/GetTags", function (data) { tags = data; });
function split(val) { return val.split(/ \s*/); }
function extractLast(term) { return split(term).pop(); }
$("#Tags")
// don't navigate away from the field on tab when selecting an item
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) event.preventDefault();
})
.autocomplete({
delay: 0,
minLength: 0,
source: function (request, response) {
response($.ui.autocomplete.filter(tags, extractLast(request.term)));
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the space at the end
terms.push("");
this.value = terms.join(" ");
return false;
}
});
});
</script>
, "js")
在使用客户端搜索时,可以非常好地工作并保存对数据库的多次调用。我正在一个小项目中使用它,所以不会有那么多的标记。嗨,Josh,我很快会尝试你的代码,希望它会成功。关于代码的一个问题是,它是否允许多个标记,比如SO支持的标记?谢谢。最上面的那个,是的。有一个名为multiple的选项,它被设置为true。分隔符是一个空格,就像这样。嗨,Josh,你能详细介绍一下这些模型和方法吗:
ProfileTagModel
,ProfileTagsByPrefixQuery
,以及存储库中的GetList
方法?另外,您是将ProfileTags作为视图还是部分视图返回?再次感谢。ProfileTags是全视图ProfileTagModel
只是我用作模型的一个类。ProfileTagsByPrefixQuery
是在GetList
中用于将linq表达式转换为linq to nhibernate的类。其要点是通过搜索传递给控制器的值来获取标记。如何获得这些标记取决于您的数据模型。我的工作流程是:1)将CSS样式复制到我的样式表中。2) 从粘贴库复制js并将其命名为tageditor.js,包括在页面中。在博客控制器内创建名为BlogTags的新ActionResult,在博客视图文件夹内创建名为BlogTags的视图。在我可以创建新博客文章的主“创建”视图中,我有一个Id=BlogTags的输入文本框,然后我使用这个脚本$(“#BlogTags”)。troppinautocomplete('Yes eth0,抱歉没有提到:')应该说“…主要基于eth0的代码”。
public ActionResult Search(string contentType, string prefix, int? limit)
{
if (!limit.HasValue)
limit = ConfigurationHelper.Paging.ProfileList;
SearchResponse response = GetSearchResults(contentType, prefix);
var dropDownResults = (from r in response.Results
select new
{
Id = r.Id,
Title = r.Name,
ImageUrl = r.DefaultImage,
ResultType = r.ResultType.ToString()
}).Distinct().Take(limit.Value);
return Json(dropDownResults.ToList(), JsonRequestBehavior.AllowGet);
}
.ac_results{
padding:0;
border:1px solid #4c4c4c;
background-color:#ffffff;
overflow:hidden;
z-index:99999;
text-align:left;
font-size: 14px; line-height:14px;
color: #333333;
}
.ac_highlight{
font-weight:bold;
text-decoration:underline;
background-color: #ff6600;
color: #ffffff;
}
.ac_results ul{
width:100%;
list-style-position:outside;
list-style:none;
padding:0;
margin:0;
}
.ac_results li{
margin:0;
padding:3px 6px 3px 6px;
cursor:default;
display:block;
line-height:14px;
overflow:hidden;
}
.ac_loading{
background:#fff url(/Content/images/loading.gif) right center no-repeat;
}
.ac_over{
background-color:#ff6600;
color:#ffffff;
}
$(document).ready(function () {
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
$("#TagsString")
// don't navigate away from the field on tab when selecting an item
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
.autocomplete({
source: function (request, response) {
$.get("/Blog/GetTags", { term: extractLast(request.term) }, function (data) {
response($.map(data.tags, function (item) {
return {
label: item.Name,
value: item.Id
}
}))
}, "json");
},
minLength: 2,
dataType: 'json',
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.label);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
});
<p>
@Html.TextBoxFor(Model => Model.TagsString, new { @tabindex = "2", @size = "22", @value = "", @class = "text_input" })
<label for="TagsString">
<strong class="leftSpace">Tags</strong></label></p>
<style>
.ui-autocomplete-loading
{
background: white url('/Content/Images/ui-anim_basic_16x16.gif') right center no-repeat;
}
</style>
[HttpGet]
public virtual JsonResult GetTags(string term)
{
var getTags = _tag.All().Where(t => t.Name.ToLower().Contains(term.ToLower())).OrderBy(t => t.Name).ToList();
TagViewModel model = new TagViewModel()
{
Tags = Mapper.Map<List<Tag>, List<TagModel>>(getTags)
};
return Json(new
{
tags = model.Tags
}, JsonRequestBehavior.AllowGet);
}
@Html.TextBoxFor(Model => Model.Tags, new { @class = "txtbox-long" })
@Html.Resource(@<link href="@Url.Content("~/Content/CSS/flick/jquery-ui-1.8.11.css")" rel="stylesheet" type="text/css" />, "css")
@Html.Resource(@<script src="@Url.Content("~/Content/JS/jquery-ui-1.8.11.min.js")" type="text/javascript" language="javascript"></script>, "js")
@Html.Resource(
@<script type="text/javascript" language="javascript">
$(document).ready(function () {
var tags; $.getJSON("/Thread/GetTags", function (data) { tags = data; });
function split(val) { return val.split(/ \s*/); }
function extractLast(term) { return split(term).pop(); }
$("#Tags")
// don't navigate away from the field on tab when selecting an item
.bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB && $(this).data("autocomplete").menu.active) event.preventDefault();
})
.autocomplete({
delay: 0,
minLength: 0,
source: function (request, response) {
response($.ui.autocomplete.filter(tags, extractLast(request.term)));
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the space at the end
terms.push("");
this.value = terms.join(" ");
return false;
}
});
});
</script>
, "js")
[Classes.Attributes.Ajax]
public JsonResult GetTags()
{
return Json(
TagService.GetTags().Select(x => x.Name),
"text/plain",
JsonRequestBehavior.AllowGet
);
}