So what's going on:
I have a parent template in Umbraco 7 which is supposed to be a dictionary and I've made each dictionary word a template-less doctype with only two properties, a title called 'leksi' and a rich text editor where the description of the word will be called 'perigrafileksis'. I have a search form on top of that page. I want the search form to search for the title or the description (within Umbraco) WITHOUT refreshing the page, in the space where the original words were. Picture for easier understanding:
I'm doing this with MVC (or will try to do it) but I pretty much have almost no idea how to use AJAX even after reading W3Schools tutorials and the such.
So far I have:
Controller:
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);
}
}
}
}
Partial:
@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>
And the actual Dictionary Page where the search form partial gets rendered:
<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>
You don't have to solve it for me, I just want to understand the logic of it. Even if you pointed me towards a tutorial that's doing what I want to do would be great because I have found none.
The question is, what's the logic in AJAX? Do I need to have an extra partial that will render the same results as the original page and make that a hidden div or what? I'm really confused. Also, I guess I need JQuery to prevent the submit > refresh page but I don't know what to write there. Also, is AJAX within a script or just inside the page? Or in a separate file?
We ARE LOSING THE WAR, SEND HELP!
How many words are you expecting to have in your dictionary? Maybe it's a possible solution to just sort it with some JS / jQuery plugin (check: https://www.sitepoint.com/14-jquery-live-search-plugins/) or even jQuery UI autocomplete?
If you want to stay inside the Umbraco and perform the action / searching via AJAX (or AJAJ) call, I suggest you to move the logic from your surface controller into the Web API controller in the first step. Umbraco is offering us an easy way to access Umbraco services and features by inheriting UmbracoApiController in your class. You can read more about it here: https://our.umbraco.org/documentation/reference/routing/webapi/. In your method you can just grab the children from the desired place and return it in the form you want to consume it in the further steps.
When you have you WebAPI controller set up, you are able to access the action from your Javascript code. Depending on the client-side library used, the call will be different, but you'll access the method via autogenerated URL e.g. http://yoursite.com/umbraco/api/dictionary/getallitems.
If you will return JSON, it's an easy way to consume & display it on your client-side code.
You can also go with Surface controllers and perform the action using Ajax.BeginForm helper method, but your case study needs to be fitted for this and really require this way of doing things. Check one of the implementation discussed on the Our: https://our.umbraco.org/forum/developers/api-questions/56579-Umbraco-7-Surfacce-Controller-AjaxBeginForm.