web-dev-qa-db-fra.com

Effondrement de l'amorce Twitter: modification de l'affichage du bouton bascule

J'utilise Twitter Bootstrap pour créer des sections réductibles de texte. Les sections sont développées quand un bouton + est enfoncé. Mon code html comme suit:

<div class="row-fluid summary">
    <div class="span11">
        <h2>MyHeading</h2>  
    </div>
    <div class="span1">
        <button type="button" class="btn btn-success" data-toggle="collapse" data-target="#intro">+</button>
    </div>
</div>
<div class="row-fluid summary">
    <div id="intro" class="collapse"> 
        Here comes the text...
    </div>
</div>

Existe-t-il un moyen de changer le bouton pour afficher - au lieu de + après le développement de la section (et revenir à + lorsqu’il est réduit à nouveau)?

Informations supplémentaires : J'espérais qu'il existerait une solution simple, basée sur Twitter, bootstrap/css/html. Jusqu'à présent, toutes les réponses utilisent JavaScript ou PHP. Pour cette raison, je souhaite ajouter quelques informations supplémentaires sur mon environnement de développement: je souhaite utiliser cette solution dans un site Web basé sur SilverStripe (version 3.0.5), ce qui a des implications pour l'utilisation de PHP JavaScript.

49
Markus M.

essaye ça. http://jsfiddle.net/fVpkm/

Html: -

<div class="row-fluid summary">
    <div class="span11">
        <h2>MyHeading</h2>  
    </div>
    <div class="span1">
        <button class="btn btn-success" data-toggle="collapse" data-target="#intro">+</button>
    </div>
</div>
<div class="row-fluid summary">
    <div id="intro" class="collapse"> 
        Here comes the text...
    </div>
</div>

JS: -

$('button').click(function(){ //you can give id or class name here for $('button')
    $(this).text(function(i,old){
        return old=='+' ?  '-' : '+';
    });
});

Update Avec des Css purs, des pseudo-éléments

http://jsfiddle.net/r4Bdz/

Navigateurs pris en charge

button.btn.collapsed:before
{
    content:'+' ;
    display:block;
    width:15px;
}
button.btn:before
{
    content:'-' ;
    display:block;
    width:15px;
}

Mise à jour 2 avec Javascript pur 

http://jsfiddle.net/WteTy/

function handleClick()
{
    this.value = (this.value == '+' ? '-' : '+');
}
document.getElementById('collapsible').onclick=handleClick;
70
PSL

Voici une autre solution CSS uniquement qui fonctionne avec n’importe quel modèle HTML.

Cela fonctionne avec n'importe quel élément que vous devez changer. Quelle que soit votre disposition de bascule, vous la placez simplement dans quelques éléments avec les classes if-collapsed et if-not-collapsed à l'intérieur de l'élément bascule.

Le seul problème est que vous devez définir l'état initial souhaité de la bascule. Si elle est initialement fermée, mettez une classe collapsed sur la bascule.

Il nécessite également le sélecteur :not, de sorte qu'il ne fonctionne pas sur IE8.

Exemple HTML:

<a class="btn btn-primary collapsed" data-toggle="collapse" href="#collapseExample">
  <!--You can put any valid html inside these!-->
  <span class="if-collapsed">Open</span>
  <span class="if-not-collapsed">Close</span>
</a>
<div class="collapse" id="collapseExample">
  <div class="well">
    ...
  </div>
</div>

Moins version:

[data-toggle="collapse"] {
    &.collapsed .if-not-collapsed {
         display: none;
    }
    &:not(.collapsed) .if-collapsed {
         display: none;
    }
}

Version CSS:

[data-toggle="collapse"].collapsed .if-not-collapsed {
  display: none;
}
[data-toggle="collapse"]:not(.collapsed) .if-collapsed {
  display: none;
}

JS Fiddle

43
Jens

Toutes les autres solutions publiées ici entraînent une désynchronisation de la bascule si vous double-cliquez dessus. La solution suivante utilise les événements fournis par le framework Bootstrap , et la bascule correspond toujours à l'état de l'élément réductible:

HTML:

<div class="row-fluid summary">
    <div class="span11">
        <h2>MyHeading</h2>  
    </div>
    <div class="span1">
        <button id="intro-switch" class="btn btn-success" data-toggle="collapse" data-target="#intro">+</button>
    </div>
