在不刷新页面的情况下使用 MVC/AJAX/JQuery 搜索 Umbraco
Search Umbraco with MVC/AJAX/JQuery without refreshing page
这是怎么回事:
我在 Umbraco 7 中有一个 parent 模板,它应该是一个字典,我已经将每个字典单词设为一个 template-less 文档类型,只有两个属性,一个名为 [=37 的标题=] 和一个富文本编辑器,其中单词的描述将被称为 'perigrafileksis'。我在那个页面的顶部有一个搜索表单。我希望搜索表单在原始单词所在的 space 中搜索标题或描述(在 Umbraco 中)而不刷新页面。图片更容易理解:
我正在用 MVC 做这个(或者会尝试做)但是我几乎不知道如何使用 AJAX 即使在阅读了 W3Schools 教程等之后。
到目前为止我有:
控制器:
using MyUmbraco.Models;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
namespace MyUmbraco.Controllers
{
public class SearchDictionarySurfaceController : SurfaceController
{
// GET: SearchDictionarySurface
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult HandleDictionarySearching(SearchBarViewModel model)
{
if (!string.IsNullOrEmpty(model.query))
{
var query = Request.QueryString["query"];
//var url = Umbraco.Content("1409");
return CurrentUmbracoPage();
}
else
{
return new RedirectResult("/homePage/", false);
}
}
}
}
部分:
@inherits Umbraco.Web.Mvc.UmbracoViewPage<SearchBarViewModel>
@using MyUmbraco.Controllers
@using MyUmbraco.Models
@using Umbraco.Web;
@{
var node = UmbracoContext.Current.PublishedContentRequest.PublishedContent;
}
@using (Html.BeginUmbracoForm<SearchDictionarySurfaceController>("HandleDictionarySearching", null, new { @class = "input-group input-lg add-on" }))
{
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
@*<form action="" method="post" target="_blank" class="input-group input-lg add-on searchbarbackground">*@
@Html.TextBoxFor(model => model.query, null, new { @class = "form-control searchbar", @method = "post", @target = "_blank", @id = "query" })
<div class="input-group-btn searchbutton">
<button class="btn" type="submit" tabindex="2" id="search">
@if (node == Umbraco.TypedContent(1254))
{
<img src="~/css/images/focal-lense-brown.png" />
}
else
{
<img src="~/css/images/focal-lense.png" />
}
</button>
</div>
@*</form>*@
}
<script>
//the script is the one that tells the controller to send the data to the model. If we don't have that, we can't do anything.
$(document).ready(function () {
$("#search").click(function (event) {
event.preventDefault();
xhttp.open("POST", "ajax_info.txt", true);
xhttp.send();
});
});
</script>
以及呈现部分搜索表单的实际词典页面:
<body>
@Html.Partial("_Navbar")
<div class="container plainwhite">
<div class="row">
<div class="col-md-12">
@{ Html.RenderPartial("_DictionarySearchBar", new SearchBarViewModel());}
</div>
</div>
<div class="row">
@foreach (var item in Model.Content.Descendants("lekseisDiatrofikouLeksikou"))
{
<div class="col-sm-3 styled">
<button data-id="@id" type="button" class="btn">
@(item.GetPropertyValue<string>("leksi"))
</button>
<div id="@("button-wrapper"+id)" class="col-xs-12 styled2 text-center nopadding">
@Html.Raw(item.GetPropertyValue<string>("perigrafiLeksis"))
</div>
</div>
id++;
}
</div>
</div>
@Html.Partial("_FooterMenu")
</body>
你不用帮我解决,我只是想了解其中的逻辑。即使您将我指向一个正在做我想做的事情的教程也会很棒,因为我发现 none.
问题是,AJAX的逻辑是什么?我是否需要有一个额外的部分来呈现与原始页面相同的结果并使其成为隐藏的 div 或什么?我真的很困惑。另外,我想我需要 JQuery 来阻止提交 > 刷新页面,但我不知道在那里写什么。另外,AJAX 是在脚本内还是在页面内?或者在单独的文件中?
我们正在丢失 WAR,发送帮助!
您希望字典中有多少个单词?也许这是一个可能的解决方案,只需使用一些 JS / jQuery 插件(检查:https://www.sitepoint.com/14-jquery-live-search-plugins/)甚至 jQuery UI 自动完成?
如果您想留在 Umbraco 中并通过 AJAX(或 AJAJ)调用执行操作/搜索,我建议您将逻辑从您的表面控制器移动到 Web API控制器在第一步。 Umbraco 通过在您的 class 中继承 UmbracoApiController 为我们提供了一种访问 Umbraco 服务和功能的简单方法。您可以在此处阅读更多相关信息:https://our.umbraco.org/documentation/reference/routing/webapi/。在您的方法中,您可以从所需位置抓取子项,然后 return 以您希望在后续步骤中使用它的形式。
设置 WebAPI 控制器后,您可以从 Javascript 代码访问该操作。根据使用的客户端库,调用会有所不同,但您将通过自动生成的 URL 访问该方法,例如http://yoursite.com/umbraco/api/dictionary/getallitems.
如果您愿意 return JSON,这是一种在客户端代码中使用和显示它的简单方法。
您也可以使用 Surface 控制器并使用 Ajax.BeginForm 辅助方法执行操作,但您的案例研究需要为此进行调整并且确实需要这种方式的做事。检查我们讨论的实现之一:https://our.umbraco.org/forum/developers/api-questions/56579-Umbraco-7-Surfacce-Controller-AjaxBeginForm.
这是怎么回事:
我在 Umbraco 7 中有一个 parent 模板,它应该是一个字典,我已经将每个字典单词设为一个 template-less 文档类型,只有两个属性,一个名为 [=37 的标题=] 和一个富文本编辑器,其中单词的描述将被称为 'perigrafileksis'。我在那个页面的顶部有一个搜索表单。我希望搜索表单在原始单词所在的 space 中搜索标题或描述(在 Umbraco 中)而不刷新页面。图片更容易理解:
我正在用 MVC 做这个(或者会尝试做)但是我几乎不知道如何使用 AJAX 即使在阅读了 W3Schools 教程等之后。
到目前为止我有:
控制器:
using MyUmbraco.Models;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
namespace MyUmbraco.Controllers
{
public class SearchDictionarySurfaceController : SurfaceController
{
// GET: SearchDictionarySurface
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult HandleDictionarySearching(SearchBarViewModel model)
{
if (!string.IsNullOrEmpty(model.query))
{
var query = Request.QueryString["query"];
//var url = Umbraco.Content("1409");
return CurrentUmbracoPage();
}
else
{
return new RedirectResult("/homePage/", false);
}
}
}
}
部分:
@inherits Umbraco.Web.Mvc.UmbracoViewPage<SearchBarViewModel>
@using MyUmbraco.Controllers
@using MyUmbraco.Models
@using Umbraco.Web;
@{
var node = UmbracoContext.Current.PublishedContentRequest.PublishedContent;
}
@using (Html.BeginUmbracoForm<SearchDictionarySurfaceController>("HandleDictionarySearching", null, new { @class = "input-group input-lg add-on" }))
{
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
@*<form action="" method="post" target="_blank" class="input-group input-lg add-on searchbarbackground">*@
@Html.TextBoxFor(model => model.query, null, new { @class = "form-control searchbar", @method = "post", @target = "_blank", @id = "query" })
<div class="input-group-btn searchbutton">
<button class="btn" type="submit" tabindex="2" id="search">
@if (node == Umbraco.TypedContent(1254))
{
<img src="~/css/images/focal-lense-brown.png" />
}
else
{
<img src="~/css/images/focal-lense.png" />
}
</button>
</div>
@*</form>*@
}
<script>
//the script is the one that tells the controller to send the data to the model. If we don't have that, we can't do anything.
$(document).ready(function () {
$("#search").click(function (event) {
event.preventDefault();
xhttp.open("POST", "ajax_info.txt", true);
xhttp.send();
});
});
</script>
以及呈现部分搜索表单的实际词典页面:
<body>
@Html.Partial("_Navbar")
<div class="container plainwhite">
<div class="row">
<div class="col-md-12">
@{ Html.RenderPartial("_DictionarySearchBar", new SearchBarViewModel());}
</div>
</div>
<div class="row">
@foreach (var item in Model.Content.Descendants("lekseisDiatrofikouLeksikou"))
{
<div class="col-sm-3 styled">
<button data-id="@id" type="button" class="btn">
@(item.GetPropertyValue<string>("leksi"))
</button>
<div id="@("button-wrapper"+id)" class="col-xs-12 styled2 text-center nopadding">
@Html.Raw(item.GetPropertyValue<string>("perigrafiLeksis"))
</div>
</div>
id++;
}
</div>
</div>
@Html.Partial("_FooterMenu")
</body>
你不用帮我解决,我只是想了解其中的逻辑。即使您将我指向一个正在做我想做的事情的教程也会很棒,因为我发现 none.
问题是,AJAX的逻辑是什么?我是否需要有一个额外的部分来呈现与原始页面相同的结果并使其成为隐藏的 div 或什么?我真的很困惑。另外,我想我需要 JQuery 来阻止提交 > 刷新页面,但我不知道在那里写什么。另外,AJAX 是在脚本内还是在页面内?或者在单独的文件中?
我们正在丢失 WAR,发送帮助!
您希望字典中有多少个单词?也许这是一个可能的解决方案,只需使用一些 JS / jQuery 插件(检查:https://www.sitepoint.com/14-jquery-live-search-plugins/)甚至 jQuery UI 自动完成?
如果您想留在 Umbraco 中并通过 AJAX(或 AJAJ)调用执行操作/搜索,我建议您将逻辑从您的表面控制器移动到 Web API控制器在第一步。 Umbraco 通过在您的 class 中继承 UmbracoApiController 为我们提供了一种访问 Umbraco 服务和功能的简单方法。您可以在此处阅读更多相关信息:https://our.umbraco.org/documentation/reference/routing/webapi/。在您的方法中,您可以从所需位置抓取子项,然后 return 以您希望在后续步骤中使用它的形式。
设置 WebAPI 控制器后,您可以从 Javascript 代码访问该操作。根据使用的客户端库,调用会有所不同,但您将通过自动生成的 URL 访问该方法,例如http://yoursite.com/umbraco/api/dictionary/getallitems.
如果您愿意 return JSON,这是一种在客户端代码中使用和显示它的简单方法。
您也可以使用 Surface 控制器并使用 Ajax.BeginForm 辅助方法执行操作,但您的案例研究需要为此进行调整并且确实需要这种方式的做事。检查我们讨论的实现之一:https://our.umbraco.org/forum/developers/api-questions/56579-Umbraco-7-Surfacce-Controller-AjaxBeginForm.