Sortables within sortables in IE
For an interactive survey builder I'm trying to construct I'm
arranging questions inside fieldsets. Both the fieldsets and the
questions within them should be sortable. My code looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/
TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<style type="text/css">
<!--
.cmsDialog {
display: none;
}
legend {
display: none;
}
-->
</style>
<link rel="stylesheet" href="/js/jquery/ui/themes/flora/flora.all.css"
type="text/css" media="screen" title="Flora (Default)" />
<script type="text/javascript" src="/js/jquery/jquery.js"></script>
<script type="text/javascript" src="/js/jquery/jquery.livequery.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.core.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.draggable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.resizable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.sortable.js"></
script>
<script type="text/javascript" src="/js/jquery/ui/ui.dialog.js"></
script>
<script type="text/javascript">
<!--
function QuestionGroup (title, subtitle, target)
{
var self = this;
self.wrapper = $('<li></li>');
self.header = $('<h3>'
+ title
+ '</h3><h4>'
+ subtitle
+ '</h4>');
self.fieldSet = $('<fieldset><legend>'
+ title
+ '</legend></fieldset>');
self.questionList = $('<ul></ul>');
self.optBar = $('<div class="optBar"></div>');
self.questionBut = $('<input type="button" class="addQ" value="Add
question" />');
self.construct = function ()
{
self.fieldSet.append (self.questionList);
self.optBar.append (self.questionBut);
self.wrapper.append (self.header);
self.wrapper.append (self.fieldSet);
self.wrapper.append (self.optBar);
target.append (self.wrapper);
self.questionList.sortable ({
handle : 'label'
});
};
self.construct ();
}
function QuestionString (target, label)
{
var self = this;
self.container = $('<li></li>');
self.label = $('<label>' + label + '</label>');
self.input = $('<input type="text" />');
self.construct = function ()
{
self.container.append (self.label);
self.container.append (self.input);
target.append (self.container);
target.sortable ('refresh');
};
self.construct ();
}
$(document).ready (function ()
{
var groupList = $('#cmsSurveyPreview').sortable ({
handle : 'h3'
});
var dialogNewGroup;
var dialogNewQ;
var activeGroup;
$('#cmsAddGroup').click (function ()
{
if (dialogNewGroup)
{
dialogNewGroup.dialog ('open');
}
else
{
dialogNewGroup = $('#cmsDgNewGroup').show ().dialog ({
title : 'New Question Group',
modal : true,
overlay : {
'background-color' : 'black',
'filter' : 'alpha(opacity=30)',
'opacity' : '0.3',
'-moz-opacity' : '0.3'
},
buttons : {
'Create' : function (evt)
{
var title = $('#groupTitle', this).val ();
var question = $('#groupQuestion', this).val ();
new QuestionGroup (title, question, groupList);
groupList.sortable ('refresh');
$(this).dialog ('close');
},
'Cancel ' : function (){$(this).dialog ('close');}
}
});
}
});
$('.addQ').livequery ('click', function ()
{
activeGroup = $('ul', $(this).parent ().parent ());
if (dialogNewQ)
{
dialogNewQ.dialog ('open');
}
else
{
dialogNewQ = $('#cmsDgNewQ').show ().dialog ({
title : 'New Question',
modal : true,
overlay : {
'background-color' : 'black',
'filter' : 'alpha(opacity=30)',
'opacity' : '0.3',
'-moz-opacity' : '0.3'
},
buttons : {
'Create' : function (evt)
{
var label = $('#label', this).val ();
if (label)
{
new QuestionString (activeGroup, label);
}
$(this).dialog ('close');
}
}
});
}
});
});
-->
</script>
</head>
<body>
<form action="">
<ul id="cmsSurveyPreview">
</ul>
</form>
<form action="">
<fieldset id="controls">
<input type="hidden" name="srv_content" />
<input type="button" id="cmsAddGroup" value="Add group" />
<input type="submit" value="Done" />
</fieldset>
<div class="cmsDialog flora" id="cmsDgNewGroup">
<ul>
<li>
<label for="groupTitle">Title</label>
<input id="groupTitle" />
</li>
<li>
<label for="groupQuestion">Question</label>
<input id="groupQuestion" />
</li>
</ul>
</div>
<div class="cmsDialog flora" id="cmsDgNewQ">
<ul>
<li>
<label for="label">Label</label>
<input id="label" />
</li>
</ul>
</div>
</form>
</body>
</html>
This works as expected in FireFox (except the handle directives don't
seem to have an effect, but this is a minor issue). However, in IE,
dragging a fieldset causes its contained sortable list to be "left
behind", causing quite significant display corruption.
Is there a way around this?