</div>
<div class="row-fluid summary">
    <div id="intro" class="collapse"> 
        Here comes the text...
    </div>
</div>

JS:

$('#intro').on('show', function() {
  $('#intro-switch').html('-')
})
$('#intro').on('hide', function() {
  $('#intro-switch').html('+')
})

Cela devrait fonctionner dans la plupart des cas. 

Cependant, j'ai également rencontré un problème supplémentaire lors de la tentative d'imbrication d'un élément compressible et de son commutateur à bascule dans un autre élément compressible. Avec le code ci-dessus, lorsque je clique sur la bascule imbriquée pour masquer l'élément réductible imbriqué, la bascule de l'élément parent change également. C'est peut-être un bug dans Bootstrap. J'ai trouvé une solution qui semble fonctionner: j'ai ajouté une classe "réduite" aux commutateurs à bascule (Bootstrap l'a ajouté lorsque l'élément réductible est masqué, mais ils ne commencent pas avec elle), puis ajouté au sélecteur jQuery pour le masquer la fonction:

http://jsfiddle.net/fVpkm/87/

HTML:

<div class="row-fluid summary">
    <div class="span11">
        <h2>MyHeading</h2>  
    </div>
    <div class="span1">
        <button id="intro-switch" class="btn btn-success collapsed" data-toggle="collapse" data-target="#intro">+</button>
    </div>
</div>
<div class="row-fluid summary">
    <div id="intro" class="collapse"> 
        Here comes the text...<br>
        <a id="details-switch" class="collapsed" data-toggle="collapse" href="#details">Show details</a>
        <div id="details" class="collapse">
            More details...
        </div>
    </div>
</div>

JS:

$('#intro').on('show', function() {
    $('#intro-switch').html('-')
})
$('#intro').on('hide', function() {
    $('#intro-switch.collapsed').html('+')
})

$('#details').on('show', function() {
    $('#details-switch').html('Hide details')
})
$('#details').on('hide', function() {
    $('#details-switch.collapsed').html('Show details')
})
5
linesarefuzzy

Ajoutez du code jquery, vous avez besoin de jquery pour faire ceci:

<script>
        $(".btn[data-toggle='collapse']").click(function() {
            if ($(this).text() == '+') {
                $(this).text('-');
            } else {
                $(this).text('+');
            }
        });
        </script>
3
AzDesign

Ma solution JS suivante est meilleure que les autres approches proposées ici, car elle garantit qu’elle dit toujours «ouverte» lorsque la cible est fermée et inversement.

HTML:

<a href="#collapseExample" class="btn btn-primary" data-toggle="collapse" data-toggle-secondary="Close">
    Open
</a>
<div class="collapse" id="collapseExample">
  <div class="well">
    ...
  </div>
</div>

JS:

$('[data-toggle-secondary]').each(function() {
    var $toggle = $(this);
    var originalText = $toggle.text();
    var secondaryText = $toggle.data('toggle-secondary');
    var $target = $($toggle.attr('href'));

    $target.on('show.bs.collapse hide.bs.collapse', function() {
        if ($toggle.text() == originalText) {
            $toggle.text(secondaryText);
        } else {
            $toggle.text(originalText);
        }
    });
});

Exemples:

