How to prevent bootstrap modal from closing from button using onclick? - javascript

i have modal with button (Save)
<button type="button" class="btn btn-success btn-sm" data-dismiss="modal" onclick="do_save()">Save
</button>
how to prevent closing when do_save() function failed? (for example when some data fails to validate)

Don't use the data-dismiss="modal" and let your function close (hide) your modal:
<button type="button" class="btn btn-success btn-sm" onclick="do_save()">Save</button>
"
function do_save()
{
if(Math.floor(Math.random() * 2)==1)
{
console.log('success');
$('#myModal').modal('hide');
return;
}
console.log('failure');
return false;
}

If you catch the click-event from the button like this:
$('#buttonId').off('click').click(function(clickEvent){
//enter code here
});
you actually can prevent the closing of your modal. For this, depending on your situation, you will find these two functions useful:
clickEvent.preventDefault();
clickEvent.stopPropagation();
If I understood this site (which is in German)
http://www.mediaevent.de/javascript/event-handler-default-verhindern.html
correctly, preventDefault() stops the immediate default action (such as following a link). However, the event itself will still travel through the DOM and can be "heard" by various event listeners, one of these is the event listener that hides the modal. For this the second function is needed, which stops the event's travel through the DOM. Thus, it can't be heard by the hiding listener and the window won't be closed (hidden). Therefore, I suggest to implement the functions like so:
$('#buttonId').off('click').click(function(clickEvent){
//enter code here
var myDataIsValid = true;
// check if Data is valid => myDataIsValid = true or false
if(myDataIsValid){
//do Stuff
}else{
clickEvent.preventDefault();
clickEvent.stopPropagation();
//do other Stuff
}
});
In my code, I only need to use stopPropagation(), as my default action is wanted, so you can use the two functions independently.
note: This solution only was tested with a Firefox browser

Since you are using jQuery anyway, try not to have JavaScript/jQuery embedded in your code.
$('#buttonId').on( 'click', function () {
// either call do_save or embed the contents of do_save in here
var myDataIsValid = true; // change to call validator function
if (myDataIsValid) {
$('#myModal').modal('hide');
}
return true; // value depends on whether you want stopPropagation or not.
});
HTML:
<button id="buttonId" type="button" class="btn btn-success btn-sm">Save</button>
As an alternative, you can probably prevent closing by intercepting the 'hide' event and returning false from that.

If you are using bootstrap 4 this is called a "static backdrop" and can be achieved by adding the data-backdrop="static" attribute
<div class="modal fade" id="modalExample" data-backdrop="static">
src: Bootstrap 4 Modal - Static backdrop

Related

Disable window beforeunload property for one button

I have disabled page redirects/reloads with window.beforeunload function, but once the form submission happens in the page, I want to redirect to the next page, without showing the window.beforeunload alerts. How can I do that?
$(window).on("beforeunload", function () {
return "Changes won't be saved.";
});
This is the button that shouldn't trigger the alert:
<form id="command" action="/some-uri" method="post">
<button type="submit" value="NEXT" class="btn btn-red- light">NEXT</button>
</form>
Check a variable
pseudo code
if some dirty change -> window.hasSomeDirtyChanges = true;
if all dirty changes saved -> window.hasSomeDirtyChanges = false;
$(window).on("beforeunload", function () {
if(!window.hasSomeDirtyChanges) return true;
return "Changes won't be saved.";
});
So this way you don't have to bind unbind every time you go to a page. This will work for all the pages, you just need to manage a variable.
add a class to every element that you don't want to trigger the event, for example ".not-trigger", then:
$(".not-trigger").on("click", function(){
$(window).off("beforeonunload");
});

Why doesn't react disable the onClick handler when disabled is true?

I would expect that setting the disabled attribute on a react component would block the onClick handler for that element.
<a role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
href={this.state.selectedObjectLink}
onClick={this.handleLink}
>View</a>
but although the element shows a "disabled" attribute it still registers a click event.
Edit: I should clarify - I handle the click event in handleLink, I want to know why the disabled attribute doesn't remove the handler? Sorry for any confusion.
The problem isn't with disabled; it's with the HTML element a. Anchor <a> cannot have a disabled property (what does that even mean?). Just because you've passed CSS to make the element look like a button, doesn't make it a button. It is still an anchor.
The solution would be either to use something else (like button):
<button
role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
onClick={this.handleLink}
>
View
</button>
You can use this.state.selectedObjectLink inside handleLink if you want to redirect to a page
Or use one of the many other suggestions on this page.
Why not just handle this in handleLink?
handleLink () {
if (!this.state.readyToView) return
// ...
}
If you really want to bind/remove the handler dynamically, you can do something like this:
const clickHandler = this.state.readyToView ? this.handleLink : null
...
<a role="button"
...
...
onClick={clickHandler}
>View</a>
You can add a condition in your click handler, something like this
<a role="button"
className={`btn btn-block btn-info`}
disabled={!this.state.readyToView}
onClick={this.state.readyToView && this.handleLink}
>
View
</a>
jsfiddle
If you are using react version 16 and up
on onClick don't call the method directly use () => method instead like this
const handleRemoveBtnClick = () => {
...
}
<button ...onClick={() => handleRemoveBtnClick} />
Another trick to disable the click to any components is to use useState with boolean value either true to disable or false to resume the click functionality
example
export default const ElementComponent() =>{
//set the initial value of disable click to false
const [disableClick,setDisableClick] = useState(false)
const anotherFunction =() =>{
console.log("I've been run")
}
const handleClick()=>{
//if disableClick is false then run this if block, else don't do anything
if(!disableClick){
anotherFunction()
}
}
return(
<img src="..." onClick={handleClick}/>
)
}
the good thing about this is that we can pass the function as a props to another components and we can run it there, we can even let's say disable a click for let's say 1 second using setTimeout function, there are tons of way you can use this method, hope it helps anyone if you want to use onClick not only on the button element itself

