Twitter Bootstrap alert message close and open again

JavascriptJqueryTwitter BootstrapAlert

Javascript Problem Overview


I have a problem with alert messages. It is displayed normally, and I can close it when the user presses x (close), but when the user tries to display it again (for example, click on the button event) then it is not shown. (Moreover, if I print this alert message to console, it is equal to [].) My code is here:

 <div class="alert" style="display: none">
   <a class="close" data-dismiss="alert">×</a>
   <strong>Warning!</strong> Best check yo self, you're not looking too good.
 </div>

And event:

 $(".alert").show();

P.S! I need to show alert message only after some event happened (for example, button clicked). Or what I am doing wrong?

Javascript Solutions


Solution 1 - Javascript

Data-dismiss completely removes the element. Use jQuery's .hide() method instead.

The fix-it-quick method:

Using inline javascript to hide the element onclick like this:

<div class="alert" style="display: none"> 
    <a class="close" onclick="$('.alert').hide()">×</a>  
    <strong>Warning!</strong> Best check yo self, you're not looking too good.  
</div>

<a href="#" onclick="$('alert').show()">show</a>

http://jsfiddle.net/cQNFL/

This should however only be used if you are lazy (which is no good thing if you want an maintainable app).

The do-it-right method:

Create a new data attribute for hiding an element.

Javascript:

$(function(){
    $("[data-hide]").on("click", function(){
        $("." + $(this).attr("data-hide")).hide()
        // -or-, see below
        // $(this).closest("." + $(this).attr("data-hide")).hide()
    })
})

and then change data-dismiss to data-hide in the markup. Example at jsfiddle.

$("." + $(this).attr("data-hide")).hide()

This will hide all elements with the class specified in data-hide, i.e: data-hide="alert" will hide all elements with the alert class.

Xeon06 provided an alternative solution:

$(this).closest("." + $(this).attr("data-hide")).hide()

This will only hide the closest parent element. This is very useful if you don't want to give each alert a unique class. Please note that, however, you need to place the close button within the alert.

Definition of .closest from jquery doc:

> For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

Solution 2 - Javascript

I just used a model variable to show/hide the dialog and removed the data-dismiss="alert"

Example:

<div data-ng-show="vm.result == 'error'" class="alert alert-danger alert-dismissable">
    <button type="button" class="close" data-ng-click="vm.result = null" aria-hidden="true">&times;</button>
    <strong>Error  !  </strong>{{vm.exception}}
</div>

works for me and stops the need to go out to jquery

Solution 3 - Javascript

I think a good approach to this problem would be to take advantage of Bootstrap's close.bs.alert event type to hide the alert instead of removing it. The reason why Bootstrap exposes this event type is so that you can overwrite the default behavior of removing the alert from the DOM.

$('.alert').on('close.bs.alert', function (e) {
	e.preventDefault();
	$(this).addClass('hidden');
});

Solution 4 - Javascript

If you're using an MVVM library such as knockout.js (which I highly recommend) you can do it more cleanly:

<div class="alert alert-info alert-dismissible" data-bind="visible:showAlert">
   <button type="button" class="close" data-bind="click:function(){showAlert(false);}>
        <span aria-hidden="true">&times;</span>
        <span class="sr-only">Close</span>
   </button>
   Warning! Better check yourself, you're not looking too good.
</div>

http://jsfiddle.net/bce9gsav/5/

Solution 5 - Javascript

This worked for me best:

$('.alert').on('close.bs.alert', function (e) {
    e.preventDefault();
    $(this).hide();
});

Solution 6 - Javascript

So if you want a solution that can cope with dynamic html pages, as you already include it you should use jQuery's live to set the handler on all elements that are now and in future in the dom or get removed.

I use

$(document).on("click", "[data-hide-closest]", function(e) {
  e.preventDefault();
  var $this = $(this);
  $this.closest($this.attr("data-hide-closest")).hide();
});

