HTML: Unable to reach a link using Tab key - javascript

I have a page where in there is form which has block of input fields. There is also a button provided to 'Add Another' which allows for the addition of more block of the same above as mentioned.
As long there is more than one block of input fields on the page, a 'Remove' link is visible for the user to allow them to remove a the corresponding block from the view.
My issue is that on pressing Tab key, the 'Remove' link never gets highlighted. The focus moves to the next block element.
I have tried using Tab index but it hasn't resolved the issue as Tab key then does not follows a sequence.
<fieldset class="fieldset" id="fieldset-${receiptDetails.id}" style="width: 100%">
<legend style="display: none;">Receipt Detail Section - ${receiptDetails.id}</legend>
<label for="id" class="visually-hidden">Id: </label>
<input type="text" name="id" id="id" style="display: none" value="${receiptDetails.id}">
<div class="form-group">
<label class="claim-label" for="nameAddressOfSupplier" id="name-address-supplier-label">
[#spring.message "receipts-upload.supplier.name.address.label.text"/]
</label>
<textarea class="govuk-textarea" id="nameAddressOfSupplier-${receiptDetails.id}" name="nameAddressOfSupplier">${receiptDetails.nameAddressOfSupplier}</textarea>
</div>
<div class="form-group">
<label class="claim-label" for="purchaseDetails" id="purchase-details-label">
[#spring.message "receipts-upload.purchase.details.label.text"/]
</label>
<textarea class="govuk-textarea" id="purchaseDetails" name="purchaseDetails">${receiptDetails.purchaseDetails}</textarea>
</div>
<div class="custom-form-group">
<label class="claim-label" for="amount" id="amount-label">
[#spring.message "receipts-upload.amount.label.text"/]
</label>
<div class="currency-input">
<div class="currency-input__denomination">£</div>
<input class="currency-input__field text-input" data-component="date-check-length" data-length="9" type="text" id="amount" value="${receiptDetails.amount}" name="amount" style="display: inline"> [#if numberOfReceiptDetails == 1]
<p class="remove-link visually-hidden" id="remove-link_${receiptDetails.id}" name="remove-link">
<span class='googleAnalyticsRemove'>
<a id="remove-receipt-detail_${receiptDetails.id}" name="remove-receipt-detail"
class="action--secondary remove-receipt-detail" style="float: right">
[#spring.message "receipts-upload.remove.text"/]
</a>
</span>
</p>
[#else]
<p class="remove-link" id="remove-link_${receiptDetails.id}" name="remove-link">
<span class='googleAnalyticsRemove'>
<a id="remove-receipt-detail_${receiptDetails.id}" name="remove-receipt-detail"
class="action--secondary remove-receipt-detail" style="float: right">
[#spring.message "receipts-upload.remove.text"/]
</a>
</span>
</p>
[/#if]
</div>
</div>
</fieldset>
<p class="add-another-link" id="add-another-link">
<a href="" id="add-another" class="action--secondary">
[#spring.message "receipts-upload.add.another.text"/]
</a>
</p>
When the user clicks on 'add-another-link' then another fieldset is added to the view with a 'remove-link' visible for each fieldset.
I expect to reach 'remove-link' within each fieldset element from the 'input#amount' when Tab key is pressed but actually the Tab key press highlights the 'textarea[name=nameAddressOfSupplier]' contained within the next fieldset.
I will be grateful for any suggestions.

If you are not using href in <a> tag, tab key (tabindex) will skip that a tag,
if you add tabindex="0", the tab key will reach the link.
Please refer the post: Why would an `a` tag need `tabindex=0`?

Related

How to show container using jQuery and CSS

I am trying to build a smiley survey using only Front-End.
After hitting one of my radio buttons, the content should become visible for comments. My CSS is set up to display: none.
I have tried to do it using jQuery but nothing seems to be working.
Many thanks for your suggestions!
$("input[type='radio']").change(function(event) {
var id = $(this).data('id');
$('#' + id).addClass('face-cc').siblings().removeClass('none');
});
<div class="cc-selector row" id="moods">
<div class="col">
<input type="radio" type="radio" name="smile" value="angry" />
<label class="face-cc" for="angry">
<span class="far fa-angry" aria-hidden="div"></span>
</label>
<p>Terrible</p>
</div>
<div class="col">
<input type="radio" name="smile" value="grin-stars"/>
<label class="face-cc" for="grin-stars">
<span class="far fa-grin-stars" aria-hidden="div"></span>
</label>
<p>Excellent</p>
</div>
</div>
<div class="none" id="text">
<div class="container">
<form action="/action_page.php">
<div class="row p-5">
<div class="col-sm-12">
<div class="form-group shadow-textarea">
<label for="feedback">If you have any additional feedback,
please let us know below...
</label>
<textarea class="form-control p-2" id="comment" rows="7"
cols="20" placeholder="Comment here...">
</textarea>
</div>
<button type="submit" class="btn btn-danger">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
There are a few things incorrect with your approach. First is your use of the radio buttons in the HTML. For you to easily grab their individual click events and inspect their value, you want to add id attributes to them. I added some id's myself based on the radio button's name attribute that you already added.
Second, the jQuery which you used I changed completely to match thew use of the id attribute which I just added. This will look to see which radio button we just clicked on and if it matches the id of the radio button which will show the element, then we show the element accordingly.
You can also accomplish show/hide via CSS. I removed your CSS class of display: none; for the above to work, but you can keep it and use jQuery's toggleClass or addClass and removeClass using the above logic.
A few other comments. I simplified the logic by adding a ternary which you can read more on if you have not seen this syntax.
Last but not least is a quick search on StackOverflow can help, I found this answer which is the exact fix which you needed in your code from a jQuery perspective. I took the time to explain my approach here because you also needed HTML and CSS fixes to your approach.
If you think this answer helped, then feel free to 'accept' or 'mark up' the answer and welcome to Stack Overflow.
var text = $('#text');
var showId = 'grin-stars';
$('input[type="radio"]').click(function() {
$(this).attr('id') === showId ? text.show() : text.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cc-selector row" id="moods">
<div class="col">
<input id="angry" type="radio" name="radioBtn" value="angry" />
<label class="face-cc" for="angry">
<span class="far fa-angry" aria-hidden="div"></span>
</label>
<p>Terrible</p>
</div>
<div class="col">
<input id="grin-stars" type="radio" name="radioBtn" value="grin-stars"/>
<label class="face-cc" for="grin-stars">
<span class="far fa-grin-stars" aria-hidden="div"></span>
</label>
<p>Excellent</p>
</div>
</div>
<div id="text">
<div class="container">
<form action="/action_page.php">
<div class="row p-5">
<div class="col-sm-12">
<div class="form-group shadow-textarea">
<label for="feedback">
If you have any additional feedback, please let us know below...
</label>
<textarea class="form-control p-2" id="comment" rows="7"
cols="20" placeholder="Comment here...">
</textarea>
</div>
<button type="submit" class="btn btn-danger">
Submit
</button>
</div>
</div>
</form>
</div>
</div>

jQuery Validation Plugin check if "total_cost" is greater than "user_credit" value in fields

I am having hard time understand how jQuery Validation Plugin works with custom method.For all the guides here i found, are either for input form or static values but mine is a bit different.
I have 2 div's like 2 values and one is value of "user_credit" which store how much user have credit. And another is "total_cost" which store total cost of some special options.
The problem and difference that i have and didn't found on any guide is that my "total_cost" is dynamically changed based on previous checkbox values.
Here's part of code from that:
<div class="row">
<div class="col-lg-12">
<label for="link_to_video">Link to video <i class="fa fa-question-circle" aria-hidden="true" data-toggle="tooltip" title="Add link to your product video. Youtube videos will be automatically embedded"></i></label>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" name="show_video" id="show_video" value="1" data-price="40">
</span>
<input type="text" class="form-control" name="link_to_video" id="link_to_video" placeholder="https://youtube.com/watch?v">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<label for="link_to_product">Link to product <i class="fa fa-question-circle" aria-hidden="true" data-toggle="tooltip" title="Add link to your product"></i></label>
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" name="show_product" id="show_product" value="1" data-price="40">
</span>
<input type="text" class="form-control" name="link_to_product" id="link_to_video" placeholder="http://yourwebsite.com/product-page">
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-inline">
<div class="col-lg-12">
<h4>Your credit <span class="label label-default" id="user_credit">2000</span></h4>
</div>
</div>
</div>
<div class="row">
<div class="form-inline">
<div class="col-lg-12">
<h4>Total cost <span class="label label-default" id="total_price">0</span></h4>
</div>
</div>
</div>
And here is part of code that change "total_price" value when some of checkboxes are checked from above.
$inputs=$('#show_product,#show_video').change(function(){
var total=0;
$inputs.filter(':checked').each(function(){
total+= $(this).data('price');
});
$("#total_price").text(total);
});
And another thing is that all guides activate validator in javascript while i activate in form it self
<form action="" name="createListingForm" id="createListingForm" method="POST" role="form" data-toggle="validator" enctype="multipart/form-data">
I have been following documentation from here https://jqueryvalidation.org/documentation/ and searched for alot of guides but no luck in finding solution.
First off, you can not validate the text within a span container. Using this plugin, you can only validate textarea, select, certain types of input elements, and elements with the contenteditable attribute... and they all must be within a form container.
Secondly, if you dynamically change the value of one of these form inputs, you simply call the .valid() method to programmatically trigger validation on this input.
$('#myinput').valid(); // trigger a validation test of #myinput element

Disable the button based on control validation which inside ng-repeat angularjs

plunkr link
https://plnkr.co/edit/vuktW1bWSNIoV43Qp8DC?p=preview
<form name="myForm">
<div ng-repeat ="ndc in NDCarray">
<div class="col-sm-4 type7" style="font-size:14px;">
<div style="margin-bottom:5px;">NDC9</div>
<label>Number:
<input type="number" ng-model="ndc.value"
min="0" max="99" name="{{'input_'+$index}}" required>
</label>
<div role="alert">
<span class="error" ng-show="myForm.input.$dirty && myForm.input.$error.required">
Required!</span>
<span class="error" ng-show="myForm.input.$error.number">
Not valid number!</span>
</div>
<tt>value = {{example.value}}</tt><br/>
<tt>myForm['input_{{$index}}'].$valid = {{myForm['input_'+$index].$valid}}</tt><br/>
<tt>myForm['input_{{$index}}'].$error = {{myForm['input_'+$index].$error}}</tt><br/>
</div>
<div class="col-sm-4 type7 " style="font-size:14px;">
<div style="padding-top:20px; display:block">
<span class="red" id="delete" ng-class="{'disabled' : 'true'}" ng-click="NDCdelete($index)">Delete</span>
<span>Cancel </span>
<span id="addRow" style="cursor:pointer" ng-click="NDCadd()">Add </span>
</div>
</div>
</div>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
<button>Save</button>
</form>
we can enter the value in number and click add, it will create new textbox with same option (delete,cancel,add). That textbox has some validation
Required
Min and Max range
If i create 4 text-boxes dynamically by clicking add and changing the value of any textbox causes validation failed means , i want to disable the save button which is outside of ng-repeat.
if any textbox failed in validation need to disable the save button.
Can you try the following:
<button ng-disabled="!myForm.$valid">Save</button>
As far as I understand your question this is what you are trying to achieve?

finding last child div in nested fieldset

Within a jquery mobile page I have a page with a nested fieldset.
I need to dynamically add an input and button field anytime a certain button is clicked.
My first step has been trying to find the id of the last dynamically added control group.
That is where I am stuck.
I have tried a lot of different ways to get to the div but haven't had any luck so I was hoping I could get some help from the experts.
My latest attempt...
$('#ServicePage #ServiceArticle #ServiceList #collapse #btnaddOther').on('click', function () {
var ct = $('#ServicePage #ServiceArticle #ServiceList #collapse');
getLastId(ct);
});
function getLastId(ct) {
var id = $(ct.last).attr('id');
addOtherItem(id);
}
Below is an example of the page. The div i'm trying to reach is below the 2nd fieldset and has an id of collapse. I need to get the last child div within the collapse div i.e. I need to return the id= addOther_1.
I hope that makes sense.
<div id="ServicePage" data-role="page" class="ui-page-theme-a">
<article id="ServiceArticle" data-role="content" class="ui-content">
<form>
<br />
<div id="ServiceList" class="ui-corner-all custom-corners">
<div class="ui-bar ui-bar-b">
<h3>Color Services</h3>
</div>
<div class="ui-body ui-body-a">
<fieldset data-role="controlgroup">
<legend>Select Color Services</legend>
<input type="checkbox" name="service" id="serviceHiLight" value="HiLight" />
<label for="serviceHiLight">Highlights</label>
<input type="checkbox" name="service" id="serviceLoLight" value="LoLight" />
<label for="serviceLoLight">Low-Lights</label>
<input type="checkbox" name="service" id="serviceRetouch" value="Retouch" />
<label for="serviceRetouch">Retouch</label>
<input type="checkbox" name="service" id="serviceHiLightRetouch" value="HiLightRetouch" />
<label for="serviceHiLightRetouch">Highlight Retouch</label>
<input type="checkbox" name="service" id="servicePainting" value="Painting" />
<label for="servicePainting">Painting like Ombre or Balayage</label>
<input type="checkbox" name="service" id="serviceAllOver" value="AllOver" />
<label for="serviceAllOver">All over color</label>
*<fieldset data-role="collapsible">
<legend>Other</legend>
<div id="collapse" data-role="controlgroup">
<div id="addOther_1" data-role="controlgroup" data-type="horizontal">
<input id="txtaddOther_1" type="text" name="service" data-wrapper-class="controlgroup-textinput ui-btn" placeholder="Enter Service Name" />
<button id="btnDeleteOther_1" style="background-color: transparent; border-style: none;" class="ui-btn-b ui-shadow ui-btn ui-icon-delete ui-btn-inline ui-btn-icon-notext ui-corner-all">Delete</button>
</div>
<a id="btnaddOther" href="#" class="ui-btn ui-shadow ui-btn-icon-left ui-icon-plus">Add</a>
</div>
</fieldset>
</fieldset>
</div>
</div>
</form>
</article>
</div>
How would I go about accessing this nested div?
Thanks
function getLastId() {
var $x = $('fieldset:last-of-type > div:first-of-type > div:first-of-type')
// addOtherItem($x.attr("id"));
// Just to show we got the id, I am putting it in a div.
// Remove when done and un-comment line 3
$('#tmpDiv').html($x.attr("id"))
}
$('#btn').on('click', function(){
getLastId();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- TMP -->
<div id="tmpDiv"></div>
<button id="btn">Click Me</button>
<!-- / TMP -->
<div id="ServicePage" data-role="page" class="ui-page-theme-a">
<article id="ServiceArticle" data-role="content" class="ui-content">
<form>
<br />
<div id="ServiceList" class="ui-corner-all custom-corners">
<div class="ui-bar ui-bar-b">
<h3>Color Services</h3>
</div>
<div class="ui-body ui-body-a">
<fieldset data-role="controlgroup">
<legend>Select Color Services</legend>
<input type="checkbox" name="service" id="serviceHiLight" value="HiLight" />
<label for="serviceHiLight">Highlights</label>
<input type="checkbox" name="service" id="serviceLoLight" value="LoLight" />
<label for="serviceLoLight">Low-Lights</label>
<input type="checkbox" name="service" id="serviceRetouch" value="Retouch" />
<label for="serviceRetouch">Retouch</label>
<input type="checkbox" name="service" id="serviceHiLightRetouch" value="HiLightRetouch" />
<label for="serviceHiLightRetouch">Highlight Retouch</label>
<input type="checkbox" name="service" id="servicePainting" value="Painting" />
<label for="servicePainting">Painting like Ombre or Balayage</label>
<input type="checkbox" name="service" id="serviceAllOver" value="AllOver" />
<label for="serviceAllOver">All over color</label>
*<fieldset data-role="collapsible">
<legend>Other</legend>
<div id="collapse" data-role="controlgroup">
<div id="addOther_1" data-role="controlgroup" data-type="horizontal">
<input id="txtaddOther_1" type="text" name="service" data-wrapper-class="controlgroup-textinput ui-btn" placeholder="Enter Service Name" />
<button id="btnDeleteOther_1" style="background-color: transparent; border-style: none;" class="ui-btn-b ui-shadow ui-btn ui-icon-delete ui-btn-inline ui-btn-icon-notext ui-corner-all">Delete</button>
</div>
<a id="btnaddOther" href="#" class="ui-btn ui-shadow ui-btn-icon-left ui-icon-plus">Add</a>
</div>
</fieldset>
</fieldset>
</div>
</div>
</form>
</article>
</div>
I like the "last-of-type" and "first-of-type" selectors
$('fieldset:last-of-type > div:first-of-type > div:first-of-type')
http://api.jquery.com/last-of-type-selector/
The above will select the last fieldset, then the first direct child div, then the first div after that (which is the one you want).
Why not keep track of the last one using an id.. For example: id = 'LastOne', now, when you add a new item, remove the attribute from the actual last one, and then just place it on the one you're about to add. Basically, something like this:
$(document).ready(function(){
$('.add').click(function(){
var nvar = $('#lo').removeAttr('id').clone();
nvar.attr('id','lo');
nvar.insertAfter($('.mydiv').last());
});
});
You click on an ADD button (with the class .add) and then it looks for the LasOne (LO for short), removes it attr, makes a clone of it and then places it below the last one. Of course, you can also remove the attr AFTER you insert. That way, you wouldn't need to use "LAST".. since you don't really know what the last one is.
Check the fiddle working here: http://jsfiddle.net/lrojas94/v26fk8yd/
I was making this wayyyyy to difficult. I got the answer by trying something that charlietfl said "Since it has an ID just use that $('#collapse') since by definition ID's are unique – charlietfl"
Because I am using jquery mobile I did have to include the page name so it was simply
$addOther = $('#ServicePage #collapse');
The name of the jquery mobile page and the id of the div I need to look into.
Thanks everyone for your help.
I forgot to add how I found the last div within that div...
$('#ServicePage #collapse').find('.a').last();
This found the last div withing a div. The div I would looking in has the id #collapse.

Why both the forms are shown

http://jsfiddle.net/pz83w/16/
check the fiddle.I have two forms in it.I have a java script for forming a slide transitin between the forms.At first when the page loads,the both forms are shown,but i want only one form shown.Later when I click the links its working fine.How can I correct this.
<div class="demo">
<form class='form show' id="formA">
Card Payment
Internet banking
<h2>Card Payment</h2>
<input type='hidden' id='ccType' name='ccType' />
<ul class="cards">
<li class="visa">Visa</li>
<li class="visa_electron">Visa Electron</li>
<li class="mastercard">MasterCard</li>
<li class="maestro">Maestro</li>
</ul>
<label for="card_number">Card number</label>
<input type="text" name="card_number" id="card_number">
<div class="vertical">
<label for="expiry_date">Expiry date <small>mm/yy</small>
</label>
<input type="text" name="expiry_date" id="expiry_date" maxlength="5">
<label for="cvv">CVV</label>
<input type="text" name="cvv" id="cvv" maxlength="3">
</div>
<div class="vertical maestro">
<label for="issue_date">Issue date <small>mm/yy</small>
</label>
<input type="text" name="issue_date" id="issue_date" maxlength="5"> <span class="or">or</span>
<label for="issue_number">Issue number</label>
<input type="text" name="issue_number" id="issue_number" maxlength="2">
</div>
<label for="name_on_card">Name On card</label>
<input type="text" name="name_on_card" id="name_on_card">
<input type="submit" value="Pay Now !">
</form>
<form class='form' id="formB">
<div id="internet">
Card Payment
Internet banking
<h2>Internet Banking</h2>
<ul class="cards">
<li class="visa">Visa</li>
<li class="visa_electron">Visa Electron</li>
<li class="mastercard">MasterCard</li>
<li class="maestro">Maestro</li>
</ul>
</form>
</div>
and javascript is
$(document).ready(function(){
$(".tabHeader").click(function(){
$(".form").each(function(){
if ($(this).hasClass('show')) {
$(this).slideUp(900).removeClass('show');
} else {
$(this).delay(900).addClass('show').slideDown();
}
});
});
});
You could hide the second form in javascript like this:
$(".form").not(':first').hide();
Or an update of the Jsfiddle: http://jsfiddle.net/pz83w/18/
By default you could use style="display:none" on the form you don't want shown.
Sorry for the bad format sent from my phone.
Update CSS to hide forms without show class
In HTML and CSS, everything is visible unless you specifically ask it not to be.
Your showing and hiding is embedded within an onclick handler, so it won't execute until the links are clicked.
Until the links are clicked, why would a form be hidden? There is nothing to hide them.
You could of course have display: none set in in a stylesheet, but you did not include any CSS, so I assume there is none.
Try putting style="display: none" on the form tag you want to initially hide, like so:
<form class='form' id="formB" style="display: none">
Well, You can add either of the following css properties.
"display: none" or "visibility:hidden"
display:none means that there will be no space allocated for it. visibility:hidden means that the tag is not visible, but space is allocated for it on that particular page.
$("#formB").css("visibility","hidden");
Add this when when you show the page and then make it visible when you want second form to appear when you click on link,
$("#formB").css("visibility","visible");

Categories

Resources