I am running into an issue creating cascading select boxes (backend Django-though I think this portion is mostly worked out). I have the following javascript code adapted from this stackoverflow response.
$(document).ready(function(){
$('select[name=experiment]').change(function(){
experiment_id = $(this).val();
request_url = '/admin/get_measurements/' + experiment_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(){
$('select[name=measurement_a]').append('<option value="' + this.key + '">' + this.value +'</option>');
// $('select[name=measurement_a]').append($("<option />").val(this.key).text(this.value))
});
},
return: false
})
})
});
In my project I select an experiment which triggers a call to "get_measurements" function and receive a list of "measurements" which should populate the measurement select box. Currently when I select the experiment I see the json response as expected:
{1: "MyFirstMeasurment", 2: "MySecondMeasurement"}
The measurement select box received 2 new selections however, both of them have the text "undefined" as opposed to "MyFirstMeasurement" and "MySecondMeasurement". I am guessing this is something simple in my code, Thank you for the help, let me know if you need more information.
It turns out I needed to do a couple of things to fix this, thanks for the help and hints. Here is the final code.
$(document).ready(function(){
$('select[name=experiment]').change(function(){
experiment_id = $(this).val();
request_url = '/admin/get_measurements/' + experiment_id + '/';
$.ajax({
url: request_url,
success: function(data){
$.each(data, function(key, value){
$('select[name=measurement_a]').append("<option value='" + value + "'>" + value +</option>");
});
},
return: false
})
})
});
Related
First, I think my title isn't very clear and very representative of what I want to achieve, but I couldn't make it clearer ...
Ok so I have a Leaderboard, created from this ajax call:
$.ajax({
url: '/handler',
dataType: 'json',
success: function(data) {
var tb = document.getElementById('Leaderboard');
while(tb.rows.length > 1) {
tb.deleteRow(1);
};
var keys = Object.keys(data);
for( key of keys) {
var username = data[key].username;
var score = data[key].score;
var row = $('<tr id = "row' + tb.rows.length + '"><td>' + username + '</td><td>' + score + '</td></tr>');
$('#Leaderboard').append(row);
if(tb.rows.length > 11){
tb.deleteRow(tb.rows.length -1);
}
}
},
error: function(jqXHR, textStatus, errorThrown){
alert('Error: ' + textStatus + ' - ' + errorThrown);
}
});
So as you can see in the Leaderboard, when clicking on a username, it opens a new page with the result of a GET request (/leaderboard/:username). My question is how can I skin this page, or even better load an html file in this page, but while keeping accessible the result of the GET request to use it inside?
That may not be clear, and that's maybe a reason why my title is not really fitting ... But anyway if you have some ideas i'll take them !!
Thanks
This is the first time ill use JSON. I used the json_encode(myarrayhere) to return array value as shown below.
There is a corresponding value on change of selected value on dropdown.
I verified that I get the array data by using alert(dataArray) and it returns like this
[{"title":"First"},
{"title":"Second"},
{"title":"Third"} ]
I used the word title as column name for a table I'm using in my database.
But the problem now is how to properly populate them in a drop down. I tried to do value.title but it looks like that title is a reserved word/method in php
$.ajax({
type: 'POST',
data: {ctgy: selected},
url: 'awts.php' ,
datatype: 'json',
success: function (dataArray) {
alert(dataArray);
var items = '';
$.each(result,function(name,value) {
items += "<option value='"+value.title+"'>"+value.title)+"</option>";
});
$("#dropdownselectid").html(items);
}
});
Thanks in advance.
Firstly, if you check the console you'll see that you have a syntax error. You have an extra ) when you append value.title to the HTML string.
Secondly, your $.each() call is attempting to loop through result when your data is in a variable named dataArray.
Try this:
$.ajax({
type: 'POST',
data: { ctgy: selected },
url: 'awts.php',
datatype: 'json',
success: function(dataArray) {
var items = '';
$.each(dataArray, function(name, value) {
items += '<option value="' + value.title + '">' + value.title + '</option>';
});
$("#dropdownselectid").html(items);
}
});
Working example
I have a function which updates a database via ajax. My issue is then how to update the data displayed on the page to show updated details. The POST data can vary and therefore the datastring would be something like this:
var dataString = '[name resource we are editing]=1' +
'¶1='+ para1 +
'¶2=' + para2+
'¶3=' + para3
I want the function below to split or loop through each of the POST variables in the datastring to update the text of an element on the page. I cannot figure out how.
function editAccount(dataString, details, form){
status = $(".status");
$.ajax({
type: "POST",
url: "<?php echo BASE_PATH; ?>/edit/",
data: dataString,
success: function(response) {
$.each(response, function(key, value) {
success_code = key;
message = value;
});
if(success_code == 1){
status.text(message).addClass("valid");
//show details and hide form
$("#" + details).show();
$("#" + form).hide();
//HOW to do below?
//update details being displayed with datasource data
//loop through dataString to assign eg. $('#para1')text(para1);
} else {
status.text(message).addClass("invalid");
}
},
error: function(response){
status.text("There was a problem updating your details into our database. Please contact us to report this error.").addClass("invalid");
}
});
}
As mentioned in a previous comment, I would suggest declaring the dataString variable as an object:
var dataString = { '[name resource we are editing]' : 1,
'para1': para1,
'para2': para2,
'para3': para3
}
Now it'll be much easier to loop over the params, just using the function each, for instance, which you already use in your code:
$.each(dataString, function(key, value) {
// Do stuff with each param
});
EDIT:
As #Qpirate suggests, you also can use the javascript for loop:
for(var key in dataString){
// value => dataString[key]
}
I wonder if I have any other method but a hidden field to post a JSON object to the server on full postback.
Imagine you have a form (with textboxes, checkboxes, etc) and you need to post a json string when the user post the form. This means, I would post all the form values + the json string but I can't come up with any solution but a hidden field.
Just wondering if there is any other option.
Thanks!
Hidden field is your only option. Unless you want to display the JSON to the user, in that case you can put it into a textarea or text input.
I used this recently in my web app:
$('#submit').live('click',function(){
var postData = {};
$('#items tr').not(':first').each(function(index, value) {
var keyPrefix = 'data[' + index + ']';
postData[keyPrefix + '[index]'] = index;
postData[keyPrefix + '[supp_short_code]'] = $(this).closest('tr').find('.supp_short_code').text();
postData[keyPrefix + '[project_ref]'] = $(this).closest('tr').find('.project_ref').text();
postData[keyPrefix + '[om_part_no]'] = $(this).closest('tr').find('.om_part_no').text();
postData[keyPrefix + '[description]'] = $(this).closest('tr').find('.description').text();
postData[keyPrefix + '[quantity_input]'] = $(this).closest('tr').find('.quantity_input').val();
postData[keyPrefix + '[cost_of_items]'] = $(this).closest('tr').find('.cost_of_items').text();
postData[keyPrefix + '[cost_total_td]'] = $(this).closest('tr').find('.cost_total_td').text();
});
$.ajax
({
type: "POST",
url: "order.php",
dataType: "json",
data: postData,
cache: false,
success: function(order_id)
{
alert("Order Saved");
$('#assigned_id').html(order_id);
}
});
});
Give this a try in your application or post you html and i can form the json...
I'm doing a simple ajax query which retrieves a variable-length list of values as JSON data. I'm trying to make a list based on this data which has click-functions based on the values I got from the JSON query. I can make this work just fine by writing the onClick-methods into the HTML like this:
function loadFooList() {
var list_area = $("#sidebar");
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' onClick='alert(\"" +
link_id + "\");'>" +
item.name + "</a></li>");
});
list_area.html(list_area.html() + "</ul>");
}
});
}
I don't like writing the onClick-function into the HTML and I also want to learn how to create this same functionality via JQuery click-function.
So the problem is obviously variable-scoping. My naive attempt here obviously won't work because the variables are no longer there when the click happens:
function loadFooList2() {
var list_area = $("#sidebar");
var link_ids = Array();
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' id='" + link_id + "'>"+item.name+"</a></li>");
link_ids.push(link_id);
});
list_area.html(list_area.html() + "</ul>");
for (link_index=0; link_index<link_ids.length; link_index++) {
$("#" + link_ids[link_index]).click(function() {
alert(link_ids[i]);
});
}
}
});
}
Obviously I'd like to do something else than just alert the value, but the alert-call is there as long as I can get that working and move forward.
I understand that I'll have to make some kind of handler-function to which I pass a state-variable. This works for a single value (I can store the whole link_ids array just fine, but then I don't know which of them is the right value for this link), but how would I do this for arbitrary-length lists?
Here is an example from JQuery docs which I'm trying to copy:
// get some data
var foobar = ...;
// specify handler, it needs data as a paramter
function handler(data) {
//...
}
// add click handler and pass foobar!
$('a').click(function(){
handler(foobar);
});
// if you need the context of the original handler, use apply:
$('a').click(function(){
handler.apply(this, [foobar]);
});
And I quess the last example here, "if you need the context of the original handler..." would probably be what I want but I don't know exactly how to get there. I tried to store the current link_id value into this, use it from this in the applied function (using apply()) but I didn't succeed. The necessary values were still undefined according to FireFox. I'm using JQuery 1.3.2.
So what's the right solution for this relatively basic problem?
Use append instead of html():
function loadFooList() {
var ul = $('<ul>');
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
var a = $('<a>').attr('href','#').bind('click', function(e) {
alert(link_id,item_name);
e.preventDefault();
});
$('<li>').append(a).appendTo(ul);
});
ul.appendTo('#sidebar'); // this is where the DOM injection happens
}
});
}
So the problem appears to be getting the link id associated with the link so that your click handler has access to it. Note that if it's alphanumeric it will qualify for the id attribute and you can extract it from there. If it is purely numeric, it will be an illegal id attribute. In that case, you can either use an attribute, like rel, or the jQuery.data() method to store the link id with the link. You can also simplify by using append. I'll show both examples.
var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>";
link.click( function() {
alert( $(this).attr('id') );
});
list_area.append(link);
or (if numeric)
var link = $("<li><a href='#'>" + item.name + "</a></li>";
link.data('identifier', link_id )
.click( function() {
alert( $(this).data('identifier') );
});
list_area.append(link);
Try this:
function loadFooList() {
var list_area = $("#sidebar");
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
var out = '<ul>';
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
out +="<li><a href='#' id='" + link_id + "'>"+item.name+"</a></li>";
});
out +="</ul>"
var $out = $(out);
$out.find('a').click(function(){
var link_id = this.id;
var item_name = $(this).text();
alert(link_id);
alert(link_name);
})
list_area.html($out);
}
});
}
Using multiple appends causing the browser to redraw multiple times in a row. You only want to modify the dom once.