$('[data-toggle-secondary]').each(function() {
    var $toggle = $(this);
    var originalText = $toggle.text();
    var secondaryText = $toggle.data('toggle-secondary');
    var $target = $($toggle.attr('href'));

    $target.on('show.bs.collapse hide.bs.collapse', function() {
        if ($toggle.text() == originalText) {
            $toggle.text(secondaryText);
        } else {
            $toggle.text(originalText);
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/Twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"/>
<script src="http://netdna.bootstrapcdn.com/Twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>

<a href="#collapseExample" class="btn btn-primary" data-toggle="collapse" data-toggle-secondary="Close">
    Open
</a>
<div class="collapse" id="collapseExample">
  <div class="well">
    ...
  </div>
</div>

JS Fiddle

Autres avantages de cette approche:

  • le code est DRY et réutilisable
  • chaque bouton de réduction reste séparé
  • il vous suffit de mettre une modification dans le code HTML: ajouter l'attribut data-toggle-secondary
2
Harvey

Je suppose que vous pourriez regarder à l'intérieur de votre code téléchargé où il y a exactement un signe + (mais cela pourrait ne pas être très facile).

Qu'est-ce que je ferais? Je trouverais la classe/id des éléments DOM contenant le signe + (supposons que ce soit ".collapsible" et avec Javascript (en fait jQuery):

<script>
     $(document).ready(function() {
         var content=$(".collapsible").html().replace("+", "-");
         $(".collapsible").html(content));
     });
</script>

edit D'accord ... Désolé, je n'ai pas examiné le code de bootstrap ... mais je suppose qu'il fonctionne avec quelque chose comme slideToggle ou slideDown and slideUp... Imaginez que c'est une slideToggle pour les éléments de la classe .collapsible , qui révèlent le contenu de certains éléments .info. Ensuite: 

         $(".collapsible").click(function() { 
             var content=$(".collapsible").html();
             if $(this).next().css("display") === "none") { 
                 $(".collapsible").html(content.replace("+", "-"));
             }
             else $(".collapsible").html(content.replace("-", "+"));
         });

Cela semble être l’inverse, mais comme l’animation réelle est parallèle, vous allez vérifier les CSS avant l’animation, c’est pourquoi vous devez vérifier si elle est visible (ce qui signifie qu’elle sera cachée une fois l’animation terminée) et puis définissez le + ou - correspondant.

1
Nico

Certains peuvent avoir des problèmes avec la modification de Bootstrap js (et peut-être valablement), mais il existe une approche en deux lignes pour y parvenir.

Dans le fichier bootstrap.js, recherchez la fonction Collapse.prototype.show et modifiez l'appel call. $ trigger pour ajouter le changement html comme suit:

this.$trigger
  .removeClass('collapsed')
  .attr('aria-expanded', true)
  .html('Collapse')

De même, dans la fonction Collapse.prototype.hide, remplacez-le par 

this.$trigger
  .addClass('collapsed')
  .attr('aria-expanded', false)
  .html('Expand')

Cela fera basculer le texte entre "Réduire" lorsque tout est développé et "Développer" lorsque tout est réduit.

Deux lignes. Terminé.

EDIT: à long terme, cela ne fonctionnera pas. bootstrap.js fait partie d'un paquet Nuget, donc je ne pense pas que cela a propagé ma modification sur le serveur. Comme mentionné précédemment, il n’est pas recommandé de modifier le fichier bootstrap.js. C’est pourquoi j’ai implémenté la solution PSL qui a très bien fonctionné. Néanmoins, ma solution fonctionnera localement si vous avez besoin de quelque chose de rapide, juste pour l'essayer.

0
scottndecker

J'ai aimé la solution CSS de PSL , mais dans mon cas, je devais inclure du code HTML dans le bouton et la propriété CSS du contenu affiche le code HTML brut avec des balises dans ce cas.

Dans le cas où cela pourrait aider quelqu'un d'autre, je me suis servi de son violon pour couvrir mon cas d'utilisation: http://jsfiddle.net/brunoalla/99j11h40/2/

HTML:

<div class="row-fluid summary">
    <div class="span11">
        <h2>MyHeading</h2>  
    </div>
    <div class="span1">
        <button class="btn btn-success collapsed" data-toggle="collapse" data-target="#intro">
            <span class="show-ctrl">
                <i class="fa fa-chevron-down"></i> Expand
            </span>
            <span class="hide-ctrl">
                <i class="fa fa-chevron-up"></i> Collapse
            </span>            
        </button>
    </div>
</div>
<div class="row-fluid summary">
    <div id="intro" class="collapse"> 
        Here comes the text...
    </div>
</div>

CSS:

button.btn .show-ctrl{
    display: none;
}
button.btn .hide-ctrl{
    display: block;
}
button.btn.collapsed .show-ctrl{
    display: block;
}
button.btn.collapsed .hide-ctrl{
    display: none;
}
0
Bruno A.

Plus facile avec le codage en ligne

<button type="button" ng-click="showmore = (showmore !=null && showmore) ? false : true;" class="btn float-right" data-toggle="collapse" data-target="#moreoptions">
            <span class="glyphicon" ng-class="showmore ? 'glyphicon-collapse-up': 'glyphicon-collapse-down'"></span>
            {{ showmore !=null && showmore ? "Hide More Options" : "Show More Options" }}
        </button>


<div id="moreoptions" class="collapse">Your Panel</div>
0
Swapna Jerin