Get last child of div in Javascript function [duplicate] - javascript

This question already has answers here:
How to select last child element in jQuery?
(6 answers)
Closed 9 years ago.
I am taking a fairly simple piece of code and wrapping into a function, the code builds a slide out menu from the items inside a div. I'm now trying to get the last child from a div:
experimentOne('#experimentOne');
function experimentOne(masterContainer) {
var experimentOneMenuButton = $('masterContainer :last-child');
... etc
However, this returns [] in the log. When I check the width, instead of the 100px it should be, it's 1420 which I'm guessing is the window width.
If I just get the last child of the ID by coding it in everything is fine, but I want the function to be as reusable as possible.
Thanks.

Try this if your masterContainer is an element:
var experimentOneMenuButton = $(':last-child', masterContainer);
Or this if it is a string for the element id
var experimentOneMenuButton = $('#'+masterContainer+' :last-child');

masterContainer is a variable containing the value of the parent container, so when you build the selector you need use it with string concatenation.
var experimentOneMenuButton = $(masterContainer + ' :last-child');
or you can use a context based lookup
var experimentOneMenuButton = $(':last-child', masterContainer);
I would recommend the second solution which make use of context bases lookup since it is neater.
Demo: Fiddle

element with id is selected with "#"
you need to target immediat children with ">", [space] target all descendants of element
$('#masterContainer>:last-child');

Well masterContainer inside the string will do nothing. I think it should be:
$(masterContainer).find(':last-child');
Also note that experimentOne('#experimentOne'); will send a string not a jQuery object. That would require experimentOne($('#experimentOne'));, which would leave:
experimentOne($('#experimentOne'));
function experimentOne(masterContainer) {
var experimentOneMenuButton = masterContainer.find(':last-child');
// Note the lack of jQuery wrapper around masterContainer in this version
Depends on whether you want to force a jQuery object in the parameter or in the function itself!

Your concatenation is wrong. Try that way:
$(masterContainer + ' :last-child')

Related

Can I use the % symbol in javascript or it is considered aspecial character?

I need some help.
I need to know if it is possible to use the % symbol in javascript.
I ask this question because I have an html table with the following ID= MRRMFBSY_%_CEC.
When I try to keep the TD of the second TR of this table the results is undefined, so it seems that it doesnt find the Table with this ID and also when it is defined well.
See my code below:
function getColumnsVal(id) {
var header = $("table#" + id + " thead tr:eq(1)");
var header_fields = $("td", header);
// If ID = MRRMFBSY_%_CEC when I try to do an alert of one of my TD,
// example the firstone it returns undefined
alert(header_fields[0]);
}
The question if you think that the problem is the % symbol or not, because when I have the other ID it works perfectly.
Thanks in advance
% is a reserved character, since its an operator (see).
It's not recommended, but you can use it as ID in an HTML element.
See this example:
const element = document.getElementById('MRRMFBSY_%_CEC');
console.log(element); // returns the div element
<div id="MRRMFBSY_%_CEC">
My div with a specific ID
</div>
ISSUE:
There is a problem when using certain special symbols %, ^, +, #, and so on, inside a jquery selector. They should be escaped with a backslash(\) when used because they are also used in forming the queries for the selector.
For instance '#divid' is a valid string in JavaScript but would be confusing to use in jQuery if the string was an actual id of an element. To get this element you have to use
$('#\#divid').
So, in your case to get your target element, $('#MRRMFBSY_\%_CEC') will get the element easily. However, you can either insert the escape character(\) manually or programmatically as done in this post with regular expression. Therefore, using the square brackets or the native getElementById in this answer, is just another way out of this problem.
You can definitely use % symbol in an id attribute (or in any string) as you would use the dash symbol -. However, you cannot use either of both for JavaScript variable names as they are reserved symbols.
SOLUTION:
Though this question has its own intricacies, #misorude has pointed out a solution here. So there lies your answer. use the square brackets [] or document.getElementById like this.
function getColumnsVal(id) {
// var element = $('[id="' + id + '"]'); // this line is equivalent to the next line.
var element = $(document.getElementById(id));
var header = element.find($("thead tr:eq(1)"));
var header_fields = $("td", header);
// If ID = MRRMFBSY_%_CEC when I try to do an alert of one of my TD,
// example the firstone it returns undefined
alert(header_fields[0]);
}

I am getting empty values for sports-title and third

i am new to js.
can you tell me why I am getting empty values for sports-title and third.
since we have one div with content in it.
sports-title---->{"0":{}}
third---->{}
providing my code below.
findStringInsideDiv() {
/*
var str = document.getElementsByClassName("sports-title").innerHTML;
*/
var sportsTitle = document.getElementsByClassName("sports-title");
var third = sportsTitle[0];
var thirdHTML = third.innerHTML
//str = str.split(" ")[4];
console.log("sports-title---->" + JSON.stringify(sportsTitle));
console.log("third---->" + JSON.stringify(third));
console.log("thirdHTML---->" + JSON.stringify(thirdHTML));
if ( thirdHTML === " basketball football swimming " ) {
console.log("matching basketball---->");
var menu = document.querySelector('.sports');
menu.classList.add('sports-with-basketball');
// how to add this class name directly to the first div after body.
// but we are not rendering that div in accordion
//is it possible
}
else{
console.log("not matching");
}
}
When you call an object in the Document Object Model (DOM) using any of the GetElement selectors, it returns an object that can be considered that HTML element. This object includes much more than just the text included in the HTML element. In order to access the text of that element, you want to use the .textContent property.
In addition, an HTML class can potentially be assigned to several elements and therefore GetElementsByClassName returns an array so you would have to do the following, for example:
console.log("sports-title---->" + JSON.stringify(sportsTitle[0].textContent));
You can find a brief introduction to the DOM on the W3Schools Website. https://www.w3schools.com/js/js_htmldom.asp If you follow along it gives an overview of different aspects of the DOM including elements.
Maybe this would be helpful
As you see sportsTitle[0].textContent returns full heading and 0 is the index thus you get "0" when you stringify (serialize) sportsTitle. Why 0? Because you have one <h1> element . See this fiddle http://jsfiddle.net/cqj6g7f0/3/
I added second h1 and see the console.log and you get two indexes 0 and 1
if you want to get a word from element so get substring use substr() method https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr
One way is to change <h1> class attr to id and do sportsTitle.textContent;
and use substr() on this string
or
2nd way is to remain class attr and do sportsTitle[0].textContent;
and substr() on this string
The 2nd is the better way

How to count through a tags and apply +1rem padding to each one?

I'm trying to style some breadcrumbs programmatically, because I don't know how many breadcrumbs there will be (due to child categories being set up by the client, etc). I've tried a few ways to count through the a tags and do this, without much success. Basically I just want each a tag to have one more 1rem of left padding than the previous one. Here is my code:
for(var i = 0; i < jQuery('.woocommerce-breadcrumb a').length; i++){
jQuery('.woocommerce-breadcrumb a:nth-child(' + i + ')').css('padding', i + 'rem');
}
Please excuse my bad coding as I'm just a novice with JavaScript/jQuery. And thank you in advance for any help.
If you want to use jQuery inside of pure CSS, you don't have to use the nth-child selector to get each a tag, you could just loop through each a tag by using the jQuery .each() function.
Something like this should work:
$('.woocommerce-breadcrumb a').each(function(i, ele) {
$(ele).css('padding-left', i + 'rem');
});
This will loop through every tag that matches .woocommerce-breadcrumb a, and then apply the relevant css. the .each() function let's you declare an index i in the function, so that lets us use incrementing padding-left for each element.
See this following code pen - http://codepen.io/anon/pen/vLyOMj - for an example as well.
jQuery.each automatically passed an index so there is no reason to do the for loop.
$('.woocommerce-breadcrumb a').each(function(i) {
$(this).css('padding', i + 'rem');
});
https://jsfiddle.net/SeanWessell/79Lnpze8/
I'd suggest, based on your stated requirements:
// selects the <a> elements contained within an element with a
// class-name of 'woocommerce-breadcrumb',
// uses the css() method to update the 'padding-left' property
// with an anonymous function, in which the first argument
// here 'i' (the index of the current element in the set returned
// by the selector):
jQuery('.woocommerce-breadcrumb a').css('padding-left', function (i) {
// returns a concatenated string, formed by the number of 1
// added to the current index and finally with the units
// added:
return 1 + i + 'rem';
});
References:
css().

Protractor - get child element of an element?

I am trying to access child element of an ng-repeat element but I am having troubles doing that.
I have searched around about the problem and the solutions that I have found did not work for me. One of those solutions was to do something like this:
var parent = element(by.repeater(''));
var child = parent.element(by.....);
When I try the child line I cant see the element function on the parent element..
http://prikachi.com/images/11/8338011u.png
If you see the screenshot above you will see the structure of the code of the page that I am trying to test.
I need to access the alt attribute of the image of the avatar and get its value (thats the Username of the User).
One thing that came to my mind is to use .getInnerHTML() on the ng-repeat row which will return a string with all that code. From there I can find the alt attribute and its value with string manipulation but this seems too brute and I am sure that there has to be a better way.
Simply I want to be able to get row 4 from the repeater and get the Username of the user at row 4, that's all I wanna do actually.
Try this,
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).first()
(or)
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).get(0)
You can get it directly using element.all() and get() locator in protractor. Here's how -
var child = element.all(by.repeater('parent_locator')).get(3); //gets 4th element in repeater. Its a 0 based index.
child.getAttribute('alt').then(function(user){
var username = user; //username contains the alt text
});
Hope this helps.
In Protractor element documentation it gives an example like this to find child elements, which is same as chaining element find:
// Chain 2 element calls.
let child = element(by.css('.parent')).
$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = element(by.css('.parent')).
$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
// Or using the shortcut $() notation instead of element(by.css()):
// Chain 2 element calls.
let child = $('.parent').$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = $('.parent').$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
https://www.protractortest.org/#/api?view=ElementFinder.prototype.$
this example could help :
return element(by.css('select.custom-select:nth-child(1) option[value="12"]'));
you can use nth-child() selector to access to a child element.
In my example i used a plugin with 2 select with same classes and i wanted to click on a defined option in the select 1, and a second in the select 2.

