Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get children and id in jQuery Nestable plugin after drag and drop item and update in database?

I'm using jQuery Nestable plugin to create a menu editor for a website. I've tried to get item ID and Children after user clicks on menu items and change their position.

Issue: I don't know how to get ID and Children and update into database.

Here is jQuery Nestable plugin

<script>     $(document).ready(function () {         var updateOutput = function (e) {             var list = e.length ? e : $(e.target), output = list.data('output');             if (window.JSON) {output.val(window.JSON.stringify(list.nestable('serialize')));//, null, 2));             } else {                 output.val('JSON browser support required for this demo.');             }         console.log(list.nestable('serialize'));         console.log(window.JSON.stringify(list.nestable('serialize')));         };         $('#nestable').nestable({             group: 1,             maxDepth: 7,         }).on('change', updateOutput);         updateOutput($('#nestable').data('output', $('#nestable-output')));     }); </script> 

Here is HTML for menus

<div class="cf nestable-lists">     <div class="dd" id="nestable">         <ol class="dd-list">             <li class="dd-item" data-id="1"> <div class="dd-handle">Item 1 when parent == 0</div> </li>             <li class="dd-item" data-id="44"> <div class="dd-handle"> Item 2 when this parent_id == its id </div>                 <ol class="dd-list">                     <li class="dd-item" data-id="3"><div class="dd-handle">Item 3</div></li>                     <li class="dd-item" data-id="4"><div class="dd-handle">Item 3</div></li>                     <li class="dd-item" data-id="5"><div class="dd-handle">Item 3</div></li>                     <li class="dd-item" data-id="6"><div class="dd-handle">Item 3</div></li>                 </ol>             </li>         </ol>     </div> </div> 

The result on Console

[{"id":1},{"id":44,"children":[{"id":3},{"id":4},{"id":5},{"id":6}]}] 

Edition

In my structure I want to update menus when Parent_id == id where menus id and create level of menus item bu number of M_order. But I don't know to create this structure.

And here is var_dump($this->input->post('list'));

 1 =>      array (size=1)       'id' => string '2' (length=1)   2 =>      array (size=1)       'id' => string '3' (length=1)   3 =>      array (size=1)       'id' => string '4' (length=1)   4 =>      array (size=1)       'id' => string '5' (length=1)   5 =>      array (size=2)       'id' => string '6' (length=1)       'children' =>          array (size=1)           0 =>              array (size=2)               ... 

Here is images of my Table structure and menus

enter image description here

like image 857
DMS-KH Avatar asked Jul 21 '15 06:07

DMS-KH


1 Answers

To send the list to PHP, you have to change your updateOutput function to post the list via AJAX:

<script> $(document).ready(function () {     var updateOutput = function (e) {         var list = e.length ? e : $(e.target), output = list.data('output');          $.ajax({             method: "POST",             url: "saveList.php",             data: {                 list: list.nestable('serialize')             }         }).fail(function(jqXHR, textStatus, errorThrown){             alert("Unable to save new list order: " + errorThrown);         });     };      $('#nestable').nestable({         group: 1,         maxDepth: 7,     }).on('change', updateOutput); }); </script> 

In PHP, you will receive $_POST['list'], which will look as shown below. In this case, I dragged the 4th item (id 6) to the 2nd place (after id 3) on the list, so the expected order is 3, 6, 4, 5:

Array (     [0] => Array (         [id] => 1     )     [1] => Array (         [id] => 44         [children] => Array (             [0] => Array (                 [id] => 3             )             [1] => Array (                 [id] => 6             )             [2] => Array (                 [id] => 4             )             [3] => Array (                 [id] => 5             )         )     ) ) 

Then you can just iterate over this array and update your database accordingly.


Edit: In order to save the data in PHP, you'll have to use recursion to navigate all the children arrays that might exist. I wrote a simple script that will save on every ordering change:

index.php

<?php require "pdoConnection.php"; $list = getFullListFromDB($conn); ?>  <html> <head> <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> <script src="https://cdn.rawgit.com/dbushell/Nestable/master/jquery.nestable.js"></script> <script> $(document).ready(function () {     var updateOutput = function (e) {         var list = e.length ? e : $(e.target), output = list.data('output');          $.ajax({             method: "POST",             url: "saveList.php",             data: {                 list: list.nestable('serialize')             }         }).fail(function(jqXHR, textStatus, errorThrown){             alert("Unable to save new list order: " + errorThrown);         });     };      $('#nestable').nestable({         group: 1,         maxDepth: 7,     }).on('change', updateOutput); }); </script> </head>  <body> <div class="cf nestable-lists">     <div class="dd" id="nestable"> <?php displayList($list); ?>     </div> </div> </body> </html>  <?php function getFullListFromDB($conn, $parent_id = 0) {     $sql = "         SELECT id, parent_id, description         FROM items          WHERE parent_id = :parent_id         ORDER BY m_order     ";      $statement = $conn->prepare($sql);     $statement->bindValue(':parent_id', $parent_id, PDO::PARAM_INT);     $statement->execute();      $result = $statement->fetchAll(PDO::FETCH_ASSOC);      foreach($result as &$value) {         $subresult = getFullListFromDB($conn, $value["id"]);          if (count($subresult) > 0) {             $value['children'] = $subresult;         }     }     unset($value);      return $result; }  function displayList($list) { ?>     <ol class="dd-list">     <?php foreach($list as $item): ?>     <li class="dd-item" data-id="<?php echo $item["id"]; ?>"><div class="dd-handle"><?php echo $item["description"]; ?></div>     <?php if (array_key_exists("children", $item)): ?>     <?php displayList($item["children"]); ?>     <?php endif; ?>     </li>     <?php endforeach; ?>     </ol> <?php } ?> 

saveList.php

<?php  require "pdoConnection.php";  if ($_POST) {     saveList($conn, $_POST['list']);     exit; }  function saveList($conn, $list, $parent_id = 0, &$m_order = 0) {     foreach($list as $item) {         $m_order++;          $sql = "             UPDATE items             SET                  parent_id = :parent_id,                 m_order = :m_order             WHERE id = :id         ";         $statement = $conn->prepare($sql);         $statement->bindValue(":parent_id", $parent_id, PDO::PARAM_INT);         $statement->bindValue(":id", $item["id"], PDO::PARAM_INT);         $statement->bindValue(":m_order", $m_order, PDO::PARAM_INT);         $statement->execute();          if (array_key_exists("children", $item)) {             saveList($conn, $item["children"], $item["id"], $m_order);         }     } }  ?> 

pdoConnection.php

<?php $server = "myServer"; $database = "DbName"; $username = "myself"; $password = "secret"; $conn = new PDO("sqlsrv:Server=$server;Database=$database", $username, $password); ?> 

Table definition (MSSQL)

CREATE TABLE [items](     [id] [int] NOT NULL,     [parent_id] [int] NOT NULL,     [description] [nvarchar](100) NOT NULL,     [m_order] [int] NOT NULL,     CONSTRAINT [PK_items] PRIMARY KEY CLUSTERED ([id] ASC) ) ON [PRIMARY]  INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (1, 0, N'Item 1', 1) INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (2, 0, N'Item 2', 2) INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (3, 2, N'Item 3.1', 3) INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (4, 2, N'Item 3.2', 4) INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (5, 2, N'Item 3.3', 5) INSERT [items] ([id], [parent_id], [description], [m_order]) VALUES (6, 2, N'Item 3.4', 6) 
like image 59
Marcos Dimitrio Avatar answered Oct 05 '22 12:10

Marcos Dimitrio