1

I am stuck here and hope to get some guidance on this. I'm trying to take XML from a feed, put some elements into an array, then pass into jQuery's DatePicker plugin. My code below is displaying the calendar, but not the events from the feed. Chrome is show no errors or warnings either. Not sure what's going on. Any assistance is much appreciated.

(My XML):

<entry>
    <published>2012-05-29T13:05:53-08:00</published>
    <updated>2012-05-29T13:05:58-08:00</updated>
    <title type="html">
       <![CDATA[ Businesses Get Help With Legal Issues ]]>
    </title>
    <content type="html">
       <![CDATA[ Click the article header for the complete story.
       <!-- /Publications/26674.htm -->
       ]]>
    </content>
    <link rel="alternate" type="text/html" href="/Publications/26675.htm"/>
</entry>

(In external JS file):

$(document).ready(function(){

    var events = new Array();
    events = getSelectedDates();

    $("div.datepicker").datepicker({
    beforeShowDay: function(date) {
        var result = [true, '', null];
        var matching = $.grep(events, function(event) {
            return event.published.valueOf() === date.valueOf();
        });

        if (matching.length) {
            result = [true, 'highlight', null];
        }
        return result;
    },
    onSelect: function(dateText) {
        var date,
            selectedDate = new Date(dateText),
            i = 0,
            event = null;

        while (i < events.length && !event) {
            date = events[i].published;

            if (selectedDate.valueOf() === date.valueOf()) {
                event = events[i];
            }
            i++;
        }
        if (event) {
            alert(event.Title);
        }
    }
});
});


function getSelectedDates()
{
    var the_selected_dates = new Array();

    $.ajax(
    {
        url: 'news.xml',
        type: 'GET',
        dataType: 'xml',
        async: false,
        success: function(data)
        {
            $(data).find('entry').each(function(i, entryObj)
            {
                var entryObj = new Object();
                entryObj.eTitle = $('title', this).text();
                entryObj.eDate = $('published', this).text();
                the_selected_dates.push(entryObj);
            });
        }
    });
    return the_selected_dates;
}
Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
Psykopup
  • 165
  • 1
  • 18

2 Answers2

1

You have several issues with this snippet, but the reason you weren't actually parsing the XML correctly so events was always empty. I changed the getSelectedDates function to perform the each over each entry (before you were searching for entry elements inside of entry elements):

function getSelectedDates() {
    return $(data).map(function() {
        return {
            title: $('title', this).text(),
            published: new Date($('published', this).text())
        };
    }).get();
}​

As you can see I also am using .map to transform the XML elements into an array of objects with properties title and published. You were using several property names (sometimes eDate, sometimes published) which was causing problems down the line, but I've fixed that as well.

The next problem is that you were comparing dates using valueOf. Since the dates passed to beforeShowDay have no time portion, there is pretty much no chance that your $.grep function is going to return true for any date. The way I fixed this was to compare against the elements of the dates we cared about (date, month, full year):

beforeShowDay: function(date) {
    var result = [true, '', null],
        matching = $.grep(events, function(event) {
            return event.published.getDate() === date.getDate() && 
                   event.published.getMonth() === date.getMonth() &&
                   event.published.getFullYear() === date.getFullYear();
        });

    if (matching.length) {
        result = [true, 'highlight', null];
    }
    return result;
},

I also made a similar change for onSelect:

onSelect: function(dateText) {
    var date, selectedDate = new Date(dateText),
        i = 0,
        event = null;

    while (i < events.length && !event) {
        date = events[i].published;

        if (selectedDate.getFullYear() === date.getFullYear() && 
            selectedDate.getMonth() === date.getMonth() && 
            selectedDate.getDate() === date.getDate()) {

                event = events[i];
        }
        i++;
    }
    if (event) {
        alert(event.title);
    }
}

I have a full working example here: http://jsfiddle.net/4extL/31/

Note: I would be very careful with the date format you're using in the XML. I'm not sure that an ISO8601 date with a time zone will always be properly parsed.

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
  • Not sure if people are still checking this since it's been marked as answered, but can anyone tell me why the above jsFiddle reference won't work in IE8? – Psykopup Jun 05 '12 at 23:05
  • @Psykopup It could be the date format you're using as I mentioned in the note at the bottom. Any chance you can change the format of the date you're passing down? – Andrew Whitaker Jun 05 '12 at 23:25
  • I tried changing the format to 2012-06-23, 06/23/2012... no improvement. – Psykopup Jun 05 '12 at 23:56
  • @Psykopup: See this MDN page for the formats supported by the Date constructor and `parse`: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/parse. Alternatively, I would look at the DateJS library which will parse pretty much anything you throw at it – Andrew Whitaker Jun 06 '12 at 00:04
  • Andrew you were right on about the date format. IE didn't like it. I tried Date.parse and it didn't like that either. I found the answer on another post on this site, by user "Qlimax". http://stackoverflow.com/questions/2182246/javascript-dates-in-ie-nan-firefox-chrome-ok – Psykopup Jun 06 '12 at 16:43
0

Thank you Andrew. This was a huge help. I have this all working with the following edits:

1...In the getSelectedDates() function, I added a 'find' to the return since I'm dealing with a whole XML file

return $(data).find('entry').map(function()

2...I used AJAX to create my data variable from my XML file:

var data = $.ajax({
     url: "news.xml",
     type: "GET",
     dataType: "xml",
     async: false,
     success: function(xml){
           return xml;
     }
 } ).responseText;
Psykopup
  • 165
  • 1
  • 18