How to get all fields in class - javascript

I have multiple classes with different number of fields inside them, 1 class example:
<div class="row form-row-extra-phone spacer">
<div class="col-12">
<div class="input-group">
<input type="tel" name="extraPhone-0-phone_number" class="form-control" placeholder="Extra Phone Number" maxlength="128" id="id_extraPhone-0-phone_number">
<div class="input-group-append">
<a class="btn btn-success btn-circle btn-sm add-form-row" href="#" role="button" id="plus_payment_data">+</a>
</div>
</div>
</div>
</div>
I want to iterate on all the fields inside the classes that have the attribute "name" and "id" , and add 1 to the number inside (in the example name="extraPhone-0-phone_number" -> name="extraPhone-1-phone_number")
I can select the class by:
$('.form-row-extra-phone')
How can I iterate on all the fileds inside it that contain the attributes 'name' and 'id'?

I assume you mean <div class="row form-row-extra-phone spacer"> when you speak about a class? This is an element, not a class.
Class can be a problematic term, because it can refer to CSS/DOM classes or Javascript classes, which are totally unrelated.
So if you have <div class="something"> then something is a CSS/DOM class, but the entire thing is not that class but an element having that class.
Now also what you refer to by fields are also just elements.
So what you want is to select all elements that have the class form-row-extra-phone and of them all descendant elements with an name attribute. And thats pretty easy. Basically in a CSS selector the (space) is the selector for descendant elements.
So you can select .form-row-extra-phone [name].
So what you probably want is something like this:
document.querySelectorAll('.form-row-extra-phone [name]')
.forEach(elem => elem.name.replace(/[0-9]/, x => Number(x) + 1));

When you use ^= it means starts with, and $= means ends with.
If condition is (name AND id)
$('.form-row-extra-phone input[name^="extraPhone"][id^="id_extraPhone"]')
If condition is (name OR id)
$('.form-row-extra-phone input[name^="extraPhone"],input[id^="id_extraPhone"]')
check this https://api.jquery.com/multiple-attribute-selector/ or google for "jQuery Multiple attributes selector"

Related

accessing second instance of element to invoke different data

I'm trying to access the second instance of 'div.question.question-dropdown input'. I have tried incorporating the typical :nth-child() and :nth-last-child() type pseudo selectors but they are being ignored. Below is the JS code I'm trying to achieve; but adding the unique Data to the second instance (but can't find a way to unique select).
.waitForElementVisible("div.question.question-dropdown input",400)
.click('div.question.question-dropdown input')
.setValue('div.question.question-dropdown input', Data.CreateOpp.motivation)
.pause(500)
.waitForElementVisible("div.question.question-dropdown input",400)
.click('div.question.question-dropdown input')
.setValue('div.question.question-dropdown input', Data.CreateOpp.motivation)
.pause(500)
.click('div.question-btn.question-btn-submit')
The mark-up is 2 different input form fields, within 2 div.question.question-dropdown.
<!-- first -->
<div class="question question-dropdown">
<div class="smart-input">
<label></label>
<input>
</div>
</div>
<!-- second -->
<div class="question question-dropdown">
<div class="smart-input">
<label></label>
<input>
</div>
</div>
In my opinion nth selector should work:
"div.question.question-dropdown:nth-of-type(2) input"
But if not, you can try XPath:
"(//div[#class="question question-dropdown"])[1]//input"

Want to get the previous input from the button where I click on it

I want to get the previous input id from the button (point of view).
With the needs of my website, there will be at least 8 inputs like this and buttons of course.
So in order to facilite the task and avoid writing one function by input, I think this is way better to get the id of the 'previous' input from the button where I click.
I've browsed StackOverflow, but found nothing interesting in my case.
So here is the HTML code :
<div class="col-sm-3">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fas fa-link"></i></span>
</div>
<input type="text" name="first_map_link" class="form-control" id="first_map_link" placeholder="Lien première map...">
</div>
</div>
<div class="row">
<div class="col-sm-1">
<button class="btn btn-outline-info btn-get-infos"><i class="fas fa-search"></i></button>
</div>
</div>
I've tried with that : Undefined
$('.btn-get-infos').closest('input').attr('id')
Same with siblings. jQuery solution is prefered.
Thanks in advance
The issue is because closest() goes up the DOM looking for parent elements, while the input you want to find is a child of a sibling to a parent of the button you click on. With that in mind you'll need a combination of closest(), prev() and find(), like this:
var id = $('.btn-get-infos').closest('.row').prev('.col-sm-3').find('input').prop('id')
You'll need to walk up and down the DOM properly to find reference. Something like this:
$('.btn-get-infos').prev().find('input').attr('id');
Or if you're firing a click event, it can use the this keyword:
$this = $(this); //ref to the button clicked
$this.prev().('input').attr('id');
Give that a go and let us know if it works, dude. attr() i think was deprecated a while back, so new practise is to use prop().
Edit: I realise now that prev() only looks through previous siblings - ignore me :)

