I am selecting all classes from an attribude like so:
var sOption = $(this).attr('class');
in console.log it returns test_1 custom_selectbox
From this i want it to select the class that starts with test_, so with this example it would only return test1. I did the following like so:
var sOption = $.trim($(this).attr('class').replace('custom_selectbox',''));
In this sittuation it returns what i want, but if i add more classes to the attribute where it takes the classes, i would need to also add those class names into replace area:
var sOption = $.trim($(this).attr('class').replace('custom_selectbox','' , 'more_classes', '', 'and_so_on' , ''));
What i want is - instead of using trim and replace , get the test_ classes from the object using regular expressions (bad example):
var sOption = $(this).attr('class'); //get the `test_1 custom_selectbox`
//somehow use the regular expression on this object, so it would select an item from sOption that starts with `test_`
Hopefully i made it understandable what im looking for..
You may split the string into an array, using space as item delimiter, and then filter that array for elements that match your string:
"test_1 custom_selectbox"
.split(' ')
.filter(function(x) { return x.indexOf('test_') == 0; })
You could of course extract that to a plugin:
$.fn.getClasses = function(prefix) {
return $(this).attr('class').split(' ').filter(function(x) { return x.indexOf(prefix) == 0; });
};
Called like so:
$(this).getClasses('test_');
Related
I want to use vanilla js to loop through a string of html text and get its values. with jQuery I can do something like this
var str1="<div><h2>This is a heading1</h2><h2>This is a heading2</h2></div>";
$.each($(str1).find('h2'), function(index, value) {
/// console.log($(value).text());
});
using $(str) converts it to an html string as I understand it and we can then use .text() to get an element (h2)'s value.
but I want to do this within my node app on the backend rather than on the client side, because it'd be more efficient (?) and also it'd just be nice to not rely on jQuery.
Some context, I'm working on a blogging app. I want a table of contents created into an object server side.
This is another way using .innerHTML but uses the built-in iterable protocol
Here's the operations we'll need, the types they have, and a link to the documentation of that function
Create an HTML element from a text
String -> HTMLElement – provided by set Element#innerHTML
Get the text contents of an HTML element
HTMLElement -> String – provided by get Element#innerHTML
Find nodes matching a query selector
(HTMLElement, String) -> NodeList – provided by Element#querySelectorAll
Transform a list of nodes to a list of text
(NodeList, HTMLElement -> String) -> [String] – provided by Array.from
// html2elem :: String -> HTMLElement
const html2elem = html =>
{
const elem = document.createElement ('div')
elem.innerHTML = html
return elem.childNodes[0]
}
// findText :: (String, String) -> [String]
const findText = (html, selector) =>
Array.from (html2elem(html).querySelectorAll(selector), e => e.textContent)
// str :: String
const str =
"<div><h1>MAIN HEADING</h1><h2>This is a heading1</h2><h2>This is a heading2</h2></div>";
console.log (findText (str, 'h2'))
// [
// "This is a heading1",
// "This is a heading2"
// ]
// :: [String]
console.log (findText (str, 'h1'))
// [
// "MAIN HEADING"
// ]
// :: [String]
The best way to parse HTML is to use the DOM. But, if all you have is a string of HTML, according to this Stackoverflow member) you may create a "dummy" DOM element to which you'd add the string to be able to manipulate the DOM, as follows:
var el = document.createElement( 'html' );
el.innerHTML = "<html><head><title>aTitle</title></head>
<body><div><h2>This is a heading1</h2><h2>This is a heading2</h2></div>
</body</html>";
Now you have a couple of ways to access the data using the DOM, as follows:
var el = document.createElement( 'html' );
el.innerHTML = "<html><head><title>aTitle</title></head><body><div><h2>This is a heading1</h2><h2>This is a heading2</h2></div></body</html>";
// one way
el.g = el.getElementsByTagName;
var h2s = el.g("h2");
for(var i = 0, max = h2s.length; i < max; i++){
console.log(h2s[i].textContent);
if (i == max -1) console.log("\n");
}
// and another
var elementList = el.querySelectorAll("h2");
for (i = 0, max = elementList.length; i < max; i++) {
console.log(elementList[i].textContent);
}
You may also use a regular expression, as follows:
var str = '<div><h2>This is a heading1</h2><h2>This is a heading2</h2></div>';
var re = /<h2>([^<]*?)<\/h2>/g;
var match;
var m = [];
var i=0;
while ( match = re.exec(str) ) {
m.push(match.pop());
}
console.log(m);
The regex consists of an opening H2 tag followed by not a "<",followed by a closing H2 tag. The "*?" take into account zero or multiple instances of which there is at least zero or one instance.
Per Ryan of Stackoverflow:
exec with a global regular expression is meant to be used in a loop,
as it will still retrieve all matched subexpressions.
The critical part of the regex is the "g" flag as per MDN. It allows the exec() method to obtain multiple matches in a given string. In each loop iteration, match becomes an array containing one element. As each element is popped off and pushed onto m, the array m ultimately contains all the captured text values.
I'm trying to assign class and id to items in an array I created in js and input into my html. I'm doing this so I can style them in my stylesheet. Each item will not be styled the same way.
I'm a beginner so trying to keep it to code I can understand and make it as clean as possible, i.e. not making each of these items an element in the html.
This part works fine:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
var letters = pool.join('');
document.getElementById('key').innerHTML = letters;
This part not so much:
var char1 = letters[1];
char1.classList.add('hoverRed');
There is a similar question here that didn't work for me, it just showed [object][object][object] when I ran it.
Your code attempts to apply a style to an array element, but CSS only applies to HTML. If you wish to style one character in a string, that character must be wrapped in an HTML element (a <span> is the best choice for wrapping an inline value).
This code shows how to accomplish this:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
var letters = pool.join('');
// Replace a specific character with the same character, but wrapped in a <span>
// so it can be styled
letters = letters.replace(letters[1], "<span>" + letters[1] + "</span>");
// Insert the letters string into the div
var theDiv = document.getElementById('key');
// Inject the string into the div
theDiv.innerHTML = letters;
// Get a reference to the span:
var theSpan = theDiv.querySelector("span");
// Add the style to the <span> that wraps the character, not the character itself
theSpan.classList.add('hoverRed');
.hoverRed {
color:red;
}
<div id="key"></div>
And, this snippet shows how you could apply CSS to any letter:
var pool =['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U'];
// Leave the original array alone so that it can be manipulated any way needed
// in the future, but create a new array that wraps each array element within
// a <span>. This can be accomplished in several ways, but the map() array method
// is the most straight-forward.
var charSpanArray = pool.map(function(char){
return "<span>" + char + "</span>";
});
// Decide which character(s) need CSS applied to them. This data can come from anywhere
// Here, we'll just say that the 2nd and 5th ones should.
// Loop through the new array and on the 2nd and 5th elements, apply the CSS class
charSpanArray.forEach(function(element, index, array){
// Check for the particular array elements in question
if(index === 1 || index === 4){
// Update those strings to include the CSS
array[index] = element.replace("<span>","<span class='hoverRed'>");
}
});
// Now, turn the new array into a string
var letters = charSpanArray.join('');
// For diagnostics, print the string to the console just to see what we've got
console.log(letters);
// Get a reference to the div container
var theDiv = document.getElementById('key');
// Inject the string into the div
theDiv.innerHTML = letters;
.hoverRed {
color:red;
}
<div id="key"></div>
You're on the right track, but missed one key thing.
In your example, pool contains characters. When you combine them using join, you get a string. Setting that string as the innerHTML of an element doesn't give the string super powers, it's still just a string.
In order to get a classList, you need to change your letters into elements and work with them.
I've included an es6 example (and a working plunker) of how to get the functionality you want below.
let pool = ['A','B','3','J','R','1','Q','F','5','T','0','K','N','C','R','U']
const letterToElement = function(char) {
//Create the element
let e = document.createElement("SPAN");
//Create the text node
let t = document.createTextNode(char);
//Put the text node on the element
e.appendChild(t);
//Add the class name you want
e.className += "hoverRed";
return e;
};
//create your elements from your pool and append them to the "key" element
window.onload = function() {
let container = document.getElementById("key");
pool.map(l => letterToElement(l))
.forEach(e => container.appendChild(e));
}
https://plnkr.co/edit/mBhA60aUCEGSs0t0MDGu
Is is possible to assign a data value to the element below - and use the numbers in the string as the value with jQuery/Vanilla JS?
I want this:
<div class="priceinfo col5">2560kr</div>
To look like this:
<div class="priceinfo col5" data-price="2560">2560kr</div>
The value is dynamic - the class of the element is the same.
This can be done with the jQuery attr() method:
var someValue = 2560;
$('.priceinfo.col5').attr('data-price', someValue);
You can set any attribute, including custom attributes such as HTML5 data- attributes, using attr().
You can also pass a function instead of a fixed value to .attr():
$('.priceinfo.col5').attr('data-price', function() {
var text = $(this).text();
return parseInt(text, 10); //drops the non-numeric characters at the end of the text
});
This is extremely useful when there are multiple elements in the jQuery set -- multiple elements with the classes priceinfo and col5.
If the value might sometimes have initial non-numeric characters, then you could use a regular expression to parse the text:
$('.priceinfo.col5').attr('data-price', function() {
var text = $(this).text();
var matches = /\d+/.exec(text);
if (!matches) {return '';}
return parseInt(matches[0], 10);
});
You can do that with plain javascript as well:
function setAttribute(selector, attribute, value) {
var elements = document.querySelectorAll(selector);
for (var index = 0; index < elements.length; index++) {
elements[index].setAttribute(attribute, (typeof value === "function" ? value(elements[index]) : value));
}
}
How can I do this:
I have object that has multiple classes. My goal is to get class name that has string(e.g. 'toaster') in it (or starting with that string) and put it in variable.Note that I know only the beggining of class name and I need to get whole.
e.g. <div class="writer quite-good toaster-maker"></div>
I have this div as my jQuery object, I only need to put class name toaster-maker in variable className;
Again I don't need to select object! I only need to put class name in variable.
A regular expression seems to be more efficient here:
classNames = div.attr("class").match(/[\w-]*toaster[\w-]*/g)
returns all class names that contain "toaster" (or an empty array if there are none).
So, assuming you already have a jQuery object with that div, you could get the value of the class attribute, split the string into the class names, iterate over them and see which one contains toaster:
var className = '';
$.each($element.attr('class').split(/\s+/), function(i, name) {
if (name.indexOf('toaster') > -1) { // or name.indexOf('toaster') === 0
className = name;
return false;
}
});
jQuery doesn't provide an specific function for that.
If you have multiple elements for which you want to extract the class names, you can use .map:
var classNames = $elements.map(function() {
$.each(this.className.split(/\s+/), function(i, name) {
if (name.indexOf('toaster') > -1) { // or name.indexOf('toaster') === 0
return name;
}
});
}).get();
classNames will then be an array of class names.
In browser which support .classList, you could also use $.each(this.classList, ...) instead of $.each(this.className.split(/\s+/), ...).
try this,
var names = $('[class*=toaster]').attr('class').split(' ');
var className;
$.each(names, function(){
if (this.toLowerCase().indexOf("toaster") >= 0)
className = this;
})
console.log(className);
fiddle is here. You can also have className as an array and push the matched class names to it.
I have an array with divs ids (in my case its all divs ID values od parent div (#area) ):
jQuery.fn.getIdArray = function () {
var ret = [];
$('[id]', this).each(function () {
ret.push(this.id);
});
return ret;
};
var array = $("#area").getIdArray();
I need to get an array field value, something like this:
var lef = $("#array".[0]).css("left");
Taking a wild swing at it (see my comment on the question):
var array = $("#area").getIdArray();
var lef=$("#" + array[0]).css("left");
That assumes that getIdArray returns an array of strings, where each string is an id value for a DOM element, and that you want to get the left value for the first of those elements.
So for instance, if the array comes back as:
["foo", "bar", "charlie"]
then the selector created by "#" + array[0] is #foo, so you end up getting the left value for the foo element.
If you have an actual JS array within your variable array just use bracket notation to access each individual ID.
// I have the # before-hand since I'm assuming you have just the ID name
var lef = $('#' + array[0]) // this will access the 1st one in the array
I think you are looking for this :
var divYouWantToChange = $("#"+array[0]);
I try to formulate this as an answer because getIdArray is not a jquery function and we don't know what it does. If you'd like to apply a custom filter to the $("#area") collection you can do so using filter. This will return a jquery object where you can get the .css("left") from.
If you'd like to save both the id's and the left property you can do so with the following code:
var objects=[];
$("#area").filter(function(){
$this=$(this);//cache the object
objects.push({id:$this.attr("id"),
left:$this.css("left")
};
});
console.log(objects);