dynamically store li id in the array - javascript

in my codes lis are generate dynamically and each li has special id.
I want to store each li "id" in the one array
this is js codes
var i=0;
$("ul#portfolio li").each(function(eval){
var idd = new Array();
idd[i]=$(this).attr("id");
i++;
});
but it dosn't work.
html
<div id="container">
<ul id="portfolio" class="clearfix">
<!-- Dynamically generated li -->
</ul>
</div>

you need to use .map()
var idd = $("#portfolio li").map(function(eval){
return this.id;
}).get();
In your case your array is local to the callback, so every iteration of the each callback you are creating a new array instead of adding the item to an existing array
var idd = new Array();
$("#portfolio li").each(function (eval) {
idd.push(this.id)
});
Make sure your script is running after the target elements are loaded to the dom(May be by using a dom ready handler)
Use this.id which is the same as $(this).attr('id')

You Can try This Also
$(document).ready(function()
for(var i=0;i<5;i++){
$('#portfolio').append("<li id='"+ i +"'>"+ i +"</li>");
}
var idArray=new Array();
$('#portfolio li').each(function(ind,val){
idArray.push(this.id)
});
console.log(idArray);
});

Related

How.. get element by class, grab id, and use id as variable to pass to php

I'm running a function on an interval. I need to get element by class name, use the id of each and pass it into a function as a variable.
I've tried looping through each class name and passing the id to php but it passes an array (i think) or maybe an html index which i cant separate.
$(".eachUnread").each(function() {
var newId = this.id;
$(".eachUnread").load("../php/unreadEach.php?id="+newId);
console.log(newId);
});
I also tried..
var x = document.getElementsByClassName("eachUnread");
var i;
for (i = 0; i < x.length; i++) {
var newId = x[i].id;
console.log(newId);
$(".eachUnread").load("../php/unreadEach.php?id="+newId);
}
When the .eachUnread div loads its cycles through all the id's. How do I get it to load only the correct id?
simply this...
$(".eachUnread").each(function() {
$(this).load("../php/unreadEach.php?id="+this.id);
});
You need add param for each function(index, item) method and use attr for get id var newId = $(item).attr('id');
$(".eachUnread").each(function(index, item) {
var newId = $(item).attr('id');
$(".eachUnread").load("../php/unreadEach.php?id="+newId);
console.log(newId);
});
$(".eachUnread").each(function(index, item) {
var newId = $(item).attr('id');
$(".eachUnread").load("../php/unreadEach.php?id="+newId);
console.log(newId);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='eachUnread' id='test1'>A</div>
<div class='eachUnread' id='test2'>B</div>
<div class='eachUnread' id='test3'>C</div>

LocalStorage and adding li to list

I'm trying to make a small script that allows for a little notes section. This section would have an input box that allows for adding elements to the list; which will be saved in localStorage so they are not lost when I refresh or close the browser. The code I have is as follows (it's all done through JS even the html, but ignore that.)
var notes = [];
var listthings = "<h2 id=\"titlething\">Notes</h2>" +
"<ul id=\"listing\">" +
"</ul>"
"<input type=\"text\" name=\"item\" id=\"textfield\">" +
"<input type=\"submit\" id=\"submitthing\" value=\"Submit\">";
JSON.parse(localStorage.getItem('notes')) || [].forEach( function (note) {
"<li id=\"listitem\">" + notes + "</li>";
})
$('#submitthing').click(function() {
notes.push($('#textfield').val());
});
localStorage.setItem('notes', JSON.stringify(notes));
Also, how would I go about appending the latest added li between the opening and closing tag? Obviously I'd usually do it using jQuery, but this is puzzling me a little. However, only the 'Notes' loads at the top, any ideas?
Your approach is way off the mark. You don't need JSON at all (this just confuses things) and you don't need to manually create HTML.
Also, you can use an array to store the notes, but since localStorage is the storage area, so an array is redundant. Additionally, without using an array, you don't need JSON. The entire problem becomes much easier to solve.
Unfortunately, the following won't run here in this snippet editor, due to security issues, but it would do what you are asking. This fiddle shows it working: https://jsfiddle.net/Lqjwbn1r/14/
// Upon the page being ready:
window.addEventListener("DOMContentLoaded", function(){
// Get a reference to the empty <ul> element on the page
var list = document.getElementById("notes");
// Loop through localStorage
for (var i = 0; i < localStorage.length; i++){
// Make sure that we only read the notes from local storage
if(localStorage.key(i).indexOf("note") !== -1){
// For each item, create a new <li> element
var item = document.createElement("li");
// Populate the <li> with the contents of the current
// localStorage item's value
item.textContent = localStorage.getItem(localStorage.key(i));
// Append the <li> to the page's <ul>
list.appendChild(item);
}
}
// Get references to the button and input
var btn = document.getElementById("btnSave");
var note = document.getElementById("txtNote");
// Store a note count:
var noteCount = 1;
// When the button is clicked...
btn.addEventListener("click", function(){
// Get the value of the input
var noteVal = note.value;
// As long as the value isn't an empty string...
if(noteVal.trim() !== ""){
// Create the note in localStorage using the
// note counter so that each stored item gets
// a unique key
localStorage.setItem("note" + noteCount, noteVal);
// Create a new <li>
var lstItem = document.createElement("li");
// Set the content of the <li>
lstItem.textContent = noteVal;
// Append the <li> to the <ul>
list.appendChild(lstItem);
// Bump up the note counter
noteCount++;
}
});
});
<input type=text id=txtNote><input type=button value=Save id=btnSave>
<ul id=notes></ul>
This is how I would approach it using jquery. but depens how complex this should be. this is just simple demo.
<input type="text" id="note" />
<button id="add">add note</button>
<ul id="notes"></ul>
javascript and jquery
function addNote(){
var data = localStorage.getItem("notes")
var notes = null;
if(data != null)
{
notes = JSON.parse(data);
}
if(notes == null){
notes = [];
}
notes.push($("#note").val());
localStorage.setItem("notes", JSON.stringify(notes));
refreshNotes();
}
function refreshNotes(){
var notesElement =$("#notes");
notesElement.empty();
var notes = JSON.parse(localStorage.getItem("notes"));
for(var i = 0; i< notes.length; i++){
var note = notes[i];
notesElement.append("<li>"+note+"</li>");
}
}
$(function(){
refreshNotes();
$("#add").click(function(){
addNote();
});
})
example:
http://codepen.io/xszaboj/pen/dOXEey?editors=1010

Set custom attribute for autodividers

I am trying to divide a ListView that is dynamically populated in jQuery-mobile. I am setting some listitems with attribute status="true" and some to status="false", and wonder if it's possible to automatically divide these into two groups (Downloaded/Not downloaded)?
This is my HTML:
<div role="main" class="ui-content jqm-content">
<div>
<ul id="linkList" data-role="listview" data-autodividers="true">
</ul>
</div>
</div>
My JS:
var $li;
var $status = 'false';
window.resolveLocalFileSystemURL(fileSource + val.title + ".pdf", success, fail);
// if file exists
function success() {
$li.find("a").on("click", function(){ openPdf(val.title); });
$status = 'true';
}
// if file doesnt exists
function fail() {
$li.find("a").on("click", function(){ downloadPdf(val.title,val.url); });
$status = 'false';
}
$li = $("<li><a href='#' status=''+status+''>"+val.title+"</a></li>");
$("#linkList").append($li).listview('refresh');
$("#linkList").listview({
autodividers: true,
autodividersSelector: function (li) {
var out = li.attr('status');
return out;
}
}).listview('refresh');
So, is it possible to do this automatically, or do I have to do the sorting by code, and add the dividers. The code as it is doesn't add any dividers at all.
First, autodividers really only works if your list is already sorted by status. So you will want to sort it before adding it to the UL.
Next, for status you can use a data-attribute on the LI or the anchor within the li:
'<li >' + item.val + '</li>'
Then when adding the items, set the autodividersSelector to retrieve the data-attribute on the anchor:
$('#linkList')
.empty()
.append(allfiles)
.listview({
autodividers:true,
autodividersSelector: function ( li ) {
var out = li.find('a').data("status");
return out;
}
})
.listview("refresh");
Working DEMO

jQuery How to use a ID grabbed from a clicked div

I have a people section on a website I'm building which uses isotope for filtering. When I click on a person I want to show their full info on the right. When the click happens I grab the id and store it as a variable. I then have variables named to match up with the grabbed IDs.
How do I use the grabbed ID to target the variables stored in my js file? Currently it only prints out the ID grabbed from the clicked div.
var userOne = "<p>userOne info<p>";
var userTwo = "<p>userTwo info<p>";
var userThree = "<p>userThree info<p>";
$('.item').on("click", function(){
var id = $(this).attr('id'); // this grabs the ID of the div eg userOne
var printId = id; //trying to change the variable so I can use it
$('.bio').html(printID); //this is where it should print out
});
You can't access a variable name like that, instead what you can do is to access a object's property with a dynamic key
Assuming the variables userOne/userTwo are in the global scope, you can use the bracket notation like
var userOne = "<p>userOne info<p>";
var userTwo = "<p>userTwo info<p>";
var userThree = "<p>userThree info<p>";
$('.item').on("click", function () {
var printId = window[this.id];
$('.bio').html(printID);
});
another option is to store those values as properties of an object
var user = {
userOne: "<p>userOne info<p>",
userTwo: "<p>userTwo info<p>",
userThree: "<p>userThree info<p>"
};
$('.item').on("click", function () {
var printId = user[this.id];
$('.bio').html(printID);
});
Try
html
<div class="item" data-user="<p>userOne info<p>"></div>
js
$(".item").on("click", function(e) {
$(".bio").html($(this).data("user"))
})
$(".item").on("click", function(e) {
$(".bio").html($(this).data("user"))
})
div:not(.bio) {
border:1px dotted grey;
width: 24px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="item" data-user="<p>userOne info<p>">1</div><br />
<div class="item" data-user="<p>userTwo info<p>">2</div><br />
<div class="item" data-user="<p>userThree info<p>">3</div><br />
<div class="bio"></div>

accessing variable modifications made from within an inline function in javascript

I'm trying to pass local variables to an inline function in javascript and have that (inline) function manipulate those variables, then be able to access the changed variable values in the containing function. Is this even possible? Here's a sample of the code I'm working with:
function addArtists(artist, request, origElm, xml){
//variables
var artistIdArray = [];
/*coding*/
//traverse xml
$('element', xml).each(function(){
/*coding*/
$.ajax({
/*parameters*/
success: function(html) {
var artistAbb = html;
/*coding*/
//add this element's id to the array of ids to make it draggable later
artistIdArray.push(artistAbb);
alert(artistIdArray[artistIdArray.length - 1]);
}//end on success
});//end ajax call
});//end each(function()
alert(artistIdArray.length);
}
The problem is I keep getting artistIdArray.length = 0, even though elements are several elements are 'alerted' after they're added to the array.
Like I said, I don't know if it's even possible without global variables or objects. Any ideas? Am I totally wrong?
Edit: Entire function
function addArtists(artist, request, origElm, xml){
//variables
var artistIdArray = [];
//create ordered list
//set new <ol>s class
var olClass = "artists"; //holds the class of new <ol>
//create id for new <ol>
var olId = "artists"; //holds the id of new <ol>
//create actual <ol> element
var ol = $('<ol></ol>').attr('id',olId)
.addClass(olClass)
.appendTo(origElm);
//create the <li> elements from the returned xml
//create class for new <li>s, (just the request minus the 's')
var liClass = request.substring(0, request.length-1);
//traverse xml
$('element', xml).each(function(){
//create id for new <li> based on artist abbreviation
var artist = $(this).text();
$.ajax({
url: "php/artistToAbb.php",
data: {artist: artist},
dataType: "html",
async: true,
success: function(html) {
var artistAbb = html;
//create li
var li = $('<li></li>').attr('id', artistAbb)
.addClass(liClass)
.appendTo(ol);
//create arrow icon/button for li
var img = $('<img />').attr('id', artistAbb + 'ArrowImg')
.attr("src","images/16-arrow-right.png")
.attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')")
.addClass("expImg")
.appendTo(li);
var artistTxt = $('<h2>' + artist + '</h2>')
.addClass("artist_txt")
.attr('onMouseOver', 'catMouseOver(this)')
.attr('onMouseOut', 'catMouseOut(this)')
.appendTo(li);
//tag the ol element's class
$($(origElm)[0]).addClass('expanded');
//add this element's id to the array of ids to make it draggable later
artistIdArray.push(artistAbb);
alert(artistIdArray[artistIdArray.length - 1]);
}//end on success
});//end ajax call
});//end each(function()
//make newly added artist elements draggable
for(var n = 0; n < artistIdArray.length; n++){
//new Draggable(artistIdArray[n], {superghosting: true, detached: true, onEnd: catClearHighlight});
alert(artistIdArray[n]);
}
alert(artistIdArray.length);
}
UPDATED: Now that you've posted your entire code. The answer is that you shouldn't store the elements in the temporary array at all, but create the draggable for each element as the AJAX call returns.
The problem is that while the array is accessible inside the AJAX callback the code at the end of the function (outside the each) executes before the AJAX calls have completed and so the array is empty. If you create each draggable as the call returns, you don't need the intermediate storage variable and the draggable is created as it is inserted into the DOM. The other alternative, would be to make your AJAX calls synchronous {aSync: false}, but this would also potentially tie up the browser until all of the elements have returned. Better, IMO, to live with the asynchronous nature of the AJAX call and handle each element as it is created.
function addArtists(artist, request, origElm, xml){
//create ordered list
//set new <ol>s class
var olClass = "artists"; //holds the class of new <ol>
//create id for new <ol>
var olId = "artists"; //holds the id of new <ol>
//create actual <ol> element
var ol = $('<ol></ol>').attr('id',olId)
.addClass(olClass)
.appendTo(origElm);
//create the <li> elements from the returned xml
//create class for new <li>s, (just the request minus the 's')
var liClass = request.substring(0, request.length-1);
//traverse xml
$('element', xml).each(function(){
//create id for new <li> based on artist abbreviation
var artist = $(this).text();
$.ajax({
url: "php/artistToAbb.php",
data: {artist: artist},
dataType: "html",
async: true,
success: function(html) {
var artistAbb = html;
//create li
var li = $('<li></li>').attr('id', artistAbb)
.addClass(liClass)
.appendTo(ol);
//create arrow icon/button for li
var img = $('<img />').attr('id', artistAbb + 'ArrowImg')
.attr("src","images/16-arrow-right.png")
.attr('onclick', "expand(this, '" + artistAbb + "', 'years', 'danwoods')")
.addClass("expImg")
.appendTo(li);
var artistTxt = $('<h2>' + artist + '</h2>')
.addClass("artist_txt")
.attr('onMouseOver', 'catMouseOver(this)')
.attr('onMouseOut', 'catMouseOut(this)')
.appendTo(li);
//tag the ol element's class
$($(origElm)[0]).addClass('expanded');
new Draggable(artistAbb, {superghosting: true, detached: true, onEnd: catClearHighlight});
}//end on success
});//end ajax call
});//end each(function()
}
You don't need to pass the values at all, just reference them directly in the inline function.
function addArtists(artist, request, origElm, xml){
//variables
var artistIdArray = new Array();
var artistNum = 0;
/*coding*/
//traverse xml
$('element', xml).each(function(){
/*coding*/
//add this element's id to the array of ids to make it draggable later
artistIdArray[artistNum] = "some value";
//alert(artistNum);
artistNum++;
}//end on success
});//end ajax call
});//end each(function()
//test how many elements
for(var n = 0; n < artistIdArray.length; n++)
alert(n);
}
I can't spot the problem, it probably lies somewhere else than in the as far provided (and edited) code.
But as you're already using jQuery, consider assigning them as "global" jQuery property.
var artistIdArray = [];
would then be
$.artistIdArray = [];
and using it would then look like
$.artistIdArray.push(artistAbb);
you could then at end access it the same way
alert($.artistIdArray.length);

Categories

Resources