I'm trying to code a simple autocomplete using LINQ to entities and Razor (new to c# sharp as well) and i'm having trouble displaying json data in my view.
My controller is as follows:
public ActionResult AutoCompleteCity(string guess)
{
List<City> listData = null;
if (!string.IsNullOrEmpty(guess))
{
listData = db.AutoCompleteCity(guess);
}
return Json(new { Data = listData });
}
AJAX call:
function getCities(input) {
var serviceURL = $("#autocompleteURL").val();
var url =
$.ajax({
type: "POST",
url: serviceURL,
data: {
'guess': input
},
dataType: 'json',
success: function (response) {
if (response.Data != null) {
if ($("#targetUL") != undefined) {
$("#targetUL").remove();
}
Data = response.Data;
$.each(Data, function (i, value) {
$("#targetUL").append($("<li class='targetLI' onclick='javascript:agregarTexto(this)'>" + JSON.stringify(value) + "</li>"));
});
});
}
I might be missing a bracket or two :D
Any way when i retrieve records from the database and try to pass JSON values to the view the output is:
{"Data":[{"Selected":false,"Text":null,"Value":null}]}
I assume I'm not passing the JSON listData correctly. Any input will be greatly appreciated, thanks!
EDIT: here is a screencap of the values returned by listData in my controller
This is my LINQ query
public List<City> AutoCompleteCity(string guess)
{
using (var context = new Sports.SportsEntities())
{
var query = (from loc in context.city
join prov in context.state on loc.STATE_ID equals prov.STATE_ID
where loc.CITY_DESC.Contains(guess.ToUpper())
select new
{
city = loc.CITY_DESC,
state = prov.STATE_DESC,
});
IEnumerable<City> cityList= from ba in query.AsEnumerable()
select new City(ba.city, ba.state);
return cityList.ToList();
}
}
This error:
{"Data":[{"Selected":false,"Text":null,"Value":null}]}
was caused by having declared private attributes in the City Class, or by failing to declare getter/setter methods if said attributes are meant to be private.
I figured that out by looking at the screen capture posted on my question, only displaying the "selected", "text" and "value" properties and not the city and state description in the query results, which was what I needed to display below the textbox input.
This controller method will do the trick:
public JsonResult AutoCompleteCity(string term)
{
List<City> listData = new List<City>();
if (!string.IsNullOrEmpty(term))
{
listData = db.AutoCompleteCity(term);
}
return Json(listData, JsonRequestBehavior.AllowGet);
}
The problem is probably this piece of code in the AJAX call:
if ($("#targetUL") != undefined) {
$("#targetUL").remove();
}
By doing this you are removing the ul tag from the DOM and therefore cannot add the li elements you are constructing in this piece of code:
$.each(Data, function (i, value) {
$("#targetUL").append($("<li class='targetLI' onclick='javascript:agregarTexto(this)'>" + JSON.stringify(value) + "</li>"));
});
If you want to clear the list use .empty():
if ($("#targetUL") != undefined) {
$("#targetUL").empty();
}
if you want to return a JSON, change that:
public ActionResult AutoCompleteCity(string guess)
by
public JsonResult AutoCompleteCity(string guess)
and also try that:
Data = JSON.parse(response.Data);
It looks like your method returns a list of City objects, so maybe you need to use the property of that objects to get to the city name, something like this:
$.each(Data, function (i, city) {
$("#targetUL").append($("<li class='targetLI' onclick='javascript:agregarTexto(this)'>" + city.Name + "</li>"));
});
Related
I have a view with a script (included below) that fires on a dropdownlist change, and the event handler should fill values for two text inputs. Values are received from controller.
The problem I'm having is, as soon as itemstatus list is populated, the controller returns back to view, and no values are passed back to AJAX function.
If I remove itemstatus list code and manually assign values as follows, it works:
var result = new { Quantity = "123", Price = "555"};
then it works.
I've also tried other ways to get data within controller but results were the same. Do you have any ideas what am I doing wrong and why controller returns back to view before "return Json"
<script type="text/javascript">
$(document).ready(function() {
//Dropdownlist Selectedchange event
$("#dropdown1").change(function ()
{
$("#txtQuantity").empty();
$("#txtPrice").empty();
$.ajax(
{
type: 'POST',
url: '#Url.Action("GetValues")',
dataType: 'json',
data: { id: $("#dropdown1").val() },
success: function(data)
{
$("#txtQuantity").val(data.Quantity);
$("#txtPrice").val(data.Price);
}
})
})
});
Controller:
public JsonResult GetValues(int id)
{
List<Item> itemstatus =
(from pd in db.Item
where (pd.itemID == id)
select new Item()
{
itemPrice = pd.itemPrice,
itemQuantity = pd.itemQuantity
}).ToList();
...
more code where i select what i need as a result i have two strings named itemquantity and itemprice
...
var result = new { Quantity= itemquantity, Price = itemprice };
return Json(result, JsonRequestBehavior.AllowGet);
}
because you are sending a list, whose data values can be accessed using
success: function(data)
{
$("#txtQuantity").val(data[0].Quantity);
$("#txtPrice").val(data[0].Price);
}
I have a controller action like this:
List<string> abcd = new List<string>()
foreach (var i in images)
{
abcd.Add("{url:'"+GetImageUrl(i)+"'}");
}
return Json(abcd, JsonRequestBehavior.AllowGet);
So the output of abcd is
["{url:'/PropertyImage/GetPropertyImage?imageId=1'}", "{url:'/PropertyImage/GetPropertyImage?imageId=2'}", "{url:'/PropertyImage/GetPropertyImage?imageId=8'}"]
But the result I want is:
images:[{url:'/PropertyImage/GetPropertyImage?imageId=1'}, {url:'/PropertyImage/GetPropertyImage?imageId=2'}, {url:'/PropertyImage/GetPropertyImage?imageId=8'}]
In my JavaScript, I have
$.ajax({
type: "GET",
url: url,
success: function (result) {
console.log(JSON.stringify(result));
var data = {
images: [result]
};
template = "{{#images}}<a href='{{url}}'><img class='imageborder' src='{{url}}' style='width:150px;height:150px'></img></a>{{/images}}";
renderedOutput= Mustache.to_html(template,data);
$('#Propertyimagelinks').html(renderedOutput);
}
});
How can I get the correct output?
Rather than trying to manually manipulate JSON strings, it seems a lot simpler to use ASP.NET MVC's built in JSON serialization functionality and a little bit of Linq, like this:
var abcd = images.Select(i => new { url = GetImageUrl(i) }).ToList();
return Json(abcd, JsonRequestBehavior.AllowGet);
And in your JavaScript result handler, use this:
var data = { images: result };
Alternatively you can use this in your controller:
var abcd = images.Select(i => new { url = GetImageUrl(i) }).ToList();
return Json(new { images = abcd }, JsonRequestBehavior.AllowGet);
And in your JavaScript:
var data = result;
I am trying to get list result in IENumerable type ViewBag that contains already a list before.
I am returning list using viewbag in action-
[HttpGet]
public ActionResult RangerCard() {
var taglist = (from u in db.TagTables
where u.TagName.Contains(tag)
select u).ToList();
ViewBag.TagName = taglist;
return View();
}
Returing List-
#if (ViewBag.TagName != null) {
foreach (var item in ViewBag.TagName) {
<p class="tag-division">
<a id="#item" class="tag-in-dropdown" href="#"># #item</a>
</p>
}
}
It looks like-
This action return all the tags in a dropdown menu. Now I wanted to filter this result as soon as a user writes in this textbox.
In case of tagName RipEnglish-
I am filtering tags according to this text using ajax query-
#cardhascode is id of input textbox.
$('#cardhashcode').keyup(function () {
var tag = $('#cardhashcode').val();
$.ajax({
url: '/Upload/JsonTagList/?tag=' + tag,
type: 'Post',
success: function (data) {
}
});
});
And then action-
[HttpPost]
public ActionResult JsonTagList(string tag) {
var taglist = (from u in db.TagTables
where u.TagName.Contains(tag)
select u).ToList();
return Json(taglist);
}
This above action filters tag but I am not able to deal with output result. How do I show this filter result in this dropdown menu as filtered result.
Note-
This result is coming in list type. So there can be more than one tag available On every keyup event.
Thanks for any help.
Do you mean something like this inside your success handler:
if(data){
data.forEach(function(item){
$('#yourtagcontainer').append('<p class="tag-division"><a id="'+item+'" class="tag-in-dropdown" href="#"># '+item+'</a></p>');
});
}
Cheers.
Is it possible for me to get the same SelectListItems in this list:
public static List<SelectListItem> GetAreaApprovingAuthorities(int id)
{
List<Employee> approvingAuthorities = new List<Employee>();
using (var db = new TLMS_DBContext())
{
approvingAuthorities = db.Employees.Where(e => e.UserRoleID > 1 && e.PersonnelAreaID == id).ToList();
}
List<SelectListItem> returned = new List<SelectListItem>();
foreach (Employee emp in approvingAuthorities)
{
returned.Add(new SelectListItem { Text = string.Format("{0} {1}", emp.FirstName, emp.LastName), Value = emp.ID.ToString() });
}
return returned;
}
and pass them into a select list using Json?
Here is the controller action where the List is acquired:
public JsonResult GetApprovingAuthorities(int id)
{
return Json(TLMS_DropDownLists.GetAreaApprovingAuthorities(id),JsonRequestBehavior.AllowGet);
}
Here is where the json object is iterated through and then passed to the select list (this is triggered when another select list's value is changed):
$.ajax({
type: 'GET',
data: { id: selectedValue },
url: '#Url.Action("GetApprovingAuthorities")',
contentType: "application/json; charset=utf-8",
global: false,
async: false,
dataType: "json",
success: function (jsonObj) {
$('#aa').empty();
$.each(jsonObj, function (key, value) {
$('#aa').append($("<option/>", {
value: key.Text,
text: value.Text
}));
});
}
});
This is working to populate the "aa" select list and I am receiving the select list's selected item via the FormCollection in a controller action, but I cannot capture the original ID from the "GetAreaApprovingAuthorities" SelectListItem's Value. Is there a way that I can make this happen?
When you're iterating on the jsonObj it should be like this
//the first parameter is just the index of the iteration
//and the second one is the json object (SelectListItem)
$.each(jsonObj, function (index, obj) {
$('#aa').append($("<option/>",
{
value: obj.Value,
text: obj.Text
}));
});
I have the following question regarding the MVC and Jquery. I would like to be able to call with JQuery an action serverside and then returned result bind to a drop down list.
At this moment i do have something like that but instead of SelectList i just get back an anonymous type collection.
I have following JQuery:
<script type="text/javascript">
(function ($) {
$.fn.cascade = function (options) {
var defaults = {};
var opts = $.extend(defaults, options);
return this.each(function () {
$(this).change(function () {
var selectedValue = $(this).val();
var params = {};
params[opts.paramName] = selectedValue;
$.getJSON(opts.url, params, function (items) {
opts.childSelect.empty();
$.each(items, function (index, item) {
opts.childSelect.append(
$('<option/>')
.attr('value', item.Id)
.text(item.Name)
);
});
});
});
});
};
})(jQuery);
$(function () {
$('#Location_CountryId').cascade({
url: '#Url.Action("Regions")',
paramName: 'countryId',
childSelect: $('#Location_RegionId')
});
$('#Location_RegionId').cascade({
url: '#Url.Action("Cities")',
paramName: 'regionId',
childSelect: $('#Location_CityId')
});
});
</script>
Which calls this action in mvc 3:
public ActionResult Cities(int regionId)
{
IList cities;
using (DatingEntities context = new DatingEntities())
{
cities = (from c in context.cities
where c.RegionID == regionId
select new
{
Id = c.CityId,
Name = c.Name
}).ToList();
};
return Json(cities, JsonRequestBehavior.AllowGet);
}
My question, can i then return SelectList instead of IList and bind it properly?
Could you provide an example with my code please? I have more complex behavriou just for simpleness i posted only part of.
Thanks
What about creating a partial that renders the html for the selectlist options and returing that?
_SelectList.cshtml:
#model IList<SelectListItem>
#{
foreach (var item in Model)
{
<option value=#item.Value>#item.Text</option>
}
}
And from your controller:
public ActionResult Cities(int regionId)
{
IList<SelectListItem> cities;
using (DatingEntities context = new DatingEntities())
{
cities = (from c in context.cities
where c.RegionID == regionId
select new SelectListItem()
{
Value = c.CityId,
Text = c.Name
}).ToList();
};
return PartialView("_SelectList", cities);
}
Your js can then look like this:
<script type="text/javascript">
(function ($) {
$.fn.cascade = function (options) {
var defaults = {};
var opts = $.extend(defaults, options);
return this.each(function () {
$(this).change(function () {
var selectedValue = $(this).val();
var params = {};
params[opts.paramName] = selectedValue;
$.get(opts.url, params, function (items) {
opts.childSelect.empty();
opts.childSelect.html(items);
}
});
});
};
})(jQuery);
$(function () {
$('#Location_CountryId').cascade({
url: '#Url.Action("Regions")',
paramName: 'countryId',
childSelect: $('#Location_RegionId')
});
$('#Location_RegionId').cascade({
url: '#Url.Action("Cities")',
paramName: 'regionId',
childSelect: $('#Location_CityId')
});
});
</script>
Although - I normally do something similar to your JSON code above :-)
HTH
How about just using some simple jQuery to iterate through the JSON object your Cities method returns. eg
<script>
$('#Location_RegionId').change(function () {
$.get('#Url.Action("Cities", "[ControllerName]")/' + $('#Location_RegionId').val(), function (data) {
$('#Location_CityId').empty();
$.each(data, function() {
$('#Location_CityId').append($('<option />').val(this.CityId).text(this.Name));
});
});
});
$('#Location_RegionId').change();
<script/>
Assuming that your select with the regions in is called Location_RegionId and your select with cities has an id of Location_CityId.
For this to work as above it will need to be at the bottom of your view file, so the #Url.Action is rendered into the appropriate URL. Otherwise you can hard code it into a .js file and surround it with document.ready.
in the controller after getting list of cities convert it to a select list item as below
var list=new List<SelectListItem>();
list.AddRange(cities.Select(o => new SelectListItem
{
Text = o.Name,
Value = o.CityId.ToString()
}));
}
return Json(list);