Selecting an element created using document.createElement jquery/javascript - javascript

I am creating a number of div and ul elements using document.createElement. In a case, when I am creating these elements I need to take reference of one of those elements that I created above and assign it as the parent to element that's next in line to be created.
I have the id (e.g "idoftheelement") of the created element but when I do
$('#idoftheelement')
I don't get the element.
Is there a possibility to get the element. If yes how ?
Edit:
Below is html structure I am trying to generate based on a JSON input data. Every element in the JSON array could have a child array of elements. All the elements will have the same markup and the difference is only in where they are getting placed. I have to construct this in a recursive way i.e for every JSON element check if child elements(and the child elements could also contain child elements) are present, if yes then i should append these child elements to corresponding parent thread block. This is why I need to know if there is a direct way to get the reference of parent element that is in context to the current element so that It can be appended.
<div id="comment-12345">
<div id="threads-block-12345"
<ul id="thread-12345">
<li id="thread-item-12346">
<div id="comment-12346">
<div id="threads-block-12346"
<ul id="thread-12346">
<li id="thread-item-12347">
<!--keeps growing if there till all the children are processed-->
</li>
</ul>
</div>
</div>
</li>
<li>
<div id="comment-xyz">
<div id="threads-block-xyz"
<ul id="thread-xyz">
<li id="thread-item-xyz">
<!--keeps growing if there till all the children are processed-->
</li>
</ul>
</div>
</div>
</li>
</ul>
</div>

The code $('#idoftheelement') tells me you are using jQuery, so you shouldn't be using document.createElement. What you need to do is create the element using jQuery and reference it by that variable. For example:
var $node = $("<div id='" + id + "'>")
$node.append( ... new elements ... )

Related

How to keep only the first element from a class when cloning with jquery

Each of my divs have a class attributes named remove, the first class has the id: remove_item then the second remove_item_1, the third remove_item_2, etc.
My problem is that i only want to clone first one with the id remove_item and remove all the other one from the clone.
If i do clone.find('.remove'); i am able to gather all the elements with remove class but from there i am kinda lost on how to do that.
Could anyone help ?
Thanks.
You can keep first div by adding :first.
clone.find('.remove:first');
I think I got what you mean
here's an example how to pick the first element of a cloned div:
lets say you have
<ul id="list">
<div id="clone">
<li class="remove remove1">Remove 1 </li>
<li class="remove remove2">Remove 2</li>
<li class="remove remove3">Remove 3</li>
</div>
</ul>
The script to clone the list and remove the first child of the clone goes like this :
<script>
let clone = $('#clone').clone().appendTo('#list');
clone.children().first().remove();
</script>
or you can select the first one by class selection as #Manashree Shah mentioned like this:
clone.find('.remove:first');
The code uses jQuery, you can add this before the script if you haven't already added it :
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

Javascript - Access multiple nested elements with Chrome Extension

I am attempting to get some values of a website using a Chrome Function i am working on. I am able to fetch the first listing-name using document.querySelector(".listing-name").textContent, however how would i go about fetching all listing-name into an Array?
DOM Structure
<div class="container">
<div class="active-listings">
<section class="listing">
<div class="listing-info">
<h3 class="listing-name">Listing 1</h3>
</div>
</section>
<section class="listing">
<div class="listing-info">
<h3 class="listing-name">Listing 2</h3>
</div>
</section>
</div>
</div>
I am new to Javascript so not entirely familiar with the correct syntax. However am i right in assuming i'd need to loop all the sections within the active-listings div and then obtain the listing-name that way?
As stated in the comments, the method you are looking for, which is available on all elements having querySelector as an available method, is querySelectorAll. Whereas querySelector returns the first element that matches, querySelectorAll matches any and returns them as an array.
As a result, in your example, if you were to get all the active-listings to get a sub-element's inner text, you'd simply do it this way (ES6):
window.onload = () => {
document.querySelectorAll(".active-listings .listing-name").forEach((element) => {
console.log(element.innerText);
});
};
<ul>
<li class="active-listings">
<h3 class="listing-name">Test</h3>
</li>
<li class="active-listings">
<h3 class="listing-name">Test</h3>
</li>
<li class="active-listings">
<h3 class="listing-name">Test</h3>
</li>
<li class="active-listings">
<h3 class="listing-name">Test</h3>
</li>
</ul>
If your nesting is more complex, or if you need to do additional processing, merely selecting active-listings is also a possibility.
You can simply use querySelectorAll : querySelectorAll
The querySelectorAll() method returns all elements in the document that matches a specified CSS selector(s), as a static NodeList object.
The NodeList object represents a collection of nodes. The nodes can be accessed by index numbers. The index starts at 0.
var matches = document.querySelectorAll("some_selector");
//then you can access the matched selector with `matches`

