I have a html code that cannot be altered directly.
<span class="class1 class2 class3 "> First name*: </span>
I need to move the * at the begining or the text. The end result should be this:
<span class="class1 class2 class3 "> *First name: </span>
I also need to make the * to be red (I need to add a class only for this character).
Any ideas?
I'd suggest:
$('span.class1.class2.class3').text(function(i, t){
/* i is in the index of the current element among those returned,
t is the text of the current element.
We return the new text, which is an asterisk, followed by the original text,
with the asterisk removed (using replace to replace the asterisk with an empty string):
*/
return '*' + t.replace(/\*/,'');
});
JS Fiddle demo.
If, however, you need a more generic approach (for example if you have multiple elements with the same/similar selectors):
// selects all the span elements, and filters:
$('span').filter(function(){
// discards the elements that *don't* have '*:' in their text:
return $(this).text().indexOf('*:') > -1;
// iterates over those elements (as above):
}).text(function(i, t) {
return '*' + t.replace(/\*/,'');
});
JS Fiddle demo.
In order to 'make it red,' you'd have to manipulate the HTML, rather than just the text, of the element:
$('span').filter(function(){
return $(this).text().indexOf('*:') > -1;
// Using 'html()' to set the HTML of the 'span' element:
}).html(function(i, h) {
// creating a span and prepending to the current element
return '<span class="required">*</span>' + h.replace(/\*/,'');
});
Coupled with the CSS:
.required {
color: red;
}
JS Fiddle demo.
Further, for simplicity, given that you want to target the * with a class-name (and therefore wrap it in an element-node), you could avoid the string-manipulation and simply float:
$('span').html(function(i,h){
// simply wrapping the `*` in a span (using html() again):
return h.replace(/(\*)/,'<span class="required">*</span>');
});
With the CSS:
.required {
float: left;
color: red;
}
JS Fiddle demo.
References:
filter().
html().
text().
If the problem is the very specific scenario you gave,
$(".class1.class2.class3").each(function() {
var inner = $(this).html();
$(this).html("*" + inner.replace("*",""));
}
var span = $('span.class1.class2.class3');
var new_text = span.text().replace(/\*/, '').replace(/^(\s*)/, '\1<span style="color:red;">*</span>');
span.html(new_text);
Demo
Related
I have multiple elements in the dom with a class of .blockbadge if the value of any .block-badge is 0 then I want to add a class to that element in order to style it differently.
My JS adds the class to all of these elements if anyone of them equal 0. How do I make it only affect those elements which equal zero?
HTML
<span class="block-badge">1</span>
<span class="block-badge">0</span> // this element should have the class 'zero' added
<span class="block-badge">4</span>
JS
var blockBadgeVal = $('.block-badge').val();
if (blockBadgeVal < 0) {
$('.block-badge').addClass('zero');
}
The code in the OP will not work because $('.block-badge').html() will return the html of the first element with class block-badge so in this case return string 1, you should parse the returned value then compare it with the 0.
You could use filter() method instead.
Description: Reduce the set of matched elements to those that match the selector or pass the function's test.
$('.block-badge').filter(function(){
return parseInt($(this).text())==0;
}).addClass('zero');
Hope this helps.
$('.block-badge').filter(function(){
return parseInt($(this).text())==0;
}).addClass('zero');
.zero{
color: red;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="block-badge">1</span>
<span class="block-badge">0</span>
<span class="block-badge">4</span>
Like this
$('.block-badge').each(function(){
if(parseInt($(this).html()) ===0){
$(this).addClass('zero');
}
});
You could use the jQuery :contains selector for that specific markup
$('.block-badge:contains(0)').addClass('zero');
it won't work if any other elements contains a zero, like 10, 101 etc. so if you need only 0, use a filter
FIDDLE
Try using .text(function(index, originalText) {}) where this is current element within collection , originalHtml is current textContent
$(document).ready(function() {
$(".block-badge").text(function(index, originalText) {
if (originalText <= 0) {
$(this).addClass("zero");
}
return originalText
});
});
jsfiddle https://jsfiddle.net/s2g3zpwr/3/
I need to select multiple elements at once for a function. I've got
jQuery
$('[class^="shapeLeft"]').click(function(){
var $parent = $(this).parent()
var $both = $(this, 'this + div[class^="shapeRight"]')
$both.css({'height': parent.height() + 20})
})
HTML
<div class="shapeLeftDiamond"></div>
<div class="shapeRightDiamond"></div>
The part where I say $(this, 'this + div[class^="shapeRight"]') doesn't seem to work.
The clicked element does get its height changed, but its direct neighbor with a class starting with shapeRight doesn't.
How do I select the clicked element and its shapeRight sibling at once?
Thanks
Starting with this, here's how to find all siblings matching a selector:
var allSiblings = $(this).siblings("the-selector-here");
Here's how to find all following siblings:
var allSiblings = $(this).nextAll("the-selector-here");
Here's how to find one following sibling that may not be adjacent:
var allSiblings = $(this).nextAll("the-selector-here").first();
More in the API documentation.
From your fiddle, I don't know which of those you want, but in a comment you said:
I want to write something that is going to select a whole lot of elements.
...which makes me think you want nextAll (without first). Then there's this comment:
I need to select the element after this AND this at the same time
...which means you also want .add(this):
$(".shapeLeftDiamond").click(function() {
var parent = $(this).parent();
var thisShape = $(this).nextAll("div[class^='shapeRight']").add(this);
thisShape.height(parent.height() + 20);
})
main {
height: 200px;
width: 200px;
background-color: #F13;
}
.shapeLeftDiamond {
float: left;
width: 80px;
height: 50px;
background-color: #FF0;
}
.shapeRightDiamond {
float: right;
width: 80px;
height: 50px;
background-color: #0FF;
}
<main>
<div class="shapeLeftDiamond">Click me</div>
<div class="shapeRightDiamond">Should also grow</div>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
You need to remove this from the selector (this has no meaning in CSS selectors) and change the order of your parameters. The selector string comes first, followed by the context:
$(".shapeLeftDiamond").click(function(){
var parent = $(this).parent();
var thisShape = $("+ div[class^='shapeRight']", this);
thisShape.height(parent.height() + 20);
});
Edit: If you want both elements to grow, use .add():
thisShape.add(this).height(parent.height() + 20);
https://jsfiddle.net/qukkwvL1/4/
Either use .next() if it is the exact following node
var thisShape = $(this).next().addBack();
or use .siblings() if they share the same parent but might have other elements in the DOM between them
var thisShape = $(this).siblings('[class^="shapeRight"]').addBack();
In both cases you alse need to add the .addBack() at the end, to include the current element in the selection (the this in your case)
Demo at https://jsfiddle.net/gaby/qukkwvL1/3/
The line:
$(this, "this + div[class^='shapeRight']");
Means:
Look for the element this in the context of this + div[class^='shapeRight']". where the second this in the string would be an element <this/>, not the object.
You want to use either $(this).next(".shapeRightDiamond") or $(this).siblings(".shapeRightDiamond") to get the element beside the one that was clicked. To link the elements to the same set, you want to use .add() or .addBack()
var elems = $(this).add( $(this).next(".shapeRightDiamond") );
or
var elems = $(this).next(".shapeRightDiamond").addBack();
.variations_button[style*="display: none;"] + div
This is my CSS selector which works fine if the style attribute is already in the DOM on page load:
http://jsfiddle.net/xn3y3hu0/
However, if i hide the .variations_button div using javascript, the selector is not working anymore:
$(document).click(function(){
$('.variations_button').hide();
});
http://jsfiddle.net/55seee1r/
Any idea whats wrong? Looks like the CSS is not refreshing, because if i edit another property using the inspector, the color changes red instantly.
Because the selector you use, [style*="display: none;"], is looking for the presence of the exact string of "display: none;" in the style attribute, it requires the browser's JavaScript engine inserts that precise string, including the white-space character (incidentally in Chrome 39/Windows 8.1 it does). For your particular browser you may need to remove the space, and to target most1 browsers, use both versions of the attribute-value string, giving:
.variations_button[style*="display: none;"] + div,
.variations_button[style*="display:none;"] + div
.variations_button[style*="display: none;"]+div,
.variations_button[style*="display:none;"]+div {
color: red;
}
<div class="variations_button" style="display: none;">asd</div>
<div>test</div>
Of course, it remains much simpler to use classes to hide an element, toggling that class with JavaScript, and using the class as part of the CSS selector, for example:
$('.variations_button + div').on('click', function() {
$('.variations_button').toggleClass('hidden');
});
.hidden {
display: none;
}
.hidden + div {
color: red;
}
.variations_button + div {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="variations_button">asd</div>
<div>test</div>
As I understand it, the problem of the above not working once jQuery is involved, is because jQuery's hide(),show() and toggle() methods seem to update the display property of the element's style property, rather than setting the attribute directly. The updated attribute-value (as represented in the style attribute) seems to be a representation of the style property (derived, presumably, from its cssText). Because the attribute is unchanged, and merely serves as a representation of a property, the CSS attribute-selectors don't, or perhaps can't, match.
That said, a somewhat clunky workaround is to directly set the attribute; in the following demo this uses jQuery's attr() method (though the native DOM node.setAttribute() would work equally well):
$(document).click(function() {
// setting the style attribute of the selected element(s),
// using the attr() method, and the available anonymous function:
$('.variations_button').attr('style', function(i, style) {
// i: the index of the current element from the collection,
// style: the current value (before manipulation) of the attribute.
// caching the cssText of the node's style object:
var css = this.style.cssText;
// if the string 'display' is not found in the cssText:
if (css.indexOf('display') === -1) {
// we return the current text plus the appended 'display: none;' string:
return css + 'display: none;';
// otherwise:
} else {
// we replace the string starting with 'display:', followed by an
// optional white-space ('\s?'), followed by a matching string of
// one or more alphabetic characters (grouping that last string,
// parentheses):
return css.replace(/display:\s?([a-z]+)/i, function(a, b) {
// using the anonymous function available to 'replace()',
// a: the complete match, b: the grouped match (a-z),
// if b is equal to none we return 'display: block', otherwise
// we return 'display: none':
return 'display: ' + (b === 'none' ? 'block' : 'none');
});
}
});
});
jQuery(document).ready(function($) {
$(document).click(function() {
$('.variations_button').attr('style', function(i, style) {
var css = this.style.cssText;
if (css.indexOf('display') === -1) {
return css + 'display: none;';
} else {
return css.replace(/display:\s?([a-z]+)/i, function(a, b) {
return 'display: ' + (b === 'none' ? 'block' : 'none');
});
}
});
});
});
.variations_button[style*="display: none;"]+div {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="variations_button">asd</div>
<div>test</div>
References:
CSS:
Substring Matching Attribute-selectors.
JavaScript:
HTMLElement.style.
JavaScript Regular Expressions.
String.prototype.indexOf().
String.prototype.replace().
jQuery:
attr().
hide().
show().
toggle().
i'm looking for a way to style the first character in a paragraph. I've used this function to return the first character
var x= $(".about p:eq(0)").text();
alert(x.charAt(0));
but don't know how to style it
You can use CSS3 to style your first character.
p::first-letter {
font-size: 200%;
color: #8A2BE2;
}
Demo:
http://jsfiddle.net/vhyqowde/
More Info:
http://www.w3schools.com/cssref/sel_firstletter.asp
Javascript approach:
$(document).ready(function () {
var elem = $("p").contents().filter(function () { return this.nodeType == 3 }).first(),
text = elem.text().trim(),
first = text.slice(0, 1);
if (!elem.length)
return;
elem[0].nodeValue = text.slice(first.length);
elem.before('<span>' + first + '</span>');
});
http://jsfiddle.net/kynt4pot/
Use CSS first-letter selector
p::first-letter {
color: #FF69B4;
}
This will select and style the first letter of every <p> element. JS Fiddle Demo
With Jquery : http://jsfiddle.net/2wkjyz4g/2/
var x= $(".about p:eq(0)").text();
var text='<span class="fChar">'+x.charAt(0)+'</span>';
$(".about p:eq(0)").html(text + x.slice(1,x.length));
With css : http://jsfiddle.net/pe5Loaqn/
.about p:first-child:first-letter {
color:red;
}
because you asked for jquery solution and you selected 1st(:eq(0)) <p> tag.
update after #Garconis' comment
var parent = "p"
function styleFirst(elem){
var content = $(elem).contents()[0];
if(content.nodeType == 1){
styleFirst(content);
}else if(content.nodeType == 3){
$(elem).html(style(String(content.nodeValue)));
}
}
function style(txt){
var newTxt = '<span class="fChar">' + txt.charAt(0) + '</span>';
return newTxt + txt.slice(1, txt.length);
}
styleFirst(parent);
.fChar {
color:red;
}
span{
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p><span><span>Win</span>ter</span> is <span>here</span> !!!!!!!!!!!</p>
Update in code:
Can retain the nodes in the para tag also can style 1st text character even if it is nested in any other element.
The code can be updated to check if 1st char is space/tab etc in style() method and subsequent styling can be applied.
After having the same initial question, I decided to take bits and pieces of other's code, and create my own solution/answer. Here is my method.
Demo: http://jsfiddle.net/Garconis/g72a4h03/
Reference notes in the jQuery to understand some of the reasoning.
(function($) {
// find each instance of your target
$('p').each(function() {
// now check if the first character is "<" character
// if is NOT a "<" character, then continue
if ($(this).html()[0] != "<") {
// good, now search the contents of the first TEXT_NODE within the selector
var node = $(this).contents().filter(function() {
return this.nodeType == 3
}).first(),
// check the start of the string (which is what the ^ is for)
// find any white space (via the "\s")
// and chunks of contiguous whitespace, which is what the + is for on "\s+"
// and keep finding all instances at the start, which is what the global "/g" is for
// and convert them into nothing
text = node.text().replace(/^\s+/g, ''),
// now start at the beginning (0 position) and grab the first character
first = text.slice(0, 1);
// if the first node isn't a TEXT_NODE, then stop here
if (!node.length)
return;
// remove the text character that we grabbed
node[0].nodeValue = text.slice(first.length);
// now add it back, before the node we checked, with a wrapper
node.before('<span class="fs-dropcap">' + first + '</span>');
};
});
})(jQuery);
span.fs-dropcap {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<hr>
<p> "[yo]"This is a test <b> Other HTML tester should not be affected by manipulations</b></p>
<hr>
<p> This is a test <b> Other HTML tester should not be affected by manipulations</b></p>
<hr>
<p><span>span tag here</span> This is a test <b> Other HTML tester should not be affected by manipulations</b></p>
<hr>
<p>test This is a test <b>Other HTML should not be affected by manipulations</b>
</p>
<hr>
<p>This is a test <b>Other HTML should not be affected by manipulations</b></p>
<hr>
<p> This is a test "Other HTML should not be affected by manipulations"
</p>
<hr>
<p><u> tester </u> This is a test "Other HTML should not be affected by manipulations"
</p>
I somehow need to trim() the innerHTML of my content... so I have something like this:
<div>
<b>test</b>
123 lol
</div>
I basically want to rid of the white space that is ONLY between <div> and the next character, and the white space just before the closing </div>.
So the outcome would be:
<div><b>test</b>
123 lol</div>
var $mydiv = $('#mydiv');
$mydiv.html($.trim($mydiv.html());
This should take the contents any element, trim the whitespace from it and reset it as the content.
I don't really know why you want to do this but it seems like you are using jquery, so you can use the trim helper:
var $stuff = $(...the messy html you have above including the outer div);
var tidy = $.trim( $stuff.html() );
// tidy has no more div wrapper so you can do this:
return "<div>" + tidy "</div>"
// or this (but i dunno that it won't pad it again)
$stuff.html(tidy)
You can easily write a jQuery plugin to do this. I created both a static and instance method for this.
You can toggle the __DEBUG__TRIM_TYPE variable below to change the technique. Each case will produce the exact same result. They are different ways of achieving the same result.
// jQuery Plugin
// =============================================================================
(function($) {
$.fn.trimHtml = function() {
return this.html(function(index, html) {
return $.trim(html);
});
};
$.trimHtml = function(selector) {
return $(selector || '*').filter(function() {
return $(this).data('trim') === true;
}).trimHtml();
}
}(jQuery));
// Example
// =============================================================================
$(function() {
var __DEBUG__TRIM_TYPE = 1; // You can change this to values between 1-3.
switch (__DEBUG__TRIM_TYPE) {
// Option #1. Select elements by a selector.
case 1:
$('.pre-block[data-trim="true"]').trimHtml();
break;
// Option #2. Filter elements by a selector and their data.
case 2:
$('.pre-block').filter(function() { return $(this).data('trim'); }).trimHtml();
break;
// Option #3. Apply function to all elements where the "trim" data is TRUE.
case 3:
$.trimHtml();
break;
}
});
h1 { font-size: 1.5em; }
.pre-block { display: inline-block; white-space: pre; border: thin solid black; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js"></script>
<h1>Not Trimmed</h1>
<div class="pre-block" data-trim="false">
Text not to be trimmed.
</div>
<h1>Already Trimmed</h1>
<div class="pre-block" data-trim="false">Text already trimmed.</div>
<h1>Trimmed</h1>
<div class="pre-block" data-trim="true">
Text that was trimmed.
</div>