Tab Ordering for Javascript "Buttons" - javascript

I'm trying to create an HTML form (using JSP) which contains Javascript buttons (rather than actual HTML buttons). Everything works great except that I'm unable to tab to the -based Javascript button after the last tabindex.
For example:
<li class="lineItem">
<f:label path="ownerPostalCode">Postal Code<em>*</em> </f:label><br />
<f:input path="ownerPostalCode" type="text" id="ownerPostalCode"
class="required" size="15" maxlength="5" value="" tabindex="16" />
</li>
<li class="lineItem">
<f:label path="ownerPostalCodeFour">+4</f:label><br />
<f:input path="ownerPostalCodeFour" type="text"
id="ownerPostalCodeFour" size="5" maxlength="5" value="" tabindex="17"/>
</li>
<span class="buttonRow">
<span class="clearButton" onclick="resetFields
('registrationForm', 'ownerInfoSection')">Clear Fields</span>
<span id="continueButton" class="greenButton" tabindex="18"
onclick="stepOneToStepTwo()">Continue</span>
</span>
</span>
I understand that tabindex only works with certain input fields (A, AREA, BUTTON, INPUT, OBJECT, SELECT, and TEXTAREA)--as such, the specification of "tabindex='18'" for the #continueButton doesn't work. The desired behavior is that after tabbing to the "ownerPostalCodeFour" field, the user can tab to the #continueButton as one would with a normal button.
Is this at all possible or am I forced to utilize standard HTML buttons to achieve this behavior?
Thanks.

Not sure what browsers you are supporting, but tabindex="0" works in latest webkit/Firefox/IE. From an accessibility standpoint, using spans is less than optimal though. Why not at least use an <a> tag?

Related

Selenium with Python -- finding element without proper identifiers

I am using selenium with python to write the code. I am looking to pull the information from a text box. The box auto fills as other information is being filled out. Inspecting the box gives the following code:
<input type="tel" autocomplete="off" name="amount" step="any" class="form-
control ng-pristine ng-untouched ng-valid ng-isolate-scope ng-not-empty"
placeholder="" tw-focusable="" show-decimals="$ctrl.showDecimals" tw-number-
input-formatter="" ng-change="$ctrl.changedAmount()" ng-
model="$ctrl.ngModel" ng-disabled="$ctrl.ngDisabled" disabled="disabled"
style="">
The issue is that there is already another input box that has the name "amount", so I can't do a simple selection by name. I am thinking this would require me to use a CSS selector but everything I have tried so far has not worked. Please let me know what I can try.
Looks like you need to use CSS or XPath locators.
Its hard to tell how exactly you can find that element since you haven't provided a source of the entire page but here are some tips.
In the worst case when you cant find any combination of attributes that will uniquely identify the element you need to rely on dom nodes hierarchy, i.e. in order to find first input on the following page:
<!DOCTYPE html>
<html>
<head>
<title>Dummy page</title>
</head>
<body>
<div>
<div>
<input type="text">
</div>
<p>
<input type="text">
</p>
<input type="text">
</div>
</body>
</html>
You can use XPath locator that might look similar to this one:
//div/div/input
But that's the worst case, usually you can use more flexible locators based on element attributes that less likely to be affected by page structure modifications. Let's say each of our inputs from the page above has "name" and "disabled" attributes.
<div>
<div>
<input name="input1" disabled="" type="text">
</div>
<p>
<input name="input1" disabled="disabled" type="text">
</p>
<input name="input2" disabled="" type="text">
</div>
Then we can find first input using the following locator:
//input[#name="input1" and #disabled=""]
Hope that helps.

Firefox ignoring tabindex 0 on <img>

I have javascript which ends up looking like this:
<input type="text" name="from" size="12" id="from" maxlength="12" value="" placeholder="dd-Mon-yyyy" class="hasDatepicker">
<img class="ui-datepicker-trigger" src="/img/calendar_icon_20x20.png" alt="" title="select start date" role="button" tabindex="0">
<input type="text" name="thru" size="12" id="thru" maxlength="12" value="" placeholder="dd-Mon-yyyy" dd-mon-yyyy'="" class="hasDatepicker">
<img class="ui-datepicker-trigger" src="/img/calendar_icon_20x20.png" alt="" title="select end date" role="button" tabindex="0">
but when tabbing through the page in Firefox, it skips from one <input> over the <img> and to the next <input>. It works perfectly in Chrome, Safari and Opera (all are current versions).
Any ideas?
As you've discovered, TabIndex is not implemented in a standard way. But, it is safe to say that it is only relevant on focusable elements. Image elements can't receive the focus.
From MDN:
The tabindex global attribute is an integer indicating if the element
can take input focus (is focusable), if it should participate to
sequential keyboard navigation, and if so, at what position. It can
take several values...
And, when you investigate HTML Global Attributes, you find the documentation telling us:
Global attributes are attributes common to all HTML elements; they can
be used on all elements, though the attributes may have no effect on
some elements.
Typically, tabindex is used on form elements (textboxes, checkboxes, radio buttons, buttons, etc.) to aid in the ability to navigate data entry.

IE11 is not letting me type into my input fields

For the following code, I'm able to type in any text in the input fields when I'm using firefox. However, the same does not hold true in IE11.
<li class="gridster-form"
aria-labeledby="Gridster Layout Form"
alt="Tile Display Input column Input Row">
<span class="dropdown-text">
Col <input type="text" value='tiledata.col' ng-model="tiledata.col" size="1" class="input-col ng-pristine ng-untouched ng-valid">
Row <input type="text" value='tiledata.row' ng-model="tiledata.row" size="1" class="input-row ng-pristine ng-untouched ng-valid">
<i class= "fa fa-arrows"></i>
</span>
</li>
How can I change this?
You have a structure like this: <a href...><input ... /></a>
This is NOT VALID
Since it is not valid, browsers are at liberty to try and make sense of what you meant. Firefox is giving the input elements priority and letting you use them. Internet Explorer is giving the link priority and not letting you use the child inputs.
Neither browser is correct as there is no correct answer.
Fix your HTML.

Is it possible to set a default value in an AngularJS expression?

I have an AngularJS expression enwrapped in a <a> tag. The expression is evaluating an allow variable.
<a href="#" >{{allow}}</a>
In case allow is null or undefined Angular shows nothing. Instead I would like to display a default string.
To give you a better understanding, this is what I'm trying to achieve.
The modal on the right is generated from the form on the left. If the user didn't enter any text for "Allow Button Text" and "Disallow Button Text" I want to display ALLOW and DON'T ALLOW respectively.
Here is my code:
<div id="test2" class="row" ng-app="">
<label for="title">Title</label>
<input type="text" name="title" ng-model="title" placeholder="https:/your website.com/wants to:">
<label for="title">Allow Button Text</label>
<input type="text" ng-model="allow" placeholder="ALLOW">
<label for="title">Disallow Button Text</label>
<input type="text" ng-model="disallow" placeholder="DONT ALLOW">
<p>{{title}}</p>
<a href="" >{{disallow}}</a>
<a href="" >{{allow}}</a>
If by placeholder you mean default value until allow is specified, then it's quite easy:
{{ allow || 'Click me' }}
Sorry my friend, But placeholder attribute is not for anchor tag. It is for input fields.
let us know what you exactly want to achieve with this and we can suggest some alternative approach.
As suggested by #dfsq, if you mean placeholder text as the text to show when allow is not defined then you can put default text like this:
{{allow | 'placeholder text'}}

JQuery .replaceWith() suddenly putting new element in the wrong place?

This one is really baffling me. I'm using replaceWith() to "clear" a file input field. However, when it replaces it, it puts it back in the wrong place, and I have no idea why. I used the term "suddenly" in the title because what's even more mysterious is that when I stopped working for the weekend the replacement was working exactly as expected. Now I get back to work and suddenly it's not.
Here's the source HTML before calling replaceWith():
<label>Audio</label>
<i style="color:#888888;">MP3 or OGG format recommended</i>
<br>
<button id="clear_audio_input" style="display:none;">Clear</button>
<input type="file" value="" name="source_audio" style="width:300px;">
<br>
<div style="margin-top:15px;">
<b>Current: </b>
<i id="current_audio_source">1360954394_121RuleOfRosePianoEtudeI.mp3</i>
<br>
<input id="source_audio_value" class="required_media" type="hidden" value="1360954394_121RuleOfRosePianoEtudeI.mp3" name="source_audio">
<span id="current_audio_info_a"><input type="checkbox" style="position:relative;top:3px;margin-left:0px;" value="yes" name="source_audio_delete">
Delete current audio?
Current audio will be replaced
Note the location of the FILE input field, named "source_audio". It's immediately after the "Clear" button.
Now, after I call replaceWith(), the HTML looks like this:
<label>Audio</label>
<i style="color:#888888;">MP3 or OGG format recommended</i>
<br>
<button id="clear_audio_input" style="display: none;">Clear</button>
<br>
<div style="margin-top:15px;">
<b>Current: </b>
<i id="current_audio_source">1360954394_121RuleOfRosePianoEtudeI.mp3</i>
<br>
<input type="file" value="" name="source_audio" style="width:300px;">
<input id="source_audio_value" class="required_media" type="hidden" value="1360954394_121RuleOfRosePianoEtudeI.mp3" name="source_audio">
<span id="current_audio_info_a" style="display: inline;"><input type="checkbox" style="position:relative;top:3px;margin-left:0px;" value="yes" name="source_audio_delete">
Delete current audio?
Current audio will be replaced
Notice that it is now several lines down and inside another DIV.
Here is the script that controls the "Clear" button's actions:
$("#clear_audio_input").live("click", function() {
$("input[name='source_audio']").replaceWith($("input[name='source_audio']").val('').clone(true));
$("#source_audio_value").val($("#current_audio_source").text());
$(this).hide();
$("#current_audio_info_a").show();
$("#current_audio_info_b").hide();
checkRequiredMedia();
return false;
});
Here's the basic intended workflow. On load, the clear button is hidden because there is nothing yet to clear. After the user has selected a file, the clear button appears. Clicking the button will clear the file input (by replacing it) and then the button will hide again, essentially returning the form to the same state it was in on load.
Any reason why this oddity is happening (especially since it wasn't happening a few days ago, and I haven't changed anything since then)?
The issue is because you have two inputs with the name source_audio. To get around this, you will need to either give the two inputs fields an id, or change the name.
For example:
$('#my_file_input').replaceWith('<input id="my_file_input" type="file" name="source_audio" />');
$('#my_hidden_file_input').val('');

Categories