how to get previous element with jquery each() - javascript

I know the each function iterates over an array. Is there way to access the indice like (this[i])? I need to be able compare current element's pubDate with the previous element's pubDate and if it's different output a new pubdate.
$(data).find('item').each(function(i, value){
var title = $(this).find('title').text().replace(/\w+\s+\(.*?\)/, "");
var link = $(this).find('link').text();
var pubDate = $(this).find('pubDate').text();
alert(title);
alert(link);
alert(pubDate);
$('#events').append("<p>" + title + "<br/>" + link + "</p>");
});

One of many potential ways would be:
var previous = null;
$(data).find('item').each(function(i, value){
if (previous) {
... do stuff with previous element ...
}
var title = $(this).find('title').text().replace(/\w+\s+\(.*?\)/, "");
var link = $(this).find('link').text();
var pubDate = $(this).find('pubDate').text();
alert(title);
alert(link);
alert(pubDate);
$('#events').append("<p>" + title + "<br/>" + link + "</p>");
previous = this;
});
You have to check to see if previous is not null, since the first iteration will contain a null value (the first element doesn't have any previous element).

How about something like
var previousDate = $(this).prev().find('pubDate');

you can use this and traverse
for example
this.parent()
gives you the index
or
i in your loop

Related

Getting Data out of a container

I wrote a function that creates new Input fields based on the number of input fields needed. That code is below.
for (i=0;i<number;i++){
container.appendChild(document.createTextNode("Guest " + (i+1)));
var input = document.createElement("input");
input.id = "Guest" + i;
container.appendChild(input);
container.appendChild(document.createElement("br"));
console.log(i.value);
It creates a new Id for each input field. In the function below,depending on the number you set for i, the function creates a generated message.
function sendInput ()
{
var guestNames = document.getElementById("Guest").value
var personName = document.getElementById("people").value;
var eventType = document.getElementById("event").value;
var date = document.getElementById("date").value;
var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date + " Thank you for coming!!";
document.getElementById('output').innerHTML = output.repeat(i);
}
The problem is it is not collecting the data for guestNames. I am pretty new to JS but have searched and cannot find a solution to my problem. Any feedback wouls be helpful.
IDs are difficult to work with in a dynamic environment, classes are generally the simplest solution. This code will convert your inputs to have classes, then loop through them and collect the names.
So change:
input.id = "Guest" + i;
to
input.setAttribute("class","guest");
And change
var guestNames = document.getElementById("Guest").value
to:
var guests = document.querySelectorAll(".guest");
var guestNames = [];
guests.forEach(function(el){
guestNames.push(el.value);
});
guestNames = guestNames.join(",");
If you are wanting a message for EACH guest, then you would use the below function:
function sendInput ()
{
var personName = document.getElementById("people").value;
var eventType = document.getElementById("event").value;
var date = document.getElementById("date").value;
var guests = document.querySelectorAll(".guest");
var guestNames = [];
document.getElementById('output').innerHTML = "";
guests.forEach(function(el){
document.getElementById('output').innerHTML += "Dear " + el.value + " You have been invited to " + personName + "'s " + eventType + " on " + date + " Thank you for coming!!";
});
}
You try to get node by id var guestNames = document.getElementById("Guest").value
But all nodes have a different id, like a Guest0,Guest1 etc. I am trying to write my own code, but your snippet isn't full. I hope I helped you.
As far as I can see, when you try to fetch the guest name
var guestNames = document.getElementById("Guest").value
you won't get any element for two reasons because there's no element with id "Guest". In fact you generate them in the form "GuestN"
`input.id = "Guest" + i;`
You probably want to add a parameter i to sendInput () function, so that internally you can concatenate it to Guest as you did above and get the correct element with getElementById().
Your code is incomplete (as far as I can tell).
You do not specify the following elements anywhere:
'container', 'guest', 'people', 'event', 'data' or 'output'
I assume they should be defined somewhere in the HTML section (not provided)
To be able to create the variable displays, you need to define the 'container' you wish to initialize it before it is used in the for() loop that follows.
Example: var container = document.getElementById('container');
Within the loop, console.log(i.value) is invalid as i is not an element that has been assigne a value to display. It is a counter of the for() loop.
The function of sendInput(), I assume, is to collect the information from the user for each "Guest#" created by the first loop of your code. However you try to collect from "Guest" which has not been defined. For a number of 5, the collections should be for "Guest1", "Guest2", "Guest3", "Guest4", "Guest5". "Guest" only can not be found anywhere in your loop creation. Same goes for 'people, 'event' and 'date' which are referenced for value collection, but there are no elements named as such.
Not exactly sure why you are mixing DOM creation techniques (???).
You create the number of element for the guest, but then output the results with .innerHTML. You should use the DOM creation method, but I have used your code as you indicated you are a beginner.
Here is some (partially) corrected code that you can continue on with.
<!DOCTYPE html><html lang="en"><head><title> Test Page </title>
<meta charset="UTF-8">
<meta name="viewport" content="width-device-width,initial-scale=1.0, user-scalable=yes"/>
<!-- link rel="stylesheet" href="common.css" media="screen" -->
<style>
</style>
</head><body>
<input type="text" value="5/28/2020" id="date">
<pre id='container'></pre>
<button id="report">Report</button>
<pre id='output'></pre>
<script>
console.clear();
function init() {
var number = 5;
var container = document.getElementById('container');
for (i=0;i<number;i++) {
var value = "Guest " + (i+1)+' ';
container.appendChild(document.createTextNode(value));
var input = document.createElement("input");
input.id = "Guest" + i;
input.value = value;
container.appendChild(input);
container.appendChild(document.createElement("br"));
console.log(i); // .value);
}
document.getElementById('report').addEventListener('click',sendInput);
} init();
function sendInput () {
var date = document.getElementById("date").value,
output = document.getElementById('output'),
info = '';
var guestNames = [...document.querySelectorAll('#container input')]; // alert(guestNames.length);
for (let i=0; i<guestNames.length; i++) {
info = `Dear ${guestNames[i].value}:\nYou have been invited to XXX's EVENT on ${date}\nThank you for coming!!\n\n`;
output.innerHTML += info;
}
// var guestNames = document.getElementById("Guest").value
// var personName = document.getElementById("people").value;
// var eventType = document.getElementById("event").value;
// var output = "Dear " + guestNames + " You have been invited to " + personName + "'s " + eventType + " on " + date + " Thank you for coming!!";
// output = `Dear ${guestNames}:\nYou have been invided to XXX's EVENT on ${date}\nThank you for coming!!`;
// document.getElementById('output').innerHTML = output.repeat(i);
}
</script>
</body></html>

InnerHTML does not outputs anchor elements but instead outputs current pg url. why?

In the following code, links_container.innerHTML = links; outputs http://localhost/pagination/js-pagination.html# instead of <a href='#'>Page 1</a>.
HTML
<div class="pagination-links"></div>
JS
function createLinks() {
var links_container = document.getElementsByClassName('pagination-links')[0];
for(i=1; i<=5; i++){
var link = document.createElement('a');
var txt = document.createTextNode('Page ' + i + " ");
link.setAttribute("href", "#");
link.appendChild(txt);
links_container.innerHTML = link;
}
}
Can anybuddy explain. why
innerHTML is a string property and thus takes a string as value. Your link is an element object and because of this it's implicitly converted to a string with its toString() method, which does indeed return the URL.
Here are two ways you can fix this:
Both of these solutions require you to clear the container before the for loop by running links_container.innerHTML = ''
Append the element with links_container.appendChild(link)
Use the outerHTML of the element object: links_container.innerHTML += link.outerHTML
The first option is the more appropriate one as it inserts the DOM element you created into the DOM directly. The second option converts your DOM element to a string and then forces the browser to create a new DOM element from that HTML. If there had been any event listeners added to the element they would've been lost.
Instead of setting innerHTML try calling appendChild. The link object is an element not an HTML string.
i.e. try changing:
links_container.innerHTML = links;
to
links_container.appendChild(link);
function createLinks() {
var links_container = document.getElementsByClassName('pagination-links')[0];
// clear out previous html
links_container.innerHTML = "";
for (i = 1; i <= 5; i++) {
var link = document.createElement('a');
var txt = document.createTextNode('Page ' + i + " ");
link.setAttribute("href", "#");
link.appendChild(txt);
// append link to container
links_container.appendChild(link);
}
}
createLinks();
<div class="pagination-links"></div>
Solution using innerHTML:
links_container.innerHTML += link.outerHTML;
or
links_container.innerHTML += "<a href='#'>Page " + i + " </a>"
function createLinks() {
var links_container = document.getElementsByClassName('pagination-links')[0];
// clear out previous html
links_container.innerHTML = "";
for (i = 1; i <= 5; i++) {
var link = document.createElement('a');
var txt = document.createTextNode('Page ' + i + " ");
link.setAttribute("href", "#");
link.appendChild(txt);
// add link
links_container.innerHTML += link.outerHTML;
// or you can use this instead of the above code
//links_container.innerHTML += "<a href='#'>Page " + i + " </a>";
}
}
createLinks();
<div class="pagination-links"></div>
Replace this line
links_container.innerHTML = links;
with
links_container.innerHTML = link;
as you do not have any links variable there.

I want to highlight all entries from a person (class), what am I missing here?

I have a generator that generates random entries from people. My goal is to mouseover an entry and have that highlight all of the other entries from that user. Each entry gets assigned two classes, one which is the name of the user.
Here's the code I have below.
$(document).ready(function(){
var $body = $('div.center');
$body.html('<header><p id="headertext">Twittler</p></header>');
var index = streams.home.length - 1;
while(index >= 0){
var tweet = streams.home[index];
var $tweet = $('<div class = "tweets"></div>');
$($tweet).addClass(tweet.user);
//I'm trying to have two classes here, and the ID. Probably don't need the ID.
$($tweet).attr("id",tweet.user);
$tweet.text('#' + tweet.user + ': ' + tweet.message + Date().toString("hh:mm tt"));
$tweet.appendTo($body);
index -= 1;
}
$("#tweetButton").click('click', function(){
index = 10;
while(index >= 0){
var tweet = streams.home[index];
var $tweet = $('<div class = "tweets"></div>');
$($tweet).addClass(tweet.user);
//I'm trying to have two classes here, and the ID. Probably don't need the ID.
$($tweet).attr("id",tweet.user);
$tweet.text('#' + tweet.user + ': ' + tweet.message + Date().toString("hh:mm tt"));
$tweet.appendTo($body);
index -= 1;
}
$('.tweets').on('mouseover',function(){
var idget = $(this).attr('class');
$('div.center').find(idget).css('background-color','pink');
});
});
}); //Ends Script area
The tweets on mouseover entry at the bottom is my attempt at doing this, but when I mouseover an entry nothing happens. I'd definitely appreciate your help on what I'm missing here to make this happen.
so if I'm reading your code right (the onmouseover bit).. you grab the value of the class attribute and place it in the idget variable. In this case that value will be "tweets". Next you request all "tweets" (as a selector) that are children of any div element with a center css class attribute, and set its background color.
If all that is correct, "tweets" is not a valid selector, unless you have markup that looks like: <tweets></tweets>. I believe you want:
$('div.center').find('.' + idget).css('background-color','pink');
I don't know your html page but my best guest is this:
first of all you can't use id for tweet.user because there can't be more than one element with same id so I suggest this code for #tweetButton:
$("#tweetButton").click('click', function(){
index = 10;
while(index >= 0){
var tweet = streams.home[index];
var $tweet = $('<div class = "tweets"></div>');
//$($tweet).addClass(tweet.user);
//I'm trying to have two classes here, and the ID. Probably don't need the ID.
$($tweet).attr("userid",tweet.user);
$tweet.text('#' + tweet.user + ': ' + tweet.message + Date().toString("hh:mm tt"));
$tweet.appendTo($body);
index -= 1;
}
for mouseover you should do this :
$('div.center').on('mouseover','.tweets',function(){
var idget = $(this).attr('userid');
$('div.center').find('[userid="'+idget+'"]').css('background-color','pink');
});

Getting group value of element ID with Regex/Javascript

I have a DIV with element id; e.g. "bgjhkn2n2-20". I'm trying to get the regex right so I can load reports dynamically into div's based on id.
console.log(elemID) prints the bgjhkn2n2-20 as expected. It's not printing the # that normally prefixes element Id. console.log(repDBID[0]) prints the full element ID; but I can not get firebug to print the groups I get from a similar test in a regextester with console.log(repDBID[0]). If I append an index number to the match statement, it returns null.
Help?
var baseURL = window.location.protocol + "//" + window.location.hostname + "/db/";
var genREP = "?a=API_GenResultsTable&qid=";
$('#tab1 div').each(function (e){
var elemID = this.getAttribute('id');
console.log(elemID);
var pattern=/([a-z0-9]{9})-([1-9]{1}[0-9]*)/g
var repDBID = elemID.match(pattern); //get dbid
console.log(repDBID[0]);
var repID = elemID.match(pattern)[2]; //get qid
//console.log(repID);
//$(this).load(baseURL+repDBID+genREP+repID);
$('#repTabs').tab(); //initialize tabs
});
Remove the g from your regex and it should work just fine:
var baseURL = window.location.protocol + "//" + window.location.hostname + "/db/";
var genREP = "?a=API_GenResultsTable&qid=";
$('#tab1 div').each(function(e) { // You might need `#tab1 > div`
var parts = this.id.match(/([a-z0-9]{9})-([1-9]{1}[0-9]*)/);
var repDBID = parts[1];
var repID = parts[2];
$(this).load(baseURL + repDBID + genREP + repID);
$('#repTabs').tab();
});
Here's what I mean:
> id.match(/([a-z0-9]{9})-([1-9]{1}[0-9]*)/g);
["bgjhkn2n2-20"]
> id.match(/([a-z0-9]{9})-([1-9]{1}[0-9]*)/);
["bgjhkn2n2-20", "bgjhkn2n2", "20"]

jquery listing HTML elements inside setInterval

I used setinterval to slide number of divs every period of time and that worked fine but the problem happend when i made function"getdata()" that testing this animation and returns the width,left postion,text inside Div for each p...please help me to improve the function "getdata()" to get these information about each p which it changes per sec or i value.
ineed to view data like that
1,left is:0,width:60
2,left is:34,width:40
3,left is:66,width:70
I want to make the data_text which is "1 or 2 or 3" is fixed while the width & data_p_l changes for each data_text "u can consider it it's an ID for the element" 4Ex "
1,left is:0,width:60
1>> this is fixed and this line won't be repeated
left is:20>> changing
width:20>> changing
Ihopt that i've cleared my question.
Thanks alot.
The HTML:
<div id="test"></div>
<div id="center">
<p id="th">3</p>
<p id="s">2</p>
<p id="f">1</p>
</div>
The jQuery:
$(document).ready(function(){
var i = null;
var width = $('#center').width();
var timer = setInterval(function() {
$('p').each(function() {
$(this).css({'left': $(this).position().left + i});
});
getdata('p' ,'#test');
i+=1;
},500);
function getdata(parentdiv,showdiv){
$(parentdiv).each(function(){
var $this = $(this);
var width = $this.width();
var data_p_l= $this.position().left;
var data_text= $this.text();
var dataset = data_text + ",Left value is: "+ data_p_l + ",
width value is: "+ width ;//+ ",id value is: "+ data_id;
$(showdiv).text($(showdiv).text() + ' ' + dataset);
});}
});
I'm not exactly sure what you are trying to do, but This might help. First in this section:
function getdata(parentdiv,showdiv){
$(parentdiv).each(function(){
var len = $( parentdiv ).length;
var width = $(e).width();
var data_p_l= $(e).position().left;
var data_text= $(e).text();
var dataset = data_text + ",Left value is: "+ data_p_l + ",width value is: "+ width;
$(showdiv).text(dataset);
});
}
You want to replace e with this.
function getdata(parentdiv,showdiv){
$(parentdiv).each(function(){
var len = $( parentdiv ).length;
var width = $(this).width();
var data_p_l= $(this).position().left;
var data_text= $(this).text();
var dataset = data_text + ",Left value is: "+ data_p_l + ",width value is: "+ width;
$(showdiv).text($(showdiv).text() + ' ' + dataset);
});
}
Inside the each function, this is used to refer to each element that gets iterated over. At the end of your function, you are putting your results into your div with id test. However, this is running in a loop, so you will only end up with output for the last p tag, and not each one. What I think you want to do is add to the test div like this: $(showdiv).text($(showdiv).text() + ' ' + dataset);

Categories