I need to have an onclick event on an <input> tag which is disabled.
Here onclick event doesn't work.
Is there any other way to work with onclick event for disabled input based on id?
I tried the code below.
First input worked but I need worked same as second one also same as of first one. (I need to call function Clicked on input only).
My code:
function Clicked(event)
{
alert(event.id)
}
function ClickedDisabled(event)
{
alert(event.ids)
}
<input type="text" id="ID" onclick="Clicked(this)" />
<input type="text" id="IDs" onclick="ClickedDisabled(this)" disabled />
function Clicked(event) {
alert(event.id)
}
function ClickedDisabled(event) {
alert(event.id)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<input type="text" id="ID" onclick="Clicked(this)" />
<span style="position:relative;">
<input type="text" id="IDs" disabled />
<div style="position:absolute; left:0; right:0; top:0; bottom:0; cursor: pointer;" id="IDs" onclick="ClickedDisabled(this)"></div>
</span>
Try this it may help you
Put
input[disabled] {pointer-events:none}
in your CSS (it prevents some browsers from discarding clicks on disabled inputs altogether), and capture the click on a parent element. It's a cleaner solution, IMHO, than putting a transparent overlay over the element to capture the click, and depending on circumstances may also be much easier than simply "simulating" the disabled state using CSS (since that won't prevent the input from being submitted, and also requires overriding the default browser 'disabled' style).
If you have multiple such buttons, you'll need a unique parent for each, in order to be able to distinguish which button was clicked, because with pointer-events:none, the click target is the button's parent rather than the button itself. (Or you could test the click coordinates, I suppose...).
If you need to support older browsers, though, do check which ones support pointer-events: http://caniuse.com/#search=pointer-events
Related
Apparently a disabled <input> is not handled by any event
Is there a way to work around this issue ?
<input type="text" disabled="disabled" name="test" value="test" />
$(':input').click(function () {
$(this).removeAttr('disabled');
})
Here, I need to click on the input to enable it. But if I don't activate it, the input should not be posted.
Disabled elements don't fire mouse events. Most browsers will propagate an event originating from the disabled element up the DOM tree, so event handlers could be placed on container elements. However, Firefox doesn't exhibit this behaviour, it just does nothing at all when you click on a disabled element.
I can't think of a better solution but, for complete cross browser compatibility, you could place an element in front of the disabled input and catch the click on that element. Here's an example of what I mean:
<div style="display:inline-block; position:relative;">
<input type="text" disabled />
<div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>
jq:
$("div > div").click(function (evt) {
$(this).hide().prev("input[disabled]").prop("disabled", false).focus();
});
Example: http://jsfiddle.net/RXqAm/170/ (updated to use jQuery 1.7 with prop instead of attr).
Disabled elements "eat" clicks in some browsers - they neither respond to them, nor allow them to be captured by event handlers anywhere on either the element or any of its containers.
IMHO the simplest, cleanest way to "fix" this (if you do in fact need to capture clicks on disabled elements like the OP does) is just to add the following CSS to your page:
input[disabled] {pointer-events:none}
This will make any clicks on a disabled input fall through to the parent element, where you can capture them normally. (If you have several disabled inputs, you might want to put each into an individual container of its own, if they aren't already laid out that way - an extra <span> or a <div>, say - just to make it easy to distinguish which disabled input was clicked).
The downside is that this trick unfortunately won't works for older browsers that don't support the pointer-events CSS property. (It should work from IE 11, FF v3.6, Chrome v4): caniuse.com/#search=pointer-events
If you need to support older browsers, you'll need to use one of the other answers!
Maybe you could make the field readonly and on submit disable all readonly fields
$(".myform").submit(function(e) {
$("input[readonly]").prop("disabled", true);
});
and the input (+ script) should be
<input type="text" readonly="readonly" name="test" value="test" />
$('input[readonly]').click(function () {
$(this).removeAttr('readonly');
});
A live example:
$(".myform").submit(function(e) {
$("input[readonly]").prop("disabled", true);
e.preventDefault();
});
$('.reset').click(function () {
$("input[readonly]").prop("disabled", false);
})
$('input[readonly]').click(function () {
$(this).removeAttr('readonly');
})
input[readonly] {
color: gray;
border-color: currentColor;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="myform">
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<input readonly="readonly" value="test" />
<button>Submit</button>
<button class="reset" type="button">Reset</button>
</form>
I would suggest an alternative - use CSS:
input.disabled {
user-select : none;
-moz-user-select : none;
-webkit-user-select : none;
color: gray;
cursor: pointer;
}
instead of the disabled attribute. Then, you can add your own CSS attributes to simulate a disabled input, but with more control.
$(function() {
$("input:disabled").closest("div").click(function() {
$(this).find("input:disabled").attr("disabled", false).focus();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div>
<input type="text" disabled />
</div>
Instead of disabled, you could consider using readonly. With some extra CSS you can style the input so it looks like an disabled field.
There is actually another problem. The event change only triggers when the element looses focus, which is not logic considering an disabled field. Probably you are pushing data into this field from another call. To make this work you can use the event 'bind'.
$('form').bind('change', 'input', function () {
console.log('Do your thing.');
});
OR do this with jQuery and CSS!
$('input.disabled').attr('ignore','true').css({
'pointer-events':'none',
'color': 'gray'
});
This way you make the element look disabled and no pointer events will fire, yet it allows propagation and if submitted you can use the attribute 'ignore' to ignore it.
We had today a problem like this, but we didn't wanted to change the HTML. So we used mouseenter event to achieve that
var doThingsOnClick = function() {
// your click function here
};
$(document).on({
'mouseenter': function () {
$(this).removeAttr('disabled').bind('click', doThingsOnClick);
},
'mouseleave': function () {
$(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled');
},
}, 'input.disabled');
I did something very similar the Andy E; except I used a surrounding tag. However, I needed the 'name' so I changed it to an tag without the 'href'.
There is no reason you can't simulate the disabled attribute using a combination of CSS and readonly:
Faux-Disabled: <input type="text" value="1" readonly="1" style="background-color:#F6F6F6;"><br>
Real-Disabled: <input type="text" disabled="true" value="1"></input>
Note: This will not have the regular behavior of disabled in the <form>, which prevents the server from seeing the field. This is just in case you want to disable a field that doesn't matter server-side.
I find another solution:
<input type="text" class="disabled" name="test" value="test" />
Class "disabled" immitate disabled element by opacity:
<style type="text/css">
input.disabled {
opacity: 0.5;
}
</style>
And then cancel the event if element is disabled and remove class:
$(document).on('click','input.disabled',function(event) {
event.preventDefault();
$(this).removeClass('disabled');
});
suggestion here looks like a good candidate for this question as well
Performing click event on a disabled element? Javascript jQuery
jQuery('input#submit').click(function(e) {
if ( something ) {
return false;
}
});
I have an input button, which when it is disabled, and someone tries to click it, needs to display an alert.
How is it possible to display a javascript message despite being disabled?
Tried this with no luck:
<input type="submit" onclick="alert('click')" value="Disabled Input Button" disabled/>
Use onmousedown instead of onclick, which is only fired when it is 'allowed' to. Some browsers, particularly Chrome, appear to disable all DOM events when a form element is disabled. While I think this is out of spec, you can use the following workaround:
Instead of using the disabled attribute, use CSS pointer-events to achieve a similar effect, illustrated here:
button.disabled {
pointer-events:none;
}
And then just use <button class="disabled"> instead of <button disabled>.
<span onclick="alert('This input is disabled')">
<input type="submit" value="Disabled Input Button" disabled/>
</span>
Wrapping it with another tag that has the on click function works.
So, for example, here's a script:
<!-- Random content above this comment -->
<input type="text" tabindex="1" />
<input type="text" tabindex="2" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<!-- Nothing underneath this comment -->
So, when the user presses tab and goes through the six textboxes, reaches the last one and then presses tab, it would go to the content above the first comment, right? Well, how do I make it start from tabindex="1" again?
Unfortunately, you can't do that without javascript. You can listen to a TAB (and make sure it's not SHIFT+TAB) key press on your last element and manually set the focus to your first element inside the handler. However, binding this logic to keyboard events (i.e. specific input method) is not universal and may not work when using:
A mobile browser
Some other entertainment device (smart tv, gaming console, etc. - they typically use a D-Pad for jumping between focusable elements)
An accessibility service
I suggest a more universal approach which is agnostic of how the focus is changed.
The idea is that you surround your form elements (where you want to create a "tabindex loop") with special "focus guard" elements that are focusable too (they have a tabindex assigned). Here is your modified HTML:
<p>Some sample content here...</p>
<p>Like, another <input type="text" value="input" /> element or a <button>button</button>...</p>
<!-- Random content above this comment -->
<!-- Special "focus guard" elements around your
if you manually set tabindex for your form elements, you should set tabindex for the focus guards as well -->
<div class="focusguard" id="focusguard-1" tabindex="1"></div>
<input id="firstInput" type="text" tabindex="2" class="autofocus" />
<input type="text" tabindex="3" />
<input type="text" tabindex="4" />
<input type="text" tabindex="5" />
<input type="text" tabindex="6" />
<input id="lastInput" type="text" tabindex="7" />
<!-- focus guard in the end of the form -->
<div class="focusguard" id="focusguard-2" tabindex="8"></div>
<!-- Nothing underneath this comment -->
Now you just listen to focus events on those guard elements and manually change focus to the appropriate field (jQuery used for the sake of simplicity):
$('#focusguard-2').on('focus', function() {
// "last" focus guard got focus: set focus to the first field
$('#firstInput').focus();
});
$('#focusguard-1').on('focus', function() {
// "first" focus guard got focus: set focus to the last field
$('#lastInput').focus();
});
As you see, I also made sure that we snap back to the last input when the focus moves backwards from the first input (e.g. SHIFT+TAB on the first input). Live example
Note that the focus guards are assigned a tabindex value too to make sure they are focused immediately before/after your input fields. If you don't manually set tabindex to your inputs, then both focus guards can just have tabindex="0" assigned.
Of course you can make this all work in a dynamic environment as well, when your form is generated dynamically. Just figure out your focusable elements (less trivial task) and surround them with the same focus guards.
Hope that helps, let me know if you have any issues.
UPDATE
As nbro pointed out, the above implementation has the unwanted effect of selecting the last element if one hits TAB after the page loads (as this would focus the first focusable element which is #focusguard-1, and that would trigger focusing the last input. To mitigate that, you can specify which element you want initially focused and focus it with another little piece of JavaScript:
$(function() { // can replace the onload function with any other even like showing of a dialog
$('.autofocus').focus();
})
With this, just set the autofocus class on whatever element you want, and it'll be focused on page load (or any other event you listen to).
Here my solution where you no need any other elements. As you can see elements will be looping inside <form> elements.
$('form').each(function(){
var list = $(this).find('*[tabindex]').sort(function(a,b){ return a.tabIndex < b.tabIndex ? -1 : 1; }),
first = list.first();
list.last().on('keydown', function(e){
if( e.keyCode === 9 ) {
first.focus();
return false;
}
});
});
Here is my solution, considering the first input has the "autofocus" attribute set:
Add this after your form element (with HTML5 it can be any tag):
<div tabindex="6" onFocus="document.querySelector('[autofocus]').focus()"></div>
Yes, after tabbing through the inputs it will jump on suitable elements that do not have a tab order specified. But also, after tabbing all "tabbable" elements, the focus will jump "outside" your page content, onto the browser's UI elements (tabs, menus, bookmarks, etc)
I think the easiest way is to handle the keyup event on the last input and intercept TAB usage (and SHIFT+TAB for that matter)
I wd suggest you to increase your tabindex ie. >100
and also give the tabIndex to your "content" container div
please note that your content container must have tabindex less than input boxes for ex.99 .
when you press tab on last input box manually set focus on your content div using javascript (you can use keypress handlers for tab key)
document.getElementById("content").focus();
you must giv tabindex to your "content" to set focus to it.
now if you press tab focus will automatically shift to first input box.
hope this will help.
Thank you
I'm trying to re-skin the input type file element.
I do this by placing two elements on top of each other. One of them is the input tag and the other is a nice button. Something like this:
<input type="file" id="filesButton" multiple>
<input type="button" id="filesButtonOverlay" value="Add Files">
The button has some nice effects when a user hovers, clicks, etc (all done is CSS). However since the input-type-file has a higher z-index (needs to be the case since you can't emulate a click on it) all these effects don't show.
Is there a nice way to delegate all events that input-type-file gets and trigger them on the button?
What if you wrapped the inputs in a div and attached the events to the div? Then target your button with your changes?
I would think you should be able to do this with a shared parent. Then you place the hover on the parent rather than the button itself.
<span id="wrapper">
<input type="file" id="filesButton" multiple>
<input type="button" id="filesButtonOverlay" value="Add Files">
</span>
$("#wrapper").hover(function(){
$("#filesButtonOverlay").dosomething();
});
or in CSS:
#wrapper:hover #filesButtonOverlay{
stuff:
}
If you could potentially have multiple on the same page, you'd want to change to using classes instead of ids
I need to have an onclick/hover event on an input tag which is disabled.
Is there another way but to wrap it in another tag and give that tag the events?
<input type="checkbox" onclick="cant_choose('event')" disabled="disabled" value="2" name="enroll_to[event][]">
You could simulate it being disabled with JavaScript and CSS.
That is, blur all focus it receives, and add a class with something like so.
input.disabled {
background: #d4d0c8;
color: #888;
cursor: default;
}
Update
See it in comparison with the normal and browser disabled input box on JSbin.
You could wrap the input field inside a container and bind the click event on it.
<div id='input-container'>
<input id='myText' disabled />
</div>
<script>
$('#input-container').click(function() {
alert('test');
});
</script>
http://jsfiddle.net/M2EYH/
If you have multiple disabled fields, and don't want to make an unique ID for each container, you can give the containers a class name instead of an ID.