0

We have this code, thanks to a helpful person here at stackoverflow but it does not fully work as expected. The problem is that it currently checks for an exact match of dates, but there are situations of times that overlap one another and that should show a conflict too (background becomes red in case of conflicts). As you can see the following date "Wednesday Oct/30 11:00 AM - 3:15 PM" overlaps with both Wednesday Oct/30 10:00 AM - 12:15 PM. Obviously one cannot be at the same time at different locations.

The code used is this:

$(".time").change(function() {
        var values = $("input.time").map(function(){
            return $(this).val();
        });
        values.each( function (){
            var overlapping = $("input.time[value='"+ this +"']");
            if (overlapping.filter(":checked").length > 1){                            
                overlapping.parents("tr").addClass("red");}
            else{
                overlapping.parents("tr").removeClass("red");
            }
        })
    });

The fiddle is here: http://jsfiddle.net/3VFRt/

I know what needs to be done but I can't seem to grasp how that is done in jQuery. I am thinking it needs to extract the date data from the columns (td's) and see if there is an overlap in time, if so show it accordingly (css class=red). Basically the script needs some refining and it will work perfectly. If anyone can help me out here I would be very grateful. Thanks in advance.

Johan
  • 13
  • 2

1 Answers1

1

Yes, you need to extract the dates manually and compare them. Here's a fiddle. Also see the SO post on comparing overlapping dates.

$(".time").change(function() {    
    removeErrors();
    var dateOverlapping = $("input.time:checked").filter(function() {
        return $("input.time[value^='"+ $(this).val().split('|')[0] +"']:checked").length > 1;
    });
    dateOverlapping.each(function(i, elem){
        var timeOverlapping = dateOverlapping.filter(function(i2, elem2) {
            return i != i2 && overlaps(range($(elem).val().split('|')[1]), 
                                       range($(elem2).val().split('|')[1]));
        });
        if(timeOverlapping.length > 0)
            $(elem).parents("tr").addClass('red');
        else
            $(elem).parents("tr").removeClass('red');
    });
});

function removeErrors() {
    $("input.time").each(function() {
        $(this).parents("tr").removeClass('red');
    });
}

function overlaps(range1, range2) {
    return (range1.start <= range2.end) && (range2.start <= range1.end);
}

function range(time) {
    var tms = time.split('-');
    return {
        start : timeToFloat(tms[0]),
        end : timeToFloat(tms[1])
    };
}

function timeToFloat(time)
{
    var toks = time.trim().split(/\s+/);
    var num = toks[0].trim().split(':');
    var val = parseFloat(num[0]) + 0.01 * parseFloat(num[1]);
    if(Math.floor(val) == 12)
    {
        if(toks[1].toLowerCase() == "am")
            val -= 12;
    }
    else if(toks[1].toLowerCase() == "pm")
        val += 12;
    return val;
}
Community
  • 1
  • 1
blackcompe
  • 3,180
  • 16
  • 27
  • 1
    It looks like function overlaps() is never called, as goes for function range(), I think this is because dateOverlapping.each(function(i, elem) returns true before it touches the functions mentioned? – Johan Sep 15 '13 at 12:53
  • The code is fixed and the fiddle link is updated. There was also a mistake in your in HTML that caused problems. I commented out the original line in the fiddle. – blackcompe Sep 15 '13 at 17:14
  • Thanks a lot for the update! Works exactly the way it needs to. Now tell me how I can buy you a beer :) – Johan Sep 16 '13 at 05:42
  • Lol. Don't sweat it. It was a good challenge as I'm just starting to learn JQuery. – blackcompe Sep 16 '13 at 11:45