MVC: Cannot get autocomplete to work - asp.net-mvc

I am looking at the book MVC 2 in Action. The chapter on autocomplete is at the end which I use as reference.
In the controller, the Json results that is returned is not transformed into a list for autocomplete. The book did not use Json but I could not use their alternative with a generic list.
So my View is;
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SHP.WebUI.Models.HolidayRequestViewModel>" %>
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$("input#SearchText").autocomplete('<%: Url.Action("FindNames", "Employee") %>');
});
</script>
<p>You must make sure that the correct person to approve your Annual Leave is currently selected</p>
<p>Your current approver is <%: Html.DisplayFor(model => model.ApproverName) %></p>
<p>If you want to change your approver, enter his/her name here and make your selection.</p>
<p><%: Html.TextBoxFor(model => model.SearchText) %></p>
<div id="test-panel" class="ui-state-default"> This panel will disappear on command.</div>
And my controller is;
public JsonResult FindNames(string q)
{
List<EmployeeName> filteredEmployees =
Employee.GetAllCurrentEmployeesNames().Where(x => x.Fullname.ToLower().Contains(q.ToLower())).ToList();
return Json(filteredEmployees, JsonRequestBehavior.AllowGet);
}
* EDITED *
The problem with sending the parameter has now been fixed by using "string q". Obvious eh? Now it is a case of getting the JSON returned into an autocomplete list.

If you are using jquery UI autocomplete the query string parameter is called term by default. So:
public ActionResult FindNames(string term)
Of course this could be personalized:
$('input#SearchText').autocomplete({
source: function(request, response) {
$.ajax({
url: '<%: Url.Action("FindNames", "Employee") %>',
dataType: 'json',
data: { searchText: request.term },
success: function(data) {
response(data);
}
});
}
});
The question is whether it is worth it.

I did a helper for this, you can use it without having to know jQuery at all
look how it works: http://demo.aspnetawesome.com/AutocompleteDemo
you can download the library from here: http://awesome.codeplex.com/

Related

Live search MVC

