views:

40

answers:

0

I've got around 85 sortable ul's all connected with each other, and initializing the sortable() function works fine in Chrome and Firefox, but in IE it causes a 5-10 second hang while it loops through and connects them all.

Yes they /do/ need to all be connected to each other unfortunately.

Any suggestions as to how I can stop IE from hanging?

The code that causes the slowdown is simply

$('.reportsList').sortable({
    connectWith: $('.reportsList'),
    receive: function(ev, ui){
        reportsSortableReceive(ev,ui);
    },
    update: function(ev, ui){
        //don't allow moves within the same list, change it back the way it was!
        $('.reportsList>li').tsort();
    }
}).disableSelection();

The full code:

var subjectsObj;
var teachersObj;
var reportsObj;
$(document).ready(function(){
    //fetch subjects
    window.subjectsObj = jQuery.parseJSON($('#subjectsArray').html());
    //fetch teachers
    window.teachersObj = jQuery.parseJSON($('#teachersArray').html());
    //fetch reports
    window.reportsObj = jQuery.parseJSON($('#reportsArray').html());

    orderByTeacher();
});

function createSubjectsMenu() {
    //create the subjects menu
    var studentReportJSMenu = $('#studentReportJSMenu');
    studentReportJSMenu.append('<div class="subjects"><h1>Subjects List & Unassigned Reports</h1><p class="whiteText">Drag and drop double arrowed boxes to assign reports</p>'+
        '<p><input type="button" value="Untick all" id="studentReportsUntickAll"/> <input type="button" value="Tick all" id="studentReportsTickAll"/></p></div><div style="clear:both;">');
    //enable tick/untick all buttons
    $('#studentReportsTickAll').click(function(){
        $(this).parents('.subjects').find('input[type=checkbox]').attr('checked',true);
        $('.studentReportSubjectDiv:not(.studentReportSubjectToggle):not(.studentReportUnassignReport):not(.studentReportDropReport)').slideDown(500);
        $.each(subjectsObj,function(index,value){
            value.excluded = 0;
        });
    });
    $('#studentReportsUntickAll').click(function(){
        $(this).parents('.subjects').find('input[type=checkbox]').attr('checked',false);
        $('.studentReportSubjectDiv:not(.studentReportSubjectToggle):not(.studentReportUnassignReport):not(.studentReportDropReport)').slideUp(500);
        $.each(subjectsObj,function(index,value){
            value.excluded = 1;
        });
    });
    //print the subjects themselves
    $.each(subjectsObj,function(index,value){
        subject = value.name;
        subjectClass = 'subject_'+subject.replace(/[^a-zA-Z0-9]+/g,''); //we can't be having non-alphanumeric chars in css class names!
        $('#studentReportJSMenu > .subjects')
            .prepend('<div class="studentReportSubjectDiv ' + subjectClass 
            + ' studentReportSubjectToggle"><h3><input type="checkbox" checked="checked" name="'+subject+'" class="reportCheckbox"> '+subject+'</h3><ul class="reportsList"></ul></div>');
    });
    //add the 'unassign report' box
    $('#studentReportJSMenu > .subjects').prepend('<div class="studentReportUnassignReport studentReportSubjectDiv"><h2> </h2><ul class="reportsList"></ul></div>');
    //enable the checkboxes on the subjects menu
    $('.reportCheckbox').change(function(){
        start = $(this);
        subject = start.attr('name');
        subjectTrimmed = subject.replace(/[^a-zA-Z0-9]+/g,''); //we can't be having non-alphanumeric chars in css class names!
        subjectClass = 'subject_'+subjectTrimmed;
        if(start.is(':checked')){
            $('.'+subjectClass +'.studentReportSubjectDiv:not(.studentReportSubjectToggle)').slideDown(500);
            window.subjectsObj[subjectTrimmed].excluded = 0;
        }else{
            $('.'+subjectClass +'.studentReportSubjectDiv:not(.studentReportSubjectToggle)').slideUp(500);
            window.subjectsObj[subjectTrimmed].excluded = 1;
        }
    });
}

function orderByTeacher(){
    var studentReportsReports = $('#studentReportsReports');
    //create the teacher divs
    $.each(teachersObj,function(index,value){
        teacherID = index;
        teacherName = value;
        studentReportsReports.append('<div id="teacher'+teacherID+'" class="studentReportTeacherDiv"><h1>'+teacherName+'</h1><div class="subjects"></div><div style="clear:both";>&nbsp;</div></div>');
        $('#teacher'+teacherID+' .subjects').append('<div class="studentReportDropReport studentReportSubjectDiv"><h2> </h2><ul class="reportsList"></ul></div>');
    });

    createSubjectsMenu();

    //create the teachers, subjects and reports
    $.each(reportsObj,function(index,value){
        defaultTeacher = value.defaultTeacher;
        studentName = value.studentName;
        studentClass = 'student_' + value.studentID;
        subject = value.subject;
        subjectClass = 'subject_'+subject.replace(/[^a-zA-Z0-9]+/g,''); //we can't be having non-alphanumeric chars in css class names!
        tempReportID = index;
        teacherElement = $('#teacher'+defaultTeacher);
        if($('.'+subjectClass, teacherElement).length == 0){
            //if this subject doesn't exist for this teacher, create it!
            $(' .subjects', teacherElement)
                .append('<div class="'+subjectClass+' studentReportSubjectDiv"><h2>'+subject+'</h2>'+
                        '<ul class="reportsList"></ul></div>');
        }

        //add the report li
        $(' .'+subjectClass+ ' ul',teacherElement).append('<li id="' +tempReportID+ '" class="'+subjectClass + ' '+ studentClass +'">'+studentName+'</li>');
    });    

    //sort the reportsLists alphabetically
    $('.reportsList>li').tsort();
    //sort the studentReportSubjectDiv alphabetically
    $('.studentReportSubjectDiv').tsort('h2');
    //sort the teachers alphabetically
    $('.studentReportTeacherDiv').tsort('h1');
    //enable drag 'n drop
    makeReportsSortableTeacher();
}

