jQuery creating and modifying elements - javascript

I'm using an HTML snippet to insert some text into the element, then display it somewhere:
var elemTemp = $('<span /><strong class="value unit" />').find('span').text('hi!').end();
elemTemp.appendTo('#someDiv');
I want to insert "hi" inside the span but could not get it working. The find() method doesn't seem to find the span.

find looks down the DOM tree, but your span is not a descendant, so find won't find it. Use siblings instead:
var elemTemp = $('<span /><strong class="value unit" />').siblings('span').text('hi!').end();
Here's a working example. Note that this produces HTML along the lines of:
<span>hi!</span>
<strong class="value unit"></strong>
I'm not sure if you were aiming for that, or if you wanted the strong to be a child of the span.

Why not do this as simply and quickly as possible?
$('#someDiv').append('<span>hi!</span>'); // or whatever HTML you want in there

You have to specify which span-tag you want to insert "hi" into. The easiest way is to set a class on the span-tag.
HTML:
<span class="hello"></span>
jQuery:
$('span.hello').html('hi');

Related

Target and alter anchor element test and attributes nested with vanilla JavaScript

I have a nested <a> element that I want to change the text and attributes for.
So far I am getting the a tag and setting the innerHtml to something else. However I feel this might be bad practise.
Heres the code I need to target and change
<li class="promo-bar">
<div>
<span class="icon-with-text">
// I want to change this a element
Free delivery
</span>
</div>
</li>
This what I have tried so far that does work. However I feel that either using innerHtml may be bad practise or that there is a cleaner way that is more descriptive.
var newLink = document
.querySelector(".promo-bar ")
.children[0].querySelector("a");
var myNewLinkHtml = `
<a
class="newClassName"
href="#"
id="new-id"
>Why choose us?</a
>
`;
newLink = newLink.innerHTML = myNewLinkHtml;
I would like to get the <a> element and change the text and have the ability to add class names and custom attributes.
If using innerHtml is ok then great, else my aim is to use only Vanilla Javascript methods to achieve this.
You can access each property independently and update them as you need.
For the content use textContent.
To add classes, classList.add().
The id can be updated assigning a new one.
const el = document.querySelector('.promo-bar a');
el.id = 'new-id';
el.classList.add('new-class');
el.textContent = 'New content';
<li class="promo-bar">
<div>
<span class="icon-with-text">
// I want to change this a element
Free delivery
</span>
</div>
</li>
If you want to use ready html instead of editing the text and each property your best bet is to place that html in a temporary element and then replace the original link with the one(s) created in the temporary element.
var newLink = document.querySelector(".promo-bar>:first-child a");
// `document.querySelector(".promo-bar a")` would probably work as well, but I don't know what your whole html looks like and used `.children[0]`
var temp = document.createElement("div");
temp.innerHTML = `<a class="newClassName" href="#" id="new-id">Why choose us?</a>`;
// using while is safer in case more than 1 nodes are added using `innerHTML = "..."`
while (temp.childNodes.length) newLink.parentElement.insertBefore(temp.firstChild, newLink);
newLink.remove();
<li class="promo-bar">
<div>
<span class="icon-with-text">
// I want to change this a element
Free delivery
</span>
</div>
</li>
General tip about innerHTML: try to avoid altering the innerHTML of the main dom tree as it could remove event listeners and change references to dom objects.

Cypress get specific text

I have this element
<label for="prod-field">Project
<span class="aui-icon">Required</span>
</label>
I want to check if Label text is equal to Project
cy.get('[for="prod-field"]').should('have.text', 'Project')
but the result is
-'ProjectRequired'
+'Project'
so this selector take also span...
How can i select them independently and check?
You can do something like:
cy.get('[for="prod-field"]').should(($el) => {
expect(
$el
.contents() // Grab all contents
.first() // The text node you're looking for
.text() // Get the text
.trim() // And trim the white space
).to.eq('Project');
});
As you can see in the above, we can do this, however the selector is over complicated. I'd recommend you to tweak the HTML a bit if you can to something like:
<label for="prod-field"
><span class="label-text">Project</span>>
<span class="aui-icon">Required</span>
</label>
Then, you can simply do this:
cy.get('[for="prod-field"] .label-text').should('have.text', 'Project');
Your locator selects label and all within it, just change the locator to the span like this:
cy.get('[for="prod-field"] span.label-text').should('have.text', 'Project')

Removing Child Elements in Javascript

I know this has been extensively answered but alas I have had no luck with previous code.
So I want to remove all the span elements in this div element when the user onclicks a button.
THE HTML
<div id="sequence-label" class="scrollingDiv" style="visibility: hidden;">
<li>H :</li>
<span class="spanUnselected">T</span>
<span class="spanUnselected">F</span>
<span class="spanUnselected">G</span>
<span class="spanUnselected">Q</span>
<span class="spanUnselected">G</span>
</div>
**THE JS **
$('#sequence-remove-pdb').click(sequenceRemovePdb);
function sequenceRemovePdb() {
document.getElementById("sequence-label").style.visibility = "hidden";
workspaceSideChain();
var mySeq = document.getElementById("sequence-label");
}
Things I have tried
Tried to remove all the elements as children of sequence-label
mySeq.empty();
Tried to remove by class selected
mySeq.remove(".spanUnselected");
Tried to remove by firstChild Elements
while (mySeq.firstChild) {
mySeq.removeChild(mySeq.firstChild);
}
Tried to remove by childNodes also over how many elements are in sequence-label and still nothing.
Any ideas?
The Problem
You're mixing jQuery and vanilla javascript in a way that does not work.
Specifically, you're getting an element in vanilla javascript here:
var mySeq = document.getElementById("sequence-label");
Then you are trying to remove elements using jQuery:
mySeq.empty();
and
mySeq.remove(".spanUnselected");
The Solution
The solution is simple enough. Get the element as a jQuery object first, then your functions will work:
var mySeq = jQuery("#sequence-label");
// Then act on it with jQuery as you see fit.
mySeq.find('.spanUnselected').remove();
Also, be sure your event bindings take place inside of a document ready:
jQuery(function($) {
$('#sequence-remove-pdb').click(function() {sequenceRemovePdb;});
});
I might be missing the point but to completely empty the item this might work:
document.getElementById("sequence-label").innerHTML = "";
It will empty out all the children (actually everything) from inside the "sequence-label" element.
Try this code :
$('#sequence-remove-pdb').click(function(){
$('span.spanUnselected').remove();
});
HTML :
<div id="sequence-label" class="scrollingDiv">
<li>H :</li>
<span class="spanUnselected">T</span>
<span class="spanUnselected">F</span>
<span class="spanUnselected">G</span>
<span class="spanUnselected">Q</span>
<span class="spanUnselected">G</span>
</div>
The remove( expr ) method removes all matched elements from the DOM.
This does NOT remove them from the jQuery object, allowing you to use
the matched elements further.
JSFIDDLE LINK

How to remove a span in-place?

I have the following input:
<p>
<span class="highlight">
Some text <b>that can have formatted components too</b>.
</span>
And some more text here of course.
</p>
And I want to achieve the following output:
<p>
Some text <b>that can have formatted components too</b>.
And some more text here of course.
</p>
I am using jquery and it has a .unwrap() function, but if I go
$('.highlight').unwrap() it removes <p>. :(
Manually hacking the DOM seems like a hassle. Do you know any short solution?
With the use of .contents() you'll get the elements inside of the parent element you want to remove.
$(".highlight").contents().unwrap();
try replace with
$('.highlight').replaceWith(function() {
return $(this).html();
});
You can simply can do this by using jQuery.
var cnt = $(".highlight").contents();
$(".highlight").replaceWith(cnt);
Quick links to the documentation:
contents( ) : jQuery
replaceWith( content : [String | Element | jQuery] ) : jQuery

I need to find the next element that is not a sibling

Let's say I have following HTML:
<span>
<span id="x1" class="x">X1</span>
</span>
<span>
<span>
<span id="x2" class="x">X2</span>
</span>
</span>
And $(this) is the <span id="x1" ...>.
What is the best way to find next element matching .x with jQuery?
The structure of the actual document is unpredictable, so the HTML provided is only an example.
I can't use nextAll as it only finds siblings.
If I do $('.x'), it finds all, but I'll have to iterate/compare.
Is there a better solution?
See also: http://jsfiddle.net/JZ9VW/1/.
Given that you seem to be unwilling to make assumptions about the structure of the markup, a class-based selector is best. If elements aren't being added/removed then you can select them once and keep them around as an optimization.
var exes = $('.x');
var x1 = $('#x1');
var nextEx = exes.eq(exes.index(x1) + 1);
http://jsfiddle.net/mattball/QKawu
With a truly unpredictable HTML structure, asking for "the next element" only makes sense in the context of "the collection of elements with the specified class name," which is exactly what the above code reflects.
Find the parent, then get the parent's next sibling, then find the class.
.parent().next().find('.x')

Categories