mrr0ng
mrr0ng

Reputation: 37

jQuery nested XML question

I am using jQuery to insert an HTML shell into a page, and populate the shell with XML. Here is the XML in question

  <minorPropCategory title="Test Title 1">
    <minorProp>FLV</minorProp>
    <minorProp>BLV</minorProp>
    <minorProp>RLV</minorProp>
  </minorPropCategory>
  <minorPropCategory title="Test Title 2">
    <minorProp>LAS</minorProp>
    <minorProp>ILV</minorProp>
    <minorProp>BIL</minorProp>
  </minorPropCategory>

So first, what I do is import an HTML snippet for each minorPropCategory, and add the title using this code

$(xml).find('minorPropCategory').each(function(){
                        var minorHeader=$(this).attr("title");
                        var minorId=$(this).attr("title").replace(/ /g,'');
                        var minorModuleContainerCode = "minorModuleContainer.html";
                        //names the div with a unique ID
                        minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
                        //Sets loading message in case it takes longer than usual to load
                        minorDiv.html("Loading......");
                        //After minorModuleContainerCode.html code loads, starts populating module
                        minorDiv.load(minorModuleContainerCode,"t",
                            function(){
                                $("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);

                            }
                        );
                        $("#minorModuleContainer").append(minorDiv);

Then, what I want to do is add another HTML snippet, and then populate it. This is where I am having a problem. I can try it like this

//Create the actual minor modules
                        $(this).find('minorProp').each(function(){
                            var minorPropCode = $(this).text();
                            var minorModuleCode = "minorModule.html";
                            minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
                            minorModuleDiv.html("Loading......");
                            minorModuleDiv.load(minorModuleCode,"b",
                            function(){
                                $.ajax({
                                    type: "GET", url: minorPropCode+".xml", dataType: "xml", 
                                    success: function(xml3) {
                                        $("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
                                            {
                                                src:$(xml3).find('smallImage').text(),
                                                alt:$(xml3).find('smallImageAlt').text()
                                            }
                                        );

                                    }
                                });
                            });
                            $("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
                        });
                    });

But it never shows up on the page, because I don't think it is firing at the proper time. Alternatively, I tried moving the creation of the minor modules into the .load function of it's parent, but I run into another problem. The code looks like this.

//MINOR MODULE CODE
                    $(xml).find('minorPropCategory').each(function(){
                        var minorHeader=$(this).attr("title");
                        var minorId=$(this).attr("title").replace(/ /g,'');
                        var minorModuleContainerCode = "minorModuleContainer.html";
                        //names the div with a unique ID
                        minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
                        //Sets loading message in case it takes longer than usual to load
                        minorDiv.html("Loading......");
                        //After minorModuleContainerCode.html code loads, starts populating module
                        minorDiv.load(minorModuleContainerCode,"t",
                            function(){
                                $("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);
                                $(this).find('minorProp').each(function(){
                                    alert("minorPropFired");
                                    var minorPropCode = $(this).text();
                                    var minorModuleCode = "minorModule.html";
                                    minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
                                    minorModuleDiv.html("Loading......");
                                    minorModuleDiv.load(minorModuleCode,"b",
                                    function(){
                                        $.ajax({
                                            type: "GET", url: minorPropCode+".xml", dataType: "xml", 
                                            success: function(xml3) {
                                                alert("test");
                                                $("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
                                                    {
                                                        src:$(xml3).find('smallImage').text(),
                                                        alt:$(xml3).find('smallImageAlt').text()
                                                    }
                                                );

                                            }
                                        });
                                });
                            $("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
                        });

The problem is, that the line with "$(this).find('minorProp').each(function(){" doesn't fire because "this" has changed. I guess, by now, my noob is showing. I feel like I am doing this in the wrong way. Any help would be appreciated. Thanks.

Posted below is the full .js file of what I am trying to do.

// JavaScript Document<script language="JavaScript" type="text/javascript">
    $(document).ready(function(){
        //gets the code for the ad from the URL.  Using URL jQuery add-on to make this super-easy
        var adCode = $.url.param("adCode");
        if (adCode != null){
            //gets the ad code's XML file
            $.ajax({
                type: "GET", url: adCode+".xml", dataType: "xml", 
                success: function(xml) {
                    //Set the header image
                    $("#headerImg").attr(
                        {
                            src:$(xml).find('headerImage').text(),
                            alt:$(xml).find('headerImageAlt').text()
                        }
                    );
                    //set the header text
                    $("#headerText").html($(xml).find('adText').text());
                    //set the top image
                    $("#topImg").attr(
                        {
                            src:$(xml).find('topImage').text(),
                            alt:$(xml).find('topImageAlt').text()
                        }
                    );
                    //MAJOR MODULE CODE - This code reads all of the major modules, then adds a majorModule div, and populates it
                    //Gets all majorProps from ad XML
                    $(xml).find('majorProp').each(function(){
                        var propCode=$(this).text();
                        var majorModuleCode = "majorModule.html";
                        //names the div with a unique ID
                        div = $("<div id='"+propCode+"majorModule' class='majorModule'>");
                        //Sets loading message in case it takes longer than usual to load
                        div.html("Loading......");
                        //After majorModule.html code loads, starts populating module
                        div.load(majorModuleCode,"t",
                            function(){
                                //Get the XML for the prop, which contains prop specific stuff
                                $.ajax({
                                    type: "GET", 
                                    url: propCode+".xml", 
                                    dataType: "xml", 
                                    success: function(xml2) {
                                        $("#"+propCode+"majorModule").find(".propImg").attr(
                                            {
                                                src:$(xml2).find('smallImage').text(),
                                                alt:$(xml2).find('smallImageAlt').text()
                                            }
                                        );
                                        $("#"+propCode+"majorModule").find(".propLogoImg").attr(
                                            {
                                                src:$(xml2).find('smallLogo').text(),
                                                alt:$(xml2).find('name').text()
                                            }
                                        );
                                        $("#"+propCode+"majorModule").find(".viewCalendarLinkA").attr(
                                            {
                                                href:"https://www.harrahs.com/AvailabilityCalendar.do?propCode="+propCode+"&showHotDeal=Y"
                                            }
                                        );
                                        $("#"+propCode+"majorModule").find(".learnMoreLinkA").attr(
                                            {
                                                href:$(xml2).find('homeLink').text()
                                            }
                                        );
                                        $("#"+propCode+"majorModule").find(".propText").html(
                                                $(xml2).find('bodyText').text()
                                        );

                                    }
                                });
                                //Get the lowest rate for the prop
                                $.ajax({
                                    type: "GET", 
                                    url: "lowest_rate\\"+propCode+".xml", 
                                    dataType: "xml", 
                                    success: function(xml3) {
                                        $("#"+propCode+"majorModule").find(".roomRate").html(
                                                "$"+($(xml3).find('roomtype').filter(
                                                    function (index) {
                                                        return $(this).attr("lowest") == "Y";
                                                    }).text()).slice(0, -3)
                                        )
                                    }
                                });
                            }
                        );
                        $("#mainModuleContainer").append(div);
                    });
                    //MINOR MODULE CODE
                    $(xml).find('minorPropCategory').each(function(){
                        var minorHeader=$(this).attr("title");
                        var minorId=$(this).attr("title").replace(/ /g,'');
                        var minorModuleContainerCode = "minorModuleContainer.html";
                        //names the div with a unique ID
                        minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
                        //Sets loading message in case it takes longer than usual to load
                        minorDiv.html("Loading......");
                        //After minorModuleContainerCode.html code loads, starts populating module
                        minorDiv.load(minorModuleContainerCode,"t",
                            function(){
                                $("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);

                            }
                        );
                        $("#minorModuleContainer").append(minorDiv);
                        //Create the actual minor modules
                        $(this).find('minorProp').each(function(){
                            var minorPropCode = $(this).text();
                            var minorModuleCode = "minorModule.html";
                            minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
                            minorModuleDiv.html("Loading......");
                            minorModuleDiv.load(minorModuleCode,"b",
                            function(){
                                $.ajax({
                                    type: "GET", url: minorPropCode+".xml", dataType: "xml", 
                                    success: function(xml3) {
                                        $("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
                                            {
                                                src:$(xml3).find('smallImage').text(),
                                                alt:$(xml3).find('smallImageAlt').text()
                                            }
                                        );

                                    }
                                });
                            });
                            $("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
                        });
                    });



                }
            });
        }
    });

Upvotes: 0

Views: 695

Answers (1)

RaYell
RaYell

Reputation: 70414

To fix this problem just before running minorDiv.load do something like this

var elem = $(this);
minorDiv.load(minorModuleContainerCode,"t", function(){
    $("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").
        html(minorHeader);

    // replace $(this) with elem here
    elem.find('minorProp').each(function(){
        ...
    }

    ...
}

This will keep the reference to correct object in your nested functions.

Upvotes: 1

Related Questions