I have the following specific problem:
I have a simple dashboard with 3 columns (left, middle, right). I have 3 separate divs which are inside these columns.
When user drag and drops a div in another column, it's position should be saved in database (with AJAX).
I had easily achieved this by saving the layout (the HTML after drag/drop) into the database.
Example:
<!-- left column -->
<div class="left column">
<!-- Div 1 -->
<div class="div1 portlet">
<div class="portlet-header">div1</div>
<div class="portlet-content">
<p> This is Div 1 </p>
</div>
</div>
</div>
<!--------------------------------------------------------------------->
<!-- middle column -->
<div class="middle column">
<!-- Div 2 -->
<div class="div2 portlet">
<div class="portlet-header">div2</div>
<div class="portlet-content">
<p> This is Div 2 </p>
</div>
</div>
</div>
<!--------------------------------------------------------------------->
<!-- right column -->
<div class="right column">
<!-- Div 3 -->
<div class="div3 portlet">
<div class="portlet-header">div3</div>
<div class="portlet-content">
<p> This is Div 3 </p>
</div>
</div>
</div>
This works great if you have static HTML elements (P elements in my case) inside the divs because when a user after dragging and dropping(which saves HTML to database) loads the data from database on the page, everything works great since it simply recreates the HTML elements.
But what if there is a piece of PHP code inside it? For example something like this:
<!-- right column -->
<div class="right column">
<!-- Div 3 -->
<div class="div3 portlet">
<div class="portlet-header">div3</div>
<div class="portlet-content">
<?php echo "This is div3"; ?>
</div>
</div>
</div>
When you try to save this to database, it is saved in database like this:
<!-- right column -->
<div class="right column">
<!-- Div 3 -->
<div class="div3 portlet">
<div class="portlet-header">div3</div>
<div class="portlet-content">
This is div3
</div>
</div>
</div>
Instead, I need to find out a way for it to remember it's PHP code content and not its output.
I have looked everywhere online but none of them covers my specific question.
Please see the example below and try drag/dropping the divs into other columns. (it works but does not save the positions yet obviously as that is my main question).
$(function () {
$(".column").sortable({
connectWith: ".column",
handle: ".portlet-header",
cancel: ".portlet-toggle",
placeholder: "portlet-placeholder ui-corner-all",
start: function (event, ui) {},
receive: function (event, ui) {
let screenLayout = $("body").html();
// Save to database
$.ajax({
type: 'POST',
url: 'saveLayout.php',
data: {
layout:screenLayout
},
success: function (data) {
console.info(data);
},
error: function (data) {
// failed request
console.error("Saving in database failed");
}
});
}
});
$(".column").droppable({
drop: function (e, ui) {
var dropped = ui.draggable;
var droppedOn = $(this);
$(this).append(dropped.clone().removeAttr('style').removeClass("item-container").addClass("item"));
dropped.remove();
}
})
$(".portlet")
.addClass("ui-widget ui-widget-content ui-helper-clearfix ui-corner-all")
.find(".portlet-header")
.addClass("ui-widget-header ui-corner-all")
.prepend("<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>");
/* Open/close boxes */
$(".portlet-toggle").on("click", function () {
var icon = $(this);
icon.toggleClass("ui-icon-minusthick ui-icon-plusthick");
icon.closest(".portlet").find(".portlet-content").toggle();
});
});
body {
min-width: 520px;
}
.column {
width: auto;
min-width: 33.33%;
max-width: 33.33%;
padding-bottom: 100px;
float: left;
text-align: center;
}
.portlet {
margin: 0 1em 1em 0;
padding: 0.3em;
background:#f5f5f5;
}
.portlet img{
width:75%;
}
.portlet-header {
padding: 0.5em 0.3em;
margin-bottom: 0.5em;
position: relative;
font-size: 0.75em;
cursor:grab;
}
.ui-widget-header:hover{
background:#d6d6d6;
}
.portlet-toggle {
position: absolute;
top: 50%;
margin-top: -8px;
cursor: pointer;
right: 5px;
}
.portlet-content {
padding: 0.4em;
}
.portlet-placeholder {
background:rgb(233, 233, 233);
border: 2px dashed #c5c5c5;
margin: 0 1em 1em 0;
height: 50px;
}
.on,
.off{
color: #FFF;
padding: 10px;
text-decoration: none;
font-weight:bold;
}
.on{
background: green;
}
.off{
background: rgb(240, 56, 0);
}
table {
border: 1px solid #ccc;
border-collapse: collapse;
margin: 0;
padding: 0;
width:100%;
table-layout: fixed;
}
table caption {
font-size: 1.5em;
margin: .5em 0 .75em;
}
table tr {
background-color: #f8f8f8;
border: 1px solid #ddd;
padding: .35em;
}
table th,
table td {
padding: .25em;
text-align: center;
}
table th {
font-size: .85em;
letter-spacing: .1em;
text-transform: uppercase;
}
@media screen and (max-width: 600px) {
table {
border: 0;
}
table caption {
font-size: 1.3em;
}
table thead {
border: none;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
table tr {
border-bottom: 3px solid #ddd;
display: block;
margin-bottom: .625em;
}
table td {
border-bottom: 1px solid #ddd;
display: block;
font-size: .8em;
text-align: right;
}
table td::before {
/*
aria-label has no advantage, it won't be read inside a table
content: attr(aria-label);
*/
content: attr(data-label);
float: left;
font-weight: bold;
text-transform: uppercase;
}
table td:last-child {
border-bottom: 0;
}
}
.left{
background:rgb(171, 171, 243);
}
.middle{
background: rgb(241, 159, 159);
}
.right{
background: rgb(168, 236, 168);
}
.portlet{
width: 95%;
}
/* @media screen and (max-width: 600px) {
.column {
width: auto;
min-width: 95%;
max-width: 95%;
padding-bottom: 100px;
text-align: center;
float: left;
position: relative;
left: 15px;
}
}
*/
<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Draggable Dashboard</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="script.js"></script>
</head>
<body>
<h1 style="text-align:center;color:#5d5d5d">Dashboard</h1>
<br>
<br>
<!--------------------------------------------------------------------->
<!-- left column -->
<div class="left column">
<!-- Div 1 -->
<div class="div1 portlet">
<div class="portlet-header">div1</div>
<div class="portlet-content">
<p> This is Div 1 </p>
</div>
</div>
</div>
<!--------------------------------------------------------------------->
<!-- middle column -->
<div class="middle column">
<!-- Div 2 -->
<div class="div2 portlet">
<div class="portlet-header">div2</div>
<div class="portlet-content">
<p> This is Div 2 </p>
</div>
</div>
</div>
<!--------------------------------------------------------------------->
<!-- right column -->
<div class="right column">
<!-- Div 3 -->
<div class="div3 portlet">
<div class="portlet-header">div3</div>
<div class="portlet-content">
<p> This is Div 3 </p>
</div>
</div>
</div>
<!--------------------------------------------------------------------->
</body>
</html>