function makeReportsSortableTeacher(){
    $('.reportsList').sortable({
        connectWith: $('.reportsList'),
        receive: function(ev, ui){
            reportsSortableReceive(ev,ui);
        },
        update: function(ev, ui){
            //don't allow moves within the same list, change it back teh way it was!
            $('.reportsList>li').tsort();
        }
    }).disableSelection();

    //doubleclick to toggle student highlighting
    $('.reportsList > li').dblclick(function(){
        start = $(this);
        //if it's not already highlighted, highlight it, otherwise, just unhighlight all
        if(start.css('backgroundColor') != 'rgb(255, 238, 170)'){
            $('.reportsList > li').css('backgroundColor','white');
            //find the studentID
            reportClasses = start.attr('class').split(' ');
            for(classIndex in reportClasses){
                if(reportClasses[classIndex].indexOf('student_') >=0){
                    reportStudentClass = reportClasses[classIndex];
                }
            }
            $('.'+reportStudentClass).css('backgroundColor','#fea');
        }else{
            $('.reportsList > li').css('backgroundColor','white');
        }
    });    

}

function reportsSortableReceive(ev,ui){
    theReport = ui.item;
    theParentList = theReport.parents('.studentReportSubjectDiv');
    theParentListClass = theParentList.attr('class');
    theParentSubjectDiv = theParentList.parents('.subjects');
    //find the report subject
    reportClasses = theReport.attr('class').split(' ');
    for(classIndex in reportClasses){
        if(reportClasses[classIndex].indexOf('subject_') >=0){
            reportSubjectClass = reportClasses[classIndex];
            reportSubject = subjectsObj[reportSubjectClass.replace('subject_','')].name;
        }
    }

    //check to make sure the report isn't being dragged onto a different subject
    if(theParentListClass.indexOf(reportSubjectClass) >= 0 || theParentListClass.indexOf('studentReportDropReport') >= 0 || theParentListClass.indexOf('studentReportUnassignReport') >= 0){

        if(theParentListClass.indexOf('studentReportDropReport') >= 0 || theParentListClass.indexOf('studentReportUnassignReport') >= 0) {
            //if we're dropping the report into a blank space

            if(theParentSubjectDiv.find('.'+reportSubjectClass +'.studentReportSubjectDiv').length == 0){
                //if this subject doesn't exist for this teacher, create it!

                theParentSubjectDiv
                    .append('<div class="'+reportSubjectClass+' studentReportSubjectDiv" style="display:none;"><h2>'+reportSubject+'</h2>'+
                            '<ul class="reportsList"></ul></div>');
                //move the report into the right subject
                theReport.prependTo(theParentSubjectDiv.find('.'+reportSubjectClass+' > ul'));
                //make sure it's sorted alphabetically with the other subject divs
                $('.studentReportSubjectDiv',theParentSubjectDiv).tsort('h2');
                //reveal it
                $('.'+reportSubjectClass,theParentSubjectDiv).slideDown(500);
                //make the new subject sortable
                makeReportsSortableTeacher();
            }else{
                //if this subject already exists for this teacher, just move to it baby!
                theReport.prependTo(theParentSubjectDiv.find('.'+reportSubjectClass+' > ul'));
                //make sure it's in the right place alphabetically
                theParentList.find('li').tsort();
            }
        }
        theReport.css('backgroundColor','#BDCDE8');
        theReport.animate(
            {backgroundColor: 'white'},
            3000);

        //if the old subject list is empty, remove it!
        if($('li',ui.sender).length == 0){
            ui.sender.parent().slideUp(500,function(){    ui.sender.parent().remove();});
        }
        //update the reports object to reflect the change
        reportsObj[theReport.attr('id')].teacher = theReport.parents('.studentReportTeacherDiv').attr('id').replace('teacher','');

        //sort the reportsLists alphabetically again, as doubtless they dropped it in the wrong fecking place!
        $('.reportsList>li').tsort();
    }else{
        //if the user dragged the report to the wrong subject, cancel it
        ui.sender.sortable('cancel');
        theReport.css('backgroundColor','red');
        theReport.animate(
            {backgroundColor: 'white'},
            500
        );
    } 
}