我正在设计一个表单构建界面。所有可用字段将位于界面左侧的无序列表中,右侧有一个大的空无序列表,它将成为我的网络表单。使该界面工作的“技巧”是通过将 html 附加到可放置的 ui 元素中,将左侧的列表项转换为有效的 html 元素,然后再将它们附加到右侧的可排序列表中。
我让它工作......主要......使用draggable()和sortable()。目前,我使用 sortable 的接收事件从可拖动元素中获取 id,我将其放入 data() 块中以传递给更新事件。从那里,我使用 id 元素进行 ajax 调用,确定它是什么类型的字段以及应该从后端添加哪些选项,构建元素,然后使用 将其放入接口中ui.item.html
,这是由更新功能。
我的方法的问题是它在拖动元素时也会触发,这会导致选择元素在无意中附加到可排序列表时在屏幕上乱扔垃圾。显然,接收事件是仅在排序从连接列表中获取项目时触发的事件。但是,如果我尝试对ui.item
元素进行内部 html,它会更改源列表,而不是所需的目标。当项目已经在右侧的网络表单列表中时,如果它们只是被排序,我绝对不想修改它们。
有什么方法可以访问和更改连接sortable()
列表接收事件中的目标 html?还有其他策略可以解决我的挑战吗?
编码:
<div class="grid_3 mainwindow formfields">
<h3>Available Fields</h3>
<div id="accordion">
<ul>
<li>First Name</li>
<li>Last Name</li>
<li>Company</li>
</ul>
</div>
</div>
</div>
<div class="grid_12 formcontainer formfields">
<h3>Webform</h3>
<form id="form" action="http://responses.smarttracks.com" method="post">
<input type="hidden" name="webform_id" id="webform_id" value="<?php echo $webform_id ?>"></input>
<ul id="webform_list"></ul>
</form>
</div>
和 jQuery
/***** Make webform fields draggable *****/
$( ".master_list li" ).draggable({
connectToSortable: "#webform_list",
helper: "clone",
revert: "invalid"
});
/***** Make form elements sortable *****/
$( "#webform_list" ).sortable({
revert: true,
cursor: 'pointer',
placeholder: "placeholderdiv",
receive: function(event, ui) {
$(this).data('id', ui.item[0].id);
var element = event.target
},
update: function(event, ui) {
var fieldname = ui.item.text();
if ($(this).data('id')) {
$.ajax({
url: "/webform/getFieldAttributes",
timeout: 30000,
type: "POST",
data: 'id='+$(this).data('id'),
dataType: 'json',
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown)
},
success: function(data){
switch (data.control_type) {
case 'text':
var inputfield = $('<input type="text">').attr('id', 'fieldname');
var field = (ui.item).text();
switch (field) {
case 'Email Address':
inputfield.addClass('validate[optional,custom[email]]');
break;
default:
inputfield.addClass('validate[required]');
break;
}
break;
case 'textarea':
var inputfield = $('<textarea>');
break;
case 'Dropdown Menu (Single Select)':
var inputfield = $('<select>');
$.each(data.field_options, function(name, value) {
inputfield.append($("<option></option>").attr("value",name).text(value))
});
inputfield.addClass('validate[required]');
break;
case 'Radio Buttons (Single Select)':
var inputfield = $('<div class="webform_radiogroup">');
$.each(data.field_options, function(name, value) {
var container = $('<div class="webform_radio_option">');
var radio = $('<input type="radio">').attr({ name: name,value: value,id: name });
radio.appendTo(container);
$('<label for="'+name+'">'+name+'</label>').appendTo(container);
$('<div class="clear">').appendTo(container);
container.appendTo(inputfield);
});
break;
}
if (data.control_type == 'Radio Buttons (Single Select)') {
ui.item.html('<div class="webform_radiogroup_label">'+fieldname+'</div>').append(inputfield).append('<div class="clear">').wrapInner('<div class="webform_questiongroup">').wrapInner('<div class="hoverdiv" />');
} else {
ui.item.html('').append('<label for="'+fieldname+'">'+fieldname+'</label>').append(inputfield).wrapInner('<div class="hoverdiv" />');
}
}
});
}
}
});