Pulling sql data into jquery autocomplete - asp.net-mvc

I've looked for an answer to this, but not finding exactly what I'm looking for. So, please excuse if this has been answered any another thread.
I have a very large sql table that I'd like to use in a jquery autocomplete input field. I know I need to return that data as json formatted, just not sure the best way to accomplish this. This field is in an ASP.net MVC application.
I know I could probably do a php page that returns the result, but that seems a bit messy to me. Is the best way to go is by creating a web service that I call?
Thanks in advance for any help.

Here's some code as to how I have accomplished this. I am using the jquery UI plugin
The javascript on my View
$(function () {
$("#suburb").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("ManufacturerAutoComplete", "AutoComplete")', type: "POST", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
success: function (data) {
response($.map(data, function (item) {
return { label: item.DisplayValue, value: item.Suburb, id: item.SuburbID, postcode: item.Postcode, state: item.State }
}))
}
})
},
select: function (event, ui) {
$("#state").val(ui.item.state);
$("#postcode").val(ui.item.postcode);
}
});
The input on my view
<input type="text" id="suburb" />
And finally the code from my Controller
[HttpPost]
public JsonResult ManufacturerAutoComplete(string searchText)
{
if (searchText.Length > 2)
{
var service = new SuburbSearchServiceClient();
var results = service.SearchSuburb(searchText, "Australia");
List<Suburbs> sList = new List<Suburbs>();
foreach (var item in results)
{
sList.Add(new Suburbs() { SuburbID = item.SuburbID, Suburb = item.Suburb, State = item.State, Postcode = item.Postcode, DisplayValue = item.Suburb + " - " + item.State + " - " + item.Postcode });
}
return Json(sList);
}
else
{
var data = string.Empty;
return Json(data);
}
}
You need to include the js and css from the jquery-ui plugin and the results of your auticomplete will be shown underneath the input element. As you can see from the JsonResult method, I am calling a web service to get my suburb data, but this could come from anywhere in reality.
Hope this helps.

Related

Passing IEnumerable through Json

I'm making a "Like" button in a simple comment database MVC program.
I'm passins the ID of the comment through to a ActionResult in the HomeController when I hover over the "Like" button. The problem (I think) is that I don't know how to pass the IEnumerable list of Likes to the ajax.
The script and HTML part:
HTML:
Like this
Script:
$(".likes").hover(function (event) {
var Liker = { "CID": event.target.id };
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Home/ShowLike/",
data: JSON.stringify(Liker),
dataType: "json",
success: function (data) {
$.each(data.Name, function (value) {
alert(value);
});
},
error: function (xhr, err) {
// Note: just for debugging purposes!
alert("readyState: " + xhr.readyState +
"\nstatus: " + xhr.status);
alert("responseText: " + xhr.responseText);
}
});
});
HomeController -> ShowLike
[HttpPost]
public ActionResult ShowLike(Liker ids)
{
LikesRepository lkrep = new LikesRepository();
IEnumerable<Like> list = lkrep.GetLikes(ids.CID);
return Json(list);
}
LikesRepository
public class LikesRepository
{
CommentDBDataContext m_db = new CommentDBDataContext();
public IEnumerable<Like> GetLikes(int iden)
{
var result = from c in m_db.Likes
where c.CID == iden
orderby c.Name ascending
select c;
return result;
}
public void AddLike(Like c)
{
m_db.Likes.InsertOnSubmit(c);
m_db.SubmitChanges(); //This works
}
}
After diving into the problem more, we found it was actually triggering an internal server error (500). This was caused by a circular reference from serializing the LINQ to SQL objects to JSON. This issue is discussed several times...
How to remove circular reference in Entity Framework?
How did I solve the Json serializing circular reference error?
Circular Reference exception with JSON Serialisation with MVC3 and EF4 CTP5w
An alternate solution is to return the data as lists of strings as they only required the names.

Populating dropdown with JSON result - Cascading DropDown using MVC3, JQuery, Ajax, JSON

