Resultaat drag and drop opslaan in database
Ik heb voor een klant een pagina ontwikkeld waar deze middels drag and drop gegevens kan verplaatsen. Kijk hiervoor op www.vanbaasbank.nl/test1.php .
Het gaat om het volgende:
Ik heb een repertoire-tabel waarin liedjes staan met een eigen id-nummer.
Deze worden ingelezen en getoond in een tabel
Nu kan de gebruiker zijn lidejes selecteren d.m.v. slepen en kan de gewenste volgorde aanbrengen en/of wijzigen.
Zodra de selectie compleet is en in de juiste volgorde staat moet e.e.a. in een andere tabel worden opgelsgen met de gewenste volgorde.
Hoe lees ik nu de "ontvangende" tabel uit om dit in een tabel vast te leggen?
Als ik kijk in de broncode zie ik dat er geen info staat in de ontvangende tabel.
Wie heeft voor mij een suggestie?
De code die ik gebruik:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<head>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<?php include "include/header.inc.php" ; ?>
<?php include "include/zoeken.inc.php" ; ?>
<?php include "include/hoofdmenu.inc.php" ; ?>
<div class="main-container" style="height: 800px;">
<div class="container1" style="height: 800px;">
<article class="box" id="home_featured21" style="height: 800px;">
<!-- Vanaf hier komt de content -->
<div class="album" style="height: 500px;">
<table>
<thead>
<th>Repertoire</th>
</thead>
<tbody>
<?php
$nTeller = 1 ;
while($row = mysqli_fetch_array($cResult)) {
$cDrag = "drag" . $nTeller;
?>
<tr>
<td >
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)">
<div id="<?php echo $cDrag ; ?>" draggable="true" ondragstart="drag(event)" style="width: 100%;"><?php echo $row['titel'] ; ?></div>
</div>
</td>
</tr>
<?php
$nTeller++;
}
?>
</tbody>
</table>
</div>
<div class="preview">
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
</div>
<!-- Tot hier komt de content -->
</article>
</div>
</div>
<?php include "include/footer.inc.php" ; ?>
</body>
George
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<?php include "include/header.inc.php" ; ?>
<?php include "include/zoeken.inc.php" ; ?>
<?php include "include/hoofdmenu.inc.php" ; ?>
<div class="main-container" style="height: 800px;">
<div class="container1" style="height: 800px;">
<article class="box" id="home_featured21" style="height: 800px;">
<!-- Vanaf hier komt de content -->
<div class="album" style="height: 500px;">
<table>
<thead>
<th>Repertoire</th>
</thead>
<tbody>
<?php
$nTeller = 1 ;
while($row = mysqli_fetch_array($cResult)) {
$cDrag = "drag" . $nTeller;
?>
<tr>
<td >
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)">
<div id="<?php echo $cDrag ; ?>" draggable="true" ondragstart="drag(event)" style="width: 100%;"><?php echo $row['titel'] ; ?></div>
</div>
</td>
</tr>
<?php
$nTeller++;
}
?>
</tbody>
</table>
</div>
<div class="preview">
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)" draggable="true" ondragstart="drag(event)"></div>
</div>
<!-- Tot hier komt de content -->
</article>
</div>
</div>
<?php include "include/footer.inc.php" ; ?>
</body>
George
Gewijzigd op 13/02/2015 13:58:39 door George van Baasbank
Quote:
Als ik kijk in de broncode zie ik dat er geen info staat in de ontvangende tabel.
Dat is vrij logisch omdat dat de broncode van het oorspronkelijke document is. Maar de "broncode" van de pagina in je browser is inmiddels wel veranderd. Deze HTML-elementen kun je inspecteren met een browsertool (zit meestal onder de functietoets F12).
Het verbaast mij enigszins dat je hier niet al gebruik van maakte (lijkt te maken) want dat helpt enorm bij de ontwikkeling van functionaliteit waarin jQuery zit.
Als je data ergens uit wilt halen is het ook handig als de data ook een beetje structuur heeft. Je zou in jouw geval gebruik kunnen maken van de id's van de draggable divs (drag1, drag2, etc.), ten minste, als deze id's de liedjes die je wilt opslaan voldoende identificeren.
Dan is er de "bak" waar je de "ballen" uit wilt vissen: je preview-div. Wellicht wil je, omdat deze "bak" deze toch een beetje een speciale betekenis heeft, ook voorzien van een id waaraan je kunt refereren.
Dan is het (slechts) een kwestie van het doorlopen van de posities van deze div, en kijken of daar een draggable element in zit.
Wat mij wel opviel is dat je meerdere liedjes op 1 positie kan zetten, is dat ook de bedoeling?
Gewijzigd op 13/02/2015 15:17:47 door Thomas van den Heuvel
Nieuwe code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
// in php-deel
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cX = $_POST['veld1'];
echo "Waarde: " . $cX;
}
?>
// in html-deel
<div class="preview">
<form action="test1.php" method="POST">
<table>
<tbody>
<?php
$nRegelmaker = 0;
while($nRegelmaker < 6) {
$cVeldnaam = 'veld' . ($nRegelmaker + 1);
echo "<tr><td><div id='div2' name='$cVeldnaam' ondrop='drop(event)' ondragover='allowDropevent)' draggable='true' ondragstart='drag(event)'></div></td></tr>";
$nRegelmaker++;
}
?>
</tbody>
</table>
<input type="submit" name="submit" value="Opslaan" />
</form>
</div>
?>
// in php-deel
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$cX = $_POST['veld1'];
echo "Waarde: " . $cX;
}
?>
// in html-deel
<div class="preview">
<form action="test1.php" method="POST">
<table>
<tbody>
<?php
$nRegelmaker = 0;
while($nRegelmaker < 6) {
$cVeldnaam = 'veld' . ($nRegelmaker + 1);
echo "<tr><td><div id='div2' name='$cVeldnaam' ondrop='drop(event)' ondragover='allowDropevent)' draggable='true' ondragstart='drag(event)'></div></td></tr>";
$nRegelmaker++;
}
?>
</tbody>
</table>
<input type="submit" name="submit" value="Opslaan" />
</form>
</div>
?>
George
Gewijzigd op 14/02/2015 16:22:59 door George van Baasbank
Ik zie trouwens niet helemaal hoe je in dit laatste voorbeeld het verband kunt leggen tussen een specifiek liedje, en een specifieke plaats (volgorde)? Waar is de "dropzone" voor deze draggable elementen?
Om niet te verzanden in een oeverloze discussie over alle verschillende mogelijke manieren om dit op te zetten geef ik een voorbeeld van de algemene aanpak. Ik laat het over als een oefening aan de lezer om dit voorbeeld vervolgens als zijn of haar speficieke situatie aan te passen. Als dit niet lukt... heb je meer oefening nodig :).
Het script spreekt redelijk voor zich en is voorzien van commentaar. De "dropzone" bevat 5 placeholders waar je liedjes kunt droppen. Ik ga er vanuit dat er maar 1 liedje per placeholder mag zijn. Hierbij heb ik mij enkel geconcentreerd op het selecteren, uitlezen en versturen van de dropzone-data omdat dit probleem volledig los behandeld kan worden van je dragdrop functionaliteit.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo '<pre>'.print_r($_POST, true).'</pre>';
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>div uitlezen</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
</head>
<body>
<div id="dropzone">
<div class="placeholder">
<div data-id="4">Liedje 4</div>
</div>
<div class="placeholder">
</div>
<div class="placeholder">
<div data-id="2">Liedje 2</div>
</div>
<div class="placeholder">
<div data-id="3">Liedje 3</div>
</div>
<div class="placeholder">
</div>
</div>
<button type="button" id="opslaan">opslaan</button>
<script type="text/javascript">
//<![CDATA[
$().ready(function() {
// indien er op de opslaan knop wordt gedrukt...
$('button#opslaan').click(function(e) {
var position = 0; // huidige te inspecteren positie
var entries = []; // accumulatie variabele met liedjes
// ... lees de placeholders uit om te kijken of hier iets in staat
$('div#dropzone').children('div.placeholder').each(function() {
// heeft het huidige element inhoud (dit wil zeggen dat er iets ingesleept is)
if ($(this).children().length > 0) {
// hierbij gaan we uit van 1 entry per placeholder
// je draggable functionaliteit zou dit af moeten (kunnen) dwingen
// lees het attribuut "data-id" uit van het eerste onderliggende argument
// en sla deze op in je entries-array
entries[position] = $(this).children().first().attr('data-id');
} else {
// anders sla een "leeg" element op
// houd voor het gemak alle waarden van hetzelfde type (string)
entries[position] = '';
}
position++;
});
// vervolgens posten we alles naar een script, in dit geval naar zichzelf
$.post('<?php echo $_SERVER['PHP_SELF'] ?>', {'entries': entries}, function() {
// en wat je na afloop (als terugkoppeling) nog wilt doen
});
});
});
//]]>
</script>
</body>
</html>
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
echo '<pre>'.print_r($_POST, true).'</pre>';
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>div uitlezen</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
</head>
<body>
<div id="dropzone">
<div class="placeholder">
<div data-id="4">Liedje 4</div>
</div>
<div class="placeholder">
</div>
<div class="placeholder">
<div data-id="2">Liedje 2</div>
</div>
<div class="placeholder">
<div data-id="3">Liedje 3</div>
</div>
<div class="placeholder">
</div>
</div>
<button type="button" id="opslaan">opslaan</button>
<script type="text/javascript">
//<![CDATA[
$().ready(function() {
// indien er op de opslaan knop wordt gedrukt...
$('button#opslaan').click(function(e) {
var position = 0; // huidige te inspecteren positie
var entries = []; // accumulatie variabele met liedjes
// ... lees de placeholders uit om te kijken of hier iets in staat
$('div#dropzone').children('div.placeholder').each(function() {
// heeft het huidige element inhoud (dit wil zeggen dat er iets ingesleept is)
if ($(this).children().length > 0) {
// hierbij gaan we uit van 1 entry per placeholder
// je draggable functionaliteit zou dit af moeten (kunnen) dwingen
// lees het attribuut "data-id" uit van het eerste onderliggende argument
// en sla deze op in je entries-array
entries[position] = $(this).children().first().attr('data-id');
} else {
// anders sla een "leeg" element op
// houd voor het gemak alle waarden van hetzelfde type (string)
entries[position] = '';
}
position++;
});
// vervolgens posten we alles naar een script, in dit geval naar zichzelf
$.post('<?php echo $_SERVER['PHP_SELF'] ?>', {'entries': entries}, function() {
// en wat je na afloop (als terugkoppeling) nog wilt doen
});
});
});
//]]>
</script>
</body>
</html>
Het POST-resultaat van het bovenstaande luidt:
Bedankt voor je hulp. Ik ga e.e.a. vandaag of morgen op mijn situatie uitproberen.
Bij hulp nodig hoor je nog van me.
George
Ik heb je PM doorgenomen en je aanbevelingen overgenomen.
1. Er wordt geen error meer gegenereerd
2. Error-melding staat op E_ALL
3. Mogelijke syntaxfout in div-element verwijderd
Helaas krijg ik op het scherm nog niet de inhoud van de array te zien.
Omdat ik niet weet welke inhoud ik een alert moet geven krijg ik nog niets te zien. Wel de alert op zich maar uiteraard geen inhoud.
Omdat jij aangeeft dat jouw versie wel werkt ga ik er van uit dat er ergens nog een foutje in moet zitten.
Volgens mij komt de POST niet aan.
Quote:
Je formulier wordt ook op de achtergrond gesubmit - je POST request wordt op de achtergrond uitgevoerd - in de huidige opzet navigeer je dus ook niet weg van deze pagina - wellicht zorgt dat ook voor verwarring?
Kijk, met jQuery maak je je pagina interactief - meestal ben je rechtstreeks je DOM (je HTML-broncode) aan het manipuleren zonder je pagina te verversen. Dit werkt dus totaal anders dan het traditionele "request response" schaakspel bij PHP.
Deze andere opzet vereist dus ook een andere aanpak waarbij je op een andere manier informatie tot je moet laten komen om iets te ontwikkelen / te debuggen.
Kijk, met jQuery maak je je pagina interactief - meestal ben je rechtstreeks je DOM (je HTML-broncode) aan het manipuleren zonder je pagina te verversen. Dit werkt dus totaal anders dan het traditionele "request response" schaakspel bij PHP.
Deze andere opzet vereist dus ook een andere aanpak waarbij je op een andere manier informatie tot je moet laten komen om iets te ontwikkelen / te debuggen.
Je kunt je POST request voorbij zien komen als je in je developer paneel (functietoets F12) in je netwerk-tab kijkt. In Internet Explorer moet je wel eerst op het "play" knopje drukken voordat je op je "opslaan" knop drukt.
Laat ik het anders vragen: wat wil je dat er gebeurt als je op de "opslaan" knop drukt? Wil je naar een aparte pagina navigeren waar de invoer wordt verwerkt of wil je dit op de zelfde pagina doen (zoals nu gebeurt, je POST wordt in de achtergrond verwerkt).
Wat wil ik doen:
Ik wil een tabel bijwerken waar het volgordenummer wordt opgeslagen en de data-id van de regel wordt opgeslagen.
Ik heb e.e.a. nu op de pagina zelf gedaan.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//echo '<pre>'.print_r($_POST, true).'</pre>';
//exit;
$aIndeling = $_POST;
$nIndeling = count($aIndeling) - 1;
$nAfteller = 0;
while($nAfteller < $nIndeling) {
$cRelatie = $aIndeling[$nAfteller];
$nPlaats = $nAfteller + 1;
$sql = "INSERT INTO test__selectie SET volgorde = '$nPlaats',relatie = '$cRelatie'";
$cResult = mysqli_query($verbinding,$sql);
$nAfteller++;
}
}
?>
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//echo '<pre>'.print_r($_POST, true).'</pre>';
//exit;
$aIndeling = $_POST;
$nIndeling = count($aIndeling) - 1;
$nAfteller = 0;
while($nAfteller < $nIndeling) {
$cRelatie = $aIndeling[$nAfteller];
$nPlaats = $nAfteller + 1;
$sql = "INSERT INTO test__selectie SET volgorde = '$nPlaats',relatie = '$cRelatie'";
$cResult = mysqli_query($verbinding,$sql);
$nAfteller++;
}
}
?>
Toevoeging op 16/02/2015 20:44:54:
Middels de F12-toets heb ik de POST voorbij zien komen. (Maar kan er zelf (nog) niets mee)