Select id closest to id with pure javascript - javascript

<div>
<div id="div2">TEXT</div>
</div>
<div>
<div id="div2">TEXT</div> <!-- select this -->
</div>
<div id="div1">TEXT</div>
How to select div2 that is closest to div1

Following w3 docs
id = name [CS]
This attribute assigns a name to an element. This name must be unique in a document.
So make sure your elements id are unique. Can switch to class instead
To select element closet to target element can use Element.closest()
The closest() method traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null
<div id="div-01">Here is div-01
<div id="div-02">Here is div-02
<div id="div-03">Here is div-03</div>
</div>
</div>
var el = document.getElementById('div-03');
var r1 = el.closest("#div-02");
// returns the element with the id=div-02

Related

How to target a div using content inside the div

I have 2 divs with same class name but different strings inside the div. I want to use an insertAfter the first div to display some additional text, but the text is being displayed under both divs:
<div class='test'>First Div</div>
<div class='test'>Second Div</div>
My approach:
if ( document.getElementsByClassName('test')[0]
&& document.getElementsByClassName('test')[0].innerHTML == 'First Div'
) {
$('<h2>Inserting New Text</h2>').insertAfter('.test')[0];
}
But this adds the text after both the First Div and the Second Div. I want to know if there is a way to insert only once or insert after matching the string
Just keep it simple, find all elements with target class and pick the first one:
const el = document.getElementsByClassName('test')
$('<div>new text</div>').insertAfter(el[0])
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='test'>First Div</div>
<div class='test'>Second Div</div>
You can ask javascript to find the elements of the class and then convert the result into an array and find the first element that matches your condition.
const elements = Array.from(document.getElementsByClassName("test"));
const target = elements.find(el => el.innerHTML === 'First Div');
$('<h2>Inserting New Text</h2>').insertAfter(target);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='test'>First Div</div>
<div class='test'>Second Div</div>
No need for jQuery here. Use insertAdjacentHTML to add the new element.
// Pick up the first element with the test class
const el = document.querySelector('.test');
// Use `insertAdjacentHTML` to add the new div after it
el.insertAdjacentHTML('afterend', '<div>new text</div>');
<div class="test">First Div</div>
<div class="test">Second Div</div>

Get div value from class name

I have a very large HTML that contains lots of divs with the same name, I want a way to only filter or extract that value from that div.
Here is an example:
<td class="last">
<div class="container-relative">
<div class="name" title=""User" <John Appleseed>"></div>
<div class="date">9/17/2019</div>
<div class="tool"></div>
</div>
</td>
I need to extract only what's between <John Appleseed>, in this case is 'John Appleseed'.
You could use querySelectorAll to take all the elements with class name, then get the title attribute with getAttribute, and finally use a regular expression to match text between <>.
document.querySelectorAll('.name').forEach(item => {
let title = item.getAttribute('title');
console.log(title.match(/\<.*\>/));
});
<td class="last">
<div class="container-relative">
<div class="name" title=""User" <John Appleseed>"></div>
<div class="date">9/17/2019</div>
<div class="tool"></div>
</div>
</td>
var divs=[];
for(i=0,j=0,obj=document.getElementsByClassName("name");i<obj.length;i++)
if(obj[i].title.includes("John Appleseed") &&
/* obj[i].title.split("\"")[2].trim()=="<John Appleseed>" && */
obj[i].tagName.toLowerCase()=="div"){
divs[j++]=obj[i];
}
console.log(divs);
separate your div using div ID. Then get your respective div using that value of ID. Then in javascript you can use getElementByID.
You can use Xpath,
.//div[contains(#class, 'Test')]
Then extract you required text from it.

How to select leaf node using jQuery :contains selector?

I want to get leaf elements containing specific text, and I used :contains selector. However, this selector selects includes every parent nodes too. Here is my example.
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>
In this case, I just want to get elements containing text balloon. I expected to get 3 elements(target1, target2, target3) by $(":contains('balloon')"), but it returns every nodes including parent nodes of targets. (e.g. html, body, and every parent div)
How can I select only targets?
p.s Above HTML is only example. HTML can be vary, so the answer should be generic.
use indexOf("balloon") > -1 to find id the word balloon is found
var arr = $("div").children().map(function(){
if($(this).text().indexOf("balloon") > -1 )
return $(this).attr("id")
}).get();
console.log(arr)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>
The solution below, look for all elements containing the word and clone these elements, This way we can be sure only to get "correct" amount of elements
Just remove .length and you have access to the elements.
var s = $(":contains('balloon')").not("script").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('balloon')").length > 0)
}).length;
console.log(s)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>