I've got a cascading drop-drown using mvc. Something like, if you select a country in the first-dropdown, the states of that country in the second one should be populated accordingly.
At the moment, all seems fine and I'm getting Json response (saw it using F12 tools), and it looks something like [{ "stateId":"01", "StateName": "arizona" } , { "stateId" : "02", "StateName":"California" }, etc..] ..
I'd like to know how to populate my second-dropdown with this data. My second drop-down's id is "StateID". Any help would be greatly appreciated.
Below is the code used to produce the JSON Response from the server:
[HttpPost]
public JsonResult GetStates(string CountryID)
{
using (mdb)
{
var statesResults = from q in mdb.GetStates(CountryID)
select new Models.StatesDTO
{
StateID = q.StateID,
StateName = q.StateName
};
locations.statesList = stateResults.ToList();
}
JsonResult result = new JsonResult();
result.Data = locations.statesList;
return result;
}
Below is the client-side HTML, my razor-code and my script. I want to write some code inside "success:" so that it populates the States dropdown with the JSON data.
<script type="text/javascript">
$(function () {
$("select#CountryID").change(function (evt) {
if ($("select#CountryID").val() != "-1") {
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: { CountryID: $("select#CountryID").val() },
success: function () { alert("Data retrieval successful"); },
error: function (xhr) { alert("Something seems Wrong"); }
});
}
});
});
</script>
To begin with, inside a jQuery event handler function this refers to the element that triggered the event, so you can replace the additional calls to $("select#CountryID") with $(this). Though where possible you should access element properties directly, rather than using the jQuery functions, so you could simply do this.value rather than $(this).val() or $("select#CountryID").val().
Then, inside your AJAX calls success function, you need to create a series of <option> elements. That can be done using the base jQuery() function (or $() for short). That would look something like this:
$.ajax({
success: function(states) {
// states is your JSON array
var $select = $('#StateID');
$.each(states, function(i, state) {
$('<option>', {
value: state.stateId
}).html(state.StateName).appendTo($select);
});
}
});
Here's a jsFiddle demo.
Relevant jQuery docs:
jQuery.each()
jQuery()
In my project i am doing like this it's below
iN MY Controller
public JsonResult State(int countryId)
{
var stateList = CityRepository.GetList(countryId);
return Json(stateList, JsonRequestBehavior.AllowGet);
}
In Model
public IQueryable<Models.State> GetList(int CountryID)
{
var statelist = db.States.Where(x => x.CountryID == CountryID).ToList().Select(item => new State
{
ID = item.ID,
StateName = item.StateName
}).AsQueryable();
return statelist;
}
In view
<script type="text/javascript">
function cascadingdropdown() {
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
var countryID = $('#countryID').val();
var Url="#Url.Content("~/City/State")";
$.ajax({
url:Url,
dataType: 'json',
data: { countryId: countryID },
success: function (data) {
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
$.each(data, function (index, optiondata) {
$("#stateID").append("<option value='" + optiondata.ID + "'>" + optiondata.StateName + "</option>");
});
}
});
}
</script>
i think this will help you......
Step 1:
At very first, we need a model class that defines properties for storing data.
public class ApplicationForm
{
public string Name { get; set; }
public string State { get; set; }
public string District { get; set; }
}
Step 2:
Now, we need an initial controller that will return an Index view by packing list of states in ViewBag.StateName.
public ActionResult Index()
{
List<SelectListItem> state = new List<SelectListItem>();
state.Add(new SelectListItem { Text = "Bihar", Value = "Bihar" });
state.Add(new SelectListItem { Text = "Jharkhand", Value = "Jharkhand" });
ViewBag.StateName = new SelectList(state, "Value", "Text");
return View();
}
In above controller we have a List containing states attached to ViewBag.StateName. We could get list of states form database using Linq query or something and pack it to ViewBag.StateName, well let’s go with in-memory data.
Step 3:
Once we have controller we can add its view and start creating a Razor form.
#Html.ValidationSummary("Please correct the errors and try again.")
#using (Html.BeginForm())
{
<fieldset>
<legend>DropDownList</legend>
#Html.Label("Name")
#Html.TextBox("Name")
#Html.ValidationMessage("Name", "*")
#Html.Label("State")
#Html.DropDownList("State", ViewBag.StateName as SelectList, "Select a State", new { id = "State" })
#Html.ValidationMessage("State", "*")
#Html.Label("District")
<select id="District" name="District"></select>
#Html.ValidationMessage("District", "*")
<p>
<input type="submit" value="Create" id="SubmitId" />
</p>
</fieldset>
}
You can see I have added proper labels and validation fields with each input controls (two DropDownList and one TextBox) and also a validation summery at the top. Notice, I have used which is HTML instead of Razor helper this is because when we make JSON call using jQuery will return HTML markup of pre-populated option tag. Now, let’s add jQuery code in the above view page.
Step 4:
Here is the jQuery code making JSON call to DDL named controller’s DistrictList method with a parameter (which is selected state name). DistrictList method will returns JSON data. With the returned JSON data we are building tag HTML markup and attaching this HTML markup to ‘District’ which is DOM control.
#Scripts.Render("~/bundles/jquery")
<script type="text/jscript">
$(function () {
$('#State').change(function () {
$.getJSON('/DDL/DistrictList/' + $('#State').val(), function (data) {
var items = '<option>Select a District</option>';
$.each(data, function (i, district) {
items += "<option value='" + district.Value + "'>" + district.Text + "</option>";
});
$('#District').html(items);
});
});
});
</script>
Please make sure you are using jQuery library references before the tag.
Step 5:
In above jQuery code we are making a JSON call to DDL named controller’s DistrictList method with a parameter. Here is the DistrictList method code which will return JSON data.
public JsonResult DistrictList(string Id)
{
var district = from s in District.GetDistrict()
where s.StateName == Id
select s;
return Json(new SelectList(district.ToArray(), "StateName", "DistrictName"), JsonRequestBehavior.AllowGet);
}
Please note, DistrictList method will accept an ‘Id’ (it should be 'Id' always) parameter of string type sent by the jQuery JSON call. Inside the method, I am using ‘Id’ parameter in linq query to get list of matching districts and conceptually, in the list of district data there should be a state field. Also note, in the linq query I am making a method call District.GetDistrict().
Step 6:
In above District.GetDistrict() method call, District is a model which has a GetDistrict() method. And I am using GetDistrict() method in linq query, so this method should be of type IQueryable. Here is the model code.
public class District
{
public string StateName { get; set; }
public string DistrictName { get; set; }
public static IQueryable<District> GetDistrict()
{
return new List<District>
{
new District { StateName = "Bihar", DistrictName = "Motihari" },
new District { StateName = "Bihar", DistrictName = "Muzaffarpur" },
new District { StateName = "Bihar", DistrictName = "Patna" },
new District { StateName = "Jharkhand", DistrictName = "Bokaro" },
new District { StateName = "Jharkhand", DistrictName = "Ranchi" },
}.AsQueryable();
}
}
Step 7:
You can run the application here because cascading dropdownlist is ready now. I am going to do some validation works when user clicks the submit button. So, I will add another action result of POST version.
[HttpPost]
public ActionResult Index(ApplicationForm formdata)
{
if (formdata.Name == null)
{
ModelState.AddModelError("Name", "Name is required field.");
}
if (formdata.State == null)
{
ModelState.AddModelError("State", "State is required field.");
}
if (formdata.District == null)
{
ModelState.AddModelError("District", "District is required field.");
}
if (!ModelState.IsValid)
{
//Populate the list again
List<SelectListItem> state = new List<SelectListItem>();
state.Add(new SelectListItem { Text = "Bihar", Value = "Bihar" });
state.Add(new SelectListItem { Text = "Jharkhand", Value = "Jharkhand" });
ViewBag.StateName = new SelectList(state, "Value", "Text");
return View("Index");
}
//TODO: Database Insertion
return RedirectToAction("Index", "Home");
}
Try this inside the ajax call:
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: {
CountryID: $("select#CountryID").val()
},
success: function (data) {
alert("Data retrieval successful");
var items = "";
$.each(data, function (i, val) {
items += "<option value='" + val.stateId + "'>" + val.StateName + "</option>";
});
$("select#StateID").empty().html(items);
},
error: function (xhr) {
alert("Something seems Wrong");
}
});
EDIT 1
success: function (data) {
$.each(data, function (i, val) {
$('select#StateID').append(
$("<option></option>")
.attr("value", val.stateId)
.text(val.StateName));
});
},
I know this post is a year old but I found it and so might you. I use the following solution and it works very well. Strong typed without the need to write a single line of Javascript.
mvc4ajaxdropdownlist.codeplex.com
You can download it via Visual Studio as a NuGet package.
You should consider using some client-side view engine that binds a model (in your case JSON returned from API) to template (HTML code for SELECT). Angular and React might be to complex for this use case, but JQuery view engine enables you to easily load JSON model into template using MVC-like approach:
<script type="text/javascript">
$(function () {
$("select#CountryID").change(function (evt) {
if ($("select#CountryID").val() != "-1") {
$.ajax({
url: "/Home/GetStates",
type: 'POST',
data: { CountryID: $("select#CountryID").val() },
success: function (response) {
$("#stateID").empty();
$("#stateID").view(response);
},
error: function (xhr) { alert("Something seems Wrong"); }
});
}
});
});
</script>
It is much cleaner that generating raw HTML in JavaScript. See details here: https://jocapc.github.io/jquery-view-engine/docs/ajax-dropdown
Try this:
public JsonResult getdist(int stateid)
{
var res = objdal.getddl(7, stateid).Select(m => new SelectListItem { Text = m.Name, Value = m.Id.ToString() });
return Json(res,JsonRequestBehavior.AllowGet);
}
<script type="text/javascript">
$(document).ready(function () {
$("#ddlStateId").change(function () {
var url = '#Url.Content("~/")' + "Home/Cities_SelectedState";
var ddlsource = "#ddlStateId";
var ddltarget = "#ddlCityId";
$.getJSON(url, { Sel_StateName: $(ddlsource).val() }, function (data) {
$(ddltarget).empty();
$.each(data, function (index, optionData) {
$(ddltarget).append("<option value='" + optionData.Text + "'>" + optionData.Value + "</option>");
});
});
});
});
</script>

