jquery MVC4 receive JSON - javascript

I want to send json data from my controller to my view when a specific action happens.
I used this on controller to send the data
[HttpGet]
public JsonResult JSONGetParking(int buildingID){
return this.Json(
new
{
Result = (from obj in db.Parkings.Where(p => p.buildingID == buildingID) select new { ID = obj.ID, Name = obj.note })
}
, JsonRequestBehavior.AllowGet
);
}
it works very good
on my script i used this:
FloorScript.js
$(document).ready(function () {
$('#buildingID').change(function () {
alert("what is not");
$.getJSON('JSONGetParking?buildingID=' + $('#buildingID').val(), function (data) {
alert("afd");
var items = " ";
$.each(data, function (obx, oby) {
items += "<option value='" + oby.ID + "'>" + oby.Name + "</option>";
});
$('#parkingID').html(items);
});
});
});
I have opened google chrome and I can see the request and the response like this:
i can see the two text that i alerted
However, on my selector, i just see undefined value
Html
<div id="editor-label">
<select id="parkingID" name="parkingID"></select>
</div>
I have added the jquery in this
#section scripts {
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/Scripts/FloorScript.js");
}

You're not looping on the correct variable.
You did this:
$.each(data, function (obx, oby) {
whereas you should do this:
$.each(data.Result, function (obx, oby) {
This is pretty visible in the Google Chrome screenshot you provided. As you can see the returned JSON has a property called Result which is the collection whereas you were looping over the data variable which is not an array - it's just a javascript object that has a property called Result which is the array you wanna be looping through.
Also I'd replace:
$.getJSON('JSONGetParking?buildingID=' + $('#buildingID').val(), function (data) {
with:
$.getJSON('JSONGetParking', { buildingID: $('#buildingID').val() }, function (data) {
and of course get rid of this hardcoded url over there and use an url helper to generate it, on the dropdown as an HTML5 data-* attribute:
#Html.DropDownListFor(
x => x.BuildingId,
Model.Buildings,
new {
id = "buildingID",
data_url = Url.Action("JSONGetParking")
}
)
and then inside the change event you can trivially easy retrieve this url and avoid hardcoding it (and of course taking the risk of breaking your code when you deploy it in IIS in a virtual directory or simply change the routing pattern of your application):
$('#buildingID').change(function () {
var url = $(this).data('url');
$.getJSON(url, { buildingID: $('#buildingID').val() }, function (data) {
Alright, now the initial mess is tidied up.

use data.Result in your each loop
$(document).ready(function () {
$('#buildingID').change(function () {
alert("what is not");
$.getJSON('JSONGetParking?buildingID=' + $('#buildingID').val(), function (data) {
alert("afd");
var items = " ";
$.each(data.Result, function (obx, oby) {
items += "<option value='" + oby.ID + "'>" + oby.Name + "</option>";
});
$('#parkingID').html(items);
});
});
});
Hope this helps...

Related

Select2 dynamic dropdowns with templating

Trying to work out how to use the select2 templating function with a dynamic select2 dropdown to also show the extra data in a JSON response
My question does not relate to how to create the HTML template formating (I have already figured that out). I want to know how to make templating work when loading remote data - at the moment the remote data load function overwrites the templating...
Below is an example of what I mean by "templating" the result. I want to be able to specific the formating for the "otherData" and "extraData" fields
Current example data format (used by the code below that does not work with templating)
{"12":"DASGDSA67"}
Proposed example data (as JSON with extra data)
{"id":"12","value":"DASGDSA67","otherData":"Brunswick","extraData":"Heads"}
View (Javascript)
<script type="text/javascript">
$(document).ready(function() {
$(".company2").select2();
$(".location2").select2({
templateResult: formatState
});
});
$(".company2").select2().on('change', function() {
var $company2 = $('.company2');
$.ajax({
url:"../api/locations/" + $company2.val(),
type:'GET',
success:function(data) {
var $location2 = $(".location2");
$location2.empty();
$.each(data, function(value, key) {
$location2.append($("<option></option>").attr("value", value).text(key));
});
$location2.select2();
}
});
}).trigger('change');
function formatState (state) {
if (!state.id) { return state.text; }
var $state = $(
'<h1>' + state.element.value() + '</h1>' + '<p>' + state.element.otherData() + '</p>'
);
return $state;
};
</script>

String Not Appended to Dynamically Created Div

I've researched this in depth on stackexchange and I don't think I am making a 'common' mistake, and the other answers have not solved this.
The problem is I am trying to append data to a DEFINITELY existing div of a certain ID. What I DO know is that the div is dynamically generated, and that is probably why it is hidden.
Despite using jquery on I cannot seem to get jquery to find the particular div.
Here is the code:
$(document).ready(function() {
function example_append_terms(data) {
var sender_id = data['sender_id'];
$.each(data, function(k, v) {
if (k != 'sender_id') {
html = '<span data-lemma="' + v['key'] + '" class="lemma">' + v['name'] + '</span>';
$('#' + sender_id + ' .lemmas').append(html);
}
});
}
function example_get_options(data) {
$.ajax({
url: '/example/',
type: 'post',
data: data,
success: function(data) {
//alert(JSON.stringify(data))
example_append_terms(data)
},
failure: function(data) {
alert('Got an error dude');
}
});
return false;
}
$(document).on('click', ".example-synset-option", function() {
var synset = $(this).data('name');
var sender_id = $(this).attr('id')
example_get_options({
'synset': synset,
'sender_id': sender_id,
});
});
});
On clicking a certain div, an action is fired to "get options" which in turn runs an ajax function. The ajax function runs the "replacer" function example_append_terms.
Having tested up to example_append_terms the .each iteration is definitely working. But when I did tested $('#' + sender_id + ' .lemmas').length I continue to get 0.
Where is this jquery newb going wrong?
I fixed it by changing stuff...
For some inexplicable reason fetching the data attribute worked better than the id..
function intellitag_append_terms(data) {
var sender_id = $('*[data-location="'+data['sender_id']+'"] .lemmas');
$.each(data, function(k, v) {
if (k != 'sender_id') {
html = $('<span data-lemma="' + v['key'] + '" class="label label-primary lemma">' + v['name'] + '</span>');
html.appendTo(sender_id)
//$('#' + sender_id).append(html);
}
});
}

Extracting data from a GET response/JSON object

Haven't touched Javascript for a bit while and cannot find a proper way to extract data from a JSON object.
So I am basically sending a simple GET request to the Giphy API and attempting to get URL's from the response but for some reason I get all kinds of errors.
This is what I tried:
$(function() {
$('#searchButton').click(function() {
console.log("test");
$("#result").append("test<br />");
var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=cats&api_key=dc6zaTOxFJmzC&limit=1");
xhr.done(function(data) {
console.log(this.fixed_height);
$("#result").append("success got data<br />" + data + "<br />");
console.log("success got data", data);
$.each(data.results, function() {
$.each(this.images, function() {
console.log(this.fixed_height);
$("#result").append(this.fixed_height + "<br />");
});
})
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button id="searchButton">search!</button>
<div id="result"></div>
You have a couple of problems. First, there is not a results member in the data object. The only thing I see that you can iterate on, in the data object is yet another data member. Second, inside the images, there is no fixed_height, just height. This works:
var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=cats&api_key=dc6zaTOxFJmzC&limit=1");
xhr.done(function (data) {
$.each(data.data, function () {
$.each(this.images, function () {
console.log(this.height);
});
})
});
http://jsfiddle.net/n9ffva83/
Remember $(function () {});is not needed in JSFiddle, so you must provided (just the way you do in the code you gave us above).
EDIT:
To just get the url of the fixed height try this:
var xhr = $.get("http://api.giphy.com/v1/gifs/search?q=cats&api_key=dc6zaTOxFJmzC&limit=1");
xhr.done(function (data) {
$.each(data.data, function () {
console.log(this.images.fixed_height.url);
})
});
It seems this url is only one, that belong to the images.
http://jsfiddle.net/n9ffva83/1/

Javascript Scope Issue Possibly

Having trouble with my variable 'html'. I think i have the scope correct but something weird happens when I run this code. the first alert of the 'html' variable produces a blank result and then I populate my select list with the same 'html' variable and it works, then i alert the 'html' variable again and the options show up.
If I remove the two alerts the list is not pop
function populateMakes(years)
{
var makes = new Array();
var html = "";
$.each(years, function () {
var uri = "/api/make?year=" + this;
$.getJSON(uri, function (data) {
$.each(data, function () {
if (jQuery.inArray(this.Id, makes) == -1)//makes not contain make
{
makes.push(this.Id);
html += "<option value=" + this.Id + ">" + this.Value + "</option>";
}
});
});
});
alert(html);
$("#Make").html(html);
alert(html);
$("#MakeSection").removeClass("hidden");
};
Document Ready Script
$(document).ready(function () {
populateYears();
$("#Year").change(function () {
$("#MakeSection").addClass('hidden');
$("#ModelSection").addClass('hidden');
$("#SubModelSection").addClass('hidden');
populateMakes($("#Year").val());
});
$("#Make").change(function () {
$("#ModelSection").addClass('hidden');
$("#SubModelSection").addClass('hidden');
populateModels($("#Year").val(), $("#Make").val());
});
$("#Model").change(function () {
$("#SubModelSection").addClass('hidden');
//
});
$("#Clear").click(function () {
$("#YearSection").addClass('hidden');
$("#MakeSection").addClass('hidden');
$("#ModelSection").addClass('hidden');
$("#SubModelSection").addClass('hidden');
populateYears();
})
});
.getJSON is async and i overlooked the timing. i needed to add the .done callback and set the output there. the script simply wasn't finished yet.
$.getJSON(uri, function (data) {
$.each(data, function () {
if (jQuery.inArray(this.Id, makes) == -1)//makes not contain make
{
makes.push(this.Id);
html += "<option value=" + this.Id + ">" + this.Value + "</option>";
}
});
}).done(function () {
$("#Make").html(html);
$("#MakeSection").removeClass("hidden");
});
I also didn't send an array in the event handler on the code I posted in the question. I fixed that first.

jQuery UI token

I have followed this tutorial which uses jQuery UI to generate Facebook tokens like:
http://net.tutsplus.com/tutorials/javascript-ajax/how-to-use-the-jquery-ui-autocomplete-widget/
My problem is I need to pass two values thru JSON: the ID and the NAME.
the server side script looks like this:
header('Content-Type: text/html; charset=iso-8859-1', true);
include($_SERVER['DOCUMENT_ROOT'].'/inrees/inrees/communaute/includes/_db.php');
$param = $_GET["term"];
$query = mysql_query("SELECT * FROM comm_carnet, in_emails
WHERE carnet_iduser=emails_id
AND emails_id!='".$_COOKIE['INREES_ID']."'
AND emails_nom REGEXP '^$param'");
//build array of results
for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
$row = mysql_fetch_assoc($query);
$friends[$x] = array("name" = > $row["emails_nom"], "id" = > $row["emails_id"]);
}
//echo JSON to page
$response = $_GET["callback"]."(".json_encode($friends).")";
echo $response;
the echo from the server side script is:
([{"name":"dupont","id":"34998"},{"name":"castro","id":"34996"},{"name":"castelbajac","id":"34995"}])
(which is exactly what I need)
I am passing the the "name" array but not the "id" which needs to be a hidden input with the corresponding id from the database, the html page where the call to the php is done looks like this:
//attach autocomplete
$("#to").autocomplete({
//define callback to format results
source: function (req, add) {
//pass request to server
$.getJSON("messages_ajax.php?callback=?", req, function (data) {
//create array for response objects
var suggestions = [];
//process response
$.each(data, function (i, val) {
suggestions.push(val.name);
});
//pass array to callback
add(suggestions);
});
},
//define select handler
select: function (e, ui) {
//create formatted friend
var friend = ui.item.value,
span = $("<span>").text(friend),
a = $("<a>").addClass("remove").attr({
href: "javascript:",
title: "Remove " + friend
}).text("x").appendTo(span);
$("<input />", {
value: "id",
type: "hidden",
name: "id"
}).appendTo(span);
//add friend to friend div
span.insertBefore("#to");
},
//define select handler
change: function () {
//prevent 'to' field being updated and correct position
$("#to").val("").css("top", 2);
}
});
//add click handler to friends div
$("#friends").click(function () {
//focus 'to' field
$("#to").focus();
});
//add live handler for clicks on remove links
$(".remove", document.getElementById("friends")).live("click", function () {
//remove current friend
$(this).parent().remove();
//correct 'to' field position
if ($("#friends span").length === 0) {
$("#to").css("top", 0);
}
});
so is basically where you see the comment: "//define select handler" that something needs to be done but I can't do it!
I added the line:
$("<input />", {value:"id", type:"hidden", name:"id"}).appendTo(span);
but it does not fetch my array "id".
your code should be:
UPDATE With DEMO
$(function() {
$("#to").autocomplete({
//define callback to format results
source: function(req, add) {
//pass request to server
$.getJSON("json.json", req,
function(data) {
add($.map(data,
function(item) {
return {
id: item.id,
label: item.name,
value: item.name
}
}));
});
},
//define select handler
select: function(e, ui) {
$('<a class="del_friend" href="#' + ui.item.id + '" title="remove">' + ui.item.label + '<span>x</span>' +
'<input name="friend[]" type="hidden" id="friend_' + ui.item.id + '" value="' + ui.item.id + '" /></a>').insertBefore('#to');
},
//define select handler
change: function() {
$("#to").val("");
}
});
//delete friends
$('a.del_friend').live('click', function(e) {
e.preventDefault();
var friend_id = this.hash.split('#')[1];
alert(friend_id); //AJAX Call and delete item by it's ID
$(this).fadeOut(500).remove()
});
});
NOTE: this assuming your json code look like:
[{"name":"dupont","id":"34998"},{"name":"castro","id":"34996"},{"name":"castelbajac","id":"34995"}]
USEFULL READS: http://jqueryui.com/demos/autocomplete/#remote-jsonp
So, it looks like you're adding only the names to the suggestions list, not the entire data object which would contain the name and id members. Instead of doing this:
suggestions.push(val.name)
try pushing the entire data object onto the list you're passing to your callback:
suggestions.push(val)
Then, in your callback, ui.item.value will contain the full data member, so you'll need to change your code around a bit. To access the name and id values separately, you could presumably do something like this:
var friendName = ui.item.value.name;
var friendID = ui.item.value.id;
Then, you can use those variables where you need to (friend becomes friendID, and instead of passing {value:"id" ...} to the hidden input, you could do {value:friendID ...}

Categories