SitePoint Sponsor

User Tag List

Results 1 to 8 of 8

Hybrid View

  1. #1
    Quality not quantity. bo5ton's Avatar
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    654
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Load multiple files into a page

    Hi Everyone. I'm working on a project that needs to extract links from external pages that are created with simplehtmldom and a cron job.

    The problem I'm having is loading these files into my page using jQuery. The link's 'href' seems to be incorrect and I can't find a solution. It seems that with each link it add's on a href from another link, then the next will add on 2 hrefs. Anyway, here's the code:
    Code JavaScript:
    <script type="text/javascript"> 
     
    var domain1 = "http://domain1.com/";
    var domain2 = "http://domain2.com/";
    var domain3 = "http://domain3.com/";
    var domain4 = "http://domain4.com/";
    var domain5 = "http://domain5.com/";
    $("document").ready(function()  {
    	if ($(window).width() > 960) {
    		$("#content ul li").load("link_extract1.html a",{},function(){
    			$("a").each(function (i) {  
    				$(this).text($(this).text().substring(0,40));
    				var  domain1_href = $(this).attr('href');  
    				var new_domain1_href = domain1 + domain1_href;  
    				$(this).attr('href',new_domain1_href);
    			});
    			$("a").append('...');    	
    		}); 
    		$("#content2 ul li").load("link_extract2.html a",{},function(){
    			$("a").each(function (i) {
    				$(this).text($(this).text().substring(0,40));
    				var  domain2_href = $(this).attr('href');  
    				var new_domain2_href = domain2 + domain2_href;  
    				$(this).attr('href',new_domain2_href);
    			});
    			$("a").append('...');
    		});
    		$("#content3 ul li").load("link_extract3.html a",{},function(){
    			$("a").each(function (i) {
    				$(this).text($(this).text().substring(0,40));
    				var  domain3_href = $(this).attr('href');  
    				var new_domain3_href = domain3 + domain3_href;  
    				$(this).attr('href',new_domain3_href);
    			});
    			$("a").append('...');
    		});
    		$("#content4 ul li").load("link_extract4.html a",{},function(){
    			$("a").each(function (i) {
    				$(this).text($(this).text().substring(0,40));
    				var  domain4_href = $(this).attr('href');  
    				var new_domain4_href = domain4 + domain4_href;  
    				$(this).attr('href',new_domain4_href);
    			});
    			$("a").append('...');
    		});
    		$("#content5 ul li").load("link_extract5.html a",{},function(){
    			$("a").each(function (i) {
    				$(this).text($(this).text().substring(0,40));
    				var  domain5_href = $(this).attr('href');  
    				var new_domain5_href = domain5 + domain5_href;  
    				$(this).attr('href',new_domain5_href);
    			});
    			$("a").append('...');
    		});
    	};
    });  
     
    </script>
    The href in each link_extract file is structured like so: <a href="../topic/4365747419">Link Here</a> -> Which in turn I'd like to appear like <a href="http://domain5.com/topic/4365747419">Link Here</a>

    So you can see how the href is loaded into the <a> for each item. But it appears to be tacking on links from the other files as well. I'm sure it's a simple answer but I can't see it. This is one of my first projects using jQuery.

    I'd also like to know how I can only load the first 5 or so links from each external file.

    Appreciate your time and help.

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Hey Bo5ton

    It looks like problem you're having is that the "domain" URLs are being prepended to all links every time you go through one of the load sequences. There is an easy fix for it though, all we need to do is make sure that a context is passed in to the $('a') selector so it doesn't target all links on the page.

    I'll just give the first one as an example (with some comments):

    Code JavaScript:
    $("#content ul li").load("link_extract1.html a", {}, function(){
     
        $context = $(this).closest("ul"); // our local context for this section
     
        $("a", $context).each(function() {  //pass the context as the second argument to the $() method
     
            var $this = $(this); // cache the object so we don't have to re-instantiate it several times
            var domain1_href = $this.attr('href');
            var new_domain1_href = domain1 + cleanRelativeLink( domain1_href ); //I wrote a function to clean up the relative URLs
     
            $this.text( $this.text().substring(0,40) + "..." ); //append your ellipsis here so we don't have to at the end
            $this.attr('href', new_domain1_href);
     
        });
     
    });
     
     
    /** Remove the relative parts of a href (i.e. the '../' part)
     * @param {String} relativeLinkString
     * @returns {String}
     */
    function cleanRelativeLink ( relativeLinkString ) {
        return relativeLinkString.replace(/\.\.\//g, '');
    }

    Since you're effectively repeating a lot of things, I'm going write a follow up post on how we could make this application a little more DRY :-)
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Ok, so here is where I'm at so far. I've created a "Syndication" class that has some internal methods to add configs and perform the transforms.

    You can add "syndication" links with minimal config in and they will be loaded in to a specific div / ul / whatever on the page. It could still be better but so far avoids the whole copy/paste thing that was happening before and pushes toward a more configurable application.

    Here goes, hopefully the comments will make enough sense out of it. Feel free to harass me if something isn't clear

    Code JavaScript:
    function Syndication() {
     
        /**
         * Configurable values
         */
        this.config = {
            maxLinktextLength: 40,
            cutoffCharacter: "...",
            contextSelector: "ul"
        };
     
     
        /**
         * placeholder for link config
         */
        this.linkConfig = [];
     
     
        /** Add a syndication link to the config
         *
         *    @param {String} parentLink - a URL that will be prefixed on all links
         *    @param {String} linksFile - a URL to extract (relative) links from
         *    @param {String} element - a selector to load the elements in to
         *
         */
        this.addLinkConfig = function( parentLink, linksFile, element) {
     
            this.linkConfig.push({
                parentLink: parentLink,
                linksFile: linksFile,
                element: element
            });
     
        }
     
     
        /**
         * Run the Syndication
         */
        this.run = function() {
            var i, len;
     
            for ( i = 0, len = this.linkConfig.length; i < len; i++) {
     
                this.extractAndTransform( this.linkConfig[i] ) ;
     
            }
     
        }
     
     
        /**
         * Extract and transform the links for the current config item
         *
         * @param {Object} currentItem - The current linkConfig to be processed
         *
         */
        this.extractAndTransform = function( currentItem ) {
            var that = this;
     
            $( currentItem.element ).load( currentItem.linksFile + " a", {}, function(){
     
                // our local context for this section
                var $context = $(this).closest( that.config.contextSelector );
     
                //pass the context as the second argument to the $() method
                $("a", $context).each(function() {
     
                    var $this = $(this),
                        //build the new link href
                        newHref = currentItem.parentLink + that.cleanRelativeLink( $this.attr('href') );
     
                    //limit the length of the link text + add an (optional) cut
                    $this.text( $this.text().substring(0, that.config.maxLinktextLength ) + that.config.cutoffCharacter );
                    //apply new href
                    $this.attr('href', newHref);
     
                });
            });
        }
     
     
        /**
         * Remove the relative parts of a href (i.e. the '../' part)
         *
         * @param {String} relativeLinkString
         * @returns {String}
         */
        this.cleanRelativeLink = function( relativeLinkString ) {
            return relativeLinkString.replace(/\.\.\//g, '');
        }
     
     
    }
     
    var syndicate = new Syndication();
     
    syndicate.addLinkConfig( 'http://example.com/posts/123/', 'links_1.html', '#content_1 ul li' );
    syndicate.addLinkConfig( 'http://example.com/posts/456/', 'links_2.html', '#content_2 ul li' );
    syndicate.addLinkConfig( 'http://example.com/posts/789/', 'links_3.html', '#content_3 ul li' );
    syndicate.addLinkConfig( 'http://example.com/posts/1011/', 'links_4.html', '#content_4 ul li' );
     
    $(document).ready(function(){
     
        syndicate.run();
     
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  4. #4
    Quality not quantity. bo5ton's Avatar
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    654
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Once again John you have come up with the goods! You're an absolute champion! It works perfectly!

    Thanks for your reply. I'm trying my best to learn all I can about Javascript & jQuery but it's just so vast and has so much in it.

    Do you recommend any books or learning tools for this kind of stuff?

  5. #5
    Quality not quantity. bo5ton's Avatar
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    654
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Also, would it be possible to only return 5 or so links instead of everything?

  6. #6
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bo5ton View Post
    Also, would it be possible to only return 5 or so links instead of everything?
    It most certainly would be possible, and with quite minimal effort.

    I added a property called maxLinks to the config

    Code JavaScript:
     
    /**
     * Configurable values
     */
    this.config = {
        maxLinktextLength: 40,
        cutoffCharacter: "...",
        contextSelector: "ul",
        maxLinks: 5 //max # of links to show, false to show all links
    };


    Then in the extractAndTransform method we simply remove the links after the index that we don't want before we go through the each loop.

    Code javascript:
    /**
     * Extract and transform the links for the current config item
     *
     * @param {Object} currentItem - The current linkConfig to be processed
     *
     */
    this.extractAndTransform = function( currentItem ) {
        var that = this;
     
        $( currentItem.element ).load( currentItem.linksFile + " a", {}, function(){
     
            // our local context for this section
            var $context = $(this).closest( that.config.contextSelector ),
                counter = 0;
     
    // ===> Select and remove all links with an index greater than our maxLinks property
            if (that.config.maxLinks !== false) {
                $("a:gt("+(that.config.maxLinks-1)+")", $context).remove();
            }
     
            //pass the context as the second argument to the $() method
            $("a", $context).each(function() {
     
     
                var $this = $(this),
                    //build the new link href
                    newHref = currentItem.parentLink + that.cleanRelativeLink( $this.attr('href') );
     
                //limit the length of the link text + add an (optional) cut
                $this.text( $this.text().substring(0, that.config.maxLinktextLength ) + that.config.cutoffCharacter );
                //apply new href
                $this.attr('href', newHref);
     
            });
     
     
        });
    }

    If you want to go back to showing more (or less, or all) links you can simply modify the maxLinks property

    Code javascript:
    $(document).ready(function(){
     
        syndicate.config.maxLinks = 10; //show 10
        syndicate.config.maxLinks = false; //show all
        syndicate.config.maxLinks = 3; //show 3
     
        syndicate.run();
     
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  7. #7
    Quality not quantity. bo5ton's Avatar
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    654
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Excellent John. Thanks again!
    I can't say I expected it to be that complicated. But looking over it now I get the gist how it works.

    I'm not sure where I went wrong on the original. But they way you set it out is much cleaner and efficient.

    As I'm not very familiar with either, is this jQuery or straight JS?

    Any book/tutorial recommendations?

  8. #8
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by bo5ton View Post
    I'm not sure where I went wrong on the original. But they way you set it out is much cleaner and efficient.

    As I'm not very familiar with either, is this jQuery or straight JS?

    Any book/tutorial recommendations?

    In the original it was just a matter of the context in which you were addressing the links. You were basically looping through all links on the page every time a file was being loaded. (Which was in turn affecting the URL for all the links as you were effectively prepending all the URLs from your list to all the links on the page.

    This code is a bit of a combination of jQuery and JS, but the pattern being used is pure JS. In it's most simplistic form it's a function that you create new instances of.

    Code javascript:
    function MyClass () {
      this.foo = "It's Foo!";
     
      this.doSomething = function() {
        console.log( this.foo );
      }
     
    }
     
    bar = new MyClass();
    bar.foo = "It's Bar!";
     
    bar.doSomething(); // will log "It's Bar!" to the console
     
    baz = new MyClass();
    baz.doSomething(); // will log "It's Foo!" to the console

    This pattern gives you the opportunity to create objects and even if they aren't being used, it will give you a nice way to encapsulate your code.

    For a slightly longer example see http://snipt.net/geekyjohn/basic-ins...bject-example/

    Some good books on JS that are probably worth reading:

    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }


Bookmarks

Posting Permissions

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