How to submit local jqgrid data and form input elements

Page contains single form with input elements and jqgrid data.
jqGrid data is retrieved in json using loadonce: true option.
Data is edited locally.
How to submit all this data if submit button is pressed?
Has jqGrid any method which can help to submit all data from all rows. jqGrid - How to edit and save multiple rows at once? mentions that jQuery ajax form plugin should be used but I havent found any sample.
jqGrid probably holds retrieved json table in element. In this case form plugin is not capable read this data.
How to get and submit all data retrieved using loadonce: true and edited?
Update1
Based on Oleg answer I tried:
function SaveDocument() {
var gridData = $("#grid").jqGrid('getGridParam','data');
var postData = JSON.stringify(gridData);
$('#_detail').val( postData );
var res = $("#Form").serializeArray();
$.ajax({ type: "POST",
url: 'Edit'
data : res
});
}
}
aspx page:
<form id="Form" class='form-fields'>
.... other form fields
<input name='_detail' id='_detail' type='hidden' />
</form>
<div id="grid1container" style="width: 100%">
<table id="grid">
</table>
</div>
In ASP.NET MVC2 Controller Edit method I tried to parse result using
public JsonResult Edit(string _detail) {
var order = new Order();
UpdateModel(order, new HtmlDecodeValueProviderFromLocalizedData(ControllerContext));
var serializer = new JavaScriptSerializer();
var details = serializer.Deserialize<List<OrderDetails>>>(_detail);
}
Exception occurs in Deserialize() call. Decimal and date properties are passed in localized format but it looks like Deserialize() does not parse
localized strings and there is no way to force it to use converter like HtmlDecodeValueProviderFromLocalizedData passed to UpdateModel.
How to fix ?
Is is reasonable/how to convert _detail parameter into NameValue collection and then use UpdateModel to update details, use some other deserialize or other idea ?
Update 2.
Decimal and Date CurrentUICulture values are present in form and in jqGrid data. Sample provided handles them in form OK but fails for jqGrid data.
This controller should handle different entity types, form fields and jqgrid columns can defined at runtime. So using hard-coded names is not possible.
Based on Oleg reply I tried to override decimal conversion by creating converter
public class LocalizedTypeConverter : JavaScriptConverter
{
public override IEnumerable<Type> SupportedTypes
{
get
{
return new ReadOnlyCollection<Type>(new Type[] { typeof(decimal) });
}
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type,
JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (type == typeof(decimal))
return decimal.Parse(dictionary["resources"].ToString(), CultureInfo.CurrentCulture);
return null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new InvalidOperationException("We only Deserialize");
}
}
But conversion still causes exception
0,0000 is not valid value for decimal. It looks like decimal converter cannot overridden. How to fix ?
First of all you can get all local data from the jqGrid with respect of
var localGridData = $("#list").jqGrid('getGridParam','data');
If you will need to send only subset of rows of the grid, like the selected rows only, you can need to get _index:
var idsToDataIndex = $("#list").jqGrid('getGridParam','_index');
To send the data to the server you can use the following function for example
var sendData = function(data) {
var dataToSend = JSON.stringify(data);
alert("The following data are sending to the server:\n" + dataToSend);
$.ajax({
type: "POST",
url: "yourServerUrl",
dataType:"json",
data: dataToSend,
contentType: "application/json; charset=utf-8",
success: function(response, textStatus, jqXHR) {
// display an success message if needed
alert("success");
},
error: function(jqXHR, textStatus, errorThrown) {
// display an error message in any way
alert("error");
}
});
};
In the demo you will find a little more sophisticated example having two buttons: "Send all grid contain", "Send selected rows". The corresponding code is below
$("#sendAll").click(function(){
var localGridData = grid.jqGrid('getGridParam','data');
sendData(localGridData);
});
$("#sendSelected").click(function(){
var localGridData = grid.jqGrid('getGridParam','data'),
idsToDataIndex = grid.jqGrid('getGridParam','_index'),
selRows = grid.jqGrid('getGridParam','selarrrow'),
dataToSend = [], i, l=selRows.length;
for (i=0; i<l; i++) {
dataToSend.push(localGridData[idsToDataIndex[selRows[i]]]);
}
sendData(dataToSend);
});
where
var grid = $("#list"),
decodeErrorMessage = function(jqXHR, textStatus, errorThrown) {
var html, errorInfo, i, errorText = textStatus + '\n<br />' + errorThrown;
if (jqXHR.responseText.charAt(0) === '[') {
try {
errorInfo = $.parseJSON(jqXHR.responseText);
errorText = "";
for (i=0; i<errorInfo.length; i++) {
if (errorText.length !== 0) {
errorText += "<hr/>";
}
errorText += errorInfo[i].Source + ": " + errorInfo[i].Message;
}
}
catch (e) { }
} else {
html = /<body.*?>([\s\S]*)<\/body>/i.exec(jqXHR.responseText);
if (html !== null && html.length > 1) {
errorText = html[1];
}
}
return errorText;
},
sendData = function(data) {
var dataToSend = JSON.stringify(data);
alert("The following data are sending to the server:\n"+dataToSend);
$.ajax({
type: "POST",
url: "yourServerUrl",
dataType:"json",
data: dataToSend,
contentType: "application/json; charset=utf-8",
success: function(response, textStatus, jqXHR) {
// remove error div if exist
$('#' + grid[0].id + '_err').remove();
alert("success");
},
error: function(jqXHR, textStatus, errorThrown) {
// remove error div if exist
$('#' + grid[0].id + '_err').remove();
// insert div with the error description before the grid
grid.closest('div.ui-jqgrid').before(
'<div id="' + grid[0].id + '_err" style="max-width:' + grid[0].style.width +
';"><div class="ui-state-error ui-corner-all" style="padding:0.7em;float:left;"><span class="ui-icon ui-icon-alert" ' +
'style="float:left; margin-right: .3em;"></span><span style="clear:left">' +
decodeErrorMessage(jqXHR, textStatus, errorThrown) + '</span></div><div style="clear:left"/></div>');
}
});
};
I think, that more difficult and more complex problem you will become on the server. In case of concurrency errors, but I wrote you about the problems before. Exactly because of the problems I personally would never implement saving of multiple rows on the server.
UPDATED: To get data from the form you can use jQuery.serialize. You should use name attribute for all fields in the form which you want to serialize. All data which you need to send are
var allData = {
localGridData: grid.jqGrid('getGridParam','data'),
formData: $("#formid").serialize()
};
You can send the data exactly like I described before: sendData(allData).