Discrepancy between elements retrieved via e.target and those shown in DOM

I'm building a todo list with nested lists. List items are attached to their respective unordered lists with the use of Handlebars templating. The list items each contain a text input to represent them in the browser, empty <ul></ul> tags for any future child list items, and a button to add those list items. This works, and the text inputs appear properly in the DOM. However, when I attempt to retrieve newly added <li></li> elements via e.target beyond the master list, nothing is detected in the child lists, despite the fact that they all appear in the DOM.
In the code, I have an event handler bound to the button which adds a new list item for each list. In this case, e.target is the button. My aim is to use jQuery's .focus() on the new item's input so the cursor is already there when it appears. I have tested out using both jQuery and vanilla JS methods in console.log() to traverse the tree, going through the button's sibling-level <ul></ul> but this does not appear to be a problem with traversal methods, as the lists are always logged, though empty.
In this scenario, one item is present on the master list. Subsequently, one item is added to the first sublist via the event handler function for the "new list item" button (which itself is inside the first item's <li></li> tags). Inside that function, I traverse the tree to access the list item's child unordered list and log the result to the console, as with the following:
console.log(e.target.closest('li').querySelector('ul'));
The returned result shows that the list is empty:
<ul id="list-2" class="parent-list">
</ul>
However, the newly appended list item is clearly visible in the DOM:
<ul id="list-2" class="parent-list">
<li data-id="...">...</li>
</ul>
The relevant HTML including script for list templating with handlebars:
<body>
<label><input type="checkbox" id="toggle-all-checkbox">Toggle All</label>
<br>
<button class="add-parent-list-todo">+</button>
<br>
<ul id="list-1" class="parent-list">
</ul>
</body>
<script id="todo-list-template" type="text/x-handlebars-template">
{{#this}}
<li {{#if completed}} class="completed" {{/if}} data-id="{{id}}">
<input class="todo-input" type="text" value="{{text}}">
<div id='options'>
<button class="delete">x</button>
<input type="checkbox">
</div>
<br>
<button class="add-parent-list-todo">+</button>
<br>
<ul id="{{childList}}" class="parent-list">
</ul>
</li>
{{/this}}
</script>
The event handler function in question:
enterTodoText: function (e) {
var parentList = $(e.target).next().next().attr('id');
this.todos.push({
text: '',
id: util.uuid(),
completed: false,
parentList: parentList,
childList: "list-" + childListId
});
childListId++;
this.render();
$(e.target).next().next().children('li:last-child').find('.todo-input').focus();
console.log(e.target.closest('li').querySelector('ul'))
}
I'd very much appreciate any insight anyone might have.
I have come to realize that this in overwhelming likeliness has something to do with e.target being inside of a Handlebars template. Using e.target from a template, I am seemingly unable to traverse beyond the template itself. This is confirmed by testing with console.log($(e.target).parents()), which shows that for sublists, the topmost detectable parent is <li> (which is the parent element in the template), when I expected it to be <html>.
The solution I came to is to just traverse the tree using $('body') as the starting point, as opposed to $('e.target').

Trouble using .closest function

I'm trying to make a sidebar menu for a dashboard. I want to implement this with .closest as it will fit with my code right. Here is a simple example of what I'm trying to do: https://jsfiddle.net/eu8kjzh4/10/
Why isn't the closest span's (and the only span in this case) text being replaced with a '-'? In my code, I have
$('.' + Key).closest( '.' + Key ).css("color", "#000");
This code works just fine, but the one in the jsfiddle does not.
closest traverses up the DOM and is used for nested elements.
In your markup, your div is not a descendant of your span, not even a sibling.
You have
1. To retrieve the previous sibling (the first li after the body)
2. And find the span inside the li
$(document).ready(function() {
$(".sub").prev().find('span').text('-');
});
Also, in your fiddle, you forgot to include jQuery.
Here is a working code : https://jsfiddle.net/qwc6pepr/1/
Incorrect function: .closest( selector ) Returns: jQuery
Description: For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree
What you want is the prev which finds the first sibling prior to the element
$(document).ready(function() {
$('.sub').prev('li').find('span').text('-');
});
From jQuery documentation
Given a jQuery object that represents a set of DOM elements, the .closest() method searches through these elements and their ancestors in the DOM tree and constructs a new jQuery object from the matching elements
Your span is neither a Parent Element of your div.sub in the DOM, nor matches with the $(".sub") rule.
The only way to make your jQuery code work with your HTML structure :
$("#plusMinus1").text("-");
Or modify your HTML structure to match with the .closest() method requierements
Fiddle
When you go to the parent you'll end up in the body. From there you can find the span.
$(document).ready(function() {
$(".sub").parent().find("span").text("-");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<body>
<li>
<a class="selected" href="#" onclick="return false;">Dashboard 1 <span id="plusMinus1">+</span></a>
</li>
<div class="sub">
<ul>
<li><a id="s1" href="">Test A</a>
</li>
<li><a id="s2" href="">Test B</a>
</li>
<li><a id="s3" href="">Test C</a>
</li>
</ul>
</div>
</body>

jQuery Editing innerHTML after selecting it with .html()

I am generating rows dynamically with PHP from DB, once it compiles the initial page code looks something like this:
Snippet
<div class="options" id="options">
<div class="left_wrap">
<ul>
<li class="col_id b-bottom"></li>
<li class="hazard_header"><h3>Hazard</h3></li>
<li class="hazard_input b-bottom"></li>
<li class="con_header b-bottom"><h3>Controls</h3></li>
<li class="cat_header"><h3>Consequence Category</h3></li>
<li class="cat_options"></li>
</ul>
</div>
<div class="right_wrap">
<h2>Inherent Risk (Assessed risk without controls)</h2>
<ul class="fields">
<li class="bg b-top b-right"><h3>Consequence Level</h3><br/><span class="con_level_val"></span></li>
<li class="b-top b-right"><h3>Probability</h3><br/>Possible</li>
<li class="bg b-top b-right"><h3>Exposure (frequency)</h3><br/></li>
After page load I grab contents of the wrap options.
jQuery Snippet:
content = $("div.options").html();
Which in turns stores the above code in the variable content. Now, my question is how can I edit contents of variable content. For example I need to add value to li with class Col_ID like 1,2,3,4 and same when I am deleting I need to modify the contents again.
How can I do something along the lines content.getElement?
If you really need to work with the HTML string, here's something you can do:
content = $("div.options").html();
var $content = $(content);
// now $content is a jQuery object with a bunch of (detached) elements
// you can use the common functions on it without problems, such as
$content.find("li.col_id").text("Some text");
// now you need to do something with $content, or everything you did will...
// ...be lost. You cold, for instance, update the other variable back:
content = $content.html();
// content now has the updated HTML
Now, if you don't need the HTML string at all, then you can work directly like:
content = $("div.options");
content.find("li.col_id").text("Some text");
// now the DOM was already updated as you are dealing with attached elements

Categories

Resources