Dynamic Menu Bar with Child Relation In MVC Ajax Call - javascript

Hi i am student working on a Project in MVC i am Creating Dynamic Menu bar i retrieve Main Menu successfully but all child menus are shown in Contact Us Dropdown menu
---------------------------
ID ParentID MenuName
---------------------------
1 NULL Home
2 Null Contact Us
3 2 Address
4 2 Place
5 1 Index
//html
<div id="menu">
<ul>
</ul>
</div>
//jquery code
function LoadMenubarSuccess(response) {
if (response != undefined && response != null && response.length > 0) {
var IncidentData = "<ul>";
$.each(response, function (index, Obj) {
if (Obj.ParentMenuID == null || Obj.ParentMenuID == 0) {
IncidentData += "<li>"
+ "<a href='" + Obj.Url + "'>" + Obj.MenuName + "</a>"
}
if (Obj.ParentMenuID == !null || Obj.ParentMenuID > 0) {
IncidentData += "<ul>"+"<li>" + "<a href='" + Obj.Url + "'>" + Obj.MenuName + "</a>" +"</li>"+ "</ul>"
}
});
IncidentData +="</li>"+"</ul>";
$("#menu").html(IncidentData.replace(/null/g, ' - '));
}
}

The Loop is wrong.
You will have to first, sort your data to your needs.
In this case, it's probably best to loop through the items and attach the ones with parentID to the main item.
After that, start another loop which will create the actual menu.
// Sort could work like this
var menuList = [];
$.each(response, function(index, object) {
if(object.ParentID != null && object.ParentID != undefined)
menuList[object.ID].Children.push(object);
else
menuList[object.ID] = { Menu = object, Children = [] };
});
This way the data will be sorted to your needs (I did not test run this code).
After that, you can just do whatever you need with it. For example:
$incidentData = "<ul>";
$.each(menuList, function(index, parent) {
$incidentData = $incidentData + "<a href='" + parent.Url + "'>" + parent.MenuName + "</a>";
if(parent.Children.length > 0) {
$.each(parent.Children, function (childIndex, child) {
$incidentData = $incidentData + "<a href='" + child.Url + "'>" + child.MenuName + "</a>";
});
}
});
$incidentData = $incidentData + "</ul>";
Something like this should work.
You can see, we are sorting the data kinda like a tree.
Item has multiple parents and each parent can have multiple children.
This way, we don't have to do anything fancy. Perhaps you can change your source to do this for you?
Code is not tested. Adjust to your needs.

Related

create and append multiple elements with data from JSON

Let data be a JSON,
what I am trying here is appending multiple elements according to the data from JSON to the div ,
<div class="studentTab" ></div>. How can I achieve this ?
(nb: please consider that we have 2 Languages and 2 Specializations)
for (i = 0; i < 10; i++) {
var html = '<div class="dtls">' +
'' +
'<h4 class="verified">' + data.student[0].firstName + '</h4 >' +
'<ul>' +
'<li>' + data.student[0].location + '</li>' +
'<li>' + data.student[0].mark + ' /hour</li>' +
'<li>' + data.student[0].year+ ' accademic year</li>' +
if (data.student[0].Languages != null)
{
var lang = string.Join(",", data.student[0].Languages.Select(it => it.Name));
<li>lang </li>
}
if (data.student[0].Specializations.length > 1)
{
var rcount = data.student[0][index].Specializations.length - 1;
<li>data.student[0].Specializations[0].Name + rcount more</li>
}
else
{
<li>data.student[0].Specializations[0].Name</li>
}
'</ul>' +
'</div>'
$('#studentTab').append(html);
};
You may use map() for solving such problem. Please make check:
If your 'data' is underfined or not;
Better save your data.student[0] in some variable;
You never know how many objects inside of data you have. Probably some times is underfined due to network errors or more or less objects due to some back-end updates

JQuery Ajax button isn't working

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>

How to append value " select " to the Select dropdown?

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');

Reference to input field added dynamically to the page

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);
}

JavaScript variable empty without previous alert messge

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++;
}

Categories