ASP.NET MVC 3 Treeview

I need to display a Treeview in my MVC3 application. There will be a self referencing hierarchical table (Folders) and another table linked to it (Documents.) (So Folders can have N-subFolders and any folder/sub folder can have many documents.)
I have looked into using third party vendors such as Telerik, DJME and MVC Controls Toolkit. While all nice packages, I'm uneasy about the licences, and since i'm new to MVC (and programming in general,) I find their documentation lacking to get the right display working.
I've also looked at the heavily referenced blogs on TreeViews:
TreeViewHelper
and the Recursive Partial View
In addition to the other less referenced articles (The top 3 are also very informative):
http://tpeczek.com/2010/01/asynchronous-treeview-in-aspnet-mvc.html
http://mikehadlow.blogspot.com/2008/10/rendering-tree-view-using-mvc-framework.html
http://www.tek-tips.com/viewthread.cfm?qid=1637392&page=4
http://weblogs.asp.net/jigardesai/archive/2008/02/04/display-hierarchical-data-in-asp-net-mvc-framework.aspx
http://www.jigar.net/articles/viewhtmlcontent311.aspx
http://help.syncfusion.com/ug_82/ASP.NETMVCUI_Tools/CreatingATreeViewControl.html
I would like to use either the TreeViewHelper or the Recursive Partial View Method.
However, in the TreeViewHelper, I can't make it pull data from the second table (ie. I can only make it list the Files, but I'm not sure how to have it list the Documents for each File.)
For the Recursive Partial View, I'm still at a loss in how to convert this to MVC3 and also general implementation. I did find a post (forums.asp.net/t/1652809.aspx/1?treeview+with+mvc+3) that gives an explanation of how to convert a bit of it to MVC3, but i'm still unclear of what to do with it. I keep getting the error for the Partial view: Cannot implicitly Convert type 'void' to type 'object'
Like I said before I'm new to MVC3 and would like insight in which method would work best for my scenario and how to implement it.
In case anyone is wondering, the way I solved this problem was to use a recursive partial view. The problem I has having with it was that I didn't have the self referencing relationship set up in SQL/EF (I just had the ParentID field which wasn't linked to the Primary Key.) I also integrated jsTree as this has a lot of slick functionality such as search.
Like I said in the comment above, #Html.Action and #Html.Partial work instead of #Html.RenderAction and #Html.RenderPartial.
give a look to the edit/add/delete/node move templated TreeView of my Mvc Controls Toolkit here: http://mvccontrolstoolkit.codeplex.com/wikipage?title=TreeView
$(document).ready(function () {
BindChart();
});
function BindChart() {
$("#org").jOrgChart({
chartElement: '#chart',
dragAndDrop: true
});
}
$(".cardadd").live("click", function ()
{
var data = { id: 0 , ParentId:$(this).parent().data('cardid')};
OpenForminWindow('divfrmChartMember', 'divChartMember', 'frmChartMember', chart.ChartMember, data, '', 400, 1000);
});
$(".cardedit").live("click", function () {
var data = { id: $(this).parent().data('cardid')};
OpenForminWindow('divfrmChartMember', 'divChartMember', 'frmChartMember', chart.ChartMember, data, '', 400, 1000);
});
$(".cardremove").live("click", function () {
});
function OpenForminWindow(popupId, targetDivId, formid, url, data, callbackfunc, heigth, width) {
$.ajax({
type: "GET",
url: url,
data: data,
cache: false,
success: function (data) {
$('#' + targetDivId).html(data);
$('#' + formid).removeData('validator');
$('#' + formid).removeData('unobtrusiveValidation');
$('#' + formid).each(function () { $.data($(this)[0], 'validator', false); }); //enable to display the error messages
$.validator.unobtrusive.parse('#' + formid);
if (callbackfunc)
return callbackfunc();
}
});
$("#" + popupId).dialog({
modal: true,
height: heigth,
width: width,
beforeClose: function (event, ui) {
if (typeof refresh !== 'undefined' && refresh == true)
ReloadCurrentPage();
}
});
}
$('#frmChartMember').live('submit', function (e) {
SubmitAjaxForm($(this).attr('id'), chart.AddMember, ReloadChart);
e.preventDefault();
});
function SubmitAjaxForm(formId, url, callBack) {
$.ajax({
url: url,
type: 'post',
cache: false,
data: $('#' + formId).serialize(),
success: function (data) {
return callBack(data);
},
});
}
function ReloadChart(result) {
ClosePopup('divfrmChartMember');
$.ajax({
type: 'GET',
url: chart.ChartList,
cache: false,
success: function (result) {
$("#orgChart").html(result);
BindChart();
}
});
}
function ClosePopup(divid) {
$("#" + divid).dialog("close");
}
public class ChartController : Controller
{
//
// GET: /Chart/
ChartContext ctx = new ChartContext();
public ActionResult Index()
{
return View();
}
public ActionResult OrgChart()
{
return PartialView("_OrgChart", ctx.Cards.ToList());
}
public ActionResult ChartMember(int id, int? ParentId = null)
{
Card card = new Card();
if (id > 0)
card = ctx.Cards.Find(id);
else
card.ParentId = ParentId;
return PartialView("_ChartMember", card);
}
public ActionResult SaveMember(Card card)
{
if (card.id == 0)
ctx.Cards.Add(card);
else
ctx.Entry(card).State = System.Data.EntityState.Modified;
ctx.SaveChanges();
return Json(true, JsonRequestBehavior.AllowGet);
}
}

