How to use the each() function to iterate through a JSON file - javascript

I would like to show elements from a JSON file.
Here is the JSON file
"2015": {
"img": "<img src = \"../images/images/images_of_members/image1.jpg\">",
"img2": "<img src = \"../images/images/images_of_members/image2.jpg\">"},
"2016": {
"img": "<img src = \"../images/images/images_of_members/image1.jpg\">",
"img2": "<img src = \"../images/images/images_of_members/image2.jpg\">" }
Here is the JavaScript file
$.ajax("gallery.json", {
dataType: 'json',
success: function (response) {
$.each(response, function () {
$.each(this, function (i, el) {
$(".photo_target").css('display', 'block');
$(".photo_target").append(el);
});
});
}
});
Here is the HTML file
<div class="years">
<p data-year="2015">Pictures 1</p>
<p data-year="2016">Pictures 2</p>
</div>
<div class="photo_target"></div>
I would like to show only the pictures from the object 2015 if I click on the paragraph with attribute data-year 2015 and show pictures from object 2016 if I click on the paragraph with attribute data-year 2016. Now it is iterate through all objects and shows all pictures what can be found in this JSON file.
What should I change in the AJAX call to get it work as I want it?
Thank you

Long time I did some JQuery but you could do something similar to this:
First change your json like so*:
{2015 : ['/images/img1', '/images/img2'], 2016 : ['/images/img2']}
Then you do:
function fetchData(year) {
$.ajax("gallery.json", {
success : function(response) {
var images = response[year];
//images is now an array you could 'for each' over
images.forEach(function(image) {
//do your append...
})
}
})
}
(*Assuming you can change the json.)

Here's a working solution: https://jsfiddle.net/hgmx71zt/2/
Basically I grouped all images per year in a container div:
for (var year in jsondata) {
var $container = $("<div/>");
$container
.addClass("year-" + year)
.appendTo($photo_target)
.addClass("year-images");
for (var img in jsondata[year]) {
var $img = $(jsondata[year][img]);
$container.append($img);
}
}
I used CSS to make them hidden by default.
.year-images {
display: none;
}
Finally, I added a click event handler that toggles the ".visible" class which makes the given container visible (again using CSS)
$(".years").on("click", "[data-year]", function(e) {
var year = $(e.currentTarget).data("year"),
container = $photo_target.find(".year-" + year);
console.log(year);
console.dir(container);
container.toggleClass("visible").siblings().removeClass("visible");
});
The CSS for the visible class:
.year-images.visible {
display: block;
}

Try this:
$.ajax("gallery.json", {
dataType: 'json',
success: function (response) {
$(".photo_target").css('display', 'block');
for(var year in response){
for(var key2 in response[year]){
var $img = $(response[year][key2]);
$img.hide();
$img.data("year", year);
$(".photo_target").append($img);
}
}
}
});
$(".years p").click(function(){
var year = $(this).data("year");
$(".photo_target").find("img").hide();
$(".photo_target").find("img[data-year='" + year + "']").show();
return false;
});