Modify class list for multiple elements

How can I modify the class list via jQuery or JavaScript for multiple classes in one step?
I have several classes in my form like
<div class="form-group has-error has-feedback">...</div>
<div class="form-group has-error has-feedback">...</div>
<div class="form-group has-error has-feedback">...</div>
How can I remove all the classes except form-group?
<div class="form-group">...</div>
<div class="form-group">...</div>
<div class="form-group">...</div>
You can use the .removeClass() method.
$(".form-group.has-error.has-feedback").removeClass("has-error has-feedback");
From the jQuery Documentation:
Description:
Remove a single class, multiple classes, or all classes from each
element in the set of matched elements.
...
If a class name is included as a parameter, then only that class will be removed from the set of matched elements. If no class names are specified in the parameter, all classes will be removed.
JQuery
You can do it using attr function :
$('div.form-group.has-error.has-feedback').attr('class', 'form-group');
JAVASCRIPT
For javascript you can use querySelector and setAttribute() function :
document.querySelector('div.form-group.has-error.has-feedback').setAttribute('class', 'form-group');
Hope this helps.

Traversing in jquery through multiple elements

So I am trying to traverse through multiple elements and I seem to be having a problem. I have 2 divs that have two child elements each - an input and a link. Inside the link there is also an image. When I click on the input button of the first div, I want to be able to traverse to it's sibling(the link{a tag}) and into the links child(the img tag) and get its source attribute which I will then use to change the image of the second div. Here's an excerpt of the code
HTML:
<div id="item">
<img src="img/deli/1.jpg" alt="Owl Image" id="homeimage">
<input type="submit" id="btn1" class="btn btn-default dropdown-toggle viewbuttons" value="View Item" onclick='changeImage( "img/deli/1.jpg" );'>
</div>
<div class="item">
<img src="img/deli/2.jpg" alt="Owl Image" id="homeimage">
<input type="submit" id="btn" class="btn btn-default dropdown-toggle viewbuttons" value="View Item" onclick='changeImage( "img/deli/2.jpg" );'>
</div>
JQUERY:
$(document).ready(function(e){
$('input#btn1').on('click', function(){
var changeThis = $('input#btn1').siblings('#yeezy').children('img').attr('src');
$("#homeimage").attr("img", changeThis);
})
});
Thank you in advance
IDs must be unique. ID selector only selects the first matching element in the document. You are getting/setting src attribute of one element, i.e. both $('input#btn1').siblings('#yeezy').children('img') and $("#homeimage") refer to the same element.
Either use different IDs or use class attributes. Also note that since IDs must be unique, $('input#btn1').siblings('#yeezy') doesn't make a lot of sense. You could simply select the element using an ID selector: $('#yeezy');
There are a few things off with your code. You use the id "homeimage" twice, but there should only ever be one of a given id. You have the onclick attributes set to a different function besides the one you want to run, so you should remove those. Finally, when you try to change the src attribute of the homeimage, you call the function on the img attr: ("img", changeThis);
Make sure that all of your ID's are unique, remove any onclick atrributes from your elements, and then replace:
$("#homeimage").attr("img", changeThis);
with:
$('#homeimage').attr('src', changeThis);

