Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 23
  1. #1
    New Coder
    Join Date
    Aug 2008
    Location
    Liverpool
    Posts
    53
    Thanks
    37
    Thanked 0 Times in 0 Posts

    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

  • #2
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,089
    Thanks
    23
    Thanked 593 Times in 592 Posts
    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?

  • Users who have thanked sunfighter for this post:

    snarf1974 (02-05-2013)

  • #3
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    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.

  • Users who have thanked Old Pedant for this post:

    snarf1974 (02-05-2013)

  • #4
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    snarf1974 (02-05-2013)

  • #5
    New Coder
    Join Date
    Aug 2008
    Location
    Liverpool
    Posts
    53
    Thanks
    37
    Thanked 0 Times in 0 Posts
    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

  • #6
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,089
    Thanks
    23
    Thanked 593 Times in 592 Posts
    @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.

  • Users who have thanked sunfighter for this post:

    snarf1974 (02-05-2013)

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    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.

  • Users who have thanked Old Pedant for this post:

    snarf1974 (02-05-2013)

  • #8
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    snarf1974 (02-05-2013)

  • #9
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    snarf1974 (02-05-2013)

  • #10
    Senior Coder
    Join Date
    Jan 2011
    Location
    Missouri
    Posts
    4,089
    Thanks
    23
    Thanked 593 Times in 592 Posts
    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.

  • Users who have thanked sunfighter for this post:

    snarf1974 (02-05-2013)

  • #11
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    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.

  • Users who have thanked Old Pedant for this post:

    snarf1974 (02-05-2013)

  • #12
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    snarf1974 (02-05-2013)

  • #13
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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...
    Last edited by rnd me; 01-30-2013 at 10:26 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%

  • Users who have thanked rnd me for this post:

    snarf1974 (02-05-2013)

  • #14
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    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.

  • Users who have thanked Old Pedant for this post:

    snarf1974 (02-05-2013)

  • #15
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,296
    Thanks
    10
    Thanked 583 Times in 564 Posts
    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.
    Last edited by rnd me; 01-30-2013 at 11:06 PM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/5/28) IE7:0.1, IE8:5.3, IE11:8.4, IE9:3.2, IE10:3.2, FF:18.2, CH:46, SF:7.9, NON-MOUSE:32%


  •  
    Page 1 of 2 12 LastLast

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •