11521 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour,

J'ai crée des DIV qui se plient et se déplient avec des champs de saisie à l’intérieur de chaque DIV. J'ai utilisé les Eléments <Details> et <Summary> pour pouvoir les utiliser sur IE11 j'ai utilisé un script.

L'utilisateur peut saisir un champ à l’intérieur d'une DIV et déplier la DIV par la suite.

Le problème, c'est que je ne sais pas comment faire pour déplier une DIV après le clic sur un bouton si la DIV contient un champ de saisie renseigné par l'utilisateur.


upload/59454-Affichage.png

Environnement: IE11
Merci pour votre aide.
Modérateur
Bonjour et bienvenue sur le forum,

Je te remercie pour cette explication. Cependant, sans bout de code, on peut pas faire grand chose.
Bonjour,

Merci pour vos réponses.

Voici une partie de mon code :

Le formulaire:

      <table>
            <tr>
                <td>N° test </td>
                <td>
                    <asp:TextBox ID="txtNum" runat="server"></asp:TextBox></td>

                <td>
                    <asp:Button ID="btnValider" runat="server" Text="Envoyer" />

                </td>
            </tr>

        </table>
    <details>
        <summary> Caractéristiques1</summary>
        <table>
            <tr>
                <td>Réference</td>
                <td>
                    <asp:TextBox ID="txtRef" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>Quantié</td>
                <td>
                    <asp:TextBox ID="txtQuantie" runat="server"></asp:TextBox>
                </td>
            </tr>
            
            <tr>
                <td>Montant TTC :</td>
                <td>
                    <asp:TextBox ID="txtMnt" runat="server"></asp:TextBox>
                    
                </td>
            </tr>
          
        </table>
    </details>

    <details>
        <summary>Caractéristiques2</summary>
        <table>
              <tr>
                <td>Date1</td>
                <td>
                    <asp:TextBox ID="txtDate1" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>Date2</td>
                <td>
                    <asp:TextBox ID="txtDate2" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>Date3</td>
                <td>
                    <asp:TextBox ID="txtDate3" runat="server"></asp:TextBox>
                </td>
            </tr>
        </table>
    </details>


Et voici le script que j'ai telechargé sur internet pour povoir utiliser les balises <details> et <summary>


/**
 * <details> crossbrowser support
 *
 * This jQuery based polyfill makes <details>/<summary> ready for use
 * in most browsers.
 *  http://dev.w3.org/html5/spec/Overview.html#the-details-element
 
 * 
 * @author Manuel Bieh
 * @url  http://www.manuel-bieh.de/
 
 * @version 0.9
 * @license  http://www.gnu.org/licenses/lgpl-3.0.txt  LGPL
 *
 * Date $LastChangedDate: 2011-08-03 08:43:30 +0200 (Mi, 03 Aug 2011) $
 *
 */