jQuery Autocomplete not working with Json data

There are a whole bunch of tutorials out there explaining how to do this, eg here and here.
Looks real easy huh? Yet I've still somehow managed to waste half a day on it without getting anything working.
Eg: the following works absolutely fine
public ActionResult FindStuff(string q)
{
return Content("test");
}
$('#MyTextBox').autocomplete("MyController/FindStuff", {
parse: function(data) {
alert('parsing');
}
});
If I change it to the following, absolutely nothing happens.
public JsonResult FindStuff(string q)
{
return Json(new { name = "test" });
}
$('#MyTextBox').autocomplete("MyController/FindStuff", {
dataType: 'json', // I've also tried with this line commented out
parse: function(data) {
alert('parsing');
}
});
So it looks like the parse call is never being hit, i.e. I'm assuming the data load is blowing up somehow or thinks there is no data. Any ideas? Thanks.
p.s. it's the Jorn Zaefferer plugin here.
Make sure that you are returning an array and that you allow GET requests (in case your are using ASP.NET MVC 2.0):
public ActionResult FindStuff(string q)
{
return Json(new[] { new { name = "test" } }, JsonRequestBehavior.AllowGet);
}
And then follow the examples:
$('#MyTextBox').autocomplete("MyController/FindStuff", {
dataType: 'json',
parse: function (data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = { data: data[i], value: data[i].name };
}
return rows;
},
formatItem: function (row, i, n) {
return row.name;
}
});
Works nicely.
Remark: FireBug helps diagnosing problems very quickly as it shows you exactly what AJAX requests are being sent and why they succeed or fail.

Resources