an array of strings as a jQuery selector? [duplicate]

This question already has answers here:
Easy way to turn JavaScript array into comma-separated list?
(22 answers)
Closed 6 months ago.
I have an array of strings that are valid jQuery selectors (i.e. IDs of elements on the page):
["#p1", "#p2", "#p3", "#p4", "#p5"]
I want to select elements with those IDs into a jQuery array. This is probably elementary, but I can't find anything online. I could have a for-loop which creates a string "#p1,#p2,#p3,#p4,#p5" which could then be passed to jQuery as a single selector, but isn't there another way? Isn't there a way to pass an array of strings as a selector?
EDIT: Actually, there is an answer out there already.
Well, there's 'join':
["#p1", "#p2", "#p3", "#p4", "#p5"].join(", ")
EDIT - Extra info:
It is possible to select an array of elements, problem is here you don't have the elements yet, just the selector strings. Any way you slice it you're gonna have to execute a search like .getElementById or use an actual jQuery select.
Try the Array.join method:
var a = ["#p1", "#p2", "#p3", "#p4", "#p5"];
var s = a.join(", ");
//s should now be "#p1, #p2, #p3, ..."
$(s).whateverYouWant();
What about $(foo.join(", "))?
Use the array.join method to join them together
$(theArray.join(','));
Going to officially answer your question: with a one-liner:
//If this is only one use variable you can use
$(['#p1','#p2','#p3','#p4','#p5'].join(',')).methodToUse();
//if you DO need it as a variable you can
var joined = ['#p1','#p2','#p3','#p4','#p5'].join(',');
$(joined).methodsToUse();
If you want them to do something individually there is also .each();
In the example below, each p ids clicks makes any one of them red:
var peas = ['#p1','#p2','#p3','#p4','#p5'];
$.each(peas, i => {
$(peas[i]).click(() => {
$(peas[i]).css({'color':'red'});
});
});
When you throw 'i' into a function parameter, it finds the values inside the arrays appropriately. When you do '.each()' the format looks like this:
$.each(array, function(i){
// any code you wish as long as you have an array selector
//$(array[i]).whatever function
});
An even bigger example. Say you want to make the P you click on red, but want the other ps return to default color. Just make a function that removes the selected ID from the array and voila!
var peas = ['#p1','#p2','#p3','#p4','#p5'],
poppy=(v,i)=>peas.toString().replace(`,${v[i]}`,'').replace(`${v[i]},`,'');
(// get each pea index
$.each(peas,i=>///funciton(i){ code inside}
(//set up each individual index's functions
$('.peastock').append(`<p id="p${[i+1]}">I am ${peas[i]}</p>`),
$(peas[i]).click(()=>(
$(peas[i]).css({"color":"red","background-color":"rgba(128,0,0,0.1)"}),
$(poppy(peas,i)).css({'color':'black','background-color':'rgba(255,255,255,0.2)'}))))),
$('.peastock').append(`
<div id="ree">ES6 isnt suitable for all of jQuery's usage!</div>
<div>Since some functions inside of jQuery's methods dont require 'this' or 'return'</div>
<div>You can learn this by going here</div>
`),
$("*").css({"margin":"0 auto","padding":"1%"}),
$("* .peastock, .peastock, .peastock *").css({"background-color":"rgba(128,0,0,0.1)"})
);
I know someone is bound to want to know about each value array as jquery selectors. Hope everything goes well!
Source:
jQuery .each()
The fiddle in action (with updates!)
I think you're looking for join.
var arr = ["#p1", "#p2", "#p3", "#p4", "#p5"];
$(arr.join(","))
Shorter:
$( ["#p1", "#p2", "#p3", "#p4", "#p5"].toString() );

Categories

Resources