Access specific child div with jQuery

I want to know how to access a specific element in a div when foreach-ing
Here is some code
HTML
<div class="row menu-filter-items">
<div class="col-md-4 margin-b-30 menu-item">
<a href="#" class="menu-grid">
<img src="images/img-1.jpg" alt="" class="img-fluid"/>
<div class="menu-grid-desc">
<!-- <span class="price float-right">$9.50</span> -->
<h4 class="a" id="title">Restaurant y</h4>
<p>
Description
</p>
</div>
</a>
</div>
</div>
Jquery:
$('#search').keyup(function(e){
var current_query = $('#search').val();
if(current_query != null)
{
$("div.menu-filter-items").hide();
$("div.menu-filter-items div.menu-item").each(function(){
var current_keyword = $(this).children('#title').text();
alert(current_keyword);
if (current_keyword.indexOf(current_query) >=0)
{
$("div.menu-filter-items").show();
}
});
}
else
{
$("div.menu-filter-items").show();
}
});
I want to access the H4 balise but I couldn't
Help please
thank you
Use
var current_keyword = $(this).find('#title').text();
instead of
var current_keyword = $(this).children('#title').text();
You should use find method.
The .children() method allows us to search through the children of these elements in the DOM tree and construct a new jQuery object from the matching elements. The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements as well.
You can use find to perform a search with Jquery lib.
See full doc here : https://api.jquery.com/find/
For your case; you can use :
$( "div.menu-filter-items" ).find( "h4" )

Selecting first child based on attributes

I wanna be able to select a specific set of child in which an attribute is defined.
But how to select childs which are first child of the root selector that having the attribute data-role
first-of-type selector doesn't work due to the type of the element.
Here we have a sample of the DOM.
<body>
<div data-role="ca:panel" title="foo">
<div data-role="ca:vbox" width="100%">
<div data-role="ca:form">
<div data-role="ca:formitem">
<div data-role="ca:hbox">
<input data-role="ca:textinput">
<div data-role="ca:menu"></div>
</div>
</div>
<div data-role="ca:formitem">
<input data-role="ca:passwordinput">
</div>
<div data-role="ca:formitem">
<select data-role="ca:combobox">
<option>[...]</option>
</select>
</div>
</div>
<table>
<tbody>
<tr>
<td>
<span data-role="ca:label"></span>
</td>
<td>
<button data-role="ca:button"></button>
</td>
<td>
<button data-role="ca:button"></button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
My filter should select only
<div data-role="ca:form">
<span data-role="ca:label"></span>
<button data-role="ca:button"></button>
<button data-role="ca:button"></button>
It should work in any case, meanings, it shouldn't be linked to a specific structure of the dom and must use data-role as 'selector'.
I'm not a relevant jQuery developer. I tried some selector such as $('[data-role]:first-of-type'); but it doesn't work.
Do you have an idea to select the right set of child.
Note: Finding the first parent is not a concern.
It is possible to do this generically using a filter, so long as you have a start node:
JSFilter: http://jsfiddle.net/TrueBlueAussie/2uppww9s/5/
var root = $('[data-role="ca:vbox"]');
var matches = root.find('[data-role]').filter(function(){
return $(this).parentsUntil(root, '[data-role]').length == 0;
});
alert(matches.length);
You can use the :first pseudonym to select the first occurance of a element like for example:
var elm = $('*[data-role="ca:form"]:first');
this will select * any type of DOM-element, with the data-role that matches "ca:form"
Since you want to return two buttons with the same data-role, we cant use ":first" for that. You would have to get the first child of a that matches in that case
var elm = $('td').children('button[data-role="ca:button"]:first');
This will look through the child elements of all TD-tags and find the first button with data-role matching "ca:button"
If you want first of all overall specifications, then you can simply use selector on all three tag types and filter them as so:
$('div, span, button').filter(function(i){
if (this.tagName == 'DIV' && $(this).data('role') == 'ca:form') return true;
if (this.tagName == 'SPAN' && $(this).data('role') == 'ca:label') return true;
if (this.tagName == 'BUTTON' && $(this).data('role') == 'ca:button') return true;
}).first();
Using .first grabs the first of them.
Also, filter can be used in a million ways to get what you want and sounds like it may get you to what you need. Just set what you're filtering for in an if/for/switch statement and return true on items that match.
jsFiddle
However, if you wanted first of each you could do something like:
$('div[data-role="ca:form"]:first, span[data-role="ca:label"]:first, button[data-role="ca:button"]:first')
If variable driven in someway, just use string concatenation.
jsFiddle

Categories