Puppeteer select element id where beginning and end are dynamically generated - javascript

I'm trying to use puppeteer to select a dynamic element id. I've found how to select and element using just the beginning or just the end, but what I'm currently trying to do is find the element by the static part of the id in the center.
await page.waitForSelector('[id^="holder"][id$="_private_1"]');
In the above code snippet the original id looks like holder123456_private_1. I've gotten that part fine. However, the end of "_private_1" the number may change. So essentially I need the same code above but leave off the number at the end.

What you probably could do is to use '[id^="holder"][id*="_private_"]' as your selector (id starts with "holder" and has "_private_" somewhere in the id name. That would work if you don't have elements with e.g. id="holder123_not_private_321" which you don't want to target.
Otherwise i don't think there is any other selector options (https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors)

Related

How to count classnames of dynamically added elements

Is there something I should keep in mind when trying to count ClassNames of dynamically added elements?
For the following description, refer to the link. Upon clicking the "(+)Course" button on any Semester (which are dynamically added), a Course will be appended to the corresponding Semester, with buttons of its own. This works. However, like I have for the Semesters, I have a limit of how many of each element there can be (i.e., 5 Semesters in total, 7 Courses per Semester), but I can't seem to be able to count my Courses.
Each Semester has a unique ClassName for its Courses, which is a concatenation of the Semester's Id and the word "Course", resulting in something like "sem#4Course". This code snippet is how I assemble and count the ClassNames for each Course. Is there something wrong with it? I've attached the rest of my code in the link.
var parentId = $(this).parent().attr('id');
var crsClass = parentId+"Course";
var crsCount = $('.'+crsClass).length;
https://jsfiddle.net/4efzf681/2/
I only started learning JavaScript/JQuery last week, so please bear with me. And I apologize for not separating my code between HTML, CSS and JavaScript. I work in a single file and separate it upon completion, and I've also never used fiddle before. I appreciate any help.
The # character in your class name values sem#1 and sem#1Course are creating a problem for the $() query selector which sees a class .sem and an id #1 or #1Course. It is better not to use the # and . characters in your class names and IDs. Instead use hyphens and underscore characters.
The improved fiddle is here: https://jsfiddle.net/6pdfjbt1/
You are confusing jQuery's selector engine by adding the parents id attribute to your course class name. The classes will inculde #, guess jquery thinks you want to select an element by it's id.
Changed that by doing
var crsClass = parentId.replace("#", "")+"Course";
I fixed your fiddle. Make sure to put your js in the bottom window next time ;).
I also moved the crsCount variable to the bottom to assign the value after the courses have been appended to the DOM.
YOUR FIDDLE
You can get the elements by class name using javascript method getElementsByClassName
var crsCount = document.getElementsByClassName(crsClass).length;

Using jQuery to get the content of div.class to replace content of title tag

I need to work around a limitation on my company's platform where pages can only be rendered with the filename as the title. I don't want to change my file-names to have values like, "This page title with spaces, and maybe illegal characters", because I don't want my URLs to have a bunch %20's and illegal characters in them, so I've been trying to figure out how to use the contents of another section of the page over which I do have control - the breadcrumb - as the "title".
I've been trying to use jQuery's .get and .replaceWith to replace the contents of the title tag with the contents of span.ms-pagetitle, which contains the part I can edit, but I'm a jQuery noob, and just haven't been able to suss it out.
This ought to do it:
$('title').text($('span.ms-pagetitle').text())
This should be run only once; usually inside a $(document).ready() function. The .ms-pagetitle element ought to have no children.
Two things are going on here:
$('span.ms-pagetitle').text() first selects any items matching span.ms-pagetitle. Hopefully there is just one, but it will grab them all. Use :first or another more specific selector to get the one you want. .text() will
Get the combined text contents of each element in the set of matched
elements, including their descendants, or set the text contents of the
matched elements.
...hence the idea to keep the span childless.
So that will result in a string of text.
$('title').text('string') will set the contents of a selected tag when passed a string (and get when used with no argument), so you are setting the selected title text as the contents of the <title> tag here.

How to use common js function for two divs containig elements of identical ids?