JQuery pseudo selector :visible is working at one place but not at other place

I am trying to select those input fields on page to validate which are visible on layout. I am able to find out this through one way but with another way its not actually working. What I am getting is my selector is working for direct child but not for grand children.
I want to select only those elements ids which are actually visible on layout to validate them as they should not be blank.
Jsfiddle Demo
HTML
<div id="createdDiv1">
<div id="row11">
<div class="hide">
<input type="text" class="blk" id="inp_11"/>
</div>
</div>
<div id="row12">
<div>
<input type="text" class="blk" id="inp_12" />
</div>
</div>
</div>
<div id="createdDiv2">
<div id="row21" class="hide">
<div>
<input type="text" class="blk" id="inp_21" />
</div>
</div>
<div id="row22" class="">
<div>
<input type="text" class="blk" id="inp_22" />
</div>
</div>
</div>
<button onclick="subCheck('#createdDiv1 :visible')">check 1st</button>
<button onclick="subCheck('#createdDiv2 :visible')">check 2nd</button>
JavaScript
function subCheck(inBlock) {
inBlock=(inBlock==undefined)?'':inBlock;
var ids=[];
$(inBlock+' .blk').each(function(){
ids.push($(this).attr('id'));
});
console.log(ids);
}
CSS
.hide{
display:none;
}
Note: I don't want to change my subCheck() function since its generalized for all valiations, what I need to know how can I make it work with :visible selector or something similar to it to work with multi-levels checks for visible elements.
Sorry If I am making it ambiguous for you. I am not sure what exactly to explain in words.
use :not to exclude the class .hide:
<button onclick="subCheck('#createdDiv1 .inputDiv:not(\'.hide\')')">
check 1st
</button>
<button onclick="subCheck('#createdDiv2 .inputDiv:not(\'.hide\')')">
check 2nd
</button>
Fiddle: http://jsfiddle.net/Z4PSV/1/
Although I wouldn't suggest using onclick at all though, instead:
<button class="subcheck" data-id="createdDiv1">check 1st</button>
<button class="subcheck" data-id="createdDiv2">check 2nd</button>
<script>
$(document).on('click', '.subcheck' function() {
//Creates string as: '#createdDiv1 .inputDiv:not('hide')
var ft = "#" + $(this).data('id') + " .inputDiv:not('.hide')";
subCheck( ft );
});
</script>
Fiddle: http://jsfiddle.net/kY8Wh/
Lastly, if you were wishing to implement your :visible then:
<button onclick="subCheck('#createdDiv1 .inputDiv:visible')">
check 1st
</button>
<button onclick="subCheck('#createdDiv2 .inputDiv:visible')">
check 2nd
</button>
Fiddle: http://jsfiddle.net/Zgm78/
Would be sufficient too.
The issue is that you scan all the inner .blk elements of a visibile top element using each, in this case the element itself is visible, but hidden from the middle parent.
I know you won't change your subCheck function, bu you can simply solve the issue by checking there the visibility of the child element .blk.
Visibile selector take care of the effective visibility of the element (direct or nested):
Elements are considered visible if they consume space in the document.
Visible elements have a width or height that is greater than zero.
Elements with visibility: hidden or opacity: 0 are considered visible,
since they still consume space in the layout.
Elements that are not in a document are considered to be hidden;
jQuery does not have a way to know if they will be visible when
appended to a document since it depends on the applicable styles.
I think that this change will not break anything in your code.
Code:
function subCheck(inBlock) {
inBlock=(inBlock==undefined)?'':inBlock;
var ids=[];
$(inBlock+' .blk:visible').each(function(){
ids.push($(this).attr('id'));
});
//console.log(ids);
alert(ids);
}
Demo: http://jsfiddle.net/IrvinDominin/her4Y/

Categories

Resources