Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-28-2013, 02:30 PM   PM User | #1
snarf1974
New Coder

 
Join Date: Aug 2008
Location: Liverpool
Posts: 53
Thanks: 37
Thanked 0 Times in 0 Posts
snarf1974 is an unknown quantity at this point
Question Display random list items from another page

Hello,

I'm trying to display random <li> from a <ul> on another page.

There are 25 list items on the other page (reports.htm) and I would like 3 to be displayed on the homepage (index.htm) randomly. The list items only have to change on page refresh (F5).

I've tried the following code, BUT this meant copying the 25 list items from reports.htm into index.htm. This only displays 1 list item, and hides the others from the screen (not good for our screen reading audience):

Code:
<script type="text/javascript">

this.randomtip = function(){
	var length = $("#tips li").length;
	var ran = Math.floor(Math.random()*length) + 1;
	$("#tips li:nth-child(" + ran + ")").show();
};

$(document).ready(function(){	
	randomtip();
});

</script>
Any tips/solutions/comments would be greatly appreciated.

Many thanks
snarf1974 is offline   Reply With Quote
Old 01-28-2013, 04:56 PM   PM User | #2
sunfighter
Senior Coder

 
Join Date: Jan 2011
Location: Missouri
Posts: 2,364
Thanks: 18
Thanked 347 Times in 346 Posts
sunfighter is on a distinguished road
Code:
<script type="text/javascript">
this.randomtip = function(){
var length = $("#tips li").length;
for($i = 0; $i < 3; $i++)
{
	var ran = Math.floor(Math.random()*length) + 1;
	$("#tips li:nth-child(" + ran + ")").show();
}
};
$(document).ready(function(){
	randomtip();
});
</script>
I didn't check this, but you see what I did right?
sunfighter is offline   Reply With Quote
Users who have thanked sunfighter for this post:
snarf1974 (02-05-2013)
Old 01-28-2013, 08:30 PM   PM User | #3
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,162
Thanks: 59
Thanked 3,992 Times in 3,961 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
I don't understand, in the least, Sunfighter. Your code still depends on having all 25 <li> items on the *current* page. You need to, instead, fetch *only* the requisite number of items from the other page. On top of that, although you try to "show" 3 items, there is no guarantee that you won't end up picking the same random item all 3 times! (Granted, that's unlikely, but it's certainly possible. And picking the same one twice will happen more often than you'd want to see.)

Snarf: There is no way to make this work as you wanted *UNLESS* both pages are present in the browser AT THE SAME TIME. Or unless you are willing to "send" the random item(s) from the one page to the other.

You need to give us more details: Is one of these pages in, for example, an <iframe> on the other of the pages? How do you expect to transfer the data from one page to the next?
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
snarf1974 (02-05-2013)
Old 01-29-2013, 05:23 AM   PM User | #4
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
i didn't see this before, but this is a perfect use case for my partial page content fetcher.
it's not setup to do 3 random items, so we'll need a slight modification:

changes in red:

Code:
function getPage(url, from, to, callBack) {
	var cached=sessionStorage[url];
   	if(!from){from="body";} // default to grabbing body tag
	if(cached){return elm.innerHTML=cached;} // cache responses for instant re-use re-use
	if(to && to.split){to=document.querySelector(to);} // a string TO turns into an element
	if(!to){to=document.querySelector(from);} // default re-using the source elm as the target elm

	var XHRt = new XMLHttpRequest; // new ajax
	XHRt.responseType='document';  // ajax2 context and onload() event
	XHRt.onload= function() { callBack(XHRt.response.querySelector(from), to);};
	XHRt.open("GET", url, true);
	XHRt.send();
	return XHRt;

}


// to use it with the callback:
$(document).ready(function() {

   getPage("./reports.htm", "ul#tips", "ul#tips", function (elm, dest) {
		var frag = document.createDocumentFragment(),
		 items = elm.getElementsByTagName("li");
		dest.innerHTML=""; //clear list

		 // grab 3 different items:
		for (var $i = 0; $i < 3; $i++) {
			frag.appendChild(items[Math.floor(Math.random() * items.length)]);
		}

		// append all 3 to UL on page:
		dest.appendChild(frag);
   });//end getPage()

});//end ready()
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
snarf1974 (02-05-2013)
Old 01-29-2013, 04:31 PM   PM User | #5
snarf1974
New Coder

 
Join Date: Aug 2008
Location: Liverpool
Posts: 53
Thanks: 37
Thanked 0 Times in 0 Posts
snarf1974 is an unknown quantity at this point
Old Pedant: I'm working on a local version of this page:
http://www.hse.gov.uk/horizons/index.htm

The box in question is the 'short form reports' box. The other page (http://www.hse.gov.uk/horizons/sfreports.htm) has the 25 reports in an unordered list. The pages are not in iframes.

It would be good to facilitate this using a client-side only script, as we don't have permission to mess around with asp.net on the server.

rnd me: The index.htm and sfreports.htm pages are in a root folder. As sfreports.htm is on the same level as index.htm, Ive done the following:

Code:
   getPage("sfreports.htm", "ul#tips", "ul#tips-index", function (elm, dest) {
Using jQuery 1.7.2

I've tried only putting the <ul> in the index page:

Code:
<ul id="tips-index">

</ul>
And also the following:

Code:
<ul id="tips-index">
<li></li>
<li></li>
<li></li>
</ul>
Unfortunately, still not working. What am I missing?

Thanks to both of you for your help thus far.

snarf1974
snarf1974 is offline   Reply With Quote
Old 01-29-2013, 05:47 PM   PM User | #6
sunfighter
Senior Coder

 
Join Date: Jan 2011
Location: Missouri
Posts: 2,364
Thanks: 18
Thanked 347 Times in 346 Posts
sunfighter is on a distinguished road
@Old Pedant This was just a fast code to show how to display three items from a group. Two questions were asked, i answered one; sort of. As I said I didn't check this and didn't think of displaying an item two or three times. If I played with it that scenario might have showed up and been dealt with.

As for getting items from another page. I could do it but it would be complicated and as I said "I didn't check this" cause I had other things to do that day. One would have hoped that snarf1974 would have seen what I did and that it only answered one of his questions.

Anyway I don't want to steal this thread and it looks like rnd me is helping him so I'll just back out of here, hat in hand, eyes downcast, bowing low, smile on my face.
sunfighter is offline   Reply With Quote
Users who have thanked sunfighter for this post:
snarf1974 (02-05-2013)
Old 01-29-2013, 08:24 PM   PM User | #7
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,162
Thanks: 59
Thanked 3,992 Times in 3,961 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
But how will you be *SURE* that a user will have *BOTH PAGES* open in their browser at the same time???

Since both come from the same domain, there is no cross-site scripting issue, but still the one page can only read items from the other page if both are open in the same browser on the same computer at the same time.

Now...

One solution would be to *force* the page you want to grab data from to be in an <iframe> on the page grabbing the data! The <iframe> can be completely invisible, so the user won't even know you are doing this.

Is this a viable path for you??
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 03:40 AM   PM User | #8
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by Old Pedant View Post
But how will you be *SURE* that a user will have *BOTH PAGES* open in their browser at the same time???

Since both come from the same domain, there is no cross-site scripting issue, but still the one page can only read items from the other page if both are open in the same browser on the same computer at the same time.
no, you can usajax to get a page from anywhere on the site or the world w/cors.

@snarf: i'll take a look later, i'm mobile right now.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 04:26 AM   PM User | #9
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
the URLs and classnames you provided are a bit out of whack, i suspect local/live drift as the culprit.

nonetheless, the following code ran in chrome's inspector from: http://www.hse.gov.uk/horizons/index.htm .



Code:
function getPage(url, from, to, callBack) {
	var cached=sessionStorage[url];
   	if(!from){from="body";} // default to grabbing body tag
	if(cached){return elm.innerHTML=cached;} // cache responses for instant re-use re-use
	if(to && to.split){to=document.querySelector(to);} // a string TO turns into an element
	if(!to){to=document.querySelector(from);} // default re-using the source elm as the target elm

	var XHRt = new XMLHttpRequest; // new ajax
	XHRt.responseType='document';  // ajax2 context and onload() event
	XHRt.onload= function() { callBack(XHRt.response.querySelector(from), to);};
	XHRt.open("GET", url, true);
	XHRt.send();
	return XHRt;

}


// to use it with the callback:
$(document).ready(function() {

  getPage("/horizons/sfreports.htm", "ul.itemThumbBook", ".hse2ColumnRight", function (elm, dest) {
		var frag = document.createDocumentFragment(),
		 items = elm.getElementsByTagName("li");
		dest.innerHTML=""; //clear list

		 // grab 3 different items:
		for (var $i = 0; $i < 3; $i++) {
			frag.appendChild(items[Math.floor(Math.random() * items.length)]);
		}

		// append all 3 to UL on page:
		dest.appendChild(frag);
   });//end getPage()

});//end ready()
i didn't see a ul#tips anywhere, so i did the best i could. kinda just threw it into a container at the bottom...

but now that it's operational, you should be able to adjust the css selectors to match the actual markup in use without much fuss. remember that the paths and css selectors have to match up, and that you can't pull the live page from your test rig, you have to pull the local copy, which i observed to be on a different url path than indicated.

the gun is firing. as long as it's pointing in the right place, it will hit the target.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 06:34 PM   PM User | #10
sunfighter
Senior Coder

 
Join Date: Jan 2011
Location: Missouri
Posts: 2,364
Thanks: 18
Thanked 347 Times in 346 Posts
sunfighter is on a distinguished road
I guess you guys got this all sorted, but it seems to me that putting those 25 things into and array and doing an array.sort on it and just picking the first three would be a whole lot easier and less code (and maybe faster ??) without trying to get them from the other page.
sunfighter is offline   Reply With Quote
Users who have thanked sunfighter for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 08:48 PM   PM User | #11
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,162
Thanks: 59
Thanked 3,992 Times in 3,961 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Sunfighter: You are, of course, correct. But it was my impression that the 25 items on that other page changed from time to time, presumably because of other external actions. So I assumed that the goal was to pick 3 of the *current* <li>s, from the live page.

RndMe's method is, as usual with his code, quite clever and correct. But I don't know, for example, how many browser support createDocumentFragment().

My own method would be a lot simpler and would work with browsers as far back as MSIE 5.

But I'm not going to bother to show it unless the OP says he wants it.
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 10:14 PM   PM User | #12
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by sunfighter View Post
I guess you guys got this all sorted, but it seems to me that putting those 25 things into and array and doing an array.sort on it and just picking the first three would be a whole lot easier and less code (and maybe faster ??) without trying to get them from the other page.
how is having to publish each content update twice faster than publishing it once?
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 10:22 PM   PM User | #13
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by Old Pedant View Post
RndMe's method is, as usual with his code, quite clever and correct. But I don't know, for example, how many browser support createDocumentFragment().

My own method would be a lot simpler and would work with browsers as far back as MSIE 5.
createDocumentFragment is dom1 thing, been around forever...
it's the ajax2 you should be complaining about

xhr.onload(), querySelectorAll(), and createDocumentFragment() should work in all known browsers to at least a couple versions back.

if you are feeling code-happy, please code an IE6/7 compatible version of the function from the POST A JAVASCRIPT section so that many coders can pickup that extra percent of old user agents with no effort.



as far as making this particular code simpler, i don't really see how that could be done. 6 lines of custom code is not very much for an ajax call, unique (non-repeating) result picking, and cross-browser dom handling. if you know a simpler way of doing all that, please, share your feelings with the group. I'd like to see that code. i don't imagine that mine is the only way or the end-all be-all right way of doing anything. furthermore, it's easier for me to find faults with other's code than my own, so it would be nice if that applied universally, and you can spot some issues i can't...
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%

Last edited by rnd me; 01-30-2013 at 10:26 PM..
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 10:33 PM   PM User | #14
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,162
Thanks: 59
Thanked 3,992 Times in 3,961 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
Well, I *did* say "for example" about createDocumentFragment.

Okay, okay...I'll show my scheme. It's not clever. It's not better. It's just simple. Back later.

But I just noticed this in your code:
Code:
		 // grab 3 different items:
		for (var $i = 0; $i < 3; $i++) {
			frag.appendChild(items[Math.floor(Math.random() * items.length)]);
		}
??? How does that answer my prior objection that you might get the same <li> all 3 times? And you will surely get the same item twice more often than would make the user happy. What am I missing?
__________________
An optimist sees the glass as half full.
A pessimist sees the glass as half empty.
A realist drinks it no matter how much there is.
Old Pedant is offline   Reply With Quote
Users who have thanked Old Pedant for this post:
snarf1974 (02-05-2013)
Old 01-30-2013, 11:02 PM   PM User | #15
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by Old Pedant View Post
Well, I *did* say "for example" about createDocumentFragment.

Okay, okay...I'll show my scheme. It's not clever. It's not better. It's just simple. Back later.

But I just noticed this in your code:
Code:
		 // grab 3 different items:
		for (var $i = 0; $i < 3; $i++) {
			frag.appendChild(items[Math.floor(Math.random() * items.length)]);
		}
??? How does that answer my prior objection that you might get the same <li> all 3 times? And you will surely get the same item twice more often than would make the user happy. What am I missing?
when you append an element to the fragment, it disappears from the nodeList...

remember, unlike arrays of elements, nodeLists from element.getXXXbyXXX() methods are live.

the other routines i imagined were much more complex, which is why i was curious about what you had in mind.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%

Last edited by rnd me; 01-30-2013 at 11:06 PM..
rnd me is offline   Reply With Quote
Reply

Bookmarks

Tags
javascript, jquery, random

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 05:11 PM.


Advertisement
Log in to turn off these ads.