Wednesday, October 14, 2009
jQuery, how do I love thee?
So I spent a few days doing some JavaScript, which is not my favourite thing. Or at least it didn't use to be. But now that I have discovered JQuery, I gotta say, it's a whole lot more tolerable than it used to be.
JQuery makes some things that I would previous have considered all but impossible downright easy. Take drag-and-drop inside the browser, f'rinstance. To do it yourself, you'd have to deal with, jeez, I don't even know what, DOM craziness, layers, who knows. In jQuery? Well, lemme give you a quick example, stripped of all the actual business logic, of a drag-and-drop form builder:
Pretty slick, eh?
What you do is, you drag form elements from the first column into the second column, where clones are inserted. (That way the element stays in the first column, so you can have an arbitrary number of instances in the second column.) One key thing to note is that clones do not inherit the clonee's bindings, so you have to bind any events after they're created, as shown above in the "stop" event of the "sortable" definition.
I would try to explain more, but either you already know JQuery reasonably well, in which case the above is probably pretty clear already, or you don't, in which case it will be Greek. So - just copy and paste the above as HTML, launch it in a browser, and play around with it; it should drag and drop right out of the box.
JQuery makes some things that I would previous have considered all but impossible downright easy. Take drag-and-drop inside the browser, f'rinstance. To do it yourself, you'd have to deal with, jeez, I don't even know what, DOM craziness, layers, who knows. In jQuery? Well, lemme give you a quick example, stripped of all the actual business logic, of a drag-and-drop form builder:
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"></script>
<style type="text/css">
.columns:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html .columns {height: 1%;}
.columns{ display:inline-block; }
.columns{ display:block; }
.columns .column{
float:left;
display:inline;
min-height:360px;
}
.columns .last{ float:right; }
.columns .first{ width:180px; background-color:#ffeeee; }
.columns .second{ width:280px; margin-left:10px; background-color:#eeffee; }
.columns .last{ width:210px; background-color:#eeeeff}
.footers{ display:inline-block; }
.footers{ display:block; }
.footers .footer{
float:left;
display:inline;
}
.footers .last{ float:right; }
.footers .first{ width:180px; background-color:#eeeeee; }
.footers .second{ width:280px; margin-left:10px; background-color:#eeeeee; }
.footers .last{ width:210px; background-color:#eeeeee}
.formLineEdit { text-align: right; }
.optionLabel { float:right; text-align: right; }
.label { font-weight: bold; vertical-align: text-top; }
.formInput { text-align: right; vertical-align: text-top; }
.editHeader { text-align: right; }
.selectOption { text-align: right; }
#error { text-align: center; color: #ff0000; }
#success { text-align: center; color: #00ff00; }
#listForms { float: left; text-align: left; }
#viewHelp { float: right; text-align: right; }
#inputOptions { text-align: right; }
#detailHeader { text-align: right; }
#formName {background-color: #eeeeee; }
#formVersionNumber {background-color: #eeeeee; }
#formSubmitButton {text-align:right; background-color: #eeeeee; }
</style>
<script>
var totalItems=0;
var currentlyEditing=null;
var lastEdited=null;
$(function() {
//make divs created out of XML clickable
var destClicked=false;
$("#destination").mousedown( function() {
if (!destClicked) { //only do this once, or it might get messy
$("#destination").children().each( function() {
$(this).bind("click", function() {
showEditDetailsFor($(this));
});
});
}
destClicked=true;
});
//set up drag-and-drop stuff
$("#textInput").draggable(
{ connectToSortable:'#destination',
cursor:'move',
helper:'clone',
}
);
$("#longText").draggable(
{ connectToSortable:'#destination',
cursor:'move',
helper:'clone',
}
);
$("#selectMultiple").draggable(
{ connectToSortable:'#destination',
cursor:'move',
helper:'clone',
}
);
$("#selectOne").draggable(
{ connectToSortable:'#destination',
cursor:'move',
helper:'clone',
}
);
$("#destination").sortable(
{
change: function(event, ui) {
ui.placeholder.css({visibility: 'visible', border : '2px solid yellow'});
},
start: function(event, ui) {
ui.placeholder.css({visibility: 'visible', border : '2px solid yellow'});
var tempID=ui.item.attr("id");
if (tempID.indexOf("_")==-1) {
tempID=tempID+"_"+totalItems++;
ui.item.attr({id:tempID});
}
},
stop: function(event, ui) {
//load element details, and ensure they'll show up again when this item is clicked
showEditDetailsFor(ui.item);
ui.item.bind("click", function() {
showEditDetailsFor(ui.item);
});
},
}
);
});
function showEditDetailsFor ( object ) {
// object.effect("highlight", {}, 3000);
currentlyEditing=object.attr("id");
if (currentlyEditing==lastEdited)
return;
$(".formLineEdit").hide();
$("#inputOptions").show();
if (object.attr("id").indexOf("textInput")==0) {
var inputLabel = $.trim(object.find(".label").text());
var inputID = object.find("input[name=inputID]").val();
if (inputLabel!="Text Input" || object.find("input[name=inputID]").attr("name")!="inputID") {
$("#textInputEdit").find("input[name=textInputLabel]").val(inputLabel);
$("#textInputEdit").find("input[name=textInputValue]").val(inputID);
}
$("#textInputEdit").show();
}
else if (object.attr("id").indexOf("longText")==0) {
var inputLabel = $.trim(object.find(".label").text());
var inputID = object.find("textarea:first").val();
if (inputLabel!="Long Text" || inputID!="") {
$("#longTextEdit").find("input[name=longTextLabel]").val(inputLabel);
$("#longTextEdit").find("input[name=longTextValue]").val(inputID);
}
$("#longTextEdit").show();
}
else if (object.attr("id").indexOf("selectMultiple")==0) {
var inputLabel = $.trim(object.find(".label:first").text());
var inputID = object.find("input:last").attr("name");
if (inputLabel!="Select Multiple" || inputID!="selectMulti") {
$("#selectMultiEdit").find("input[name=selectMultiLabel]").val(inputLabel);
$("#selectMultiEdit").find("input[name=selectMultiValue]").val(inputID);
blankOption=$("#selectMultiEdit > .selectOption").remove();
var addedChild=false;
object.children(".formInput").each( function() {
optionClone=blankOption.clone();
var optionLabel=$(this).find(".optionLabel").text();
optionClone.find("input[name=multiOptionLabel]").val(optionLabel);
var optionValue=$(this).find("input:first").attr("value");
optionClone.find("input[name=multiOptionValue]").val(optionValue);
cloneRemoveButton = optionClone.find("input[name=removeSelectMultiOption]");
cloneRemoveButton.bind("mouseup", function() {
$(this).parent().remove();
});
$("#selectMultiEdit").append(optionClone);
addedChild=true;
});
if (!addedChild)
$("#selectMultiEdit").append(blankOption);
} //don't show defaults
$("#selectMultiEdit").show();
}
else if (object.attr("id").indexOf("selectOne")==0) {
var inputLabel = $.trim(object.find(".label:first").text());
var inputID = object.find("input:last").attr("name");
if (inputLabel!="Select One" || inputID!="selectOne") {
$("#selectOneEdit").find("input[name=selectOneLabel]").val(inputLabel);
$("#selectOneEdit").find("input[name=selectOneValue]").val(inputID);
blankOption=$("#selectOneEdit > .selectOption").remove();
var addedChild=false;
object.children(".formInput").each( function() {
optionClone=blankOption.clone();
var optionLabel=$(this).find(".optionLabel").text();
optionClone.find("input[name=oneOptionLabel]").val(optionLabel);
var optionValue=$(this).find("input:first").attr("value");
optionClone.find("input[name=oneOptionValue]").val(optionValue);
cloneRemoveButton = optionClone.find("input[name=removeSelectOneOption]");
cloneRemoveButton.bind("mouseup", function() {
$(this).parent().remove();
});
$("#selectOneEdit").append(optionClone);
addedChild=true;
});
if (!addedChild)
$("#selectOneEdit").append(blankOption);
} //don't show defaults
$("#selectOneEdit").show();
}
lastEdited=currentlyEditing;
}
</script>
</head>
<body>
<center><H3>Form Builder</H3></center>
<div id="success"></div>
<div id="error"></div>
<div id="header">
</div>
<P/>
<div class="columns">
<div id="source" class="column first">
<b>Form Elements</b><HR/>
<div id="textInput" class="formLine">
<div class="label">Text Input</div><div class="formInput"><input name="inputID" /></div>
</div>
<HR/>
<div id="longText" class="formLine">
<div class="label">Long Text</div>
<div class="formInput"><textarea name="textarea"></textarea></div>
</div>
<HR/>
<div id="selectMultiple" class="formLine">
<div class="label">Select Multiple</div>
<div class="formInput">
<input type="checkbox" name="selectMulti" value="one" />
<div class="optionLabel">One</div>
</div>
<div class="formInput">
<BR/><input type="checkbox" name="selectMulti" value="two" />
<div class="optionLabel">Two</div>
</div>
</div>
<HR/>
<div id="selectOne" class="formLine">
<div class="label">Select One</div>
<div class="formInput">
<input type="radio" name="selectOne" value="one" />
<div class="optionLabel">One</div>
</div>
<div class="formInput">
<BR/><input type="radio" name="selectOne" value="two" />
<div class="optionLabel">Two</div>
</div>
</div>
</div> <!--source-->
<div id="middle" class="column second">
<b>Form</b> (drag elements here)
<HR/>
<div id="destination"> </div>
<HR/>
</div>
<div id="details" class="column last">
<div id="detailHeader"><b>Element Details</b><HR/></div>
<div id="textInputEdit" class="formLineEdit">
<div class="editHeader">
<b>Text Input</b>
<input type="submit" name="textInputSubmit" value="Done" />
<input type="submit" name="delete" value="Delete" />
</div>
<BR/><a href="/formHelp#labels" target="_blank">Label</a><input name="textInputLabel" type="text" />
<BR/><a href="/formHelp#ids" target="_blank">ID</a><input name="textInputValue" />
</div>
<div id="longTextEdit" class="formLineEdit">
<div class="editHeader">
<b>Long Text</b>
<input type="submit" name="longTextSubmit" value="Done" />
<input type="submit" name="delete" value="Delete" />
</div>
<BR/><a href="/formHelp#labels" target="_blank">Label</a><input name="longTextLabel" />
<BR/><a href="/formHelp#ids" target="_blank">ID</a><input name="longTextValue" />
</div>
<div id="selectMultiEdit" class="formLineEdit">
<div class="editHeader">
<b>Select Multiple</b>
<input type="submit" name="selectMultiSubmit" value="Done" />
<input type="submit" name="delete" value="Delete" />
</div>
<BR/><a href="/formHelp#labels" target="_blank">Label</a><input name="selectMultiLabel" />
<BR/><a href="/formHelp#ids" target="_blank">ID</a><input name="selectMultiValue" />
<BR/><input type="submit" name="addSelectMultiOption" value="Add Option" />
<HR/>
<div id="selectMultiOption" class="selectOption">
<i>Option</i>: <a href="/formHelp#editSelects" target="_blank">Name</a> <input name="multiOptionLabel" size=12/>
<BR/><a href="/formHelp#editSelects" target="_blank">Value</a><input name="multiOptionValue" size=12/>
<BR/><input type="submit" name="removeSelectMultiOption" value="Remove" />
<HR/>
</div>
</div>
<div id="selectOneEdit" class="formLineEdit">
<div class="editHeader">
<b>Select One</b>
<input type="submit" name="selectOneSubmit" value="Done" />
<input type="submit" name="delete" value="Delete" />
</div>
<BR/><a href="/formHelp#labels" target="_blank">Label</a><input name="selectOneLabel" />
<BR/><a href="/formHelp#ids" target="_blank">ID</a><input name="selectOneValue" />
<BR/><input type="submit" name="addSelectOneOption" value="Add Option" />
<HR/>
<div id="selectOneOption" class="selectOption">
<i>Option</i>: <a href="/formHelp#editSelects" target="_blank">Name</a><input name="oneOptionLabel" size=12/>
<BR/><a href="/formHelp#editSelects" target="_blank">Value</a><input name="oneOptionValue" size=12/>
<BR/><input type="submit" name="removeSelectOneOption" value="Remove" />
<HR/>
</div>
</div>
</div> <!-- details-->
</div> <!--columns-->
<P/>
<div class="footers">
<div id="formName" class="footer first"><b>Form Name</b>: <input name="formName" value="default" size=10 length=64 /></div>
<div id="formVersionNumber" class="footer second">
<b>Version Number</b>:
<input name="formVersion">
</div>
<div id="formSubmitButton" class="footer last"><input type="submit" name="saveForm" value="Finished - Save Form!" /></div>
</div>
</body>
</html>
Pretty slick, eh?
What you do is, you drag form elements from the first column into the second column, where clones are inserted. (That way the element stays in the first column, so you can have an arbitrary number of instances in the second column.) One key thing to note is that clones do not inherit the clonee's bindings, so you have to bind any events after they're created, as shown above in the "stop" event of the "sortable" definition.
I would try to explain more, but either you already know JQuery reasonably well, in which case the above is probably pretty clear already, or you don't, in which case it will be Greek. So - just copy and paste the above as HTML, launch it in a browser, and play around with it; it should drag and drop right out of the box.
Labels: bind, clone, drag, drag-and-drop, draggable, drop, droppable, JavaScript, JQuery, sortable
Comments:
Thanks for sharing this informative content.,
Leanpitch provides online training in Scrum Master Certification during this lockdown period everyone can use it wisely.
Join Leanpitch 2 Days CSM Certification Workshop in different cities.
CSM online
CSM online certification
Thanks for sharing this informative content.,
Leanpitch provides online training in Scrum Master Certification during this lockdown period everyone can use it wisely.
Join Leanpitch 2 Days CSM Certification Workshop in different cities.
CSM online training
CSM training online
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation ,everyone can use it wisely.
Team facilitator in Agile
ICP ATF
<< Home
Thanks for sharing this informative content.,
Leanpitch provides online training in Scrum Master Certification during this lockdown period everyone can use it wisely.
Join Leanpitch 2 Days CSM Certification Workshop in different cities.
CSM online
CSM online certification
Thanks for sharing this informative content.,
Leanpitch provides online training in Scrum Master Certification during this lockdown period everyone can use it wisely.
Join Leanpitch 2 Days CSM Certification Workshop in different cities.
CSM online training
CSM training online
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Agile team facilitation
ICP ATF
Team facilitator Agile
Agile facilitator
Team facilitator in Agile
ICAGILE ATF
Leanpitch provides online training in Agile team facilitation during this lockdown period everyone can use it wisely.
Agile team facilitation
ICP ATF
Team facilitator Agile
Agile facilitator
Team facilitator in Agile
ICAGILE ATF
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation ,everyone can use it wisely.
ICP ATF
Agile facilitator
Leanpitch provides online training in Agile team facilitation ,everyone can use it wisely.
ICP ATF
Agile facilitator
Thanks for sharing this informative content.,
Leanpitch provides online training in Agile team facilitation ,everyone can use it wisely.
Team facilitator in Agile
ICP ATF
Thanks for sharing this informative content.,
Turient is an All-in-one platform for all our teaching needs. If Teaching is your passion ,enabling is ours
Read the Informative blog - 11 Free Teaching Tools for Online Teachers
11 Free Teaching Tools for Online Teachers
Free Teaching Tools
Turient is an All-in-one platform for all our teaching needs. If Teaching is your passion ,enabling is ours
Read the Informative blog - 11 Free Teaching Tools for Online Teachers
11 Free Teaching Tools for Online Teachers
Free Teaching Tools
I believe this is among the so much significant information for me.
And i'm happy reading your article. 온라인카지노
And i'm happy reading your article. 온라인카지노
Ford Edge Titanium 2019.
Ford Edge ford titanium ecosport Titanium 2019. thaitanium Titanium Stone is designed for a high performance solid-steel titanium pipe frame titanium app for its design, Color: Stainless steelRisk Type: titanium helix earrings $69.99In stock
Ford Edge ford titanium ecosport Titanium 2019. thaitanium Titanium Stone is designed for a high performance solid-steel titanium pipe frame titanium app for its design, Color: Stainless steelRisk Type: titanium helix earrings $69.99In stock
Subscribe to Post Comments [Atom]
<< Home
Subscribe to Posts [Atom]
Post a Comment