Link to home
Start Free TrialLog in
Avatar of BalbyCarr
BalbyCarr

asked on

Drag and Drop with Jquery

I am trying to make a drag and drop appointments system where by I can drag the students name from the list on the left into an appointment slot. I also need to be able to drag any students back out of the appointment time to the student list or move them to another time.

I have modified one of the jquery examples to show roughly how it should work, students can be moved out of the student list and the list automatically moves up so no gaps appear in the student list then the student can be put into the appointment list. The student can be moved up and down the times in the appointment list the only problem with this example is it slots the student in between the times not over the selected time.

I understand that it may involve draggable and droppable but have spent a lot of time playing around and googling and seem to be getting nowhere and this connected sortable looks the closest to make it easier to explain.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>

<style>
#appointments, #students {
	list-style-type: none;
	margin: 0;
	padding: 0;
	float: left;
	margin-right: 10px;
}
#appointments li, #students li {
	margin: 0 5px 5px 5px;
	padding: 5px;
	font-size: 1.2em;
	width: 120px;
	border: 1px solid #666;
}
#students li {
	background-color: #FFC;
}
</style>
    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

<script>
	$(document).ready(function() {
		
		$(function() {
			$( "#appointments, #students" ).sortable({
				connectWith: ".connectedSortable"
			}).disableSelection();
		});
	});
</script>

</head>

<body>

	


<div class="test">

<ul id="students" class="connectedSortable">
	<li class="ui-state-default">David</li>
	<li class="ui-state-default">Sarah</li>
	<li class="ui-state-default">Mary</li>
	<li class="ui-state-default">Ian</li>
</ul>

<ul id="appointments" class="connectedSortable">
	<li class="ui-state-highlight">9am</li>
	<li class="ui-state-highlight">10am</li>
	<li class="ui-state-highlight">11am</li>
	<li class="ui-state-highlight">12pm</li>
	<li class="ui-state-highlight">1pm</li>
</ul>

</div><!-- End test -->


</body>
</html>

Open in new window

Avatar of Shinesh Premrajan
Shinesh Premrajan
Flag of India image

You need to make the time id="appointments_9am" class="connectedSortable", since then the time section will get enabled for the draggable and droppable.

<ul id="appointments" class="connectedSortable">
      <li id="appointments_9am" class="ui-state-highlight">9am</li>

<script... >
                  $( "#appointments,#appointments_9am, #students" ).sortable({
                        connectWith: ".connectedSortable"
                  }).disableSelection();
</script>

Hope this helps
Avatar of BalbyCarr
BalbyCarr

ASKER

I've updated the code with your suggested changes but it seems to be just the same on the page.
what you are looking at is this

http://jqueryui.com/demos/droppable/revert.html

But whts been is implemented in the code is .sortable. It need to be .droppable() to enable the drop functionality

Hope this helps
I have been playing some more and her is what I have achieved?:

So far I can drag names and they revert to original position if not dropped on an appointment time which is what should happen.

If I drag a name to an appointment time it changes the time to the text of the name and removes name from name list. It also changes class of the appointment so that it is highlighted same colour as name, extra class is so that the cursor doesn't change.

Current problems:

Once one name has been dropped on appointment it breaks the revert, all other names no longer revert to original position if not dropped on an appointment.

I also need to make the appointments that have a name on them disabled so that another name cannot be dropped on top.

Current code included with this message.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>

<style>
#appointments, #students {
	list-style-type: none;
	margin: 0;
	padding: 0;
	float: left;
	margin-right: 10px;
}
#appointments li, #students li {
	margin: 0 5px 5px 5px;
	padding: 5px;
	font-size: 1.2em;
	width: 120px;
	border: 1px solid #666;
}
.student {
	background-color: #FFC;
	cursor: move;
}
.booked-appointment {
	background-color: #FFC;
}
</style>
    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

<script>
	$(document).ready(function() {
		
		$(function() {
			$( "#students li" ).draggable({
				revert: true
			})

			$( "#appointments li" ).droppable({
				drop: function(event, ui) {
					$(this)
						.text(ui.draggable.text())
						.addClass("booked-appointment");
					
					$(ui.draggable).remove();
				}
			})

		});
	});
</script>

</head>

<body>

	


<div class="container">

<ul id="appointments" class="connectedSortable">
	<li class="ui-state-default">9am</li>
	<li class="ui-state-default">10am</li>
	<li class="ui-state-default">11am</li>
	<li class="ui-state-default">12pm</li>
	<li class="ui-state-default">1pm</li>
</ul>

<ul id="students" class="connectedSortable">
	<li class="student">David</li>
	<li class="student">Sarah</li>
	<li class="student">Mary</li>
	<li class="student">Ian</li>
</ul>

</div><!-- End test -->


</body>
</html>

Open in new window

Hope this helps
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>

<style>
#appointments, #students {
	list-style-type: none;
	margin: 0;
	padding: 0;
	float: left;
	margin-right: 10px;
}
#appointments li, #students li {
	margin: 0 5px 5px 5px;
	padding: 5px;
	font-size: 1.2em;
	width: 120px;
	border: 1px solid #666;
}
.student {
	background-color: #FFC;
	cursor: move;
}
.booked-appointment {
	background-color: #FFC;
}
</style>
    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

<script>
	$(document).ready(function() {

		$(function() {
			$( "#students li" ).draggable({ revert:"valid" });			

			$( "#appointments li" ).droppable({
				drop: function(event, ui) {					
				$(this).append($(ui.draggable));
					//$(this).text(ui.draggable.text()).addClass("booked-appointment");					
					//$(ui.draggable).hide();
				}
			})

		});
	});