$(function () {
$('.years p').on('click', function () {
$(".photo_target").children().remove();
var attr = $(this).attr('data-year');
if (typeof attr !== typeof undefined && attr !== false) {
var number = $(this).data('year');
console.log(number);
$.ajax("gallery.json", {
dataType: 'json',
success: function (response) {
$.each(response[number], function (i, el) {
$(".photo_target").css('display', 'block');
$(".photo_target").append(el);
});
}
})
}
})});
Here is my solution.
I have changed this line
success: function (response) {
$.each(response, function () {
$.each(this, function (i, el) {
$(".photo_target").css('display', 'block');
$(".photo_target").append(el);
to this
success: function (response) {
$.each(response[number], function (i, el) {
$(".photo_target").css('display', 'block');
$(".photo_target").append(el);
It works fine now.
Thank you for all your help.

Related

How to apply a function on an element without any event handler after just creating it

I made a dynamic element on javascript. Actually i am retrieving some data from db and on response i made an element in javascript
$.ajax({
url: 'php/count_comments.php',
type: 'post',
data: {
},
success: function(response) {
var data = JSON.parse(response);
if(data!='') {
$.each(data, function(i, item) {
var span3=document.createElement("span");
span3.appendChild(document.createTextNode("No Comments"));
span3.setAttribute("id",n+newsid);
span3.setAttribute("class","ment");
p1.appendChild(span3);
});
}else if(data==''){
alert("Admin has not uploaded any news yet");
return false;
}
}
});
Now when the element has been created and every element has a unique id now i want to run a function without any event handler for each element
this is function i want to run
function comments{
var target = event.target || event.srcElement;
var ids = target.id;
var id = ids.slice(-14);
// alert(id);
$.ajax({
url: 'php/count_comments.php',
type: 'post',
data: {
id:id
},
success: function(response) {
var data = JSON.parse(response);
if(data!='') {
$.each(data, function(i, item) {
// var target = event.target || event.srcElement;
// var ids = target.id;
// alert(ids);
// alert(document.getElementById(ids).innerHTML);
document.getElementById(ids).innerHTML=data[i].comments+ " Comment(s)";
});
}else if(data==''){
//alert("No comments yet");
return false;
}
}
});
}
You can call your function immediately in the loop which creates elements.
$.each(data, function(i, item) {
var span3=document.createElement("span");
span3.appendChild(document.createTextNode("No Comments"));
span3.setAttribute("id",n+newsid);
span3.setAttribute("class","ment");
p1.appendChild(span3);
//call from here with the id
comments(n+newsid)
});
Also, comments function is wrongly declared, correct it and have id as parameter.
function comments(id) {
// do your stuff
}
if you want to call comment method silently then use a timeout function while calling
setTimeout(function() {
comments(n+newsid);
}, 0)

jQuery-Ajax created Checkboxlist does not respond to click

I have a radio button list (rblCategories) and when selected value is changed I create a checkbox list using ajax and populate it. I need to update my datatable when any checkbox is checked/unchecked but I can't get it to respond to to change in state.
This is what i have and what I have tried (I removed all unnecessary stuff like styling, etc.)
<div class="row">
<div class="col-sm-2">
<label for="ddlYear">Select Year</label>
<asp:DropDownList runat="server" ID="ddlYear" ClientIDMode="Static">
</asp:DropDownList>
</div>
<div class="col-sm-4">
<label for="rblCategories">Categories</label>
<asp:RadioButtonList runat="server"
ID="rblCategories"
ClientIDMode="Static"
DataTextField="Name"
DataValueField="TypeID"
AppendDataBoundItems="true">
</asp:RadioButtonList>
</div>
<div class="col-sm-6" id="divSubCategory">
</div>
</div>
//Using the selected values of ddlYear and rblCategories, populate table
function bindDataTable() {
var year = $('#ddlYear').val();
var selCategoryID = $('#rblCategories input:checked').val()
var url = "";
var params = "";
// -1 refers to "All" categories
if ('-1' == selCategoryID) {
url = "../services/exp.asmx/GetExpenseByYear";
params = JSON.stringify({ "Year": year });
}
else {
url = "../services/exp.asmx/GetExpenseByYearByCategory";
params = JSON.stringify({ "Year": year, "CategoryID": selCategoryID });
}
populteTable(url, params, tblExpenses);
}
//for testing
function bindDataTable(subCategories) {debugger
}
// create and populate sub-category checkbox list based on selected category
function updateSubTypes(typeID) {
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: '<%=ResolveUrl("~/services/exp.asmx/GetExpenseSubTypeItems") %>',
cache: false,
data: "{ 'TypeID': '" + typeID + "' }",
success: AjaxSucceeded,
error: AjaxFailed
});
}
function AjaxFailed(result) {
alert('Failed to load checkbox list');
}
function AjaxSucceeded(result) {
BindCheckBoxList(result);
}
function BindCheckBoxList(result) {
$('#divSubCategory').empty();
var items = JSON.parse(result.d);
if (items.length > 0)
CreateCheckBoxList(items);
}
function CreateCheckBoxList(checkboxlistItems) {
var lbl = $('<label></label>').text('Sub-Categories');
$('#divSubCategory').append(lbl);
var table = $('<table></table>').attr({ id: 'cblSubCategory', class: 'form-control' });
var row = table.append($('<tr></tr>'));
var counter = 0;
$(checkboxlistItems).each(function (i) {
row.append($('<td></td>').append($('<input>').attr({
type: 'checkbox', name: 'chklistitem', value: this.ExpenseSubTypeID, id: 'chklistitem' + counter
})).append(
$('<label>').attr({
for: 'chklistitem' + counter++
}).text(this.Name)));
});
$('#divSubCategory').append(table);
}
$(document).ready(function () {
$('#rblCategories input').change(function () {
var selCategoryID = $(this).val();
if (selCategoryID != null) {
updateSubTypes(selCategoryID)
}
bindDataTable();
});
// This never gets hit; I tried chklistitem instead of cblSubCategory too
$('#cblSubCategory input').change(function () {debugger
var selCategoryID = $('#rblCategories input:checked').val()
var names = $('.parent input:checked').map(function () {
return this.name;
}).get();
bindDataTable(names);
});
})
$('#cblSubCategory input').change(function () {
TO
$('#cblSubCategory').on('change','input', function () {
Use jQuerys .on() method when loading elements dynamically, which will look for any new elements added to the DOM that match that selector. Otherwise jQuery will only parse the DOM once on initial execution.
$(document).ready(function () {
$('#rblCategories').on('change','input', (function () {
var selCategoryID = $(this).val();
if (selCategoryID != null) {
updateSubTypes(selCategoryID)
}
bindDataTable();
});
// This never gets hit; I tried chklistitem instead of cblSubCategory too
$('#cblSubCategory').on('change','input', function () {debugger
var selCategoryID = $('#rblCategories input:checked').val()
var names = $('.parent input:checked').map(function () {
return this.name;
}).get();
bindDataTable(names);
});
})
The following changes fixed the issue; However, I marked cantucket's reply as answer cause he put me in the right direction.
I added an attr line to "createCheckBoxList" function; right after I append the resulting table to div:
function createCheckBoxList(checkboxlistItems) {
var lbl = $('<label></label>').text('Sub-Categories');
$('#divSubCategory').append(lbl);
var table = $('<table></table>').attr({ id: 'cblSubCategory', class: 'form-control' });
var row = table.append($('<tr></tr>'));
var counter = 0;
$(checkboxlistItems).each(function (i) {
row.append($('<td></td>').append($('<input>').attr({
type: 'checkbox', name: 'cblSubCategory', value: this.ExpenseSubTypeID, id: 'cblSubCategory' + counter
})).append(
$('<label>').attr({
for: 'cblSubCategory' + counter++
}).text(this.Name)));
});
$('#divSubCategory').append(table);
// added this line
$('#divSubCategory').attr({ onclick: "onSubCatChange()" });
}
I added "onSubCatChange()" function:
function onSubCatChange() {
// Both following methods work to get list o checked items
var names = [];
$('#cblSubCategory input:checked').each(function() {
names.push(this.value);
});
var names2 = $('#cblSubCategory input:checked').map(function () {
return this.value;
}).get();
bindDataTable(names);
}
And I removed the checkbox list's on change handler in document.ready() function.

get each column without using row.find('td:eq(0)')

How can I get each column in row without using .find('td:eq(0)')? I need another way to get each column.
$(document).on('click', '.delete_librarian', function()
{
var librarianDataRow=$(this).closest('tr');
var librarianId=parseInt(librarianDataRow.find('td:eq(0)').text());
var librarianName=librarianDataRow.find('td:eq(1)').text();
$('#confirm-model-body').text("Are you sure you want to delete "+librarianName+" data");
$('#confirm-modal').modal({backdrop: 'static'});
$('#confirm-model-yes-button').click(function () {
$.ajax({
url: "/api/admin/librarian",
type: "DELETE",
dataType: "json",
data: JSON.stringify({id:librarianId}),
success:function (data) {
if(data.success == true)
{
window.location.reload();
}
else
{
alert(data.message);
}
}
});
});
});
You could use vanilla JS instead if you don't want to use jQuery methods for whatever reason:
$(document).on('click', '.delete_librarian', function() {
var librarianDataRow = this.closest('tr');
var librarianId = Number(librarianDataRow.children[0].textContent);
var librarianName = librarianDataRow.children[1].textContent;
// ...
Could also use
$(document).on('click', '.delete_librarian', function() {
var librarianDataRow = this.closest('tr');
var librarianId = Number(librarianDataRow.cells[0].textContent);
var librarianName = librarianDataRow.cells[1].textContent;
// ...

How to alert the data-id attribute value in laravel?

Ajax1:
<script type="text/javascript">
$(document).ready(function () {
$('.CategoryName').click(function() {
var categoryName = $(this).attr("data-id");
var url="{{url('getSubCategoryName/').'/'}}" + categoryName;
$.ajax({
url : url,
type: 'GET',
dataType:'json',
success:function(data){
$.each(data, function( index, value ) {
var output = '';
output = ' ' + value.subCategoryName + '';
**$(".subcategory").append('<ul><li data-
id="'+value.subCategoryName+'" class="getDeviceCategoryName">'+value.subCategoryName+'</li></ul>')**
});
}
});
});
});
</script>
The code which is marked in bold has the value for data-id attribute..And I need to pass that value when class named getDeviceCategoryName is clicked.
AJAX2:
<script type="text/javascript">
$(document).ready(function () {
$('.getDeviceCategoryName').click(function() {
var subCategoryName = $(this).attr("data-id");
alert(subCategoryName);
});
});
</script>
This is one I tried for that..But its not working.It doesnot alerts or shows any error.
You should consider jquery event delegation:
Change your jquery selector line like this:
<script type="text/javascript">
$(document).ready(function () {
$(document).on('click','.getDeviceCategoryName',function() {
var subCategoryName = $(this).attr("data-id");
alert(subCategoryName);
});
});
</script>
Here you go with a solution
$(document).ready(function () {
$(document).on('click', 'li.getDeviceCategoryName', function() {
console.log($(this).data("id"));
});
});
Since the elements are generated dynamically, so you need to delegate events.
For receiving the data-attribute you can do $(this).data("attribute-name"); in your scenario it will be $(this).data('id');
Hope this will help you.
Personally I think code is more efficient if the click event is applied to the element right after it's created.
$(function () {
$('.CategoryName').click(function () {
var categoryName = $(this).attr('data-id');
var url = '{{url(\'getSubCategoryName/\').\'/\'}}' + categoryName;
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
success: function (data) {
$.each(data, function (index, value) {
var output = '';
output = ' ' + value.subCategoryName + '';
$('.subcategory').append($('<ul/>').append('<li data-id="' + value.subCategoryName + '" class="getDeviceCategoryName">' + value.subCategoryName + '</li>')
.find('li')
.click(function () {
var subCategoryName = $(this).attr('data-id');
alert(subCategoryName);
});
);
});
}
});
});
});
$(document).ready(function () {
$(document).on('click', '.getDeviceCategoryName', function(){
var subCategoryName = $(this).attr("data-id");
alert(subCategoryName);
});
});

Chosen plug-in is not working when i create the element dynamically

Chosen plug-in is not working when i create the element dynamically
i created Select list dynamically from ajax response and the problem is Chosen plug-in not working with it , Please help me to solve it
here is my code:
function GetSubCategories(ID) {
$.ajax({
cache: false,
url: '/Home/GetSubCategoriesByAjax',
type: 'GET',
datatype: 'Json',
data: { id: ID },
success: function (data) {
if (data.length > 0) {
console.log(data)
$("#SubListSelect").empty();
var $SubListSelect = $('<select id ="SubListSelect" class = "form-control"></select>');
$SubListSelect.append('<option>Select Sub Category</option>');
$.each(data, function (i, value) {
$SubListSelect.append('<option value=' + value.SubCategoryId + '>' + value.SubCategoryName + '</option>');
});
$("#Div1").empty();
$("#Div1").append($SubListSelect);
}
else {
}
},
error: function (r) {
alert('Error! Please try again.');
console.log(r);
}
});
}
and and plugin code:
$(document).ready(function ($) {
$(function () {
$("#SubListSelect").chosen();
});
Thank you
My proposal:
in my demo I used a different url for the ajax and I figured out a possible HTML.
function GetSubCategories(ID) {
$.ajax({
cache: false,
url: "https://api.github.com/users",
type: 'GET',
dataType: "json",
data: { id: ID },
success: function (data) {
if (data.length > 0) {
var SubListSelect = $('<select id ="SubListSelect" class = "form-control"></select>')
.append('<option>Select Sub Category</option>');
$.each(data, function (i, value) {
SubListSelect.append('<option value=' + value.id + '>' + value.login + '</option>');
});
$("#Div1").empty().append(SubListSelect);
$("#Div1").find(SubListSelect).chosen()
} else {
}
},
error: function (r) {
alert('Error! Please try again.');
console.log(r);
}
});
}
$(document).ready(function ($) {
$("#SubListSelect").chosen();
$('#btn').on('click', function(e) {
GetSubCategories('1');
});
});
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<!--
The next two lines are the include files for chosen plugin
-->
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/chosen/1.1.0/chosen.min.css">
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/chosen/1.1.0/chosen.jquery.min.js"></script>
<div id="Div1">
This is the starting div:
</div>
<button id="btn">Click Me To Create New chosen object into DIV</button>
I assume the select is in #Div1 which you are emptying, then re-appending.
in that case you need to re-initialize it:-
$("#Div1").empty();
$("#Div1").append($SubListSelect);
$("#SubListSelect").chosen();
A better option though would be to only empty the select and re-append the options to the select without emptying the #Div1. then call:-
$("#SubListSelect").trigger("chosen:updated");
also, this
$(document).ready(function ($) {
and this
$(function () {
mean the same thing, with the latter being short hand. Therefore you only need one.

Categories

Resources