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";> </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
);
}
}