Disabled button still fires using ".click()"

It seems disabled button "onclick" function is still fired when triggering it programmaticaly, eg:
<div>
<input type="button" onclick="save()" id="saveButton" value="save" disabled="disabled" />
<input type="button" onclick="byPassDisabled()" value="bypass disabled button"/>
<div id="counter">0</div>
function save(){
var count = parseInt($('#counter').html());
$('#counter').html(++count);
}
function byPassDisabled(){
$('#saveButton').click();
}
see http://jsfiddle.net/WzEvs/363/
In my situation, keyboards shortcuts are bound to functions triggering the ".click()" on buttons. I'll find it very annoying to have to disable the shorcuts or check if the button is disabled myself. I'd prefer a general solution fixing this problem.
But why? This behavior doesn't seem fair to me.
Any workaround?
The attribute only disables user interaction, the button is still usable programmatically.
So yeah, you gotta check
function byPassDisabled(){
$('#saveButton:enabled').click();
}
Alternatively don't use inline handlers.
$(document).on('click', '#saveButton:enabled', function(){
// ...
});
For future use...the OP code works because jQuery will still call it's own handlers even if the DOM element is disabled. If one were to use vanilla javascript, the disabled attribute would be honored.
const element = document.getElementById('saveButton');
element.click() //this would not work
You can programmatically trigger click on a disabled button.
There are ways to find if the event is a click on button by user or it has been trigger programmatically. http://jsfiddle.net/WzEvs/373/
$(function () {
$("#saveButton").on('click', function (e) {
if (!e.isTrigger) {
var count = parseInt($('#counter').html());
$('#counter').html(++count);
}
});
$("#bypassButton").on('click', function (e) {
$("#saveButton").click();
});
});
e.isTrigger is true if you call the click() programmatically. Basically you are triggering the click event manually in code.
You can trigger click still although made it disable .As Spokey said it just shows the user-interaction(the usability still persists that can be turned on programmatically) .
off or unbind the click will solve this issue.
Thanks

Handle consecutive button clicks in jQuery

Question: How to handle consecutive button clicks in jQuery. For example I am submitting the form to server but in the meantime user clicks button again then duplicate request has been generated for the same. How to handle this efficiently in jQuery.
HTML Code:
<a id="submitBtn" href="javascript:void(0);"
onclick="login.validateLogin();"
class="btn btn-lg btn-success btn-block">Login</a>
jQuery code:
var login = {
validateLogin:function(){
$("#errormsg").hide();
login.validate();
if($('#loginForm').valid() === false){
return;
}
$("#submitBtn").prop('onclick',null);
/* Server request */
},
validate:function(){
$("#loginForm").validate({
ignore:"",
submitHandler: function(form) { return false; }
});
},
}
Disable the <submit> button or any other button which on clicked, submits the form, so only first click gets counted and the end user is prevented from clicking it. It is also semantic way of doing as just unbinding any event associated with the button while still allowing to click, will in some way confuse the users.
$("#loginForm").validate({
ignore: "",
submitHandler: function(form) {
$('#submitBtn').prop('disabled', true); // disable so it won't be clicked
return false;
}
});
Not sure why you have the .validate() method inside a function like that. The .validate() method is supposed to be called once and only used for initializing the plugin.
You should use a type="submit" button so that you can properly integrate with the plugin and enable/disable it much easier than trying to manually capture/deactivate/activate an anchor element. (Use CSS on the button element to make it look exactly like your anchor element.)
Then use .prop('disabled', 'disabled') within the submitHandler to disable the button as soon as the properly validated form is submitted.
As you can see by the demo, most of your code was not needed as the plugin takes care of nearly everything automatically.
$(document).ready(function() {
$("#loginForm").validate({ // <- initialize plugin on form
ignore: [], // <- proper way to set ignore to nothing
submitHandler: function(form) {
$('#submitBtn').prop('disabled', 'disabled');
alert('submitted'); // <- for demo
return false;
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.1/jquery.validate.js"></script>
<form id="loginForm">
<button id="submitBtn" class="btn btn-lg btn-success btn-block">Login</button>
</form>

Ajax request on dismissal of twitter bootstrap alerts

I'm using the "alert" functionality from Twitter Bootstrap to display user notifications, like so:
<div class="notification alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
My message goes here
</div>
These notifications are persistent until the user dismisses them, so when the user clicks the "close" button I would like to fire off an ajax query to the server indicating that the notification should be permanently dismissed.
I'm using jQuery's on() function like so:
$(document).on('click', '.notification .close', function (e) {
alert('hi!');
console.log(e);
e.preventDefault();
});
This works fine, but I'm wondering if there is there a "Bootstrappy" way of doing this?
In Bootstrap 3.0 you need to use namespaced event name:
$('.alert').bind('closed.bs.alert', function () {
var id = $(this).data('some_id');
$.get('closed.php?id='+id);
})
According to the Bootstrap docs on alerts, I'd bind to the closed or close event, which are custom to Bootstrap.
$(document).on('close', '.alert', function ()
{
var id = $(this).data('some_id');
$.get('closed.php?id='+id);
});
there are two events exposed via the API:
close - which is fired immediately
closed - fires after all animations have completed. I'd opt for close - this way you do it immediately and if they navigate / close before the animation completes, it will still be hidden.
The data attribute is to be able to have the server side script differentiate between the alerts. The markup would be:
<div class="alert" data-some_id='foobar'>
Close me!
</div>

Categories