programing

Twitter 부트 스트랩 축소 : 토글 버튼 표시 변경

nasanasas 2020. 12. 27. 11:06
반응형

Twitter 부트 스트랩 축소 : 토글 버튼 표시 변경


축소 가능한 텍스트 섹션을 만들기 위해 Twitter Bootstrap을 사용하고 있습니다. +버튼을 누르면 섹션이 확장됩니다 . 내 html 코드는 다음과 같습니다.

<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>

디스플레이 버튼을 변경하는 방법이 -아닌 +부분 확장 (과로 변경 다시 후 +이 다시 붕괴 될 때)는?

추가 정보 : 내 문제에 대한 간단한 twitter-bootstrap / css / html 기반 솔루션이 있기를 바랐습니다. 지금까지의 모든 응답은 JavaScript 또는 PHP를 사용합니다. 이 때문에 개발 환경에 대한 정보를 더 추가하고 싶습니다.이 솔루션을 SilverStripe 기반 (버전 3.0.5) 웹 사이트에서 사용하고 싶습니다.이 솔루션은 PHP와 JavaScript 모두 사용에 영향을줍니다.


이 시도. 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=='+' ?  '-' : '+';
    });
});

순수 CSS, 유사 요소로 업데이트

http://jsfiddle.net/r4Bdz/

지원되는 브라우저

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

순수한 Javascript로 2 업데이트

http://jsfiddle.net/WteTy/

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

모든 HTML 레이아웃에서 작동하는 또 다른 CSS 전용 솔루션이 있습니다 .

전환해야하는 모든 요소와 함께 작동합니다. 토글 레이아웃이 무엇이든간에 토글 요소 내부의 if-collapsedif-not-collapsed클래스를 사용하여 두 개의 요소 안에 넣습니다 .

유일한 문제는 토글의 원하는 초기 상태를 설정해야한다는 것입니다. 처음에 닫혔다 collapsed면 토글에 클래스 를 넣으 십시오.

또한 :not선택기 가 필요 하므로 IE8에서는 작동하지 않습니다.

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>

더 적은 버전 :

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

CSS 버전 :

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

JS 바이올린


여기에 게시 된 다른 모든 솔루션으로 인해 두 번 클릭하면 토글이 동기화되지 않습니다. 다음 솔루션은 Bootstrap 프레임 워크 에서 제공 하는 이벤트를 사용하며 토글은 항상 축소 가능한 요소의 상태와 일치합니다.

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('+')
})

대부분의 경우 작동합니다.

그러나 하나의 접을 수있는 요소와 다른 접을 수있는 요소 안에 토글 스위치를 중첩하려고 할 때 추가 문제가 발생했습니다. 위의 코드에서 중첩 된 축소 가능 요소를 숨기기 위해 중첩 된 토글을 클릭하면 상위 요소의 토글도 변경됩니다. 부트 스트랩의 버그 일 수 있습니다. 작동하는 것처럼 보이는 솔루션을 찾았습니다. 토글 스위치에 "collapsed"클래스를 추가했습니다 (부트 스트랩은 축소 가능 요소가 숨겨져 있지만 시작되지 않을 때 추가 함). 그런 다음 jQuery 선택기에 추가했습니다. 숨기기 기능 :

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')
})

jquery 코드를 추가하면 jquery가 필요합니다.

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

내 다음 JS 솔루션은 대상이 닫힐 때 항상 '열림'이라고 말하고 그 반대의 경우도 마찬가지이기 때문에 여기에서 다른 접근 방식보다 낫습니다.

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);
        }
    });
});

예 :

$('[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 바이올린

Other benefits of this approach:

  • the code is DRY and reusable
  • each collapse button stays separate
  • you only need to put one change into the HTML: adding the data-toggle-secondary attribute

I guess you could look inside your downloaded code where exactly there is a + sign (but this might not be very easy).

What I'd do? I'd find the class/id of the DOM elements that contain the + sign (suppose it's ".collapsible", and with Javascript (actually jQuery):

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

edit Alright... Sorry I haven't looked at the bootstrap code... but I guess it works with something like slideToggle, or slideDown and slideUp... Imagine it's a slideToggle for the elements of class .collapsible, which reveal contents of some .info elements. Then:

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

This seems like the opposite thing to do, but since the actual animation runs in parallel, you will check css before animation, and that's why you need to check if it's visible (which will mean it will be hidden once the animation is complete) and then set the corresponding + or -.


I liked the CSS-only solution from PSL, but in my case I needed to include some HTML in the button, and the content CSS property is showing the raw HTML with tags in this case.

In case that could help someone else, I've forked his fiddle to cover my use case: 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;
}

Easier with inline coding

<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>

Some may take issue with changing the Bootstrap js (and perhaps validly so) but here is a two line approach to achieving this.

In bootstrap.js, look for the Collapse.prototype.show function and modify the this.$trigger call to add the html change as follows:

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

Likewise in the Collapse.prototype.hide function change it to

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

This will toggle the text between "Collapse" when everything is expanded and "Expand" when everything is collapsed.

Two lines. Done.

EDIT: longterm this won't work. bootstrap.js is part of a Nuget package so I don't think it was propogating my change to the server. As mentioned previously, not best practice anyway to edit bootstrap.js, so I implemented PSL's solution which worked great. Nonetheless, my solution will work locally if you need something quick just to try it out.

ReferenceURL : https://stackoverflow.com/questions/16224636/twitter-bootstrap-collapse-change-display-of-toggle-button

반응형