Click and Drop Sorting
These demos show a method of sorting and rearranging items on a page using a combination of PHP and Javascript. As a Javascript novice, it was a LOT easier than trying to code a drag and drop applicaton. The first version provides a way of rearranging a list of names, and the second is for sorting a group of images.
Files and Folders for Demo 1CENTER
index.php ▾
<?php
include ("inc/header.php");
echo "<h1>List of Names</h1>";
$string = file_get_contents ("list.txt");
$array1 = explode (",", $string);
echo "<div class = 'half-column'>";
foreach ($array1 as $item1) {
echo "<div class = 'list'>";
echo $item1 ;
echo "</div>";
}
echo "</div><div class = 'half-column'>";
echo "<a class = 'button' href = 'organize-list.php'>Click here to Sort</a>";
echo "</div>";
include ("inc/footer.php");
list.txt ▾
Tanster,Rosebud,Ralph,Boris,Izzy,Tuna,Miss Kitty
organize-list.php ▾
<?php
$string = file_get_contents ("list.txt");
$array1 = explode (",", $string);
$length = sizeof ($array1);
$limit = ($length * 2) + 1;
$listarray = array();
if ($_SERVER ["REQUEST_METHOD"] == "POST" ) {
if (isset($_POST['listarray'])) {
$listarray = $_POST['listarray'];
$listarray = array_filter ($listarray);
$newarray = array();
foreach ($listarray as $id => $item) {
$item = strip_tags ($item);
$newarray[$id] = $item;
}
$string = implode (",", $newarray);
file_put_contents ("list.txt", $string);
$array1 = $newarray;
$string = file_get_contents ("list.txt");
$array1 = explode (",", $string);
}
}
include ("inc/header.php");
?>
<h1>Organize Names</h1>
<div class = 'content-column'>
<form method = 'post' action = 'organize-list.php'>
<div id= 'slots'>
<?php
$id = 0;
//Show initial empty slot
echo "<div id = '" . $id . "' class = 'jssort1 pink ' onclick = 'clickOnList(id)'></div>";
echo "<input class = 'jssort4 hidden' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
$id = 1;
foreach ($array1 as $item) {
if ($id <= $limit) {
//Create a slot with a value from array1;
echo "<div id = '". $id . "' class = 'jssort1' onclick = 'clickOnList(id)'>" . $item;
echo "</div>";
//Create a checkbox for this slot
echo "<input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '" . $item . "' checked />" ;
$id++;
//Create an empty slot
echo "<div id = '" . $id . "' class = 'jssort1 pink ' onclick = 'clickOnList(id)'></div>";
//Create a checkbox for this slot
echo "<input class = 'jssort4 hidden' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
$id++;
}
}
?>
</div>
<br><br><input class = 'submitbutton' type = 'submit' name = 'update' value='Update List'/>
</form>
</div><div class = 'sidebar-column'>
<div id = 'saved-resources'></div>
<br><a class = 'button' href = 'index.php'>← Return</a>
Click on name to select
Click on pink bar to insert
</div>
<?php
include ("inc/footer.php");
?>
inc
footer.php ▾
<br><br><br>Copyright © <?php echo date('Y'); ?> Susan Rodgers, <a href = 'https://lilaavenue.com'>Lila Avenue</a><br><br>
</main>
<script src= 'inc/functions.js'></script>
</body>
</html>
functions.js ▾
function clickOnList(id) {
//Column 1 - Resources
var resourcearray = document.getElementsByClassName ('resource-blocks');
//Column2 All slots, filled and empty
var array1 = document.getElementsByClassName('jssort1');
//Column 2 - Innut form checkboxes
var array4 = document.getElementsByClassName('jssort4');
//Reset background in resources
for (i = 0; i < resourcearray.length ; i++) {
resourcearray[i].style.backgroundColor = '#fff';
}
//Reset background and color in list
var limit = array1.length;
//NON-EMPTY SLOT - item is saved and can be moved or deleted
if (array1[id].innerHTML !== "" ) {
//Item to be moved or deleted
var newvalue = array1[id].innerHTML;
var oldvalue = document.getElementById('saved-resources').innerHTML;
if (document.getElementById(id).style.backgroundColor === 'blue') {
document.getElementById(id).style.backgroundColor = '#eee';
newvalue = oldvalue.replace (newvalue, '');
}
else {
newvalue = oldvalue + ',' + newvalue;
document.getElementById(id).style.backgroundColor = 'blue';
}
document.getElementById('saved-resources').innerHTML = newvalue;
}
else {
//EMPTY SLOT - any previously saved resources and list items will be moved to slot
//Retrieve list of new resources
var savedResources = document.getElementById('saved-resources').innerHTML;
var savedResourcesArray = savedResources.split(',');
var savedlength = savedResourcesArray.length;
//delete items with blue background
for ( i = 0; i < limit ; i++) {
if (array1[i].style.backgroundColor === 'blue') {
//remove contents of slot
array1[i].innerHTML = "";
array4[i].value = "";
}
}
//create array of non-empty slots
var updatedarray = new Array();
for (i = 0; i < limit ; i++) {
if (i == id) {
for (j = 0; j < savedlength; j++){
//insert saved resources into updated array
if (savedResourcesArray[j] !== ""){
updatedarray.push (savedResourcesArray[j]);
}
}
}
else if (array1[i].innerHTML !== '') {
updatedarray.push (array1[i].innerHTML);
}
}
//show updated resource list on page
document.getElementById('slots').innerHTML = "<div id = '0' class = 'jssort1 pink' onclick = 'clickOnList(id)'></div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
var id = 1;
for (i = 0; i < updatedarray.length ; i++) {
if (updatedarray[i] !== "" && updatedarray[i] !== ','){
//Filled slot
document.getElementById('slots').innerHTML +=
"<div id = '" + id + "' class = 'jssort1' onclick = 'clickOnList(id)'>" + updatedarray[i] + "</div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '" + updatedarray[i] + "' checked />";
id++;
//empty slot
document.getElementById('slots').innerHTML +=
"<div id = '" + id + "' class = 'jssort1 pink' onclick = 'clickOnList(id)'></div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
id++;
}
}
//Return saved resources list to empty
document.getElementById('saved-resources').innerHTML = "";
}
}
function chooseToDelete() {
//Array1 - all itmes inlist, empty and filled
var array1 = document.getElementsByClassName('jssort1');
//array4 - Input form checkboxes
var array4 = document.getElementsByClassName('jssort4');
//Remove item with blue background
var limit = array1.length;
for (var i = 0; i < limit ; i++) {
if (array1[i].style.backgroundColor === 'blue') {
//remove contents of slot
array1[i].innerHTML = "";
array4[i].value = "";
array1[i].style.backgroundColor = '#eac0c7';
}
}
//remove item from saved resources.
document.getElementById('saved-resources').innerHTML = '';
}
header.php ▾
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Click and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Elsie" rel="stylesheet">
<link rel= 'stylesheet' type='text/css' href= 'inc/style.css'>
</head>
<body>
<main>
<a class = 'return' href = '../../projects'>← Return</a> <br>
style.css ▾
body {
font-family: "Arial", sans-serif;
text-align: center;
margin: 0 auto;
background-color: #434460;
line-height: 140%;
}
h1, h2 {
letter-spacing: 1px;
}
main {
text-align: center;
background-color: white;
width: 900px;
max-width: 100%;
display: block;
margin: 20px auto;
}
.jssort1, #open-slot {
display: block;
padding: 5px;
border: 1px solid #bbb;
margin: 5px auto;
max-width: 100%;
font-size: .9em;
cursor: pointer;
background-color: #eee;
width: 160px;
}
.pink {
background-color: pink;
}
.hidden {
display:none;
}
.select-image {
cursor: pointer;
}
.content-column, .sidebar-column {
display: inline-block;
padding: 20px;
box-sizing: border-box;
vertical-align: top;
text-align: center;
max-width: 100%;
}
.content-column {
width: 75%;
}
.sidebar-column {
width: 25%;
}
a.button:hover {
color: purple;
}
input {
background-color: darkmagenta;
color: white;
padding: 10px;
border: 1px solid purple;
border-radius: 4px;
font-size: 1em;
font-weight: bold;
width: 120px;
}
.button {
width: 120px;
background-color: #37376f;
border: 1px solid black;
border-radius: 4px;
padding: 10px;
margin: 20px auto;
text-decoration: none;
display: block;
}
a.button {
color: white;
font-weight: bold;
font-size: 1em;
font-weight: bold;
}
#saved-resources {
display: none;
}
.list {
padding: 10px;
background-color: #ddd;
margin: 5px auto;
display: block;
width: 160px;
}
@media only screen and (max-width: 550px) {
.half-column {
width: 100%;
}
}
Files and Folders for Demo 2
index.php ▾
<?php
//Copyright (c) 2021, Susan V. Rodgers, Lila Avenue, LLC, lilaavenue@gmail.com
include ("inc/header.php");
echo "<h1>Gallery</h1>";
$string = file_get_contents ("data/list.txt");
$array1 = explode (",", $string);
foreach ($array1 as $item1) {
$name = $image = "";
if (file_exists ("data/cats/" . $item1 . ".txt")) {
$string2 = file_get_contents ("data/cats/" . $item1 . ".txt");
$array2 = explode ("%%%", $string2);
if (array_key_exists (0, $array2)) {
$name = $array2[0];
}
if (array_key_exists (1, $array2) ) {
$image = $array2[1];
}
}
echo "<div class = 'gridcolumn'>";
echo "<img src = '" . $image . "' alt = '" . $name . "' width= '80' /><br>";
echo ucwords (str_replace ("-", " ", $item1)) ;
echo "</div>";
}
echo "<br><br><a class = 'button' href = 'organize-list.php'>Click here to Sort</a>";
include ("inc/footer.php");
?>
organize-list.php ▾
<?php
//Copyright (c) 2021, Susan V. Rodgers, Lila Avenue, LLC, lilaavenue@gmail.com
$string = file_get_contents ("data/list.txt");
$array1 = explode (",", $string);
$length = sizeof ($array1);
$limit = ($length * 2) + 1;
$listarray = array();
if ($_SERVER ["REQUEST_METHOD"] == "POST" ) {
if (isset($_POST['listarray'])) {
$listarray = $_POST['listarray'];
$listarray = array_filter ($listarray);
$newarray1 = array();
foreach ($listarray as $id => $item) {
$item = strip_tags ($item);
$newarray[$id] = $item;
}
$string = implode (",", $newarray);
file_put_contents ("data/list.txt", $string);
$array1 = $newarray;
}
}
include ("inc/header.php");
?>
<br>
<h1>Organize Images</h1>
<div class = 'content-column'>
<form method = 'post' action = 'organize-list.php'>
<div id= 'slots'>
<?php
$id = 0;
//Show initial empty slot
echo "<div id = '" . $id . "' class = 'jssort1 pink ' onclick = 'clickOnList(id)'></div>";
echo "<input class = 'jssort4 hidden' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
$id = 1;
foreach ($array1 as $item) {
if ($id < $limit) {
$string2 = $image = $name = "";
if (file_exists ('data/cats/' . $item . ".txt")) {
$string2 = file_get_contents ("data/cats/" . $item . ".txt");
}
$array2 = explode ("%%%", $string2);
if (array_key_exists (0, $array2)) {
$name = $array2[0];
}
if (array_key_exists (1, $array2) ) {
$image = $array2[1];
}
//Create a slot with a value from array1;
echo "<div id = '". $id . "' class = 'jssort1' onclick = 'clickOnList(id)'>" . $item;
echo "<img src = '" . $image . "' alt = '" . $name . "' width= '80' /><br>";
echo "</div>";
//Create a checkbox for this slot
echo "<input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '" . $item . "' checked />" ;
$id++;
//Create an empty slot
echo "<div id = '" . $id . "' class = 'jssort1 pink ' onclick = 'clickOnList(id)'></div>";
//Create a checkbox for this slot
echo "<input class = 'jssort4 hidden' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
$id++;
}
}
?>
</div>
<br><br><input type = 'submit' name = 'update' value='Update List'/>
</form>
</div><div class = 'sidebar-column'>
<div class = 'hidden'>
<div id = 'saved-resources'></div>
</div>
<a class = 'button' href = 'index.php'>← Return </a><br>
Click an image to select<br>
Click on pink bar to insert
</div>
<?php
include ("inc/footer.php");
?>
inc
footer.php ▾
<br><br><br>Copyright © <?php echo date('Y'); ?> Susan Rodgers, <a href = 'https://lilaavenue.com'>Lila Avenue</a><br><br>
<script src= 'inc/functions.js'></script>
</main>
</body>
</html>
functions.js ▾
function clickOnList(id) {
//Column 1 - Resources
var resourcearray = document.getElementsByClassName ('resource-blocks');
//Column2 All slots, filled and empty
var array1 = document.getElementsByClassName('jssort1');
//Column 2 - Innut form checkboxes
var array4 = document.getElementsByClassName('jssort4');
//Reset background in resources
for (i = 0; i < resourcearray.length ; i++) {
resourcearray[i].style.backgroundColor = '#fff';
}
//Reset background and color in list
var limit = array1.length;
//NON-EMPTY SLOT - item is saved and can be moved or deleted
if (array1[id].innerHTML !== "" ) {
//Item to be moved or deleted
var newvalue = array1[id].innerHTML;
var oldvalue = document.getElementById('saved-resources').innerHTML;
if (document.getElementById(id).style.backgroundColor === 'blue') {
document.getElementById(id).style.backgroundColor = '#eee';
newvalue = oldvalue.replace (newvalue, '');
}
else {
newvalue = oldvalue + ',' + newvalue;
document.getElementById(id).style.backgroundColor = 'blue';
}
document.getElementById('saved-resources').innerHTML = newvalue;
}
else {
//EMPTY SLOT - any previously saved resources and list items will be moved to slot
//Retrieve list of new resources
var savedResources = document.getElementById('saved-resources').innerHTML;
var savedResourcesArray = savedResources.split(',');
var savedlength = savedResourcesArray.length;
//delete items with blue background
for ( i = 0; i < limit ; i++) {
if (array1[i].style.backgroundColor === 'blue') {
//remove contents of slot
array1[i].innerHTML = "";
array4[i].value = "";
}
}
//create array of non-empty slots
var updatedarray = new Array();
for (i = 0; i < limit ; i++) {
if (i == id) {
for (j = 0; j < savedlength; j++){
//insert saved resources into updated array
if (savedResourcesArray[j] !== ""){
updatedarray.push (savedResourcesArray[j]);
}
}
}
else if (array1[i].innerHTML !== '') {
updatedarray.push (array1[i].innerHTML);
}
}
//show updated resource list on page
document.getElementById('slots').innerHTML = "<div id = '0' class = 'jssort1 pink' onclick = 'clickOnList(id)'></div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
var id = 1;
for (i = 0; i < updatedarray.length ; i++) {
if (updatedarray[i] !== "" && updatedarray[i] !== ','){
//Filled slot
document.getElementById('slots').innerHTML +=
"<div id = '" + id + "' class = 'jssort1' onclick = 'clickOnList(id)'>" + updatedarray[i] + "</div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '" + updatedarray[i] + "' checked />";
id++;
//empty slot
document.getElementById('slots').innerHTML +=
"<div id = '" + id + "' class = 'jssort1 pink' onclick = 'clickOnList(id)'></div><input class = 'jssort4 hidden ' type = 'checkbox' name = 'listarray[]' value = '' checked />" ;
id++;
}
}
//Return saved resources list to empty
document.getElementById('saved-resources').innerHTML = "";
}
}
function chooseToDelete() {
//Array1 - all itmes inlist, empty and filled
var array1 = document.getElementsByClassName('jssort1');
//array4 - Input form checkboxes
var array4 = document.getElementsByClassName('jssort4');
//Remove item with blue background
var limit = array1.length;
for (var i = 0; i < limit ; i++) {
if (array1[i].style.backgroundColor === 'blue') {
//remove contents of slot
array1[i].innerHTML = "";
array4[i].value = "";
array1[i].style.backgroundColor = '#eac0c7';
}
}
//remove item from saved resources.
document.getElementById('saved-resources').innerHTML = '';
}
header.php ▾
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Click and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Elsie" rel="stylesheet">
<link rel= 'stylesheet' type='text/css' href= 'inc/style.css'>
</head>
<body>
<main>
<a class = 'return' href = '../../projects'>← Return</a> <br>
style.css ▾
body {
font-family: "Arial", sans-serif;
text-align: center;
margin: 0 auto;
background-color: #434460;
line-height: 170%;
}
h1, h2 {
letter-spacing: 1px;
line-height: 140%;
}
main {
text-align: center;
background-color: white;
width: 900px;
max-width: 100%;
display: block;
margin: 20px auto;
padding: 20px;
box-sizing: border-box;
}
.content-column, .sidebar-column {
display: inline-block;
width: 50%;
padding: 20px;
box-sizing: border-box;
vertical-align: top;
}
.content-column {
width: 75%;
}
.sidebar-column {
width: 25%;
}
a.button:hover {
color: purple;
}
.jssort1, #open-slot {
display: inline-block;
padding: 5px;
border: 1px solid #bbb;
margin: 3px 5px;
max-width: 100%;
font-size: .9em;
cursor: pointer;
background-color: #eee;
height: 120px;
vertical-align: top;
}
.jssort1 img {
max-height: 80px;
}
.pink {
background-color: pink;
}
.hidden {
display:none;
}
.select-image {
cursor: pointer;
}
input {
background-color: darkmagenta;
color: white;
padding: 10px;
border: 1px solid purple;
border-radius: 4px;
font-size: 1em;
font-weight: bold;
width: 120px;
}
.button {
width: 120px;
background-color: #37376f;
border: 1px solid black;
border-radius: 4px;
padding: 10px;
margin: 10px auto;
text-decoration: none;
display: block;
}
a.button {
color: white;
font-weight: bold;
font-size: 1em;
font-weight: bold;
}
.gridcolumn {
display: inline-block;
box-sizing: border-box;
vertical-align: top;
padding: 10px 5px 5px 5px;
background-color: #ddd;
margin: 5px;
width: 140px;
height: 160px;
max-width: 100%;
}
#saved-resources {
display: none;
}
@media only screen and (max-width: 550px) {
.half-column {
width: 100%;
}
}
data
list.txt ▾
tanster,rosebud,boris,tuna,miss-kitty,ralph