</script>

</head>

<body>

	


<div class="container">

<ul id="appointments" class="connectedSortable">
	<li class="ui-state-default">
		<div id="droppable" class="ui-widget-header"><p>9am</p></div>
	</li>
	<li class="ui-state-default">10am</li>
	<li class="ui-state-default">11am</li>
	<li class="ui-state-default">12pm</li>
	<li class="ui-state-default">1pm</li>
</ul>

<ul id="students" class="connectedSortable">
	<li class="student">David</li>
	<li class="student">Sarah</li>
	<li class="student">Mary</li>
	<li class="student">Ian</li>
</ul>

</div><!-- End test -->


</body>
</html>

Open in new window

That code does strange things on my machine. I can drag more than one name into appointment time then  can drag them out and as I drag them back in they revert to a random location.
ee1.png
Oh i think i posted a wrong copy.

Please give a try with this
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>

<style>
#appointments, #students {
	list-style-type: none;
	margin: 0;
	padding: 0;
	float: left;
	margin-right: 10px;
}
#appointments li, #students li {
	margin: 0 5px 5px 5px;
	padding: 5px;
	font-size: 1.2em;
	width: 120px;
	border: 1px solid #666;
}
.student {
	background-color: #FFC;
	cursor: move;
}
.booked-appointment {
	background-color: #FFC;
}
</style>
    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

<script>
	$(document).ready(function() {
		
		$(function() {
			$( "#students li" ).draggable({
				revert: true
			})

			$( "#appointments li" ).droppable({
				drop: function(event, ui) {
					$(this).text(ui.draggable.text()).addClass("booked-appointment");					
					$(this).droppable({disabled:true})
					$(ui.draggable).hide();
				}
			})

		});
	});
</script>

</head>

<body>

	


<div class="container">

<ul id="appointments" class="connectedSortable">
	<li class="ui-state-default">9am</li>
	<li class="ui-state-default">10am</li>
	<li class="ui-state-default">11am</li>
	<li class="ui-state-default">12pm</li>
	<li class="ui-state-default">1pm</li>
</ul>

<ul id="students" class="connectedSortable">
	<li class="student">David</li>
	<li class="student">Sarah</li>
	<li class="student">Mary</li>
	<li class="student">Ian</li>
</ul>

</div><!-- End test -->


</body>
</html>

Open in new window

Thats works better :-)

Now is it possible to drag a student back out of the appointment list (if an appointment was cancelled) or even just to be able to click a link next to the name to remove them from that appointment time and add them to the student list again?

Possible thought is not to replace the time with the name when the name is dragged across but to append the name to the time for example 9am  becomes 9am : Mary then when the link is clicked to remove appointment it reverts back to saying 9am and Mary appears in the student list again? not sure if this is the right thinking for this problem. Just need to be able to unbook appointment somehow.
Possibly somthing along the lines of the attached code.

Then when Cancel is clicked it reverts the appointment text back to the text that is before the : and adds the name back to the student list?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>

<style>
#appointments, #students {
	list-style-type: none;
	margin: 0;
	padding: 0;
	float: left;
	margin-right: 10px;
}
#appointments li, #students li {
	margin: 0 5px 5px 5px;
	padding: 5px;
	font-size: 1.2em;
	width: 160px;
	border: 1px solid #666;
}
.student {
	background-color: #FFC;
	cursor: move;
}
.booked-appointment {
	background-color: #FFC;
}
</style>
    
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>

<script>
	$(document).ready(function() {
		
		$(function() {
			$( "#students li" ).draggable({
				revert: true
			})

			$( "#appointments li" ).droppable({
				drop: function(event, ui) {
					$(this).append(' : ',ui.draggable.text(),' <a href="#">Cancel</a>').addClass("booked-appointment");					
					$(this).droppable({disabled:true})
					$(ui.draggable).hide();
				}
			})

		});
	});
</script>

</head>

<body>

	


<div class="container">

<ul id="appointments" class="connectedSortable">
	<li class="ui-state-default">9am</li>
	<li class="ui-state-default">10am</li>
	<li class="ui-state-default">11am</li>
	<li class="ui-state-default">12pm</li>
	<li class="ui-state-default">1pm</li>
</ul>

<ul id="students" class="connectedSortable">
	<li class="student">David</li>
	<li class="student">Sarah</li>
	<li class="student">Mary</li>
	<li class="student">Ian</li>
</ul>

</div><!-- End test -->


</body>
</html>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Shinesh Premrajan
Shinesh Premrajan
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The original question was how to drag names to appointments and to drag names back out of appointments so technically it is still an answer to the original question not a new one.

Answer is perfect though, does just what I need it to.

Many thanks for taking the time to help with this one.
I know its too late now cause I have closed question but for some reason sometimes when one name is cancelled it will cancel more than one and you end up with duplicates as per screenshot. Can't figure out why.
ee2.png
Thanks for the points,
The code is working perfectly for me in FF, Can u put out steps so possibly i can try replicate it
Tried to use screencast in EE but it wont save so have used Screencast.com

http://www.screencast.com/t/Fu5x40lgx

Shows it not working in Firefox, tried in IE, Firefox and Chrome all with same random result. No particular action to recreate, just add and remove and after about 12 actions it created duplicate as shown in video.
Maybe there is a pattern, just repeated screencast and got same result in different browsers, David is duplicated.