0

I am a bit stuck with the following problem.

I have several XML files tagged by an ID (every XML is id'd by a value). I am now trying to loop through these files and output its contents to HTML.

However it starts the loop before it does the call back

Loop0 Loop1 Loop2 Callback0 Callback1 Callback2

I would need Loop0 Callback0 Loop1 Callback1

As I need to control the results at some point.

        var allContent=["xmlfile1","xmlfile2","xmlfile3","xmlfile4"];
        var totalSearch = 0;
        var countSearch = 0;

        function doSearch() {

            var oldContentID = contentID;

            for (iSearch=0;iSearch<allContent.length;iSearch++) {
                totalSearch = totalSearch + countSearch;
                contentID = allContent[iSearch];
                defineContent();

                getXML();

            }
        } 

        function getXML() {
            $.ajax({
                type: "GET",
                url: langFile,
                dataType: "xml",
                beforeSend: function(){

                    $('#results-list').empty();
                    $('#results-list').hide();
                    $('#loading').addClass('loading');
                },
                success: function(xml) {

                    var totalElements;
                    var intSearch = 0;
                    totalSearch = totalSearch + countSearch;
                    countSearch = 0;
                    var searchText = $('#text').val().toLowerCase();

                    totalElements = $(xml).find('news').length;


                    while (intSearch < totalElements) {
                        oFeed = $(xml).find('news:eq('+intSearch+')');
                        var headline = oFeed.find('headline').text();
                        var newsText = oFeed.find('detail').text();
                        var section = oFeed.find('section').text();
                        var category = oFeed.attr('category');

                        var stripEnters = newsText.match(/\r?\n|\r/gi);
                        if (stripEnters != null) {
                            for (var s = 0; s < stripEnters.length ; s++ ){
                                newsText = newsText.replace(stripEnters[s],'');
                            }
                        }

                        var newsText2 = $.htmlClean(newsText, {format:true});
                        var newsText3 = $(newsText2)
                        var newsText4 = $(newsText3).text();
                        var newsText5 = newsText4.replace( /\W/gi, "" );

                        if (section.toLowerCase() == "news" || section.toLowerCase() == "featured") {
                            if (headline.toLowerCase().indexOf(searchText) >= 0) {
                                $('<dt></dt>').html(headline).appendTo('#results-list');
                                $('<dd></dd>').html(newsText).appendTo('#results-list');
                                countSearch++;
                            }//end if
                            else if (newsText5.toLowerCase().indexOf(searchText) >= 0) {
                                $('<dt></dt>').html(headline).appendTo('#results-list');
                                $('<dd></dd>').html(newsText).appendTo('#results-list');
                                countSearch++;
                            }
                        }
                        intSearch++;
                    }           

                }   
            }); 
        }

At the end of the call backs I need to run the following, however it now executes this function before it finishes all call backs.

        function displayResults() {
            if (totalSearch == 0)
            {
                alert("No results found");
                $('#loading').removeClass('loading');
                $('#main').fadeIn(1000);
            }
            else {
                dynamicFaq();
                $('<p></p>').html(totalSearch + ' Results found').prependTo('#results-list');
                $('#results-list').fadeIn(1000);
                $('#loading').removeClass('loading');
            }   
        }

3 Answers 3

1

If I understood you correctly, you want to load 1 xml file, loop, and then start to load the next xml file. If so, here is a little pseudo code:

function doSearch(int xmlFileIterator){
    if (xmlFileIterator < allContent.length) {
        ...
        contentID = allContent[xmlFileIterator];
        ...
        getXml(xmlFileIterator);
    } else {
        //no more xml files left
        displayResults();
    }
}

function getXml(int xmlFileIterator) {
    ...
        success: function() {
            ...
            doSearch(++xmlFileIterator);
        }
}

The first call is doSearch(0) which loads the first xml file. After the file is loaded and the loop is done (in success) you can call the doSearch function again with a higher number (iterator).

Sign up to request clarification or add additional context in comments.

Comments

0

I see your AJAX call is Asynchronous. Try using

            ....
            type: "GET",
            url: langFile,
            async: false,
            dataType: "xml",
            .....

2 Comments

You should never use synchronous calls, never. It will stuck the browser (and that's only one aspect why you should avoid sync calls).
the async worked however it freezes IE7/8 for quite a bit which isn't really an option in long term, I am having a look at below options now and will then re-evaluate my answer. Thanks though Indoknight
0

Maintain a ajax queue so thos ajax call will be done one by one. plus maintain a global variable searchedCount which will maintain how main xml are proccessed.

In complete callback of ajax check for the searchedCount and call displayResults function .

var allContent = ["xmlfile1", "xmlfile2", "xmlfile3", "xmlfile4"];
var totalSearch = 0;
var countSearch = 0;
var searchedCount = 0;

var ajaxQueue = $({});
$.ajaxQueue = function (ajaxOpts) {
    // Hold the original complete function.
    var oldComplete = ajaxOpts.complete;
    // Queue our ajax request.
    ajaxQueue.queue(function (next) {
        // Create a complete callback to fire the next event in the queue.
        ajaxOpts.complete = function () {
            // Fire the original complete if it was there.
            if (oldComplete) {
                oldComplete.apply(this, arguments);
            }
            // Run the next query in the queue.
            next();
        };
        // Run the query.
        $.ajax(ajaxOpts);
    });
};

function doSearch() {

    var oldContentID = contentID;
    searchedCount = 0;
    for (iSearch = 0; iSearch < allContent.length; iSearch++) {
        totalSearch = totalSearch + countSearch;
        contentID = allContent[iSearch];
        defineContent();
        searchedCount++;
        getXML();

    }
}

function getXML() {
    $.ajaxQueue({
        type: "GET",
        url: langFile,
        dataType: "xml",
        beforeSend: function () {

            $('#results-list').empty();
            $('#results-list').hide();
            $('#loading').addClass('loading');
        },
        success: function (xml) {

            //your code 

        },
        complete: function () {
            if (searchedCount == allContent.length) {
                displayResults()
            }
        }
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.