I'm looking for live search for ASP.NET and entity framework. I'm a little bit green with it. I read that it needs to use ajax, but I never used it before and can't get good example. Here is a piece of code, cshtml (part of textbox)
<div class="form-horizontal">
<hr />
<h4>Search for a client: </h4>
<div class="input-group">
<span class="input-group-addon" id="Name">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Name", "", new { #class = "form-control", placeholder = "Name" })
</div>
<div><h6></h6></div>
<div class="input-group">
<span class="input-group-addon" id="Surname">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Surname", "", new { #class = "form-control", placeholder = "Surname" })
</div>
<div><h6></h6></div>
<button type="submit" class="btn btn-default" data-toggle="modal" data-target="#infoModal">Search</button>
</div>
this is a part of controller:
public ActionResult Index(string Name, string Surname)
{
var SearchList = from m in db.Klienci
select m;
if (!String.IsNullOrEmpty(Name))
{
SearchList = SearchList.Where(s => s.Name.Contains(Name));
}
if (!String.IsNullOrEmpty(Surname))
{
SearchList = SearchList.Where(s => s.Nazwisko.Contains(Surname));
}
return View(SearchList);
}
So it search for me clients by name and surname, but it refresh full page when it lost focus or after clicking the button. How to solve it, to get live search? after each keystroke search through database? I'm a little bit green, would you Help me?
You can listen to the keyup event on your input element, read the value and send it to the server using ajax. Return the results and in the ajax call's success callback, update the ui with the results.
$(function() {
$("#Name,#SurName").keyup(function(e) {
var n = $("#Name").val();
var sn = $("#SurName").val();
$.get("/Home/Index?Name="+n+"&SurName="+sn,function(r){
//update ui with results
$("#resultsTable").html(r);
});
});
});
The code basically listens to the key up event on the two input textboxes and read the values and send to the /Home/Index action method using jquery get method asynchronously.When the action method returns the response, we update the DOM.
Assuming resultsTable is the Id of the table where we list the results.
Also, since you are returning the partial view result ( without layout headers), you should use return PartialView() instead of return View()
if(Request.IsAjaxRequest())
return PartialView(SearchList);
return View(SearchList);
Here is nice example/tutorial how to use Ajax with ASP.NET MVC
http://www.itorian.com/2013/02/jquery-ajax-get-and-post-calls-to.html
EDITED: 2016-07-20
Example:
$(function () {
$("searchField").keyup(function () {
$.ajax({
type: "POST",
url: "/Controller/Action",
data: data,
datatype: "html",
success: function (data) {
$('#result').html(data);
}
});
});
You have to visit the server to get data from server and without ajax it is not possible. Now the question is how to make ajax call, you can use jQuery js lib to do but I would recommend you to try angular as data binding in angular will fulfill your needs.
Take a look at followings links
Angular Ajax Service -
jQuery Ajax

two submit buttons on a form

lets say I have a set of establishments, each establishments know who his father is and a establishment can have many childs. now I created a set of cascading dropdowns for this problem so on the first whe find the ones that have no father ( tier 0 if you might), once the user selects an item the list on the second list its children are loaded ( if it has any children) and so on until tier 3, heres my code:
Index.cshtml:
#model WebUI.Controllers.IndexViewModel
<script src="#Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"> </script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
#Html.Partial("ParentEstablishments",Model)
<div id="FirstHeritage">#Html.Partial("FirstHeritageChildren",Model)</div>
<div id="SecondHeritage">#Html.Partial("SecondHeritageChildren",Model)</div>
Each partial view has an ajax form like the following:
#model WebUI.Controllers.IndexViewModel
#using (Ajax.BeginForm("SelectParent","Ticket",new AjaxOptions{UpdateTargetId="FirstHeritage"}))
{
<fieldset>
<legend>Entidad departamental</legend>
#Html.DropDownListFor(
m => m.SelectedParentId ,
new SelectList( Model.AvailableParents , "EstablishmentId" , "Name" ) ,
"[Por favor seleccione una entidad departamental]"
)
<input type="submit" value="Select" />
</fieldset>
}
so what i want to create is a submit button that lets the user tell me hes selected the entity he needs and to call a method on my controller where i check every id for a value, i tried to put the partial views inside a form but every submit button of the ajax forms calls the method of the form i create, how can i make a button without interfering with the ajax forms?
Modify the Button like below.
<input type="button" value="Select" class="btnSubmit" />
Mofify the Form Tag as mentioned below
#using (Ajax.BeginForm("SelectParent","Ticket", FormMethod.Post,
new { id = "myForm" }))
{
}
Modify the Div as mentioned below. Add an attribute which will have value corresponding to it's Controller's Action method.
<div id="FirstHeritage" attr-Url="#Url.Action("ActionName", "ControllerName",
new { area = "AreaName" })"></div>
Now in Jquery. Follow below steps.
Load Partial View
Fetch the Div Attribute Value
Use On for the Button event.
Ajax Request
JQuery
$(document).ready(function () {
var FirstHeritage = $('#FirstHeritage');
var url = FirstHeritage.attr('attr-Url');
FirstHeritage.load(url, function () {
var $form = $('#myForm');
$.validator.unobtrusive.parse($form);
$(document).on('click', '.btnSubmit', function () {
if ($form.valid()) {
$.ajax({
url: Url,
async: true,
type: 'POST',
beforeSend: function (xhr, opts) {
},
contentType: 'application/json; charset=utf-8',
complete: function () { },
success: function (data) {
$form.html(data);
$form.removeData('validator');
$form.removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse($form);
}
});
}
});
});
});
Hope this will help you.
You can't, essentially. The script that makes the AJAX form an AJAX form binds to the submit event, so any submit will be caught.
Remember all the HTML helpers and controls in ASP.NET are there to cover common scenarios and make your life easier when you're actually in a common scenario. The more "custom" your code gets (such as a second submit button that will do a regular POST instead of an AJAX POST), the more work you need to do (and the less you should be using the builtin helpers and controls).
Just create a regular form (Html.BeginForm), add your two submit buttons, and then attach a click event on the AJAX version, and then send the POST as AJAX yourself.

ASP.NET MVC 3 EF Code First - Master Details CRUD

I am using ASP.NET MVC 3 EF Code First with Razor + SQLserver and Want to implement Master Details scenario (like Order, Orderlines) with CRUD operations. I have come across some online examples like http://hasibulhaque.com/index.php/2011/master-detail-crud-operations-ef-asp-net-mvc-3/ but they heavily depends on JQuery or other complex implementations. Can somebody suggest me some step by step approach with a clean code?
there are good tutorials at the asp.net site.
and i recommend you switch to mvc4 learning.
here is a link:
http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
If you want scaffolding do it for you, unfortunately it's not possible and you can't do that simply. Besides, you must use jquery and ajax to implement what you want.
I think the best and simplest way for you is that you have a view for creating Form and at the bottom of it put a fieldset to assign FormFields to it.
For the fieldset, you should have two partial views: One for create and another for edit. The partial view for creating should be something like this:
#model myPrj.Models.Form_FormFieldInfo
#{
var index = Guid.NewGuid().ToString();
string ln = (string)ViewBag.ListName;
string hn = ln + ".Index";
}
<tr>
<td>
<input type="hidden" name="#hn" value="#index" />
#Html.LabelFor(model => model.FormFieldID)
</td>
<td>
#Html.DropDownList(ln + "[" + index + "].FormFieldID",
new SelectList(new myPrj.Models.DbContext().FormFields, "ID", "FieldName"))
</td>
<td>
<input type="button" onclick="$(this).parent().parent().remove();"
value="Remove" />
</td>
</tr>
By calling this partial view in the create place view ajaxly, you can render some elements for each tag. Each line of elements contains a label, a DropDownList containing tags, and a remove button to simply remove the created elements.
In the create place view, you have a bare table which will contain those elements you create through the partial view:
<fieldset>
<legend>Form and FormFields</legend>
#Html.ValidationMessageFor(model => model.FormFields)</label>
<table id="tblFields"></table>
<input type="button" id="btnAddTag" value="Add new Field"/>
<img id="imgSpinnerl" src="~/Images/indicator-blue.gif" style="display:none;" />
</fieldset>
and you have the following script to create a line of elements for each tag:
$(document).ready(function () {
$("#btnAddField").click(function () {
$.ajax({
url: "/Controller/GetFormFieldRow/FormFields",
type: 'GET', dataType: 'json',
success: function (data, textStatus, jqXHR) {
$("#tblFields").append(jqXHR.responseText);
},
error: function (jqXHR, textStatus, errorThrown) {
$("#tblFields").append(jqXHR.responseText);
},
beforeSend: function () { $("#imgSpinnerl").show(); },
complete: function () { $("#imgSpinnerl").hide(); }
});
});
});
The action method GetFormFieldRow is like the following:
public PartialViewResult GetFormFieldRow(string id = "")
{
ViewBag.ListName = id;
return PartialView("_FormFieldPartial");
}
and your done for the create... The whole solution for your question has many codes for views, partial views, controllers, ajax calls and model binding. I tried to just show you the way because I really can't to post all of them in this answer.
Here is the full info and how-to.
Hope that this answer be useful and lead the way for you.

JQuery.load() return only first answer fresh and after only same old data

