Put event handler on a HTML button without overriding its default functionality? - javascript

I'm trying to modify a contact form so that the submit button is disabled for five seconds after being clicked, to prevent accidental repeat submissions.
The problem is that disabling the button (by setting its 'disabled' attribute) prevents it from actually submitting. Setting any kind of even handler on them seems to override the default action, even though I'm not using .preventDefault();.
Is there a way I can bind a click event handler to a button that will operate in addition to its pre-existing functionality?
Here's the code I'm using:
jQuery(function() {
jQuery(":submit").on('click', function(e) {
jQuery(this).attr('disabled','disabled');
});
});

DEMO: http://jsfiddle.net/souviiik/4AsHc/
HTML
<form action="#" id="myForm">
<input type="text">
<input type="submit" value="Submit" class="btnSubmit">
</form>
JQUERY
var st;
$("#myForm").on("submit", function () {
if ($(".btnSubmit").hasClass("btnDisabled")) {
return false;
} else {
alert("clicked!");
$(".btnSubmit").addClass("btnDisabled");
st = setInterval(enableBtn, 5000);
}
});
function enableBtn() {
$(".btnSubmit").removeClass("btnDisabled");
clearInterval(st);
}
CSS
.btnSubmit {
background: #d33;
color: #FFF;
border: 1px solid #d33;
}
.btnDisabled {
background: #fefefe;
color: #aaa;
border: 1px solid #aaa;
}

if you want to use submit button only once you can use jquery .one() function

Related

how to validate the input while entering the data using Jquery event?