.alert-success {
    background-color: #dff0d8;
    border-color: #d6e9c6;
    color: #3c763d;
}
.alert {
    border: 1px solid transparent;
    border-radius: 4px;
    margin-bottom: 20px;
    padding: 15px;
}
.close {
    color: #000;
    float: right;
    font-size: 21px;
    font-weight: bold;
    line-height: 1;
    opacity: 0.2;
    text-shadow: 0 1px 0 #fff;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alert alert-success">
  <a class="close" data-hide-closest=".alert">×</a>
  <strong>Success!</strong> Your entries were saved.
</div>

Solution 7 - Javascript

All of the above solutions use external libraries, either angular or jQuery, and an old version of Bootstrap. So, here is Charles Wyke-Smith's solution in pure JavaScript, applied to Bootstrap 4. Yes, Bootstrap requires jQuery for its own modal and alerts code, but not everyone writes their own code with jQuery any more.

Here is the html of the alert:

<div id="myAlert" style="display: none;" 
    class="alert alert-success alert-dismissible fade show">
    <button type="button" class="close" data-hide="alert">&times;</button>
    <strong>Success!</strong> You did it!
</div>

Note that initially the alert is hidden (style="display: none;"), and instead of the standard data-dismiss="alert", we have here used data-hide="alert".

Here is the JavaScript to show the alert and override the close button:

var myAlert = document.getElementById('myAlert');
// Show the alert box
myAlert.style.display = 'block';
// Override Bootstrap's standard close action
myAlert.querySelector('button[data-hide]').addEventListener('click', function() {
    myAlert.style.display = 'none';
});

If you wish to hide or show the alert programmatically elsewhere in the code, just do myAlert.style.display = 'none'; or myAlert.style.display = 'block';.

Solution 8 - Javascript

I ran into this problem as well and the the problem with simply hacking the close-button is that I still need access to the standard bootstrap alert-close events.

My solution was to write a small, customisable, jquery plugin that injects a properly formed Bootstrap 3 alert (with or without close button as you need it) with a minimum of fuss and allows you to easily regenerate it after the box is closed.

See https://github.com/davesag/jquery-bs3Alert for usage, tests, and examples.

Solution 9 - Javascript

I agree with the answer posted by Henrik Karlsson and edited by Martin Prikryl. I have one suggestion, based on accessibility. I would add .attr("aria-hidden", "true") to the end of it, so that it looks like:

$(this).closest("." + $(this).attr("data-hide")).attr("aria-hidden", "true");

Solution 10 - Javascript

The problem is caused by using the style="display:none", you should hide the alert with Javascript or at least when showing it, remove the style attribute.

Solution 11 - Javascript

Based on the other answers and changing data-dismiss to data-hide, this example handles opening the alert from a link and allows the alert to be opened and closed repeatedly

$('a.show_alert').click(function() {
    var $theAlert = $('.my_alert'); /* class on the alert */
    $theAlert.css('display','block');
   // set up the close event when the alert opens
   $theAlert.find('a[data-hide]').click(function() {
     $(this).parent().hide(); /* hide the alert */
   });
});

Solution 12 - Javascript

I've tried all the methods and the best way for me is to use the built-in bootstrap classes .fade and .in

Example:

<div class="alert alert-danger fade <?php echo ($show) ? 'in' : '' ?>" role="alert">...</div>

Note: In jQuery, addClass('in') to show the alert, removeClass('in') to hide it.

Fun fact: This works for all elements. Not just alerts.

Solution 13 - Javascript

Here is a solution based on the answer by Henrik Karlsson but with proper event triggering (based on Bootstrap sources):

$(function(){
	$('[data-hide]').on('click', function ___alert_hide(e) {
		var $this = $(this)
		var selector = $this.attr('data-target')
		if (!selector) {
			selector = $this.attr('href')
			selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
		}

		var $parent = $(selector === '#' ? [] : selector)

		if (!$parent.length) {
			$parent = $this.closest('.alert')
		}

		$parent.trigger(e = $.Event('close.bs.alert'))

		if (e.isDefaultPrevented()) return

		$parent.hide()

		$parent.trigger($.Event('closed.bs.alert'))
	})
});

The answer mostly for me, as a note.

Solution 14 - Javascript

Can this not be done simply by adding a additional "container" div and adding the removed alert div back into it each time. Seems to work for me?

HTML

<div id="alert_container"></div>

JS

 $("#alert_container").html('<div id="alert"></div>');			
 $("#alert").addClass("alert alert-info  alert-dismissible");
 $("#alert").html('<a href="#" class="close" data-dismiss="alert" aria-label="close">&times;</a><strong>Info!</strong>message');

Solution 15 - Javascript

There's a very simple way to do this using JQuery

If you delete data-dismiss="alert" from the alert div, you can just hide the alert using the x button, by adding a click events and interacting with the display css attribute of the alert.

$(".close").click(function(){
   $(this).parent().css("display", "none");
});

Then, whenever you need it again, you can toggle the display attribute again.

Full Example:

<div class="alert alert-danger" role="alert" id="my_alert" style="display: none;">
   Uh Oh... Something went wrong
  <button type="button" class="close" aria-label="Close">
     <span aria-hidden="true">&times;</span>
  </button>
</div>

<script>
   $(".close").click(function(){
      $(this).parent().css("display", "none");
   });

   //Use whatever event you like
   $("#show_alert").click(function(){
      $("#my_alert).css("display", "inherit");
   });
<script>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser721588View Question on Stackoverflow
Solution 1 - JavascriptHenrik KarlssonView Answer on Stackoverflow
Solution 2 - Javascriptuser1661621View Answer on Stackoverflow
Solution 3 - JavascriptkimbaudiView Answer on Stackoverflow
Solution 4 - JavascriptOhad SchneiderView Answer on Stackoverflow
Solution 5 - JavascriptLonareView Answer on Stackoverflow
Solution 6 - JavascriptJoschiView Answer on Stackoverflow
Solution 7 - JavascriptJaifroidView Answer on Stackoverflow
Solution 8 - JavascriptDave SagView Answer on Stackoverflow
Solution 9 - JavascriptcfnerdView Answer on Stackoverflow
Solution 10 - JavascriptPlamen NikolovView Answer on Stackoverflow
Solution 11 - JavascriptCharles Wyke-SmithView Answer on Stackoverflow
Solution 12 - JavascriptclodalView Answer on Stackoverflow
Solution 13 - JavascriptmaxkoryukovView Answer on Stackoverflow
Solution 14 - JavascriptLightning_youngView Answer on Stackoverflow
Solution 15 - JavascriptOscar ChambersView Answer on Stackoverflow