I have common jQuery function and two div tags. Both div tags have different names but both containing elements of identical ids now i want to use this common Jquery function for them both?
I have implemented common function but it's not working for both.
Here's link to my jsfiddle -jsfiddle.net/xS7zF/1/
In my jsfiddle there are two div tags namely example1 and example2 and both tags have elements of identical ids. Function is working fine for first div but not for second.
please help me to sort out this.
Yeah, under the hood, jQuery selection on an ID will use the Document.GetElementById() function implemented by the browser, which is really fast, but (i guess depending on the browser) will stop after it finds the first element, since ID's should be unique and no further searching is needed after the first one is found.
For instance, rename the divs with id="eb" to class="eb" and you can still target specific elements using $("#example1 .eb") and $("#example2 .eb")
UPDATE:
Using your new Fiddle I created this: http://jsfiddle.net/xS7zF/5/
I cleaned up a lot of code and hopefully you can see what I have done. I changed all elements that appear twice from id to class. Now, when you attach an event to an element using $(".classname").click(), it attaches to all the elements. In the handler function where you set HTML and do your show()/hide(), you don't target a specific element using it's ID, but you find it relative to the element that does the event. You can do this using parent(), parentsUntil(), next(), find(), etc. Check jQuery docs for all possibilities. So for instance, the change-handler attaches to all inputs with name=Assets. But instead of doing $("#b1").show(), I go to the parent of the specific input that fires using $(this).parent(). Then I find the element with a class=".b1", which it will only find the one that is next to this specific input and I set the HTML to just that element.
Since there is another input, the same actions happen when THAT input changes, but instead it finds IT's parent, and finds the element with class=".b1" that is next to IT. So both divs with input are contained since they act on elements relative to itself and not across the document.
For extra fun and to show you how flexible this way of programming is, here is a fiddle with the Javascript-code unchanged, but with the exact same question-div copied 8 times. No matter how many times you repeat this, the same code will act on as many divs as you create since everything works relative. http://jsfiddle.net/xS7zF/7/
Hopefully this helps, the rest is up to you!
ID's must be unique, you should not repeat them. You could replace id with class and in the jQuery function do (".ub").each() or manually referencing the object using eq(x). e.g. (".ub").eq(1).
You shouldn't assign same id's to different elements.
You CAN but you SHOULDN'T. Instead of giving the same id, use class
IDs must be unique, try fix this, change to classes.
You can try something like this:
$("div div:first-child")
instead of
$("#eb")
But depends of the rest of your page code. So, change to classes first and use
$(".eb")
when jQuery / javascript find the first ID it would ignore the rest, please read more about it
http://www.w3schools.com/tags/att_global_id.asp

How to count the number of listitems in an asp.bulletedlist with JavaScript

I have an asp:bulletedlist control, which sits inside a div tag, and I need to count the number of list items inside the control. Searching the internet, and noting the fact the html given back by the items is a list i.e. <li>, I thought I could use an example of:
var listcontrol = document.getElementById('BulletedList1');
var countItems = listcontrol.getElementByTagName('li').length;
However, when I do this, it throws and error saying that no object exists for this control.
So, my problem is, and because I must do this clientside because I want to use this to set the height of the div tag, is how do you count the number of items inside a asp:bulletedlist control with javascript?
You can't use document.getElementById like you are using it because the actual ID for an Asp.Net control when rendered is different than what you set for the ID on the control. View the source of your page and you will see what the actual ID is. You can then use that if you want and this code should work, but it would break if you ever moved the bulletedlist control, since the hierarchy would change.
Another way to do this would be to use jQuery. In your example, you could do this:
$('[id$=BulletedList1]').children('li').size()
This would select the element that ends with 'BulletedList1', gets the li children, and then returns the size of the collection.

Help me with my selector, the ID is dynamically changing every page load

I want to scan a website using jQuery, but the ID is constantly changing, but there's a permanent pattern for the ID that I'm searching for:
app7019261521_the_coinb4678bc2
app7019261521_the_coind42fgr23
app7019261521_the_coing0992gvb
app7019261521_the_coin12e5d0aa
The IDs always starts with app7019261521_the_coin
But my problem is I don't know how to put that in jQuery selector.
$("#app7019261521_the_coin")
Doesn't seem to work
So how can I make this work?
$("[id^=app7019261521_the_coin]")
Should work - but its MUCH slower selector than knowing the real ID - or assigning a class. This selector will scan every element on the page one at a time, there is no good way for this selector to be optimizied. 9 times out of 10 though you could build a better selector: Is this #app7019... element the direct child of another element that is easier to determine? like a id='container'?
$("#conainter > [id^=app7019261521_the_coin]"); for instance
From the jQuery Selector Documentation
[attribute^=value] Returns: Array<Element(s)>
Matches elements that have the specified attribute and it starts
with a certain value.
can you set a class and just call it by a class name?
you may also be able to try
$("div[id^=app7019261521_the_coin]")
This will find all div's that start with app7019261521_the_coin
Replace div with whatever element type you are searching for.
$j('div[id^=app7019261521_the_coin]')
Remember this is not very optimal, as it causes the script to check the id attribute of every matched element.
You might want to see how you can add a class to the element or at least find the parent element first and traverse from there.

Categories