I am extremely new at writing ajax and working with a restful api... so, bear with me.
I have a Laravel 5.2 RESTful API that I am using on the backend, and I'm attempting to simply load a list of categories using Jquery / Ajax. As you click through the categories, each child category loads fine, but I cannot seem to get the "back" button to work (by this, I mean the LI I am generating, not the browser back button). When you click it, it shows the alert - and the data is correct, but that's it. The list doesn't refresh and populate with the appropriate items.
EDIT
There are no errors being thrown to the javascript console either. It just won't populate from the ajax call.
EDIT
I removed the request.abort() right after I made the original post.
EDIT
Here is the JSON returned from the URL api/categories/4 - as an example.
[{"id":6,"parent":4,"name":"sub_subcat4_1","slug":"sub_subcat4_1","description":null,"created_at":null,"updated_at":null},{"id":7,"parent":4,"name":"sub_subcat4_2","slug":"sub_subcat4_2","description":null,"created_at":null,"updated_at":null}]
EDIT
Here is the HTML for the #categories
<div class="row">
<div class="col-sm-12">
<ul id="categories">
</ul>
</div>
The Javascript
<script>
/*
* This loads the default / root categories.
*/
function getRootCategories() {
$.getJSON("api/categories", function(data) {
var categories = [];
$("#categories").html("");
$.each(data, function(key, val) {
$("#categories").append("<li class='subcat' data-id='" + val.id + "' onClick='getSubcats(this);'>" + val.name + '</li>');
});
});
}
/*
* This loads the sub categories if there's any data returned. Otherwise, just leave the user where they are.
*/
function getSubcats(cat) {
var dataID = cat.getAttribute("data-id");
alert(dataID);
if(dataID == "null") {
getRootCategories();
}
else {
$.getJSON("api/categories/" + dataID, function (data) {
if (data.length != 0) {
$("#categories").html("");
var newCats = '';
var parent = '';
$.each(data, function (key, val) {
parent = "<li class='subcat' data-id='" + val.parent + "' onClick='getSubcats(this);'>Back</li>";
newCats += "<li class='subcat' data-id='" + val.id + "' onClick='getSubcats(this);'>" + val.name + '</li>';
});
$("#categories").append(parent + newCats);
}
});
}
}
$(document).ready(function() {
$.ajaxSetup({ cache:false });
getRootCategories();
});
</script>
Ok, I just had my variables all mixed up. I wasn't setting the correct parent id.
The new script looks like this -
<script>
var previous = null;
/*
* This loads the default / root categories.
*/
function getRootCategories() {
$.getJSON("api/categories", function(data) {
var categories = [];
$("#categories").html("");
$.each(data, function(key, val) {
$("#categories").append("<li class='subcat' data-parent='" + val.parent + "' data-id='" + val.id + "' onClick='getSubcats(this);'>" + val.name + '</li>');
previous = val.parent;
});
});
}
/*
* This loads the sub categories if there's any data returned. Otherwise, just leave the user where they are.
*/
function getSubcats(cat) {
var dataID = cat.getAttribute("data-id");
previous = cat.getAttribute("data-parent");
if(dataID == "null") {
getRootCategories();
}
else {
$.getJSON("api/categories/" + dataID, function (data) {
if (data.length != 0) {
$("#categories").html("");
var newCats = '';
var parent = '';
$.each(data, function (key, val) {
parent = "<li class='subcat' data-id='" + previous + "' onClick='getSubcats(this);'>Back</li>";
newCats += "<li class='subcat' data-parent='" + val.parent + "' data-id='" + val.id + "' onClick='getSubcats(this);'>" + val.name + '</li>';
});
$("#categories").append(parent + newCats);
}
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + " - " + error);
});
}
}
$(document).ready(function() {
$.ajaxSetup({ cache:false });
getRootCategories();
});
</script>
I want add "All" option to the existing dropdown as a first option. Pls help me
if(own != null)
{
var ar = own.replace("[","").replace("]","").split(",");
var output = $("#status_type");
output.empty();
for(var i=0;i<ar.length/2;i++)
{
output.append("<option value='" + $.trim(ar[i*2+1]) + "'>" + $.trim(ar[i*2+1]) + "</option>");
//alert ("val " +$.trim(ar[i*2+1]));
}
}
I want "All" to be the first option in select dropdown
Instead of empty() use .html() and pass the html of the All Option. This will clear the select first then will add all option and then will add other options, and will save you an unnecessary .empty() operation.
if(own != null)
{
var ar = own.replace("[","").replace("]","").split(",");
var output = $("#status_type");
output.html('<option value="'+all+'">All</option>');
for(var i=0;i<ar.length/2;i++)
{
output.append("<option value='" + $.trim(ar[i*2+1]) + "'>" + $.trim(ar[i*2+1]) + "</option>");
//alert ("val " +$.trim(ar[i*2+1]));
}
Try this: You can add ALL option just right after emptying the output variable as shown below -
if(own != null)
{
var ar = own.replace("[","").replace("]","").split(",");
var output = $("#status_type");
output.empty();
output.append("<option value='ALL'></option");//add here
for(var i=0;i<ar.length/2;i++)
{
output.append("<option value='" + $.trim(ar[i*2+1]) + "'>" + $.trim(ar[i*2+1]) + "</option>");
//alert ("val " +$.trim(ar[i*2+1]));
}
}
Try this:
$('#mysampledropdown').empty();
$.each(response.d, function(key, value) {
$("#mysampledropdown").append($("<option></option>").val(value.ID).html(value.text));
});
$('<option>').val("").text('--ALL--').prependTo('#mysampledropdown');
In one of the jsp pages of my project, I have this jquery code, which fill a table with dynamic data from server (the json strings):
$('document').ready(function(){
var obj_data = jQuery.parseJSON( '{"Data":[{"data":"2014-04-10","string":"10/MAR"},{"data":"2014-04-11","string":"11/MAR"},{"data":"2014-04-12","string":"12/MAR"},{"data":"2014-04-13","string":"13/MAR"},{"data":"2014-04-14","string":"14/MAR"},{"data":"2014-04-15","string":"15/MAR"},{"data":"2014-04-16","string":"16/MAR"},{"data":"2014-04-17","string":"17/MAR"},{"data":"2014-04-18","string":"18/MAR"},{"data":"2014-04-19","string":"19/MAR"}]}' );
var obj_hora = jQuery.parseJSON( '{"Hora":[{"hora":"04:30:00","string":"4:30-4:30"},{"hora":"05:00:00","string":"5:0-5:0"},{"hora":"05:30:00","string":"5:30-5:30"},{"hora":"06:00:00","string":"6:0-6:0"},{"hora":"06:30:00","string":"6:30-6:30"},{"hora":"07:00:00","string":"7:0-7:0"},{"hora":"07:30:00","string":"7:30-7:30"},{"hora":"08:00:00","string":"8:0-8:0"},{"hora":"08:30:00","string":"8:30-8:30"},{"hora":"09:00:00","string":"9:0-9:0"},{"hora":"09:30:00","string":"9:30-9:30"},{"hora":"10:00:00","string":"10:0-10:0"}]}' );
var obj_horario = jQuery.parseJSON( '{"Horario":[{"horario":"2014-04-11 06:00:00","data":"2014-04-11","string_data":"11/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-11 06:30:00","data":"2014-04-11","string_data":"11/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-11 07:00:00","data":"2014-04-11","string_data":"11/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-12 06:00:00","data":"2014-04-12","string_data":"12/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-12 06:30:00","data":"2014-04-12","string_data":"12/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-12 07:00:00","data":"2014-04-12","string_data":"12/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-13 06:00:00","data":"2014-04-13","string_data":"13/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-13 06:30:00","data":"2014-04-13","string_data":"13/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-13 07:00:00","data":"2014-04-13","string_data":"13/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-14 06:00:00","data":"2014-04-14","string_data":"14/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-14 06:30:00","data":"2014-04-14","string_data":"14/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-14 07:00:00","data":"2014-04-14","string_data":"14/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-15 06:00:00","data":"2014-04-15","string_data":"15/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-15 06:30:00","data":"2014-04-15","string_data":"15/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-15 07:00:00","data":"2014-04-15","string_data":"15/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-16 06:00:00","data":"2014-04-16","string_data":"16/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-16 06:30:00","data":"2014-04-16","string_data":"16/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-16 07:00:00","data":"2014-04-16","string_data":"16/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-17 06:00:00","data":"2014-04-17","string_data":"17/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-17 06:30:00","data":"2014-04-17","string_data":"17/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-17 07:00:00","data":"2014-04-17","string_data":"17/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-18 06:00:00","data":"2014-04-18","string_data":"18/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-18 06:30:00","data":"2014-04-18","string_data":"18/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-18 07:00:00","data":"2014-04-18","string_data":"18/MAR","hora":"07:00:00","string_hora":"7:0-7:0"}]}' );
var newRow1 = $('<tr>');
for(var item in obj_hora.Hora) {
newCol1 = "<td></td>";
for(var item2 in obj_data.Data) {
newCol1 += '<td>' + obj_data.Data[item2].string + '</td>';
}
}
newRow1.append(newCol1);
$("table.horarios").append(newRow1);
var counter = 1;
var newRow2 = "";
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
for(var item2 in obj_data.Data) {
newCol2 += '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
newRow2.append(newCol2);
$("table.horarios").append(newRow2);
}
});
My problem is with this line:
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
that line should make the checkbox with similar values of date and time checked, but when I run the application and open this page, nothing is checked, despite I have data in the variable 'obj_horario', as you can see in the code above.
Someone can see what i am doing wrong here?
UPDATE
I change the code highlight above to this:
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data) {
console.info('counter='+counter);
console.info('Hora = ' + obj_hora.Hora[item].hora + '| Horario.hora = ' + obj_horario.Horario[index].hora);
console.info('Data = ' + obj_data.Data[item2].data + '| Horario.data = ' + obj_horario.Horario[index].data);
var checkbox = $('input[name='+counter+']');
$(checkbox).attr("checked", "true");
}
}
to include the console.info() function; now, i can see in the browser console that the itens which should be checked are being selected correctly by the if sentence, but i guess this snippet of the code:
var checkbox = $('input[name='+counter+']');
$(checkbox).attr("checked", "true");
aren't working properly. My guess it's because it is referring a dynamically created object - I have a similar problem before, and solve including the dynamic object inside a static one, and binding an event to this static element, but now I can't figure out how to do the same, since I'm triggering any event, just are adding the element to the page.
Anyone can point me a direction for solving this?
In this part:
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
for(var item2 in obj_data.Data) {
newCol2 += '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
newRow2.append(newCol2);
$("table.horarios").append(newRow2);
}
you are not appending newCol2 to the DOM (with .append()) until the end of the for loop. As a result, within the for loop, where your $('input [name='+counter+']') gets executed, there is not (yet) such an element within the DOM.
Possible solutions:
(1st solution) Add this for loop after your .append() (so after the code snippet you pasted):
for(var item in obj_hora.Hora) {
for(var item2 in obj_data.Data) {
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
}
(2nd solution) Replace your original code with something like this:
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
newRow2.append(newCol2);
for(var item2 in obj_data.Data) {
newCol2 = '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
newRow2.append(newCol2);
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
$("table.horarios").append(newRow2);
}
I'm using the following function to create a list of links from a JSON-File and put them into a span element (jquery has been initialized)
$(document).ready(function() {
function createjson(category) {
var content = "";
i = 0;
$.getJSON(category + ".txt", function(data){
while(data[i] != null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}
});
document.getElementById("list_" + category).innerHTML = content;
}
createjson("cat1");
});
However, if I use it like this, the span element remains empty. It is only when I replace
document.getElementById("list_" + category).innerHTML = content;
with
alert("test");
document.getElementById("list_" + category).innerHTML = content;
that I get the desired output. How can I get it without printing out an alert message beforehand?
That is becuase .getJSON() is an asynchronous method. Your code will try to update the DOM with content, before the server had time to respond to the request. Therefor no content is inserted.
With the alert, you stop the execution long enough for the server to respond, therefor it works when you add the alert.
The correct way to do it would be to move your content update into the success-callback instead, which is always run after the server has responded:
$.getJSON(category + ".txt", function(data){
while(data[i] != null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}
$("#list_" + category).html(content);
});
I replaced your document.getElementById("list_" + category).innerHTML = content; with the somewhat shorter jQuery equivalent $("#list_" + category).html(content); in the above example as well.
It's not the alert which is fixing this, the alert is basically blocking the UI for long enough for the AJAX request to complete.
$.getJSON is an asyncronous method. This means that the result of the function call is not always available immediately, you'll need to move your code which sets the list element HTML inside the $.getJSON callback:
$.getJSON(category + ".txt", function (data) {
while(data[i] != null) { ... }
document.getElementById("list_" + category).innerHTML = content;
});
Put the html append in callback, also reset the i when call back starts.
$(document).ready(function() {
function createjson(category) {
$.getJSON(category + ".txt", function(data)
{
var content = "";
for(i=0; i<data.length; i++)
{
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
}
document.getElementById("list_" + category).innerHTML = content;
});
}
createjson("cat1");
});
Use this !== to compare with not equal to NULL
while(data[i] !== null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}