天天看点

如何使用jQuery UI的sortable组件做一个更为友好的界面(中)

Realize the Two-way Drag & Drop Lists

Set up Basic Program

Now it's time to do it in action. Let's create the two-way drag-&-drop lists firstly, since it seems more easy.

We setup the basic HTML and CSS, which is the flesh of the program:

<!DOCTYPE html>

<html >

<head>

	<meta charset="utf-8">

	<title>Assign Scheduler to Panel - Scheduler lists</title>

	<link rel="stylesheet" href="script/css/custom-theme/jquery-ui-1.8.18.custom.css" target="_blank" rel="external nofollow" >

	<script src="script/js/jquery-1.6.2.min.js"></script>

	<script src="script/js/jquery-ui-1.8.21.custom.min.js"></script>

	<style>

		#scheduler-list-container {

			width: 360px; 
			height: 780px; 
			border: 1px solid crimson; 
			float: right;

		}

		#scheduler-list {

			width: 260px; 
			min-height: 280px; 
			padding-left: 0px;
			border: 1px solid lime; 

		}
		
		.scheduler-list-item {

			width: 200px; 
			height: 26px; 
			border: 1px solid #DDD;
			background-color: #FBFBFB;
			background-image: url('images/scheduler-icon.png');
			background-repeat: no-repeat;
			background-position: top left;
			margin-top: 5px;
			padding: 4px;
			list-style-type: none;

		}

		.scheduler-list-item label {

			margin-left: 26px;
			font-size: 0.8em;

		}

		.hightlight-target-background{

			background-color: rgb(255, 228, 122);

		}


		#panel-scheduler-container {

			width: 228px; 
			min-height: 80px; 
			border: 1px solid mediumvioletred; 
			float: left;

		}

		#panel-schedulers {

			width: 220px; 
			min-height: 60px; 
			border: 2px solid hotpink; 
			padding-left: 0px;

		}

	</style>

</head>

<body>


	<div id="scheduler-list-container">

		<label id="title">schedulers</label>

		<ul id="scheduler-list"> 

			<li id="schdl_1" class="scheduler-list-item"><label>how could a</label></li> 
			<li id="schdl_2" class="scheduler-list-item"><label>scheduler-02</label></li> 
			<li id="schdl_3" class="scheduler-list-item"><label>scheduler-03</label></li> 
			<li id="schdl_4" class="scheduler-list-item"><label>scheduler-04</label></li> 

		</ul>

	</div>


	<form action="" method="post" id="form-panel-schdl">

		<div id="panel-scheduler-container">

			<label>panel-01</label>

			<ul id="panel-schedulers">
			</ul>

		</div>

		<input type="submit" value="submit"/>

	</form>


	<script>

	$(function() {

		$( "#scheduler-list" ).sortable({

			connectWith: "#panel-schedulers",

		}).disableSelection();

		$( "#panel-schedulers" ).sortable({

			connectWith: "#scheduler-list",

		}).disableSelection();

	});

	</script>


</body>

</html>
           

For easy debug, I draw the border of all the container elements, to highlight their areas. And even contains nothing, we still want the container is visible to user, so we set the minimal height of them. 

如何使用jQuery UI的sortable组件做一个更为友好的界面(中)

Pass the Data to Server

And now let's explore how to send the data to server. According to the official online docs, Sortable offers two methods to collect the data of the list, before sending them: serialize and toArray. Both of them can combine all the list ids within one single string.

Let's try them, first of all, add one hidden input tag to the form:

<input type="hidden" name="panel-schedule" id="panel-schedule">
           

And before submission of the form, assign the string generated by Sortable method to this hidden input. So add lines to javascript block:

$("#form-panel-schdl").submit(

	function(e)

	{

		var $o = $("#panel-schedulers").sortable('serialize');

		//var $o = $("#panel-schedulers").sortable('toArray').toString();

		$("#panel-schedule").val($o);

		return true;

	}

);
           

Let's send the data created by both methods to the server, and see what it gets. Now we need a PHP script:

<?php
$panel_schedule = $_REQUEST['panel-schedule'];
print $panel_schedule;
exit;
?>
           

And assign this file to the action attribute of the form.

Below is the state of page before submitting:

如何使用jQuery UI的sortable组件做一个更为友好的界面(中)

For case of serialize, server gets:

schdl[]=2&schdl[]=1&schdl[]=4
           

For case of toArray:

schdl_2,schdl_1,schdl_4
           

Actually, for both cases, we need to split up the string into array to extract the id of the schedulers, we do the same much effort in both cases. But for further compatibility, we should apply the first approach, since it can be sent to the server directly when using get method.

And now, finish the PHP script for the serialize case:

<?php

$panel_schedule = (isset($_REQUEST['panel-schedule']) ? trim($_REQUEST['panel-schedule']) : '');

$schdl_ids = explode("&", $panel_schedule);

$ids = array();

foreach($schdl_ids as $ps)
{
	$xxx = explode("=", $ps);
	
	$ids[] = $xxx[1];
}

print_r($ids);

exit;
?>
           

Improve the User Experience

In practice, the design of a pure color border is not always reasonable, however, on most occasions, we need a design with no border, so the user might not be able to realize the areas exactly where he can drop the items. jQuery provides an event for that purpose, Sortable will receive 'activate' event when an acceptable item is being dragged, and 'deactivate' when the dragging is finished. Now, what we want to do is changing the background color of the panel list when the scheduler item is being dragged. But let's take a look at how the events of activation works. Change the Javascript code to:

$( "#scheduler-list" ).sortable({

	connectWith: "#panel-schedulers",

	activate: function(event, ui){

		console.log('act by schd');
		
	},

	deactivate: function(event, ui){

		console.log('deact by schd');

	}

}).disableSelection();


$( "#panel-schedulers" ).sortable({

	connectWith: "#scheduler-list",

	activate: function(event, ui){

		console.log('act by panel');

	},

	deactivate: function(event, ui){

		console.log('deact by panel');

	}

}).disableSelection();
           

Then drag the item:

如何使用jQuery UI的sortable组件做一个更为友好的界面(中)

And drop it in half-way:

如何使用jQuery UI的sortable组件做一个更为友好的界面(中)

From the console, we can figure out that the panel receive the event prior to the scheduler. But we only need to change the background color of panel, which is receiving container. We just use toggleClass() provided by jQuery.

Add the new CSS rule:

.hightlight-target-background{

	background-color: rgb(255, 228, 122);

}
           

Then change the Javascript code to:

$( "#scheduler-list" ).sortable({

	connectWith: "#panel-schedulers"

}).disableSelection();



$( "#panel-schedulers" ).sortable({

	connectWith: "#scheduler-list",

	activate: function(event, ui){

		$(this).toggleClass('hightlight-target-background');

	},

	deactivate: function(event, ui){

		$(this).toggleClass('hightlight-target-background');

	}

}).disableSelection();
           

You already see the result in the above pictures.