I need to write a code to add IDs to all element in one class. The IDs have to be based on innerText.
Elements look like that:
<lable class="sf-label-radio">Name1<span>Some Other Text that I do not need</span><label>
<lable class="sf-label-radio">Name2<span>Some Other Text that I do not need</span><label>
etc.
Here is my code:
<script>
addIDtoGI();
function addIDtoGI() {
let searchButtons = document.getElementsByClassName('sf-label-radio');
for(i = 0; i < searchButtons.length; i++) {
x = searchButtons[i].innerHTML;
x = x.substr(0, x.search("<")).replace(/\s+/g, '-').toLowerCase();
x = onlyEngLetters(x);
searchButtons[i].setAttribute('id',x);
}
}
function onlyEngLetters(text) {
text=text.replace("ę","e");
text=text.replace("ó","o");
text=text.replace("ą","a");
text=text.replace("ś","s");
text=text.replace("ł","l");
text=text.replace("ż","z");
text=text.replace("ź","z");
text=text.replace("ć","c");
text=text.replace("ń","n");
return text;
}
</script>
Thank You for help!
Iterate the childnodes until you get to the first textNode that isn't empty to get the text you want. Note also thaat replace() only works on first instance found and you probably want to convery to lower case to match your replacements
addIDtoGI()
function addIDtoGI(){
document.querySelectorAll('.sf-label-radio').forEach(el=>{
let txtNode = el.childNodes[0];
while(!txtNode.textContent.trim()){
txtNode = txt.nextSibling
}
el.id = onlyEngLetters(txtNode.textContent);
console.log(el.id)
});
}
function onlyEngLetters(text) {
return text.toLowerCase()
.replaceAll("ę","e")
.replaceAll("ó","o")
.replaceAll("ą","a")
.replaceAll("ś","s")
.replaceAll("ł","l")
.replaceAll("ż","z")
.replaceAll("ź","z")
.replaceAll("ć","c")
.replaceAll("ń","n")
}
<label class="sf-label-radio">Name1<span>Some Other Text that I do not need</span><label>
<label class="sf-label-radio">Name2<span>Some Other Text that I do not need</span><label>
First, you define your function but you never call it.
In your script, add the "()" to "addIDToGI;": addIGToGI();
There's also a typo on searchButtons.lenght, it should be length.
It should resolve your errors.
EDIT: Also, as someone mentionned in the comments, <lable> should be <label>.
First you must call function with () and when using for loop must use variables=>
for(let i = 0; i < searchButtons.length; i++) . length is true not lenght. and of course
let x = searchButtons[i].innerHTML;
and ...
const addIdToClassByInnerHTML = cls => {
const elements = document.querySelectorAll('.' + cls);
elements.forEach(el=>{
el.setAttribute('id', el.innerHTML);
});
}
note that do not use this function if the element contains child.
if your element contains one or more child(ren), use this:
const addIdToClassByInnerHTML = cls => {
const elements = document.querySelectorAll('.' + cls);
elements.forEach(el=>{
let html = el.innerHTML;
el.querySelectorAll('*').forEach(sub=>{
html = html.replace(sub.outerHTML, '');
});
el.setAttribute('id', html);
});
}
codepen demo
snippets
const addIdToClassByInnerHTML = cls => {
const elements = document.querySelectorAll('.' + cls);
elements.forEach(el=>{
let html = el.innerHTML;
el.querySelectorAll('*').forEach(sub=>{
html = html.replace(sub.outerHTML, '');
});
el.setAttribute('id', html);
});
}
addIdToClassByInnerHTML('sf-label-radio');
console.log(document.querySelectorAll('.sf-label-radio')[0]);
label{
display: block;
}
<label class="sf-label-radio">Name1<span>Some Other Text that I do not need</span><label>
<label class="sf-label-radio">Name2<span>Some Other Text that I do not need</span><label>
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 want to add id for all the heading tag from dynamic content. The id should be based on innertext of the same element(this is to create the link for particular section).
Ex:
if heading tag have <h1 class="title_tag">Key Programming Language</h1>,
the output should be <h1 id="key-programming-language" class="title_tag">Key Programming Language</h1>
i am not sure how get innerHTML value into id. Please suggest me the solution using any javascript(or)jquery(or)PHP
const convertToKebabCase = (string) => {
return string.replace(/\s+/g, '-').toLowerCase();
}
const h1 = document.querySelectorAll("h1");
h1.forEach(el=>{
const kebabCaseText = convertToKebabCase(el.innerText);
el.id = kebabCaseText;
})
<h1 class="title_tag">Key Programming Language</h1>
This what you're trying to do?
$("h1").each(function(){
var newId = $(this).text().replace(" ", "-");
//console.log(newId);
$(this).attr('id', newId);
});
or pure Javascript:
var elements = document.getElementsByTagName("1");
for (i = 0; i < elements.length; i++) {
elemelements[i].id = elements[i].innerHTML;
}
I am trying to call another function inside the getElement but it is not working everything when i change my selection. When i select Car, in the textbox my varxumb should populate. Any idea...
document.getElementById("mycall1").insertRow(-1).innerHTML = '<td><select id = "forcx" onchange="fillgap()"><option>Select</option><option>Force</option><option>Angle</option><option>Area</option></select></td>';
function fillgap() {
var xnumb = 20;
var forcxlist = document.getElementById("forcx");
if (forcxlist == "Force") {
document.getElementById("result1").value = xnumb;
}
}
I don't know how this "Force" value is coming to check.
you can try these solutions.
if (forcxlist == "Force")
instead use
var forcxlistText = forcxlist.options[forcxlist.selectedIndex].text;
if (forcxlistText == "Force")
or use value technique
<div id ="mycall1">
</div>
<div id ="result1">
</div>
<script>
document.getElementById("mycall1").innerHTML = '<td><select id = "forcx" onchange="fillgap(this.value)"><option value="1">Select</option><option value="2">Force</option><option value="3">Angle</option><option value="4">Area</option></select></td>';
function fillgap(value){
var xnumb = 20;
if (value == "2"){
document.getElementById("result1").innerHTML = xnumb;
}
}
</script>
or use
<div id ="mycall1">
</div>
<input type="text" id="result1" value=""/>
<script>
document.getElementById("mycall1").innerHTML = '<td><select id = "forcx"><option value="1">Select</option><option value="2">Force</option><option value="3">Angle</option><option value="4">Area</option></select></td>';
document.getElementById("forcx").onchange = function (){
var xnumb = 20;
var forcxlist = document.getElementById("forcx");
var forcxlistValue = forcxlist.options[forcxlist.selectedIndex].value;
if (forcxlistValue == "2"){
document.getElementById("result1").value = xnumb;
}
}
</script>
The forcxlist variable is an element object, returned by the document.getElementById method. Afterwards, you are checking if this element object is equal to "Force", which is a string (meaning the contents of your if block will never be executed). Did you mean to check if the contents of that object are equal to Force?
Instead of
if (forcxlist == "Force"){
use
if (forcxlist.innerHTML == "Force"){
I hope this helps!
Can't use innerHTML so i changed it to .value
document.getElementById("result1").value = xnumb;
There are a couple issues here.
First, you are expecting forcxlist to be a string, not an element, so you need to use .value to get the selected value of the dropdown.
Second, you should do your comparison with === not ==, as this ensures type equality as well, and is best practice.
I would also recommend building your select using HTML elements. It keeps things cleaner, is more readable, and is easier to maintain.
Since you are using the same id for the select, you would have to change the selector in your fillgap handler to var forcxlist = e.target.value;, this way the event will fire based on only the select that you are interacting with, regardless of how many rows you have in the table.
Updated code is below, and an updated working fiddle here. As per your comment about adding additional rows, the fiddle has this working as well.
<input type="button" value="Add Row" onclick="addDropDown()">
<table id="mycall1"></table>
<script>
function addDropDown() {
var tbl = document.getElementById("mycall1");
var newRow = tbl.insertRow(-1);
var newCell = newRow.insertCell(0);
newCell.appendChild(createDropDown("forcx", fillgap));
}
function createDropDown(id, onchange) {
var dd = document.createElement('select');
dd.id = id;
dd.onchange = onchange;
createOption("Select", dd);
createOption("Force", dd);
createOption("Angle", dd);
createOption("Area", dd);
return dd;
}
function createOption(text, dropdown) {
var opt = document.createElement("option");
opt.text = text;
dropdown.add(opt);
}
function fillgap() {
var xnumb = 20;
var forcxlist = e.target.value;
if (forcxlist === "Force") {
document.getElementById("result1").value = xnumb;
}
}
</script>
<input type="text" id="result1">
I am using Meteor and I am trying to check if a text is html. But usual ways do not work. This is my code:
post: function() {
var postId = Session.get("postId");
var post = Posts.findOne({
_id: postId
});
var object = new Object();
if (post) {
object.title = post.title;
if ($(post.content).has("p")) { //$(post.content).has("p") / post.content instanceof HTMLElement
object.text = $(post.content).text();
if (post.content.match(/<img src="(.*?)"/)) {
object.image = post.content.match(/<img src="(.*?)"/)[1];
}
} else {
console.log("it is not an html------------------------");
object.text = post.content;
}
}
return object;
}
Actually, this is the most "working" solution I have used up to now. Also, I pointed out the two most common ways which I use (next to the if statement). Is it possible to happen without regex.
Can use approach you already started with jQuery but append response to a new <div> and check if that element has children. If jQuery finds children it is html.
If it is html you can then search that div for any type of element using find().
// create element and inject content into it
var $div=$('<div>').html(post.content);
// if there are any children it is html
if($div.children().length){
console.log('this is html');
var $img = $div.find('img');
console.log('There are ' + $img.length +' image(s)');
}else{
console.log('this is not html');
}
Use the jquery $.parseHTML function to parse the string into an array of DOM nodes and check if it has any HTMLElement.
var htmlText = "----<b>abc</b>----<h3>GOOD</h3>----";
htmlText = prompt("Please enter something:", "----<b>abc</b>----");
var htmlArray = $.parseHTML(htmlText);
var isHtml = htmlArray.filter(function(e){ return e instanceof HTMLElement;}).length;
console.log(htmlText);
//console.log(htmlArray);
if (isHtml)
console.log(isHtml + " HTML Element(s) found.");
else
console.log("No HTML Elements found!");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I am trying to get the inner text of HTML string, using a JS function(the string is passed as an argument). Here is the code:
function extractContent(value) {
var content_holder = "";
for (var i = 0; i < value.length; i++) {
if (value.charAt(i) === '>') {
continue;
while (value.charAt(i) != '<') {
content_holder += value.charAt(i);
}
}
}
console.log(content_holder);
}
extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");
The problem is that nothing gets printed on the console(*content_holder* stays empty). I think the problem is caused by the === operator.
Create an element, store the HTML in it, and get its textContent:
function extractContent(s) {
var span = document.createElement('span');
span.innerHTML = s;
return span.textContent || span.innerText;
};
alert(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>"));
Here's a version that allows you to have spaces between nodes, although you'd probably want that for block-level elements only:
function extractContent(s, space) {
var span= document.createElement('span');
span.innerHTML= s;
if(space) {
var children= span.querySelectorAll('*');
for(var i = 0 ; i < children.length ; i++) {
if(children[i].textContent)
children[i].textContent+= ' ';
else
children[i].innerText+= ' ';
}
}
return [span.textContent || span.innerText].toString().replace(/ +/g,' ');
};
console.log(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>. Nice to <em>see</em><strong><em>you!</em></strong>"));
console.log(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>. Nice to <em>see</em><strong><em>you!</em></strong>",true));
One line (more precisely, one statement) version:
function extractContent(html) {
return new DOMParser()
.parseFromString(html, "text/html")
.documentElement.textContent;
}
textContext is a very good technique for achieving desired results but sometimes we don't want to load DOM. So simple workaround will be following regular expression:
let htmlString = "<p>Hello</p><a href='http://w3c.org'>W3C</a>"
let plainText = htmlString.replace(/<[^>]+>/g, '');
use this regax for remove html tags and store only the inner text in html
it shows the HelloW3c only check it
var content_holder = value.replace(/<(?:.|\n)*?>/gm, '');
Try This:-
<!DOCTYPE html>
<html>
<body>
<script type="text/javascript">
function extractContent(value){
var div = document.createElement('div')
div.innerHTML=value;
var text= div.textContent;
return text;
}
window.onload=function()
{
alert(extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>"));
};
</script>
</body>
</html>
For Node.js
This will use the jsdom library, since node.js doesn't have dom features as in browser.
import * as jsdom from "jsdom";
const html = "<h1>Testing<h1>";
const text = new jsdom.JSDOM(html).window.document.textContent;
console.log(text);
Use match() function to bring out HTML tags
const text = `<div>Hello World</div>`;
console.log(text.match(/<[^>]*?>/g));
You could temporarily write it out to a block level element that is positioned off the page .. some thing like this:
HTML:
<div id="tmp" style="position:absolute;top:-400px;left:-400px;">
</div>
JavaScript:
<script type="text/javascript">
function extractContent(value){
var div=document.getElementById('tmp');
div.innerHTML=value;
console.log(div.children[0].innerHTML);//console out p
}
extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");
</script>
Using jQuery, in jQuery we can add comma seperated tags.
var readableText = [];
$("p, h1, h2, h3, h4, h5, h6").each(function(){
readableText.push( $(this).text().trim() );
})
console.log( readableText.join(' ') );
you need array to hold values
function extractContent(value) {
var content_holder = new Array();
for(var i=0;i<value.length;i++) {
if(value.charAt(i) === '>') {
continue;
while(value.charAt(i) != '<') {
content_holder.push(value.charAt(i));
console.log(content_holder[i]);
}
}
}
}extractContent("<p>Hello</p><a href='http://w3c.org'>W3C</a>");