jQuery(function ($) {

    (function () {

        var me = this;

        this.hideDetailChildren = function (detail) {

            var children = detail instanceof jQuery ? detail[0].childNodes : detail.childNodes,
				childrenLength = children.length;

            $(detail).attr('open', false);

            // Double iteration workaround because otherwise Safari leaves out certain text nodes arbitrarily(?)
            if ($.browser.safari == true) {

                for (var i = 0; i < childrenLength; i++) {

                    if (children[i].nodeType == 3 && children[i].textContent != "") {
                        var span = $('<span />');
                        span.text(children[i].textContent).hide();

                        $(children[i]).after(span);
                        children[i].textContent = '';
                        childrenLength++;

                    }

                }

            }

            $.each(children, function (cKey, childElement) {

                if ($(childElement)[0].nodeType == 1
					&& childElement == $(childElement).parent().find('> summary:first-of-type')[0]) {

                    if ($(childElement).data('processed') != true) {

                        $(childElement).css({ "display": "block", "cursor": "pointer" }).data('processed', true).addClass('detailHidden').bind('click', function () {
                            me.toggleDetailChildren($(this));
                        });

                        $(detail).prepend($(childElement));

                    }

                } else if ($(childElement)[0].nodeType == 3
					&& !childElement.isElementContentWhitespace
					&& !!$.browser.safari == false) {

                    var span = $('<span />');
                    span.text(childElement.textContent).hide();

                    $(childElement).after(span);
                    childElement.textContent = '';
                    /*
                    */
                } else if ($(detail).find('> summary').length == 0) {

                    var summary = $('<summary />').text('Details').css({ "display": "block", "cursor": "pointer" }).data('processed', true).addClass('detailHidden').bind('click', function () {
                        me.toggleDetailChildren($(this));
                    });

                    $(detail).prepend(summary);

                }

                $(detail).find('> :visible:not(summary:first-child)').hide();

            });

        }

        this.showDetailChildren = function (detail) {

            $(detail).attr('open', true);

            $.each($(detail).find('> *'), function (key, childNode) {
                $(childNode).show();
            });

        }

        this.toggleDetailChildren = function (summary) {

            if (summary.hasClass('detailHidden')) {
                summary.removeClass('detailHidden');
                me.showDetailChildren(summary.parents('details')[0]);
            } else {
                summary.addClass('detailHidden');
                me.hideDetailChildren(summary.parents('details')[0]);
            }

        }

        // Feature test from Mathias Bynens
        //  http://mathiasbynens.be/notes/html5-details-jquery
 
        var isDetailsSupported = (function (doc) {
            var el = doc.createElement('details'),
				fake,
				root,
				diff;
            if (!('open' in el)) {
                return false;
            }

            root = doc.body || (function () {
                var de = doc.documentElement;
                fake = true;
                return de.insertBefore(doc.createElement('body'), de.firstElementChild || de.firstChild);
            }());

            el.innerHTML = '<summary>a</summary>b';
            el.style.display = 'block';
            root.appendChild(el);
            diff = el.offsetHeight;
            el.open = true;
            diff = diff != el.offsetHeight;
            root.removeChild(el);

            if (fake) {
                root.parentNode.removeChild(root);
            }

            return diff;

        }(document));

        if (isDetailsSupported == false) {

            if ($("details").length !== 0) {
                var style = $('<style />').text('summary {-webkit-text-size-adjust: none;}  details > summary:first-child:before {content: "?"; font-size:.9em;padding-right:6px;font-family:"Courier New";} details > summary.detailHidden:first-child:before {content: "?";font-size:.9em;padding-right:6px;font-family:"Courier New";}');
                $('head').append(style);
            }

            $.each($('details'), function (dKey, detailElement) {

                me.hideDetailChildren(detailElement);

            });

        }

    })();

});


Ce code fonctionne bien. j'arrive à plier et déplier les Divisions.

Mon problème est le suivant:

Si l'utilisateur saisi une valeur dans un champ il pourra plier la division. Dans ce cas après le clic sur le bouton "Envoyer" je veux que les divisions contenant des valeurs saisies par l'utilisateur s'ouvrent.

Merci pour votre aide.[/i][/i][/i][/i][/i]
Bonjour,

Si vous avez d'autres idées pour les DIV qui se plient et se déplient je suis prenante.

Les DIV par défaut sont pliées.

Elles se déplient au clic sur le titre de la DIV et à l'envoi du formulaire si cette dernière contient des valeurs saisies par l'utilisateur.

Merci pour votre aide.
là où j'ai pas compris,

c'est que tu dis

" Mon problème est le suivant:

Si l'utilisateur saisi une valeur dans un champ il pourra plier la division. Dans ce cas après le clic sur le bouton "Envoyer" je veux que les divisions contenant des valeurs saisies par l'utilisateur s'ouvrent. "

et ensuite tu dis

"Les DIV par défaut sont pliées.

Elles se déplient au clic sur le titre de la DIV et à l'envoi du formulaire si cette dernière contient des valeurs saisies par l'utilisateur."

donc tu viens simplement te dire que ton problème n'est plus un problème et que tout fonctionne.......

peux-tu faire des phrases clair ?
Modifié par JENCAL (22 Jul 2015 - 10:28)
Bonjour,

Merci pour ta réponse.

