11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour, premièrement je suis vraiment débutant avec jQuery

Alors j'ai fait un petit bout de code qui permet d'ajouter des champs (ou ce qu'on veut) dans un formulaire. J'utilise pour cela clone(). Mais voilà je voudrais pouvoir effacer le valeur contenu dans les inputs qui sont clonés mais je n'y arrive pas

$(".ajoutArticle").click(function (){ 
		var article = $(this).parents("form").children(".article:last");
		var n = $(".article").length;
		
		article.after(article.clone().hide());

// C'est ici que j'essaye de résoudre le problème -------------------------------
		article.find("input").not(".alignement").next().val('');
		
			
		article.find(".titre").attr("name","titre_article" + n);
		article.find(".texte").attr("name","texte_article" + n);
		article.find(".alignement").attr("name","alignement" + n);
		article.find(".url").attr("name","url" + n);


Une petite idée pour m'aider
Modifié par bwaais (16 Jul 2009 - 13:04)
Salut,

a écrit :
je n'y arrive pas
Tu pourrais probablement décrire un peu plus en détails ce qui se passe quand tu essayes. Et le code HTML de ton form serait bien utile également.

En attendant, je me risque à un diagnostic Smiley smile :
var article = $(this).parents("form").children(".article:last");
Après cette ligne, la variable article pointe sur le dernier .article
article.after(article.clone().hide()); 
Et ici tu insères un nouvel .article, la variable article pointe donc désormais sur l'avant-dernier .article et c'est donc sur lui que tout le code suivant s'appliquera (et non sur le .article cloné).
Alors,
J'ai regardé plus attentivement ce qu'il se passait.
la fonction clone puis vide les valeurs des inputs dans le première élément (qui a servit à cloné) et non pas le nouvel élément (qui vient d'être cloné).

Je voudrais pouvoir vider les champs de l'élément qui vient d'être cloné au clique. Je pense deviner que l'élément cloné n'existe pas au clique. Pourtant je dois pouvoir faire quelques choses, non?

Concernant,
article.after(article.clone().hide()); 

Je ne sais pas comment je m'y suis pris au départ mais c'est le seul moyen de cloner l'élément précèdent.
bwaais a écrit :
la fonction clone puis vide les valeurs des inputs dans le première élément (qui a servit à cloné) et non pas le nouvel élément (qui vient d'être cloné).
C'est donc bien ce que je te pensais. Voici une proposition de correction :
$(".ajoutArticle").click(function (){  
    // liste des éléments ayant la classe article et qui sont enfants immédiats de ton form
    var articles = $(this).parents("form").children(".article");
    var n = articles.length;
    // on clone le dernier article
    articles.eq(n-1).clone()
        // on vide les input (du clone)
        .find("input").val('').end()
        // on change le name des éléments suivants (du clone)
        .find(".titre").attr("name", "titre_article" + n).end()
        .find(".texte").attr("name", "texte_article" + n).end()
        .find(".alignement").attr("name", "alignement" + n).end()
        .find(".url").attr("name", "url" + n).end()
        // on le cache (le clone)
        .hide()
        // enfin on l'insère (le clone) après le dernier article
        .insertAfter(articles.eq(n-1));
});
Tu n'as toujours pas donné ton code HTML, donc ne t'attends pas à ce que ça fonctionne "out of the box", il te faudra probablement adapter un peu, mais j'espère que tu as compris la logique.
J'ai bien compris la logique mais rien à faire même en adaptant le code ça ne fonctionne pas. Je pense que j'ai pas encore tout saisi (je débute avec jQuery) alors voilà mon code HTML (en espérant apprendre quelques choses) :


<div class="article">
						<label>Titre article</label><br />
						<input type="text" name="" class="titre"/><br /><br />
						
						<label>Texte article</label><br />
						<textarea name="" class="texte"></textarea><br />
						
						<label>Texte à gauche</label>
						<input type="radio" value="gauche" name="" class="alignement"/>
						<label>Texte à droite</label>
						<input type="radio" value="droite" name="" class="alignement"/><br /><br />
						
						<input type="file" name="image" value="" /><br /><br />
						<label>Ajouter un lien</label>
						<input type="text" name="" class="url"/>
					</div>
					
					<div id="ajoutSupprimerArticle">
					<a href="javascript:;" title="Ajouter un article" class="ajoutArticle" rel="article"><img class="ajoutArticle" src="img/admin_projets/btn_ajouter_un_article.png" /></a>
					<a href="javascript:;" title="Supprimer un article" class="supprimerArticle" rel="article"><img src="img/admin_projets/btn_supprimer_un_article.png" /></a>
var articles = $(this).parents("form").children(".article"); 
On cherche les articles dans un <form>. Mais maintenant, à voir ton code HTML, il n'y a visiblement pas de form. Alors évidemment, ça marche pô Smiley smile . Tu peux facilement modifier cette ligne toi-même.

Attention, conformément à ton premier code, le nouvel .article inséré est ausi masqué (hide()). Il est donc bien visible dans le DOM, mais pas sur la page.

Enfin, tu verras qu'il est inséré deux fois, pour la bonne et simple raison que ton <a> et l'<img> qu'il contient ont tous les deux la classe ajoutArticle.
Modifié par marcv (20 Jul 2009 - 11:38)
Il y a une balise form pas de panique j'ai juste copié collé la partie en rapport avec le code cité plus haut. Quand même ! je suis débutant avec jQuery beaucoup moins avec l'HTML et les CSS Smiley langue

Et pour la classe ajoutArticle, ce n'est qu'une petite erreur de frappe Smiley cligne

Alors, si on prend en compte une jolie balise <form> que j'ai volontairement omit d'ajouter et la petite erreur (a force de chercher une solution) sur l'ajoutArticle y vient d'où le problème.
Modifié par bwaais (20 Jul 2009 - 16:08)
a écrit :
Il y a une balise form pas de panique[...]
Et pour la classe ajoutArticle, ce n'est qu'une petite erreur de frappe
Bwaais, il faut que tu comprennes que quand tu poses une question, on a besoin de bases solides pour te répondre. J'ai dû te demander ton code deux fois pour que tu nous le donnes, et encore, c'est à nous de deviner si l'absence du form est voulue ou pas, et idem pour la classe répétée.... Si tu avais donné tous les éléments nécessaires, ça fait 4 jours que ta question serait résolue. Au lieu de ça, on joue à deviner à quoi doit resembler ton code, là-bas chez toi, on passe 10 fois plus de temps que nécessaire à te répondre, et évidemment, on tombe rarement juste.

a écrit :
Alors, si on prend en compte [...] y vient d'où le problème ?
Pour te répondre, j'ai fait un test en local chez moi et tout fonctionne parfaitement. Donc il y a obligatoirement encore quelque chose que tu ne nous as pas dit... Mets une page de test en ligne, là au moins on sera sûr de tout avoir.
Modifié par marcv (20 Jul 2009 - 16:41)
Ok désolé, voilà tout mon code :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Newsletter</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" type="text/css" href="style_backoff.css"/>
<link rel="stylesheet" type="text/css" href="newsletter.css"/>
<script type="text/javascript" src="checking.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
	
	$(".supprimerArticle").hide();
	
	$(".ajoutArticle").click(function (){
	var article = $(this).parents("form").children(".article:last"); 
        var n = $(".article").length; 
         
        article.after(article.clone().hide()); 
 
        article.find("input").not(".alignement").next().val(''); 
         
             
        article.find(".titre").attr("name","titre_article" + n); 
        article.find(".texte").attr("name","texte_article" + n); 
        article.find(".alignement").attr("name","alignement" + n); 
        article.find(".url").attr("name","url" + n);
		
		$(this).parents("form").children(".article:last").fadeIn("slow");
		
		if ( $(".article").length > 1 ) { $(".supprimerArticle").fadeIn("fast"); } 
	});
		
	
	$(".supprimerArticle").click(function (){ 
		var article = $(".article:last"); 
		article.remove(); 
	
		// S'il y a moins de 2 articles (autrement dit un seul) on cache le bouton supprimer.        
		if ( $(".article").length < 2 ) { $(".supprimerArticle").fadeOut("fast"); } 
	
	});
	
		
});
</script>
</head>
<body>

<div id="header"><a class="deco" href="#"><img src="img/deco.png" border="0" /></a>
	<ul id="menu">
		<li id="nav_projets" class="inactive"><a href="administration_clients.html">CLIENTS</a></li>
		<li id="nav_actualites" class="inactive"><a href="admin_actu.html">ACTUALITÉS</a></li>
		<li id="nav_news" class="active">NEWSLETTER</li>
	</ul>
</div>

<div id="contenu">
	<div id="contenu2">
		<h1>Nouvelle Newsletter</h1>
		<h6 style="margin-top:-20px"><a href="#">Nouvelle Newsletter</a> | <a href="contact.html">Liste des contacts</a></h6>
		<div id="top_actu_list">
			<form method="get" action="#">
					<div class="langue">
						<img src="img/fr.gif" />
						<input type="radio" value="francais" name="langue"/>
					
						<img src="img/gb.gif" />
						<input type="radio" value="anglais" name="langue" />
					</div>
					
						<label>Titre</label><br />
						<input type="text" name="titre" class="titre"/><br />
						
					<div id="chapeau">
						<label>Titre chapeau</label><br />
						<input type="text" name="titre_chapeau" class="titre" /><br />
						
						<label>Texte chapeau</label><br />
						<textarea name="texte_chapeau" class="texte"></textarea><br /><br />
					</div>
					
					<div class="article">
						<label>Titre article</label><br />
						<input type="text" name="" class="titre"/><br /><br />
						
						<label>Texte article</label><br />
						<textarea name="" class="texte"></textarea><br />
						
						<label>Texte à gauche</label>
						<input type="radio" value="gauche" name="" class="alignement"/>
						<label>Texte à droite</label>
						<input type="radio" value="droite" name="" class="alignement"/><br /><br />
						
						<input type="file" name="image" value="" /><br /><br />
						<label>Ajouter un lien</label>
						<input type="text" name="" class="url"/>
					</div>
					
					<div id="ajoutSupprimerArticle">
					<a href="javascript:;" title="Ajouter un article" class="ajoutArticle" rel="article"><img src="img/admin_projets/btn_ajouter_un_article.png" /></a>
					<a href="javascript:;" title="Supprimer un article" class="supprimerArticle" rel="article"><img src="img/admin_projets/btn_supprimer_un_article.png" /></a>
					</div>
					<div id="enregistrerNewsletter">
					<a href="javascript:;" title="Prévisualiser" class="previewArticle" rel="article"><img src="img/admin_projets/btn_previsualiser.png" /></a>
					<input type="image" name="submit" value="" src="img/admin_projets/btn_enregistrer.png" />
				</form>
		</div>
</div>


</body>
</html>

Modifié par bwaais (20 Jul 2009 - 17:11)
J'ai copié-collé tout ça, remplacé le code js par celui que je t'ai donné, et... ça marche parfaitement Smiley biggol .

À tout hasard, je rappelle :
marcv a écrit :
Attention, conformément à ton premier code, le nouvel .article inséré est ausi masqué (hide()). Il est donc bien visible dans le DOM, mais pas sur la page.
Ahem, voici une version légerement modifié, qui fonctionne correctement pour moi :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Newsletter</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" type="text/css" href="style_backoff.css"/>
<link rel="stylesheet" type="text/css" href="newsletter.css"/>
<script type="text/javascript" src="checking.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {

    $(".supprimerArticle").hide();

    $(".ajoutArticle").click(function (){
        var form = $(this).closest('form');
        var articleList = form.find('.article');
        // Le nombre d'articles déjà présents
        var n = articleList.length;
        // Le premier article que l'on va cloner
        var firstArticle = $(articleList[0]);
        // Le dernier article de la liste
        var lastArticle = $(articleList[n-1]);
        // Un article cloné
        var clonedArticle = firstArticle.clone();

        // Pour chaque input clonés
        clonedArticle.find(':input').each(function() {
            // On vide la valeur
            $(this)
                .filter(':text,:file').val('').end()
                .filter(':radio').attr('checked', false);
            // On change le nom en ajoutant le numero
            $(this).attr('name', $(this).attr('name')+n)
        })

        // On l'ajoute au dom après les autres
        clonedArticle.insertAfter(lastArticle).hide().fadeIn('slow');

        // On ajoute le le lien de suppression
        $(".supprimerArticle").fadeIn("fast");

    });


    $(".supprimerArticle").click(function (){
        var article = $(".article:last");
        article.remove();

        // S'il y a moins de 2 articles (autrement dit un seul) on cache le bouton supprimer.
        if ( $(".article").length < 2 ) { $(".supprimerArticle").fadeOut("fast"); }

    });


});
</script>
</head>
<body>

<div id="header"><a class="deco" href="#"><img src="img/deco.png" border="0" /></a>
    <ul id="menu">
        <li id="nav_projets" class="inactive"><a href="administration_clients.html">CLIENTS</a></li>
        <li id="nav_actualites" class="inactive"><a href="admin_actu.html">ACTUALITÉS</a></li>
        <li id="nav_news" class="active">NEWSLETTER</li>
    </ul>
</div>

<div id="contenu">
    <div id="contenu2">
        <h1>Nouvelle Newsletter</h1>
        <h6 style="margin-top:-20px"><a href="#">Nouvelle Newsletter</a> | <a href="contact.html">Liste des contacts</a></h6>
        <div id="top_actu_list">
            <form method="get" action="#">
                    <div class="langue">
                        <img src="img/fr.gif" />
                        <input type="radio" value="francais" name="langue"/>

                        <img src="img/gb.gif" />
                        <input type="radio" value="anglais" name="langue" />
                    </div>

                        <label>Titre</label><br />
                        <input type="text" name="titre" class="titre"/><br />

                    <div id="chapeau">
                        <label>Titre chapeau</label><br />
                        <input type="text" name="titre_chapeau" class="titre" /><br />

                        <label>Texte chapeau</label><br />
                        <textarea name="texte_chapeau" class="texte"></textarea><br /><br />
                    </div>

                    <div class="article">
                        <label>Titre article</label><br />
                        <input type="text" name="titre_article" class="titre"/><br /><br />

                        <label>Texte article</label><br />
                        <textarea name="texte_article" class="texte"></textarea><br />

                        <label>Texte à gauche</label>
                        <input type="radio" value="gauche" name="alignement_article" class="alignement"/>
                        <label>Texte à droite</label>
                        <input type="radio" value="droite" name="alignement_article" class="alignement"/><br /><br />

                        <input type="file" name="image_article" value="" /><br /><br />
                        <label>Ajouter un lien</label>
                        <input type="text" name="url_article" class="url"/>
                    </div>

                    <div id="ajoutSupprimerArticle">
                    <a href="javascript:;" title="Ajouter un article" class="ajoutArticle" rel="article"><img src="img/admin_projets/btn_ajouter_un_article.png" /></a>
                    <a href="javascript:;" title="Supprimer un article" class="supprimerArticle" rel="article"><img src="img/admin_projets/btn_supprimer_un_article.png" /></a>
                    </div>
                    <div id="enregistrerNewsletter">
                    <a href="javascript:;" title="Prévisualiser" class="previewArticle" rel="article"><img src="img/admin_projets/btn_previsualiser.png" /></a>
                    <input type="image" name="submit" value="" src="img/admin_projets/btn_enregistrer.png" />
                </form>
        </div>
</div>


</body>
</html>


- J'ai mis sous forme de variables les éléments jQuery pour rendre cela plus lisible et simplifier les selections.
- Ca simplifie certaines selection pour etre moins dépendante du code html
- J'ajoute l'élément cloné au DOM après avoir fait mes opérations dessus (vider les value et changer les name) pour éviter des redraws inutiles.
- J'ai aussi ajouté des names aux input de l'article original qui n'en avaient pas (?!)

A vue de nez, si je me souviens du problème original, c'était que tu continuait de faire des modifications sur ta variable 'article' qui avait servi de base au clonage, et non pas sur le nouvel article cloné
Modifié par Tymlis (20 Jul 2009 - 21:00)