I have a multiple tag in my webpage with the same class called price. Each tag is of that form
<p class="price">Price: 45$</p>
<p class="price">Price: 32$</p>
What I need at the end is to separate the price text in a span and the price in another so that it will be like that
<p class="price"><span class='h1'>Price:</span> <span class="h2">45$</span></p>
This is what I do until now but problem is that the span is not a tag but is insert as a simple string
let price = $(".price");
for (let i = 0; i < price.length; i++) {
let priceTitle = price[i].innerText.split(":")[0];
let priceToPay = price[i].innerText.split(":")[1];
price[i].innerText = ''; //Delete content of price
$(".price")[i].append("<span class='h1'>"+ priceTitle+"</span> <span class='h2'>"+ priceToPay +"</span>");
}
}
Can you help me fix this issue and perhaps optimize the code I already do.
You've just a few syntax errors e.g. you've set priceToPay then used price_toPay in your final line of code. Also jQuery.append() method is setting your content as textContent and not HTML but just use innerHTML instead. I've added a button for you to click so you can see the before and after effects. See below
window.onload = () => {
document.getElementById('mybutton').addEventListener('click', doFormat);
}
function doFormat() {
let price = $(".price");
for (let i = 0; i < price.length; i++) {
const priceTextContentArray = price[i].innerText.split(":");
let priceTitle = priceTextContentArray[0];
let priceToPay = priceTextContentArray[1];
price[i].innerHTML =
"<span class='h1'>" +
priceTitle +
"</span> <span class='h2'>" +
priceToPay +
"</span>";
}
}
.h1 {
background-color: skyblue;
}
.h2 {
background-color: coral;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer" defer></script>
<button id='mybutton'>Format</button><br>
<p class="price">Price: 45$</p>
<p class="price">Price: 32$</p>
If you want to do it "the jQuery way", to build elements from strings you must use the $ constructor:
replace:
price[i].innerText = ''; //Delete content of price
$(".price")[i].append("<span class='h1'>"+ priceTitle+"</span> <span class='h2'>"+ priceToPay +"</span>");
by:
$(price[i]).html('').append( $("<span class='h1'>"+ priceTitle +"</span> <span class='h2'>"+ priceToPay +"</span>") );
As you see in jQuery you can also chain the calls, and use the .html() or .text() dedicated functions. html is more suitable here as you want to delete all inside your element, not just the text part
Notice that I also corrected your $(".price")[i] to $(price[i]), it is safer to use the var you loop on instead of doing a new jQuery selection and assume it will have the same index as in your loop
Related
I have 2 variables contain data i need to call in HTML based on js logic, can you check and fix code for me what i am missing.
${specialprice} and ${price}
I need javascript condition to be define in javascript file and call it in html. ( JS file already connected to html )
What i need is to complete this logic is if ${specialprice} contain any value then show it together with ${price}
if is empty then show only ${price}.
condition in JS File:
hasspecialprice() {
if(${specialprice} != ''){
var data = "<p class="specialprice">"۔${specialprice}",-</p>
<p class="price"><span class="visibleprice">"۔${price}",-</span></p>"
}
else
{
var data = "<p class="price"><span class="visibleprice">".${price}",-</span></p>"
}
}
Call this function in HTML:
<div class="priceplace">
<script>hasspecialprice();</script>
</div>
Here's an example of how you could change the content of a div dynamically using js. The important thing to note (besides the corrected syntax) is that I selected the output-target in js and then updated it's content based on the relevant values.
// select the form used for the demo
const form = document.querySelector('form');
// select the output div
const target = document.querySelector('.priceplace');
// define our example data
const data = {
price: 0,
specialprice: 0
};
// when a formfield is changed, we change our example data and update the output
form.onchange = ({ target: { value, name } }) => {
data[name] = value;
hasspecialprice(data.price, data.specialprice);
};
function hasspecialprice(price, specialprice) {
// using a ternary expression is equivalent to a simple if/else
// we change the output's html based on the condition
target.innerHTML = specialprice !== ''
? `<p class="specialprice">${specialprice},-</p>
<p class="price"><span class="visibleprice">${price},-</span></p>`
: `<p class="price"><span class="visibleprice">${price},-</span></p>`
}
<form>
Specialprice:
<input name="specialprice">
Price:
<input name="price">
</form>
<div class="priceplace" style="border: 1px solid black; height: 16px"></div>
In Javascript code you dont need to use the ${} statement. The ${} only uses when you need to concatenate string with variables. You only need to remove this from your if statement. You could improve to use
hasspecialprice() {
if(specialprice != ''){
var data = "<p class="specialprice">"۔${specialprice}",-</p>
<p class="price"><span class="visibleprice">"۔${price}",-</span></p>"
}
else
{
var data = "<p class="price"><span class="visibleprice">".${price}",-</span></p>"
}
}
If have an way to call the hasspecialprice() function then you must try this.
hasspecialprice() {
const inputDiv = document.getElementsByClassName("priceplace");
if(${specialprice} != ''){
var pElement = document.createElement('p'); // CREATING AN ELEMENT
pElement.className += "specialprice"; // ADDING CLASSE TO IT
pElement.innerText = specialprice; // ADDING DATA TO IT
var secondPElement = document.createElement('p');
secondPElement.className += "price";
var spanElement = document.createElement('span');
spanElement.className += "visibleprice";
spanElement.innerText = price;
inputDiv.append(pElement);
secondPElement.appendChild(spanElement);
inputDiv.append(secondPElement);
}
else{
var secondPElement = document.createElement('p');
secondPElement.className += "price";
var spanElement = document.createElement('span');
spanElement.className += "visibleprice";
spanElement.innerText = price;
secondPElement.appendChild(spanElement);
inputDiv.append(secondPElement);
}
}
I have a string of text here that will be dynamically generated to be one of the following:
<h1 id="headline">"Get your FREE toothbrush!"</h1>
OR
<h1 id="headline">"FREE floss set and dentures!"</h1>
Since this will be dynamically generated I won't be able to wrap a <span> around the word "FREE" so I want to specifically target the word "FREE" using Javascript so that I can style it with a different font-family and font-color than whatever styling the <h1> is set to. What methods do I use to go about doing this?
You can search and replace the substring 'FREE' with styled HTML. If 'FREE' occurs more than once in the string you may need to use regex (unless you don't need to support Internet Explorer). See How to replace all occurrences of a string?
In your case:
let str = '<h1 id="headline">"FREE floss set and dentures!"</h1>'
str = str.replace(/FREE/g, '<span color="red">FREE</span>');
The property you are looking for is innerHTML, look the following example:
var word = document.getElementById('word');
function changeWord(){
word.innerHTML = "another";
word.style.backgroundColor = 'black';
word.style.color = 'white';
}
<h1 id="headline">
<span id="word">some</span> base title
</h1>
<button onClick="changeWord()">
change
</button>
Here is a working example using slice and some classic concatenation.
EDIT: Code for the second string is also included now.
//get headline by id
var headline = document.getElementById("headline");
//declare your possible strings in vars
var string1 = "Get your FREE toothbrush!"
var string2 = "FREE floss set and dentures!"
//declare formatted span with "FREE" in var
var formattedFree = "<span style='color: blue; font-style: italic;'>FREE</span>"
//target positions for the rest of your string
var string1Position = 13
var string2Position = 4
//concat your vars into expected positions for each string
var newString1 = string1.slice(0, 9) + formattedFree + string1.slice(string1Position);
var newString2 = formattedFree + string2.slice(string2Position)
//check if strings exist in html, if they do then append the new strings with formatted span
if (headline.innerHTML.includes(string1)) {
headline.innerHTML = newString1
}
else if (headline.innerHTML.includes(string2)) {
headline.innerHTML = newString2
}
<!-- As you can see the original string does not have "FREE" formatted -->
<!-- Change this to your other string "FREE floss set and dentures!" to see it work there as well -->
<h1 id="headline">Get your FREE toothbrush!</h1>
You can split the text and convert the keyword "FREE" to a span element. So you can style the keyword "FREE". This method is safe because does not alter any non-text html element.
var keyword = "FREE";
var headline = document.getElementById("headline");
var highlight, index;
headline.childNodes.forEach(child => {
if (child.nodeType == Node.TEXT_NODE) {
while ((index = child.textContent.indexOf(keyword)) != -1) {
highlight = child.splitText(index);
child = highlight.splitText(keyword.length);
with(headline.insertBefore(document.createElement("span"), highlight)) {
appendChild(highlight);
className = 'highlight';
}
}
}
});
.highlight {
/* style your keyword */
background-color: yellow;
}
<div id="FREE">
<h1 id="headline">"Get your FREE toothbrush! FREE floss set and dentures!"</h1>
</div>
I'm trying to select all spans with class .normal on my site, cut the first character and add € as the last character. I'm trying really hard but it just doesn't work even when I try to just replace that with "abc" or any string.
My javascript looks like that:
$(document).ready(function(){
var prices = document.querySelectorAll('span.normal');
for (i=0; i<prices.length; i++) {
prices[i].textContent = prices[i].substring(1) + "€";
}
}
});
Since you are using jQuery already how about making it completely in jQuery?
$(document).ready(function() {
$('span.normal').each(function() {
$(this).text($(this).text().substring(1) + '€');
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>abc</span>
<span class="normal">abc</span>
<span>abc</span>
<span class="normal">abc</span>
var prices = document.querySelectorAll('span.normal');
for (var i = 0; i < prices.length; i++) {
prices[i].innerHTML = prices[i].innerHTML.substring(1) + "€";
}
.normal{
font-color:black;
}
<span class=normal >3543</span>
<span class=normal >34534</span>
I wish to know the best way to write only once the same thing and repeat inside the same page. For example:
<div>
<p id="description1"></p>
</div>
<div>
<p id="description1"></p>
</div>
--
I wish to write only one time the description1 inside the body. I think this could be achieved using the DOM.
Put the elements in the same class using the class attribute, then get the list of all elements using the getElementsByClassName() DOM function. You can then go over the list using a for loop.
[].forEach.call(document.getElementsByClassName("description"), function(elem) {
elem.innerHTML = "StackOverflow saved my day!";
});
You can even put the text in all elements of the same class using no JavaScript and only CSS by using the content attribute.
First of all, the ID field should be unique per element.
If you give all the tags a class <p class="description"></p> then you can use jQuery to set them all by calling:
$('.description').text('This is the text')
In javascript:
var elements = document.getElementsByClassName("description");
for (var i = 0; i < elements.length; i++) {
elements[i].innerHTML = "This is the text.";
}
Have a look at the solutions proposed here
How to repeat div using jQuery or JavaScript?
this one seems to work pretty well:
html:
<div id="container">data</div>
js:
var container = document.getElementById('container');
function block(mClass, html) {
//extra html you want to store.
return '<div class="' + mClass + '">' + html + '</div>';
}
// code that loops and makes the blocks.
// first part: creates var i
// second: condition, if 'i' is still smaller than three, then loop.
// third part: increment i by 1;
for (var i = 0; i < 3; i++) {
// append the result of function 'block()' to the innerHTML
// of the container.
container.innerHTML += block('block', 'data');
}
JSFIDDLE
Just added with a code by using
getElementsByClassName()
`<html>
<body>
<div class="example">First div element with class="example".</div>
<p class="example">Second paragraph element with class="example".</p>
<p>Click the button to change the text of the first div element with class="example" (index 0).</p>
<button onclick="myFunction()">Try it</button>
<p><strong>Note:</strong> The getElementsByClassName() method is not supported in Internet Explorer 8 and earlier versions.</p>
<script>
function myFunction() {
var x = document.getElementsByClassName("example");
for(var i=0;i< x.length;i++)
x[i].innerHTML = "Hello World!";
}
</script>
</body>
</html>`
If you wish to keep id, change your code like this :
script :
var pcount = 2// # p
var desc = document.getElementById('description1');
for(i=0; i<pcount;i++){
document.getElementById('description' + i).innerHTML = desc;
}
html
<div>
<p id="description1"></p>
</div>
<div>
<p id="description2"></p>
</div>
two elements cannot have same id but can have same class
<head>
<script>
var x = document.getElementsByClassName("description");
for (var i = 0; i < x.length; i++) {
x[i].innerHTML = "This is the text.";
}
</script>
<style>
.description1 { // this will apply the same style to all elements having class as description1
text-align: center;
color: red;
}
</style>
</head>
<body>
<div>
<p class="description1"></p>
</div>
<div>
<p class="description1"></p>
</div>
</body>
See the script tag. this solves your problem
I have following html:
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
How can I get textarea element? I can't use document.getElementById("textid") for it
I'm doing it like this now:
var note = document.getElementById("note");
var notetext = note.querySelector('#textid');
but it doesn't work in IE(8)
How else I can do it? jQuery is ok
Thanks
If jQuery is okay, you can use find(). It's basically equivalent to the way you are doing it right now.
$('#note').find('#textid');
You can also use jQuery selectors to basically achieve the same thing:
$('#note #textid');
Using these methods to get something that already has an ID is kind of strange, but I'm supplying these assuming it's not really how you plan on using it.
On a side note, you should know ID's should be unique in your webpage. If you plan on having multiple elements with the same "ID" consider using a specific class name.
Update 2020.03.10
It's a breeze to use native JS for this:
document.querySelector('#note #textid');
If you want to first find #note then #textid you have to check the first querySelector result. If it fails to match, chaining is no longer possible :(
var parent = document.querySelector('#note');
var child = parent ? parent.querySelector('#textid') : null;
Here is a pure JavaScript solution (without jQuery)
var _Utils = function ()
{
this.findChildById = function (element, childID, isSearchInnerDescendant) // isSearchInnerDescendant <= true for search in inner childern
{
var retElement = null;
var lstChildren = isSearchInnerDescendant ? Utils.getAllDescendant(element) : element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].id == childID)
{
retElement = lstChildren[i];
break;
}
}
return retElement;
}
this.getAllDescendant = function (element, lstChildrenNodes)
{
lstChildrenNodes = lstChildrenNodes ? lstChildrenNodes : [];
var lstChildren = element.childNodes;
for (var i = 0; i < lstChildren.length; i++)
{
if (lstChildren[i].nodeType == 1) // 1 is 'ELEMENT_NODE'
{
lstChildrenNodes.push(lstChildren[i]);
lstChildrenNodes = Utils.getAllDescendant(lstChildren[i], lstChildrenNodes);
}
}
return lstChildrenNodes;
}
}
var Utils = new _Utils;
Example of use:
var myDiv = document.createElement("div");
myDiv.innerHTML = "<table id='tableToolbar'>" +
"<tr>" +
"<td>" +
"<div id='divIdToSearch'>" +
"</div>" +
"</td>" +
"</tr>" +
"</table>";
var divToSearch = Utils.findChildById(myDiv, "divIdToSearch", true);
(Dwell in atom)
<div id="note">
<textarea id="textid" class="textclass">Text</textarea>
</div>
<script type="text/javascript">
var note = document.getElementById('textid').value;
alert(note);
</script>
Using jQuery
$('#note textarea');
or just
$('#textid');
$(selectedDOM).find();
function looking for all dom objects inside the selected DOM.
i.e.
<div id="mainDiv">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<div id="innerDiv">
link
<p>Paragraph 3</p>
</div>
</div>
here if you write;
$("#mainDiv").find("p");
you will get tree p elements together. On the other side,
$("#mainDiv").children("p");
Function searching in the just children DOMs of the selected DOM object. So, by this code you will get just paragraph 1 and paragraph 2. It is so beneficial to prevent browser doing unnecessary progress.