So I have several input forms that are disabled until they are filled out in sequence because of data calls to the server based on their selections. I have a custom dropdown that allows me to do a typeahead and click the item I want. When I click the item, the field unlocks with a combination of onblur and onchange events that take place for my data model. The issue that comes into play for me is I want the user to be able to tab. But when I hit tab, the onblur and onchange haven't disabled the field so it skips several fields that it shouldn't. Is there any suggestions on preventing a tab keypress skipping the disabled element? Can I tab and focus on a disabled element?
That is not possible, as the docs say:
A form control is disabled if its disabled attribute is set, or if it is a descendant of a fieldset element whose disabled attribute is set and is not a descendant of that fieldset element's first legend element child, if any.
A form control that is disabled must prevent any click events that are queued on the user interaction task source from being dispatched on the element.
So you can not click on those elements, and you can not focus element, that can not be clicked.
https://www.w3.org/TR/html5/forms.html#concept-fe-disabled
So the only option if you need to allow focusing of those elements is not to use disabled attribute at all. You could use .disabled class instead and bind on key events to suppress editing of the value.
Assuming you are willing to temporarily enable the disabled element (thus making it writable), this can be done by checking whether the next element has the disabled attribute with hasAttribute(). If it does, you can change this attribute to false before the keydown returns true, and thus the keyup will tab to the disabled element.
Additionally, you can set a new attribute wasDisabled, which you can then check against with $(this)[0]. If the element has this class, you can re-disable the element once you tab off it again.
This can be seen in the following jQuery example:
$('input').on('keydown', function(e) {
if (e.keyCode == 9) {
if ($(this).next()[0].hasAttribute('disabled')) {
$(this).next().attr('disabled', false);
$(this).next().attr('wasdisabled', true);
}
if ($(this)[0].hasAttribute('wasdisabled')) {
$(this).attr('disabled', true);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input>
<input disabled>
<input>
Hope this helps! :)
I ended up switching it to a readonly property. The readonly allowed me to tab to it and focus on it while not being able to type in it until the the blur and change completed.
Related
I have custom input component in vue js, and in this component i have input and two buttons.when input loose focus, i want to focus on next input, but now it focus on those buttons.
finally i should press tab key three times to focus on next input.
Is there any html attribute for disabling focus on some elements? or there is a javascript way?
The tabindex attribute controls tabbing. Set it to -1 and the tab key will not stop on that element.
<button tabindex="-1">click me</button>
You could use the blur event which is an equivalent of https://www.w3schools.com/jsref/event_onfocusout.asp
<input v-on:blur="handleBlur">
To trigger something when you lose focus.
You also could create a tabindex tabindex="0" on elements to determine the order of tabbing.
Unfortunately you can't make an element non focus-able unless you want to disable the whole element. Because then you couldn't type anything into that input.
In the following snippet, why does divClicked() trigger twice when the <label> is clicked, but only once when <input> is clicked?
function divClicked(_index) {
console.log("div click event");
}
function inputClicked(_index) {
console.log("input click event");
}
<div class="option" onclick="divClicked(1)">
<input id="1_1" name="group_1" type="radio" value="1" onclick="inputClicked(1)" />
<label for="1_1">label</label>
</div>
Note: I want to know why this happens, not a "quick fix" like: put onclick() on label.
This happens because of what the HTML spec describes at 4.10.4:
For example, on platforms where clicking a checkbox label checks the
checkbox, clicking the label in the following snippet could trigger
the user agent to run synthetic click activation steps on the input
element, as if the element itself had been triggered by the user:
<label><input type=checkbox name=lost> Lost</label>
On other platforms, the behavior might be just to focus the control,
or do nothing.
This means that when a <label> is clicked, the browser creates a second "synthetic" click event on the associated <input> element, in order to toggle its state.
The reason divClicked is triggered twice, is because the first event which comes from the <label> bubbles up to the <div>, and also the second, synthetic click event bubbles up to the <div>.
This is usually be cause of the bubbling principle of click event:
When an event happens on an element, it runs on it, its associated elements,its parent and other ancestors.
Now, The relation is when you click on label there a are two events which bubbles up here:
1) Click on div (which you expect)
2) Click on input (which is also expected)
2.1) When click on input is triggered then a click on div is also triggered again here
You can confirm this behavior by using event.bubbles prop.
EDIT:
The reason for the connection between label and input: (I know this is absolutely not required, as it's present all over the place yet)
A <label> can be associated with a control either by placing the control element inside the <label> element, or by using the for attribute. Such a control is called the labeled control of the label element. One input can be associated with multiple labels.
Taken from: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
Which means placing for on label referencing id of an input element will stimulate the behavior as if the element is inside the label. This would bubble a event on input onto label like any event on child to parent
At some moments, check also if the javascript file asset isn't loaded twice .... it shouldn't happen, but you never know.
A little Explanation : I am using List view control of kendo UI(Telerik). I am triggering an update event of that control after editing the fields in list view. The list view control is having some text-boxes, a dropdown,checkbox and a submit button. When a user change something, ideally it should trigger update but its not doing update because control is not able to judge if there is a change in model.
It is only working if I input something in textbox and just click on outside of textbox i.e just do a onblur before hitting submit. I don't know why it is happening but what I need is to just trigger a focus event but in a hidden mode so that user is unaware of it but it just happens after a user input something in textbox so that the list view control works successfully.
I am trying to do it like below but it will get noticed to user. How can i trigger focus in hidden mode after a user just enter something in textbox before hitting a submit?
function BlurFunc() {
debugger;
$(this).closest('li').find('.inputField').focus();
}
Without your code it is not clear whether you are using MVVM data binding to your model, but this may help; from http://docs.telerik.com/kendo-ui/framework/mvvm/bindings/value:
By default the value binding relies on the change DOM event, which is
raised after blurring the element whose value has changed. This means
that the value from the View-Model is updated when the element loses
focus. The data-value-update attribute can be used to specify a
different DOM event, such as keyup or keypress. The keydown event is
not supported, because the DOM element value is not yet updated when
that event triggers.
For example, try adding data-value-update="keyup" as an attribute to your text box input element:
<input data-value-update="keyup" data-bind="value: inputValue" />
This should then update the model value upon each key press and not wait until focus has been removed.
In the following snippet, why does divClicked() trigger twice when the <label> is clicked, but only once when <input> is clicked?
function divClicked(_index) {
console.log("div click event");
}
function inputClicked(_index) {
console.log("input click event");
}
<div class="option" onclick="divClicked(1)">
<input id="1_1" name="group_1" type="radio" value="1" onclick="inputClicked(1)" />
<label for="1_1">label</label>
</div>
Note: I want to know why this happens, not a "quick fix" like: put onclick() on label.
This happens because of what the HTML spec describes at 4.10.4:
For example, on platforms where clicking a checkbox label checks the
checkbox, clicking the label in the following snippet could trigger
the user agent to run synthetic click activation steps on the input
element, as if the element itself had been triggered by the user:
<label><input type=checkbox name=lost> Lost</label>
On other platforms, the behavior might be just to focus the control,
or do nothing.
This means that when a <label> is clicked, the browser creates a second "synthetic" click event on the associated <input> element, in order to toggle its state.
The reason divClicked is triggered twice, is because the first event which comes from the <label> bubbles up to the <div>, and also the second, synthetic click event bubbles up to the <div>.
This is usually be cause of the bubbling principle of click event:
When an event happens on an element, it runs on it, its associated elements,its parent and other ancestors.
Now, The relation is when you click on label there a are two events which bubbles up here:
1) Click on div (which you expect)
2) Click on input (which is also expected)
2.1) When click on input is triggered then a click on div is also triggered again here
You can confirm this behavior by using event.bubbles prop.
EDIT:
The reason for the connection between label and input: (I know this is absolutely not required, as it's present all over the place yet)
A <label> can be associated with a control either by placing the control element inside the <label> element, or by using the for attribute. Such a control is called the labeled control of the label element. One input can be associated with multiple labels.
Taken from: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label
Which means placing for on label referencing id of an input element will stimulate the behavior as if the element is inside the label. This would bubble a event on input onto label like any event on child to parent
At some moments, check also if the javascript file asset isn't loaded twice .... it shouldn't happen, but you never know.
I have a select element with an onChange event that does fire when I click the select box and select a new value within it. But, when I tab to the select box and press the up or down arrows to change the select box's value, the event does not fire.
I am using jQuery().change(function(){ ... }); to set the event
When you tab into a <select> element, the change event doesn't fire until you press the Enter key.
For an onChange() to fire the value must be changed and the input must be blur()-ed (focus moved elsewhere); which is why it fires in your first case, but not in the second.
The change event is sent to an element when its value changes. This event is limited to <input> elements, <textarea> boxes and <select> elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.
Reference:
change().
As others have stated, the change event doesn't happen until the blur event. You'll need to monitor keyup as well to capture someone moving changing the values with the arrow keys.
Monitor keyup and change,
$('select').bind('change keyup', function() {
// Handle
});
http://jsfiddle.net/robert/Je26w/
You can trigger the blur event on keyup on the select and then give back focus, which will trigger the change:
$('select').keyup(function(){
$(this).blur().focus();
});
example: http://jsfiddle.net/niklasvh/XEg36/