Mon problème est le suivant:

Lorsqu'une DIV contient une valeur saisie par l'utilisateur (un ou plusieurs champ de saisie n'est pas vide) il faut qu'elle se déplie (si l'utilisateur l'a plié après sa saisie) au moment du clic sur le bouton Envoyer.



J’espère que j’étais claire.
Une solution est faisable facilement,

en jquery, lors du clic sur le bouton envoyer, tu test si tes aspTextBox sont vides a chaque test invalide tu met un boolean a false si il est true, tu déplie.

je n'est jamais utilisé aspTextBox , mais toujours des <input type="text" /> et si tu avais des input j'aurai pu te faire le code
Modifié par JENCAL (22 Jul 2015 - 10:49)
Merci énormément.

Pourras tu me faire le code avec les input STP, j'essayerais de rendre le code fonctionnel avec les Textbox.
Si caractéristique 1 contient un input avec une valeur , caractéristique 2 doit également être ouverte ? ou seulement la 1 ?
Uniquement pour les divisions contenant un input avec une valeur.
Si caractéristique 1 contient un input avec une valeur et ou caractéristique 2 contient un input avec une valeur.
Ok je te laisse tester ici ! = sur codepen
mais je vais quand même expliquer un peu

voici le code html :
<table>
            <tr>
                <td>N° test </td>
                <td>

                <td>
                  <input type="button" ID="btnValider" Value="Envoyer"  runat="server"/>

                </td>
            </tr>

        </table>
    <details >
        <summary id="summary1"> Caractéristiques1</summary>
        <table>
            <tr>
                <td>Réference</td>
                <td>
                  <input type="text" class="caract1" ID="txtRef" runat="server"/>
                </td>
            </tr>
            <tr>
                <td>Quantié</td>
                <td>
                  <input type="text" class="caract1" ID="txtQuantie" runat="server"/>
                </td>
            </tr>
            
            <tr>
                <td>Montant TTC :</td>
                <td>
                  <input type="text" class="caract1" ID="txtMnt" runat="server"/>
                    
                </td>
            </tr>
          
        </table>
    </details>

    <details>
        <summary id="summary2">Caractéristiques2</summary>
        <table>
              <tr>
                <td>Date1</td>
                <td>
                  <input type="text" class="caract2" ID="txtDate1" runat="server"/>
                </td>
            </tr>
            <tr>
                <td>Date2</td>
                <td>
                  <input type="text" class="caract2" ID="txtDate2" runat="server"/>
                </td>
            </tr>
            <tr>
                <td>Date3</td>
                <td>
                    <input type="text" class="caract2" ID="txtDate3" runat="server"/>
                </td>
            </tr>
        </table>
    </details>


j'ai rajouté :
- des input type text à la place des as textbot (désolé)
- un ID unique sur les balise <details>
- une class sur chaque INPUT (si les inputs est dans caractéristique 1 alors les input auront la class caract1)

et voici le code jquery

	$(document).ready(function() { //
		$('#btnValider').click( function() { // Lors du clic sur le bouton valider
       if( $('.caract1').val().length != 0) { // si les inputs ayant la class caract1 sont pas vide
          $("#detail1").attr("open", "open"); // alors on ouvre detail 1
       }
      if( $('.caract2').val().length != 0) { // si les inputs ayant la calss caract2 sont pas vide
          $("#detail2").parent().attr("open", "open"); // alors on ouvre detail 2
       }
		});
	});

Modifié par JENCAL (22 Jul 2015 - 11:58)
Merci beaucoup, c'est exactement ça qu'il me faut.

Je vais changer le code et je te tiens au courant du résultat.

Merci encore une fois.
Voici mon code dans une page HTML



<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <table>
        <tr>
            <td>
                <input type="button" id="btnValider" value="Envoyer" runat="server" />
            </td>
        </tr>

    </table>
    <details id="detail1">
        <summary> Caractéristiques1</summary>
        <table>
            <tr>
                <td>Réference</td>
                <td>
                    <input type="text" class="caract1" id="txtRef" runat="server" />
                </td>
            </tr>
            <tr>
                <td>Quantié</td>
                <td>
                    <input type="text" class="caract1" id="txtQuantie" runat="server" />
                </td>
            </tr>

            <tr>
                <td>Montant TTC :</td>
                <td>
                    <input type="text" class="caract1" id="txtMnt" runat="server" />

                </td>
            </tr>

        </table>
    </details>

    <details id="detail2">
        <summary>Caractéristiques2</summary>
        <table>
            <tr>
                <td>Date1</td>
                <td>
                    <input type="text" class="caract2" id="txtDate1" runat="server" />
                </td>
            </tr>
            <tr>
                <td>Date2</td>
                <td>
                    <input type="text" class="caract2" id="txtDate2" runat="server" />
                </td>
            </tr>
            <tr>
                <td>Date3</td>
                <td>
                    <input type="text" class="caract2" id="txtDate3" runat="server" />
                </td>
            </tr>
        </table>
    </details>
    <script type="text/javascript">
        function openDiv() {
            $(document).ready(function () { //
                $('#btnValider').click(function () { // Lors du clic sur le bouton valider
                    if ($('.caract1').val().length != 0) { // si les inputs ayant la class caract1 sont pas vide
                        $("#detail1").attr("open", "open"); // alors on ouvre detail 1
                    }
                    if ($('.caract2').val().length != 0) { // si les inputs ayant la calss caract2 sont pas vide
                        $("#detail2").attr("open", "open"); // alors on ouvre detail 2
                    }
                });
            });
        }
    </script>
</body>
</html>


Modérateur
Smiley eek

pas de details, summary et autres exotismes.... Comment voulez vous construire une maison de plusieurs étages, alors que les bases ne sont pas solides ?

donc même si tu as un beau script qui dit au dom, oui oui, il y a de nouvelles balises. Ce n'est pas valide ! Je vais aller encore plus loin dans ma réflexion. Si le navigateur n'accepte pas le JS, il y a beaucoup plus de chances qu'il y ait des bugs.

Un code html riche (sémantique) et valide est gage de sureté !

Je n'ai pas essayé le code de Jencal. Cependant, non, là encore, pas d'accord. Au mieux, il faudrait écrire cela :

$("#detail1").data("open", "open"); // en sortie (valide html 5) : <div id="detail1" data-open="open"> .... 
.
Lorsque l'on veut inclure un attribut exotique dans un element html 5 (uniquement), il est conseillé de préfixer par "data-". Certains vont me dire : avec Angular, tu peux ecrire ng-... et ça fonctionne parfaitement.
Avec Angular on peut créer aussi ces propres éléments via les directives. Ça fonctionne aussi. Il faut pas oublier qu'on est dans un moteur de template. Pour les attributs, on peut toujours préfixer par data et pour les éléments exotiques, je ne vois pas l'intérêt. Le HTML est un langage riche et très bien pensé.

Vu sur le net, une directive personnelle créée avec Angular (du grand n'importe quoi):

<sz-tooltip text="mon tooltip" orientation="bottom">
  Une info-bulle ...
  Voilà ...
</sz-tooltip>

Exemple corrigé (html 5):

<span class="tooltip" data-text="mon tooltip" data-orientation="bottom">
  Une info-bulle ...
</span>

Exemple corrigé (xhtml 1 strict):

<span class="tooltip bottom">
<span class="text">mon tooltip</span>
  Une info-bulle ...
</span>



Mon conseil ultime à propos d'Angular est que si on ne connait pas bien le html, css et js, on acquiert de très mauvaises méthodes d'écriture HTML. Ce qui revient à dire, les fondations de l'application seront bancales si l'on doit par la suite développer une application en natif...

Ces prochains jours, je vais être moins disponible. Cependant, je vais garder une attention à ce sujet.

@Celine : peux tu corriger ton html et nous présenter un code valide stp ?
@Jencal : Joue avec les class (ajoute/supprime/modifie) et essai le plus souvent possible de solliciter le css au lieu du JS Smiley cligne
Modifié par niuxe (22 Jul 2015 - 23:49)
Pages :