Resultaat drag and drop opslaan in database

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

George van Baasbank

George van Baasbank

13/02/2015 13:53:11
Quote Anchor link
Hallo allemaal,

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)
PHP script in nieuw venster Selecteer het PHP script
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
<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
Gewijzigd op 13/02/2015 13:58:39 door George van Baasbank
 
PHP hulp

PHP hulp

26/11/2020 21:55:56
 
Thomas van den Heuvel

Thomas van den Heuvel

13/02/2015 15:16:20
Quote Anchor link
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
 
George van Baasbank

George van Baasbank

14/02/2015 13:31:23
Quote Anchor link
Ik heb de code iets aangepast op suggestie van Thomas. Maar hoe lees ik nu de inhoud uit mijn "ontvangende" <div>? Middels een $_POST ??

Nieuwe code:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>

?>



George
Gewijzigd op 14/02/2015 16:22:59 door George van Baasbank
 
Thomas van den Heuvel

Thomas van den Heuvel

14/02/2015 17:41:43
Quote Anchor link
De data die je wilt versturen hoeft niet eens in een formulier te staan. Je kunt de uiteindelijke "toestand" van je data via een AJAX-request (in jQuery) sturen naar een script die deze data verwerkt. En je kunt, zoals in het bovenstaande voorbeeld, een knop gebruiken om dit proces in gang te zetten.

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)
PHP script in nieuw venster Selecteer het PHP script
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
<?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>


Het POST-resultaat van het bovenstaande luidt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
Array
(
    [entries] => Array
        (
            [0] => 4
            [1] =>
            [2] => 2
            [3] => 3
            [4] =>
        )

)
 
George van Baasbank

George van Baasbank

15/02/2015 11:58:47
Quote Anchor link
Hey Thomas,
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
 
George van Baasbank

George van Baasbank

16/02/2015 19:52:46
Quote Anchor link
Thomas,

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.
 
Thomas van den Heuvel

Thomas van den Heuvel

16/02/2015 20:26:12
Quote Anchor link
Uit mijn PM:
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.


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).
 
George van Baasbank

George van Baasbank

16/02/2015 20:37:54
Quote Anchor link
Thomas,

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)
PHP script in nieuw venster Selecteer het PHP script
1
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++;
    }
}

?>



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)
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.