Editeur wysiwyg minimal & mise à jour BDD par ajax en focusout
Posté : 12 sept. 2019, 14:12
Bonjour à tous,
Je travaille actuellement sur un petit éditeur de texte en wysiwyg, avec une mise en forme minimale (juste gras, italique, liste à puce et lien hypertexte). Le texte se trouve dans un div en contenteditable=true, et la mise à jour dans la base de données se fait grâce à une requête en Ajax.
Voici les différents scripts (je vous épargne le CSS) :
La page sur laquelle se trouvent les champs à éditer :
Fichier ajax.editlive.js (inclus dans <head></head>) :
FICHIER _editlive.php (mise à jour de la base de données) :
Voilà pour le code : tout fonctionne à merveille, la mise en forme en wysiwyg se passe bien, l'exécution du script en Ajax aussi, la base de données se met à jour lorsque je sors le focus du champ éditable. Le problème c'est pour faire disparaître la toolbar après édition : j'ai essayé de placer le code $('#toolbar').css('display', 'none'); à divers endroits, mais ce n'est pas satisfaisant.
Quand je mets le $('#toolbar').css('display', 'none'); avant ou après le "return true;" du script ajax, ça fonctionne mais la toolbar disparaît même si on a encore du texte à éditer (évidemment, puisqu'en cliquant dans la toolbar, on perd le focus et ça exécute le script). L'idée serait donc de faire exécuter le script du focusout SAUF si on clique sur un élément de la toolbar ou son conteneur parent.
Est-ce possible ? Merci pour votre aide !
Je travaille actuellement sur un petit éditeur de texte en wysiwyg, avec une mise en forme minimale (juste gras, italique, liste à puce et lien hypertexte). Le texte se trouve dans un div en contenteditable=true, et la mise à jour dans la base de données se fait grâce à une requête en Ajax.
Voici les différents scripts (je vous épargne le CSS) :
La page sur laquelle se trouvent les champs à éditer :
Code : Tout sélectionner
// Toolbar
echo "<div id='toolbar'>";
echo "<a href='#' data-command='undo'></a>";
echo "<a href='#' data-command='redo'></a>";
echo "<a href='#' data-command='bold'></a>";
echo "<a href='#' data-command='italic'></a>";
echo "<a href='#' data-command='insertUnorderedList'></a>";
echo "<a href='#' data-command='insertOrderedList'></a>";
echo "<a href='#' data-command='createLink'></a>";
echo "<a href='#' data-command='unlink'></a>";
echo "</div>";
// Contenu à éditer
echo "<article class='ARTICLE'>";
$result = mysqli_query($DB, "SELECT * FROM bdd_textes ORDER BY ordre ASC");
while($row = mysqli_fetch_array($result))
{
echo "<div class='EDITLIVE' data-id='".$row['id']."' contenteditable='true'>".$row['texte']."</div>";
}
echo "</article>";Fichier ajax.editlive.js (inclus dans <head></head>) :
Code : Tout sélectionner
$(document).ready(function()
{
// ****** PRISE DE FOCUS
$('.EDITLIVE').on('focusin', function()
{
// Apparition de la toolbar
$('#toolbar').css('display', 'block');
// Définition de sa position (juste au dessus du champ d'édition)
position = $(this).position();
toolbarX = position.left;
toolbarY = position.top - 27;
$('#toolbar').offset({ top:toolbarY, left:toolbarX });
});
// ****** APPUI SUR UN BOUTON DE LA TOOLBAR
$('#toolbar a').click(function()
{
var command = $(this).data('command');
if(command == 'createlink')
{
url = prompt('Entrer le lien : ', 'http:\/\/');
document.execCommand($(this).data('command'), false, url);
}
else
{
document.execCommand($(this).data('command'), false, null);
}
// Supprime le comportement par défaut du lien
event.preventDefault();
});
// ****** PERTE DE FOCUS : exécution de" _editlive.php"
$('.EDITLIVE').on('focusout', function()
{
// Récupération de data['xxx'] ==> définit les valeurs de $_POST['xxx']
data = {};
data['valeur'] = $(this).html();
data['id'] = $(this).attr('data-id');
// Requête ajax et update BDD
$.ajax(
{
type:"POST",
url:"_editlive.php",
cache:false,
data:data,
dataType:"text",
success:function(reponse)
{
// Succès : exécute le script _editlive.php
return true;
},
error:function(reponse)
{
// Erreur : message d'alerte
alert("Erreur update : id n°"+data['id']);
return false;
}
});
});
});FICHIER _editlive.php (mise à jour de la base de données) :
Code : Tout sélectionner
// INTERDICTION DE L'ACCES DIRECT A LA PAGE
if(!(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest')) trigger_error('Accès refusé', E_USER_ERROR);
$id = $_POST['id'];
$valeur = $_POST['valeur'];
// Suppression des éventuelles balises html non autorisées et des retours chariots
$valeur = strip_tags($valeur, "<b><strong><i><em><br><ol><ul><li><a>");
$valeur = str_replace("\n", "", $valeur);
// Update de la base de données
mysqli_query($DB, "UPDATE bdd_textes SET texte=\"".addslashes($valeur)."\" WHERE id=".$id);Voilà pour le code : tout fonctionne à merveille, la mise en forme en wysiwyg se passe bien, l'exécution du script en Ajax aussi, la base de données se met à jour lorsque je sors le focus du champ éditable. Le problème c'est pour faire disparaître la toolbar après édition : j'ai essayé de placer le code $('#toolbar').css('display', 'none'); à divers endroits, mais ce n'est pas satisfaisant.
Quand je mets le $('#toolbar').css('display', 'none'); avant ou après le "return true;" du script ajax, ça fonctionne mais la toolbar disparaît même si on a encore du texte à éditer (évidemment, puisqu'en cliquant dans la toolbar, on perd le focus et ça exécute le script). L'idée serait donc de faire exécuter le script du focusout SAUF si on clique sur un élément de la toolbar ou son conteneur parent.
Est-ce possible ? Merci pour votre aide !