how to validate the input while entering the data using Jquery event?
$("#lname").blur(function() {
if ($("#lname").val().trim().match(/^[a-zA-Z ]+$/)) {
$("#lname").css({"border":"1px solid #cecece"});
$("#error_lname").css("display","none");
}
else{
$("#error_lname").css("display","block");
}
});
If you want to validate as the user types, use the input event instead of blur:
$("#lname").on('input', function() {
if ($("#lname").val().trim().match(/^[a-zA-Z ]+$/)) {
$("#lname").css({"border":"1px solid #cecece"});
$("#error_lname").css("display","none");
}
else{
$("#error_lname").css("display","block");
}
});
You should however note that to follow best practices you should avoid using css() and instead add/remove a class that's defined in an external stylesheet, something like this:
$("#lname").on('input', function() {
var $el = $(this);
var valid = $el.val().trim().match(/^[a-zA-Z ]+$/);
$el.toggleClass('invalid', !valid);
$el.next('.error-msg').toggle(!valid);
});
.invalid { border: 1px solid #CECECE; }
Note that the above is assuming the input you're validating has a following sibling which is the error message which has the class of .error-msg. Organising the logic in this way means that the validation logic can easily be genericised - instead of being tied to each control due to the #error_lname selector.
The answer of Rory is perfect I just want to add that you can also use onkeyup event also to get the same effect.
$("#lname").on('keyup', function() {
var $el = $(this);
var valid = $el.val().trim().match(/^[a-zA-Z ]+$/);
$el.toggleClass('invalid', !valid);
$el.next('.error-msg').toggle(!valid);
});
.error-msg{
display:none;
color:red;
}
.invalid{
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="lname">Last Name:</label>
<input type="text" id="lname">
<span class="error-msg">Error message here ...</span>

:not selector with <a> in <div>

I have an a in a div and want to change the window location on click of div.
<div class="div-class">
</div>
$(document).on("click", ".div-class:not(.a-class, .a-class-2)", function() {
window.location = "/somewhere-else";
}
When clicking on either a, a new tab opens and the current window changes location. I want it to be that if you click on any a it will open a new tab, if you click on the containing div it will change window location.
To achieve this you can hook to the a elements directly and call stopPropagation() on the event passed to the handler. This will stop the event bubbling to the div and will ensure only the new tab is opened.
Similarly, you can hook to the click event of the div element to call window.location.assign() to change the page URL. Try this:
$(document).on("click", ".a-class, .a-class-2", function(e) {
e.stopPropagation();
console.log('a clicked');
}).on('click', '.div-class', function() {
console.log('div clicked');
// location.assign("/somewhere-else"); // commented out to stop breaking the snippet
});
/* this is only to make the hit areas more obvious in the snippet */
a { border: 1px solid #C00; }
div { border: 1px solid #0C0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div-class">
a-class
a-class-2
</div>
Rory's answer works, but I don't think it needs two handlers or to call stopPropagation (which can be harmful). You can filter on the event target using jQuery.is
$(document).on("click", ".div-class", function(event) {
if (!$(event.target).is(".a-class, .a-class-2")) {
console.log("going /somewhere-else");
}
// You could also do
if( $(event.target).is(".div-class") ) {
console.log("going /somewhere-else v2");
}
});
a { background-color: #eee; }
div { border: 1px solid #0C0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="div-class">
link 1
link 2
</div>

Jquery: How to dynamically bind a textbox with onload event?

A textbox is created on runtime in Javascript. It gets open when user clicks a button.
<input type="text" id="documentTitle" name="documentTitle" value="<spring:message code="document.Title"/>"
On click I want to display textbox text highlighted.
How to fire onload element using JQuery?
Tried following JQuery, but not successful:
$(document).on("load", "#documentTitle" , function() {
myquery.highlightText(this);
});
i don't what you exactly want but here some code that may help you ?
$(document).ready(function() {
alert("on load event fire");
$("button").click(function() {
$("textarea").show();
})
});
textarea {
display: block;
width: 400px;
color: black;
padding: 10px;
text-shadow: 0px 0px 2px rgba(255, 0, 0, 1);
height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea style="display:none">asdasdasd</textarea>
<button>
show
</button>
You dont have the choice there is no event fired when an arbitrary DOM element such as a <div> becomes ready.
$(document).ready(function(e) {
$(document).on("click", "#test", function() {
$("#content").append('<input type="text" id="documentTitle" name="documentTitle" value=""/>');
//do your highlight here
$("#content #documentTitle").val("test");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="test" value="test" />
<div id="content"></div>
If you really want an event you should create a custom one
$(document).ready(function(e) {
$(document).on("click", "#test", function() {
$("#content").append('<input type="text" id="documentTitle" name="documentTitle" value=""/>');
$("#content #documentTitle").trigger("myLoadedevent");
});
$(document).on("myLoadedevent", "#documentTitle", function() {
//do your highlight here
alert('event');
});
});

JQuery - Disable submit button unless original form data has changed

I found the following code here (Disable submit button unless original form data has changed) and it works but for the life of me, I can't figure out how to change the properties, text and CSS of the same submit button.
I want the text, background and hover background to be different when the button is enabled/disabled and also toggle another DIV visible/hidden.
$('form')
.each(function(){
$(this).data('serialized', $(this).serialize())
})
.on('change input', function(){
$(this)
.find('input:submit, button:submit')
.prop('disabled', $(this).serialize() == $(this).data('serialized'))
;
})
.find('input:submit, button:submit')
.prop('disabled', true);
Can someone please provide a sample. I have no hair left to pull out :-)
The answer you've copied isn't that great because a form doesn't have change or input events. Form elements do, instead. Therefore, bind the events on the actual elements within the form. Everything else looks okay except that you need to store the state of whether or not the stored/current data is equal to each other and then act accordingly. Take a look at the demo that hides/shows a div based on the state.
$('form')
.each(function() {
$(this).data('serialized', $(this).serialize())
})
.on('change input', 'input, select, textarea', function(e) {
var $form = $(this).closest("form");
var state = $form.serialize() === $form.data('serialized');
$form.find('input:submit, button:submit').prop('disabled', state);
//Do stuff when button is DISABLED
if (state) {
$("#demo").css({'display': 'none'});
} else {
//Do stuff when button is enabled
$("#demo").css({'display': 'block'});
}
//OR use shorthand as below
//$("#demo").toggle(!state);
})
.find('input:submit, button:submit')
.prop('disabled', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input name="tb1" type="text" value="tbox" />
<input name="tb2" type="text" value="tbox22" />
<input type="submit" value="Submit" />
</form>
<div id="demo" style="margin-top: 20px; height: 100px; width: 200px; background: red; display: none;">Data isn't the same as before!</div>
And the rest could be done via CSS using the :disabled selector(CSS3) or whatever is appropriate.
You can change the hover style of the button using css. CSS has hover state to target:
[type='submit']:disabled {
color: #ddd;
}
[type='submit']:disabled:hover {
background-color: grey;
color: black;
cursor: pointer;
border: none;
border-radius: 3px;
}
[type='submit']:disabled {
color: #ccc;
}
For showing and hiding, there are many tricks to do it. I think following would be the simplest trick to do and and easier for you to understand.
Add this in your html
<div id="ru" class="hide">this is russia</div>
<div id="il" class="hide">this is israel</div>
<div id="us" class="hide">this is us</div>
<div id="in" class="hide">this is india</div>
Add this in your css
.hide {
display: none;
background: red;;
}
Update your javascript like following:
$('form').bind('change keyup', function () {
.....
// get id of selected option
var id = $("#country-list").find(":selected").val();
$('.hide').hide(); // first hide all of the divs
$('#' + id).show(); // then only show the selected one
....
});
Here is the working jsfiddle. Let me know if this is not what you are looking for and I will update the answer.
The detection of change occurs on change input event.
You can change your code to the following in order to use this calculated value:
$('form')
.each(function(){
$(this).data('serialized', $(this).serialize())
})
.on('change input', function(){
var changed = $(this).serialize() != $(this).data('serialized');
$(this).find('input:submit, button:submit').prop('disabled', !changed);
// do anything with your changed
})
.find('input:submit, button:submit')
.prop('disabled', true)
It is good if you want to work with other divs. However, for styling, it is better to use CSS :disabled selector:
For example, in your CSS file:
[type='submit']:disabled {
color: #DDDDDD;
}
[type='submit']:disabled {
color: #CCCCCC;
}

css/javascript element returning false when it should return true

I have a one field form (text input and submit button). Here is the form code:
<form id="new_skill" class="new_skill" method="post" action="/skills" >
<li>
<input id="resume-field" class="field field288" type="text"
value="Type a speciality you want to add to your profile"
title="Type a speciality you want to add to your profile"
name="skill[label]"></input>
</li>
<li class="td80">
<input class="button button-add button-add-disabled"
type="submit" value="ADD +" name="commit"></input>
</li>
</form>
Using javascript, if text is entered in the text field, the submit button should be unclickable. If there is no text in the field, it should be clickable. I am doing that by using javascript to remove and/or put back the button-add-disabled class. Here is the javascript:
(function($){
$(document).on('focusin', '#resume-field', function() {
$(this).parents().find('.button-add-disabled').removeClass('button-add-disabled');
}).on('focusout', '#resume-field', function(){
if(this.value==' '||this.title==this.value) {
$(this).parents().find('.button-add').addClass('button-add-disabled');
} else {
$(this).parents().find('.button-add').removeClass('button-add-disabled');
}
});
$('.button-add-disabled').click(function(){
return false;
});
}(jQuery));
And here is the css:
.button-add { width: 49px; height: 28px; border: solid 1px #8c8c8c; display: block;
font-size: 11px; line-height: 28px ; color: #fff; text-align: center;
font-family: 'Ubuntu', sans-serif; transition: none; margin: 0 0 0 auto;
border-radius: 3px; }
.button-add:hover { text-decoration: none;
-webkit-transition:none;
-moz-transition:none;
-ms-transition:none;
-o-transition:none;
transition:none;
}
.td80 .button-add { margin-left:35px !important; }
.button-add-disabled { background: url(/assets/add-specialities-disabled.png)
repeat-x 0 0; box-shadow: 0 0 0 0; margin-left:35px; }
.button-add-disabled:hover { background: url(/assets/add-specialities-disabled.png)
repeat-x 0 0; box-shadow: 0 0 0 0; }
The classes are changing as expected and the javascript is working. For some reason though, even if .button-add-disabled is not applied to the form element, the form element is still returning false and therefore won't submit. When "button-add-disabled" is removed by the javascript, the form should submit. I can see the server logs. If I remove the line from the javascript "return: false", the form works, So i know the form itself works. I'm pretty sure something is wrong with the javascript. Any ideas?
That's not how that works. Events are bound to elements, which are reached via selectors; they are not bound to selectors.
When you bind the event directly to the element, the event is now bound to that element until you explicitly unbind it. The original selector is no longer relevant.
You need to do this, or something like it:
$('.button-add-disabled').click(function(){
return !$(this).hasClass('button-add-disabled');
});
That is, test whether the button is currently disabled by your class at the point the event is raised.
As an aside, this...
if(this.value==' '||this.title==this.value) {
$(this).parents().find('.button-add').addClass('button-add-disabled');
} else {
$(this).parents().find('.button-add').removeClass('button-add-disabled');
}
should be this:
var disabled = this.value == ' ' || this.title == this.value;
$(this).parents().find('.button-add').toggleClass('button-add-disabled', disabled);
You want to set/remove the disabled attribute of the input element, not set a CSS style which is for display purposes only
$('#resume-field').on('change', function() {
if ($(this).val().length == 0) {
$(this.form).find('input[type=submit]').attr('disabled', false).removeClass('button-add-disabled');
} else {
$(this.form).find('input[type=submit]').attr('disabled', true).addClass('button-add-disabled');
}
})
jsFiddle Demo
Also be sure that you handle the submission of the form when the user presses enter in the input field, you can do that using the jQuery .submit event handler and preventing the default behaviour. It is also essential you handle this server side.
EDIT: I just noticed what the CSS was doing, updated answer.

Categories

Resources