I use function JQuery.load().
On first call, there is return correct partial view.
I expected that if I click on check box again and again, on each click in td "example" refresh actual time.
Problem is that function return correct time only on first call. On next call, it returns same value (in this moment old time).
In debug, break-point in controller catch only first call. Other calls ignore.
It seems that ASP generate partial view just once and return it again and again.
What I can do if i need on each call fresh data?
For this example exist solution without ajax, but i need it for more complex problem.
java:
<script type="text/javascript">
function Example() {
jQuery('#example').load('/Home/Example/1/1');
}
</script>
View:
...
<table>
<tr>
<td>
<% Html.RenderPartial("Example"); %>
</td>
<td id="example">xxx
</td>
</tr>
</table>
<input class="checkbox" type="checkbox" name="xxx" id="xxx"
onclick="Example();" />
...
Partial View "Example.ascx":
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<%# Import Namespace="System" %>
<%= DateTime.Now.ToLongTimeString() %>
Controller:
public ActionResult Example(string locality, int id)
{
return PartialView("Example");
}
PS: If i call it by HTML.RenderPartial, it is fresh on each refresh, but call by ajax is fresh only on first call on compile. After resresh it returns still old data.
Stop jQuery .load response from being cached
You need .ajax :)
You could use $.ajax and set cache: false
Like this:
$.ajax({
url: '<%: Url.Action("Requests", "Home", new{ area = "Competition"})%>',
cache: false,
type: "GET",
dataType: "html",
success: function (result) {
$("#divCompetitionRequests").html(result);
}
});
and there is a nice solution #ayk answer.

ASP.NET MVC.NET JQueryUI datepicker inside a div loaded/updated with ajax.actionlink

I'm trying to incorporate jqueryUI's datepicker inside a partialview like this:
<% using (Ajax.BeginForm("/EditData",
new AjaxOptions { HttpMethod = "POST",
UpdateTargetId = "div1" }))
{%>
Date:
<%= Html.TextBox("date", String.Format("{0:g}", Model.date), new { id = "datePicker"})%>
<% } %>
<script type="text/javascript">
$(function() {
$("#datePicker").datepicker();
});
</script>
When I directly call the url to this partial view, so it renders only this view the datepicker works perfectly. (For the purpose of testing this I added the needed jquery and jqueryui script and css references directly to the partial view)
But if I use a Ajax.Actionlink to load this partial view inside a div (called div2, submitting the above form should update div1) like this:
<div id="div1">
<%= Ajax.ActionLink("Edit", "/EditData", new { id = Model.id }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "div2" } )%>
</div>
<div2>placeholder for the form</div>
The datepicker won't appear anymore.
My best guess is the javascript included in the loaded html doesn't get executed,
($(document).ready(function() {
$("#datepicker").datepicker();
}); doesnt work either
If that's the case how and where should I call the $("datepicker").datepicker(); ?
(putting it in the ajaxoptions of the ajax.actionlink as oncomplete = "$(function() {
$('#datepicker').datepicker();});" still doesnt work.
If that's not the case, then where's my problem?
The answer given by veggerby probably will be working in the given scenario, therefor i marked it as correct answer.
My problem here was that the javascript is in a portion of html being dynamicly loaded thrue ajax. Then the loaded javascript code wont be picked up by the javascript interpreter (or whatever im supposed to call the javascript handling on the clientside).
In my case veggerby's sollution wouldnt work either but that's because in my app i even loaded that piece of html+javascript thrue ajax. which results in the same problem.
i didnt feel like putting the javascript in the first normally loaded page, since it doesnt always load the same piece of app (thus possibly executing code when its not needed).
i resolved this by creating a sepperate .js script which is included in the site.master:
function rebindJQuery(data) {
jQuery('#div2').html(data.get_data());
jQuery('#datepicker').datepicker();
return false; //prevent original behavior, in this case folowing the link
}
which gets executed by
<%= Ajax.ActionLink("Edit", "/EditData", new { id = Model.id }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "div2" , oncomplete="rebinJQuery" } )%>
i have yet to find a way to get the UpdateTargetId into my rebindJQuery(data) function, so this can be more generic. Nontheless this solves my problem. (and a couple of compairable questions asked here on stackoverflow)
I don't know why that does not work, but you could skip using the Ajax.ActionLink and instead use JQuery on itself to do this task, i.e.:
<div id="div1">
<%= Html.ActionLink("Edit", "/EditData", new { id = Model.id } )%>
</div>
<div2>placeholder for the form</div>
<script type="text/javascript">
$(document).ready(function() {
$("#div1 a").click(function() {
$.get(
$(this).attr("href"),
null,
function (data) {
$("#div2").html(data);
$("#datepicker").datepicker();
});
return false; // to prevent link
});
});
</script>
jQuery live events might be useful.
http://docs.jquery.com/Events/live

Resources