Někdy je zapotřebí ukládat pozici volně přesouvatelných prvků na stránce. Může se jednat například o boxy na nějakém větším administračním panelu, přičemž uživatelé si chtějí boxy rozmístit podle svého uvážení. Není problém nastavit box jako „draggable“ pomocí jQuery UI, ale jak uložit jeho pozici automaticky bezprostředně po přesunu?
Problém: Chci ukládat pozici myší přesunutého boxu ihned po přesunutí.
test.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<!doctype html> <html lang="cs"> <head> <meta charset="utf-8"> <title></title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> <script> $(document).ready(function() { $("#boxdraggable").draggable({ }) }); </script> </head> <body> <div id="boxdraggable" style="border: 1px solid black; padding:20px; width:150px; position:absolute; left:50px; top:200px; cursor:move;"> Uchopte tento box myší a přesuňte jej </div> </body> </html> |
Výše uvedený skript umožňuje objekt boxdraggable přesouvat, nicméně po obnovení okna (F5) je načtena výchozí pozice. Potřebujeme po každém přetažení myší uložit aktuální souřadnice a dále je nutné zařídit, aby se výchozí souřadnice načítaly z databáze.
Problém vyřešíme v těchto krocích:
- Vytvoříme databázi a tabulku s daty
- Nakonfigurujeme připojení k databázi
- Vytvoříme skript pro obsluhu ajaxu
- Doplníme výše uvedený odladěný html kód o php a jQuery
- Otestujeme (např. ve Firebug)
Databázi vytvořte nejlépe v phpmyadmin (nebo v admineru).
Každý řádek v tabulce info_box bude obsahovat jednoznačný identifikátor id (zajištěno pomocí PRIMARY KEY (‚id‘)), souřadnice [x,y] a v posledním sloupci obsah boxu (text).
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE TABLE IF NOT EXISTS `info_box` ( `id` mediumint(3) unsigned NOT NULL AUTO_INCREMENT, `x` smallint(2) unsigned NOT NULL DEFAULT '0', `y` smallint(2) unsigned NOT NULL DEFAULT '0', `text` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO `info_box` (`id`, `x`, `y`, `text`) VALUES (1, 64, 48, 'Uchopte tento box myší a přesuňte jej'), (2, 295, 91, 'Ukládá se pozice obou boxů'); |
Připojení k databázi můžete napsat například takto:
config.php
1 2 3 4 5 6 7 8 9 10 11 |
<?php $db_host = "localhost"; // url adresa databáze (většinou localhost) $db_name = "info_boxy"; // název používané databáze $db_user = "db_username"; // uživatelské jméno $db_pass = "db_password"; // heslo $dblink = mysqli_connect($db_host, $db_user, $db_pass) or die("Chyba připojení k db: " . mysqli_error()); mysqli_select_db($dblink, $db_name) or die("Chyba připojení k db: " . mysqli_error()); ?> |
V této ukázce budeme používat procedurální rozhraní. Chcete-li pracovat s objekty, lze samozřejmě využít i objektové rozhraní.
Ajax volání bude obsluhovat skript:
ajax-update-box-position.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php require_once('config.php'); $x = mysqli_real_escape_string($dblink, preg_replace('/[^\d\s]/', '', $_POST['x'])); $y = mysqli_real_escape_string($dblink, preg_replace('/[^\d\s]/', '', $_POST['y'])); $id = mysqli_real_escape_string($dblink, preg_replace('/[^\d\s]/', '', $_POST['id'])); if( $id ) { $sql = "UPDATE info_box SET x = '$x', y = '$y' WHERE id=$id"; $res = mysqli_query($dblink, $sql); if( $res ) { echo "success"; } } ?> |
Pro nás je klíčové, jaké jsou souřadnice bezprostředně po uvolnění tlačítka myši. Ke zjištění využijeme sledování události mouseup() a takto zjistíme souřadnice: $(this).position() .
Soubor test.html vylepšíme o php kód a jQuery a přejmenujeme na index.php. Změníme také název selektoru jednotlivých <div> boxů a sice z boxdraggable na box_1, kde číslo za podtržítkem bude identifikátor (shodný s id v tabulce info_box).
index.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 |
<?php require_once('config.php'); //načteme soubor s připojením k databázi ?><!doctype html> <html lang="cs"> <head> <meta charset="utf-8"> <title></title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script> </head> <body> <?php $res = mysqli_query($dblink, "SELECT * FROM info_box"); while ($row = mysqli_fetch_array($res)) { $id = $row ['id']; $x = $row['x']; $y = $row['y']; $text = $row['text']; echo '<div id="box_'.$id.'" style="border: 1px solid black; padding:20px; width:150px; position:absolute; left:'.$x.'px; top:'.$y.'px; cursor:move;"> '.$text.' </div>'; echo <script> $(document).ready(function() { $("#box_'.$id.'").draggable({ }).mouseup(function(){ var souradnice = $(this).position(); var box_data = { x: souradnice.left, y: souradnice.top, id:'.$id.' }; request = $.ajax({ url: "ajax-update-box-position.php", type: "post", data: box_data }); // success request.done(function (response, textStatus, jqXHR){ console.log("Uložení pozice proběhlo v pořádku!"); }); // error request.fail(function (jqXHR, textStatus, errorThrown){ console.error("Při zpracování požadavku došlo k chybě: " + textStatus, errorThrown ); }); }); }); </script> '; } ?> </body> </html> |
Po zjištění pole souřadnic z něj vezmeme levou a horní vzdálenost od kraje obrazovky. Obě hodnoty vložíme do pole box_data spolu s identifikátorem id a předáme k odeslání funkci ajax(). Požadavek bude odeslán na adresu url. Vytvořené pole předáme pomocí data. Jde v podstatě o předání zapouzdřených dat typu POST, což jsme určili pomocí parametru type.
V souboru pro obsluhu ajax volání pracujeme již přímo s $_POST[‚x‘], $_POST[‚y‘], $_POST[‚id‘], která pouze preventivně ošetříme. Předaná data se nemusí nijak „rozbalovat“.
Běh skriptu sledujte pomocí konzole. Ve Firefoxu to vypadá následovně:
Při úspěšném uložení souřadnic je volána funkce done(). Při neúspěšném fail().
Soubory ke stažení: ukladani-objektu-po-presunu-na-strance.zip