jQuery Locating Element Several Levels Up - javascript

I am attempting to locate an input field using the following:
parent = $(this).parent().parent().$('input[type="text"]').attr('id');
However, my script appears to be crashing whenever this runs. Basically, I have a tree of input fields within nested using <ul>'s and <li>'s, and I am trying to access the parent input field of $(this). Any help would be hugely appreciated!

You're probably missing the find function:
parent = $(this).parent().parent().find('input[type="text"]').attr('id');
Maybe this can simplify your code:
parent = $(this).closest('li').find('input[type="text"]').attr('id');

The syntax for your statement is incredibly wrong =D
It sounds like you are looking for the find function:
$(this).parent().parent().find('input[type="text"]').attr('id')

$(this).parent().parent().$('input[type="text"]').attr('id'); is not valid
one possible solution may be
$(this).parent().parent().find('input[type="text"]').attr('id');

parent = $(this).parents('#parentElementID').find('input[type="text"]')[0].id;
Where #parentElementID is the closest parent of the input targeted.

Related

Protractor: How to locate a sibling of a given element?

<div>
<a href='...'>LINK</a>
<img class='image' />
</div>
<div>
...
</div>
I want to get a protractor element for the img tag with image class. I already know the link text 'LINK'. In other words, "How do I locate a sibling of a given element?".
The first line of the code could look like this:
browser.findElement(by.linkText('LINK'))
Any ideas?
Thanks & Cheers
Thanks for the inspiration. Here's my solution, not the one I was hoping for, but it works:
element(by.css('???')).element(by.xpath('..')).element(by.css('???')).click();
The chaining and the by.xpath, which allows to get back to the parent are the keys of the solution.
This is what I actually implement on a Page Object:
this.widgets['select-status'] = this.ids['select-status']
.element(by.xpath('following-sibling::div[1]'));
this.widgets['select-status.dropdown'] = element(by.css('.btn-group.bootstrap-select.open'));
The page is based on Bootstrap along with Bootstrap Select. Anyways, we traverse the DOM along the following-sibling axis. Refer to XPATH specification for yourself.
Using Xpath selectors is not a better choice as it slows down the element finding mechanism.
I have designed a plugin to address this specific issues: protractor-css-booster
The plugin provides some handly locators to find out siblings in a better way and most importantly with CSS selector.
using this plugin, you can directly use:
var elem = await element(by.cssContainingText('a','link text')).nextSibling();
elem.click(); //proceed with your work
or, use this as by-locator
var elem = element(by.cssContainingText('a','link text')).element(by.followingSibling('img'));
You can always checkout the other handy methods available here...
Now, you can find web elements such as:
Finding Grand Parent Element
Finding Parent Element
Finding Next Sibling
Finding Previous Sibling
Finding any Following Sibling
Finding First Child Element
Finding Last Child Element
And, guess what, everything you can find using 💥 CSS Selectors 💥
Hope, it will help you...

Show context-menus only when certain elements are clicked

I am kinda stuck with something and I need your help.
I am trying to show context-menus only when a user right-clicks on a certain elements in the page.
I thought I solve this problem by using getElementByClassName(...) and adding an onClick listener to each one of the elements, and when the user clicks on any of them I will then create the context-menus. And then remove the content menu later when everything is done.
Problem is that I don't have the full class names of those elements, all I know that they start with "story".
I am not sure how to go about doing this. Is there a way to use regex and getting all elements with a class name of story? Or is that not possible.
Thanks in advance,
There's this library that allows for regex selectors.
<div class="story-blabla"></div>
$("div:regex(class, story.*)")
However, you may not want to implement a full library. There's another solution:
$('div').filter(function() {
return this.class.match(/story.*/);
})
This will return the objects you want.
You can do this using attribute starts with selector
document.querySelectorAll("[class^=story]")

Jquery .children() not working as expected

I am trying to make a basic captcha module for jQuery. I have a decent start on it, but for some reason .children() doesn't seem to work. See it here: http://jsfiddle.net/pTbeW/
I currently have this:
$(this).children('.captchain-start').hide();
$(this).children('.captchain-show').show();
If I change it to
$('.captchain-start').hide();
$('.captchain-show').show();
it works perfectly. But this solution is less than ideal, because it wouldn't allow two instances of this captcha to be on the same page. I suspect it has to do with the html being set by query, but I'm not sure how. I'm far from a javascript and jQuery expert, but this seemed like a relatively easy thing to do. What am I missing? Do I have tired eyes from looking at it so long? Any help would be appreciated.
Because the '.captchain-*' elements are not children, but are siblings. Try the following:
$(this).nextAll('.captchain-start').hide();
$(this).nextAll('.captchain-show').show();
You should use $(this).nextAll() instead of $(this).children() because the elements you want to hide and show are not children of the a element, but siblings.
See http://api.jquery.com/nextAll/
this
In your click event references the clicked element, which is the element with the class 'captchain-start'. So you do not have to scan for the children, you can use:
$(this)
for the actually clicked element or the element selector instead
instead.

Getting id then selecting that element - jQuery

I'm often finding myself getting various attributes, such as the id of an element or class, then selecting that element and doing something.
What I do now for example is:
var id = $(this).closest(".item").attr('id');
$('#'+id).hide();
Is using '#' and including the id the best way to do this? is there a way to maybe chain these actions together?
Thank you!
If you also want the id at the end, you can chain them like this:
var id = $(this).closest(".item").hide().attr('id');
If you are then going on to manipulate the elements as you do above, a more flexible way would be:
var item = $(this).closest(".item");
item.hide();
Nothing wrong with that method. You might be able to scrunch it into one line, but why?
var id = $(this).closest(".item").hide().attr('id');
Is there a reason why you can't just do
$(this).closest(".item").hide();
Getting the ID and then performing another jQuery selection is going to be slower than this.
You're selecting the item in order to get the id. All you have to do is hide() it there:
$(this).closest(".item").hide()
Just curious as to whether using $(this).closest(".item") without selecting the .attr("id") would work, then just hiding the found closest element. That would save the last line of code, roll it into one line of code. jQuery commands are chainable, so you should just be able to extend your hide command off the same line of code as the .closest() function will return the desired element.
example:
$(this).closest(".item").hide();
I'm not certain if I've understood you correctly, but are you looking for something like this:
$(this).closest(".item").hide();
Here's an example http://jsfiddle.net/alexkey/UtcKk/

Mootools each on childs

I am working on a script what uses MooTools, and i want to select all input's in one element, but the problem is that I don't know the ID of the element, the element is a variable. (In The function is formElement = $('form#aForm'))
Does someone know how I can use the each function on all input in one element. Now I am using:
$$('input').each(function(el) {
alert(el.get('value'));
});
But this script uses all elements in the document, and I want use only the elements in formElement. How is this possible?
Tom
PS: Sorry for my bad English.
Use Element.getElements:
formElement.getElements('input').each(function(el) {
alert(el.get('value'));
});

Categories