removeClass before html() - javascript

I have a variable which has two classes. I am wanting to remove the small class before the html() pushes the div to DOM.
As of right now, the div is rendering with the small class. I am wanting that to be removed.
I have tried switching the order of the removeClass to place it before the html(), but that didn't work.
$('#review').removeClass('small').html(prev);
Does anyone know how I can do this?
var prev = "<div class='big small'>Hello</div>";
$('#review').html(prev).removeClass('small');
.big {
color: red;
font-size: 2rem;
}
.small {
color: blue;
font-size: 1.1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="review"></div>
UPDATE
I tried to make my question really basic for simplicity, but it turns out, the array I had in my actual code made this more complex.
$('body').on('change', '.option-check', function() {
var calSelectionImg = [];
$('.calendar-check:checked').each(function() {
calSelectionImg.push($(this).data('calendar-img'));
});
$('#pg-img-review').html(calSelectionImg);
});
.cal-selected-img {
color: red;
font-size: 2rem;
}
.small {
color: blue;
font-size: 1.1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" class="option-check" data-cal-choice="<div class='cal-selected-img small'>Hello</div>">
<input type="checkbox" class="option-check" data-cal-choice="<div class='cal-selected-img small'>Goodbye</div>">
<div id="pg-img-review" class="margin15"></div>

You're modifying #review, not your new code. So, I added appendTo. It's a minor restructure, but it fixes the issues with minimal complications.
var prev = "<div class='big small'>Hello</div>";
$(prev).removeClass('small').appendTo("#review");
.big {
color: red;
font-size: 2rem;
}
.small {
color: blue;
font-size: 1.1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="review"></div>

In the example you've given, the HTML in prev is just a string. You need to parse it into a DOM object before you can call a function such as .removeClass() on it.
jQuery provides a number of options for parsing HTML elements, but as a vanilla JS over jQuery proponent, I often favour this particular approach:
var tempDiv = document.createElement('div');
tempDiv.innerHtml = "<p class='small'>The string of HTML</p>";
var parsedElement = tempDiv.firstChild;
I can then call the jQuery method parsedElement.removeClass("small") or Vanilla JS parsedElement.classList.remove("small") to successfully remove the class.

var prev = "<div class='big small'>Hello</div>";
$('#review').html(prev).find('.small').removeClass('small');
.big {
color: red;
font-size: 2rem;
}
.small {
color: blue;
font-size: 1.1rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="review"></div>

You may need this:
var prev = "<div class='big small'>Hello</div>";
$('#review').html(prev);
$(".big").removeClass('small');
Add your DIV first, and then remove the class you don't need later.
Don't worry
$(".big").removeClass('small');
would cause any problem. If there is no CLASS [small], the DOM will ignore the js.
That's all.O(∩_∩)O~

Related

HTML element to display tooltip on hover

I have several HTML elements that I need to display a tooltip on hover. These are not conventional HTML elements and come from a generated script on the backend, which I do not have permissions to alter. What I want to know, from a front end perspective, is how I can display a tooltip without declaring this in the HTML.
I tried using Bootstrap tooltips, but you need to declare this in the HTML tag as a title, so it's not useful. So, as the example shows below, I need some text saying 'Action' to appear in a tooltip when you hover over the 'Action' element that contains 'should'. Same will be applied when you hover over the text 'approximate number of' contained in the 'Quantifier' element - the word 'Quantifier' should be displayed. Hope this makes sense.
<body>
One string that <Action>should</Action> work is
<Quantifier>approximate number of</Quantifier> other things.
<script>
$(document).ready(function(){
$("Action").hover(function(){
});
$("Quantifier").hover(function(){
});
});
</script>
<body>
So far non-conclusive, as I can only change CSS values and not tooltip text.
You can try updating the title property on those elements. One thing to note is that HTML tags will appear in lowercase when compiled.
$(document).ready(function() {
var style = document.createElement('style');
style.type = 'text/css';
$('head')[0].appendChild(style);
style.innerHTML =
`action, quantifier {
position: relative;
display: inline-block;
margin-top: 20px;
}
action[title]:hover:after, quantifier[title]:hover:after {
content: attr(title);
position: absolute;
top: -100%;
left: 0;
}
action[title]:hover:after {
color: red;
border: solid 1px black;
}
quantifier[title]:hover:after {
color: blue;
border: solid 1px black;
}`;
$('action')[0].title = 'Action';
$('quantifier')[0].title = 'Quantifier';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
One string that <Action>should</Action> work is
<Quantifier>approximate number of</Quantifier> other things.
</body>
add a tooltip for an tag with JS/jQuery without change the html structure. You can modify the css based on requirement.
jQuery(function($){
//If you are able to add class then use $('.add_tooltip').hover
// use $('Quantifier, Action').hover
$('Quantifier, Action').hover(
function () {
//let text = $(this).html(); //this is for html content of hover element
let text = $(this).prop("tagName");
//Add the tag name of hover element to tooltip div
$(this).append('<div class = "tooltip">'+text+'</div>');
//display the tooltip with animation.
$(this).find('.tooltip').hide().fadeIn('slow');
},
//On hover out remove the tooltip.
function () {
$(this).find('.tooltip').remove();
}
);
});
Quantifier, Action{
cursor: pointer;
position:relative;
}
.tooltip{
display: inherit;
background: black;
margin: auto;
padding: 10px;
position: absolute;
z-index: 1000;
width: 200px;
height: 40px;
color: #fff;
top: 18px;
left:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
One string that <Action>should</Action> work is
<Quantifier>approximate number of</Quantifier> other things.

PrismJS no line breaks

Not sure if anyone has come across this. I'm using PrismJS syntax highlighter to highlight code. Application is written in Reactjs and what I'm trying to do is inside a WYSIWYG editor I'm wrapping user selected text with pre + code when user wants to insert code block. PrismJS seems to tokenize elements correctly as you would expect:
But as you can probably see from the image above, everything is put into a single line. Rather then nice code block:
I'm not sure what's wrong, using css from prismjs site:
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
#media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #dd4a68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
Here is outputted html:
EDIT:
If adding word-wrap: pre-wrap this is the outcome:
I had a similar issue when initializing the element manually. I stumbled upon this discussion, which had a fix that worked for me: https://github.com/PrismJS/prism/issues/1764
HTML - Load script with flag data-manual:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/prism.min.js" data-manual></script>
JS - Add the following hook:
Prism.hooks.add("before-highlight", function (env) {
env.code = env.element.innerText;
});
Prism.highlightElement(code);
Working example:
https://codepen.io/Ukmasmu/pen/xxZLwxG?editors=1010
Try to update the CSS file with:
white-space: pre-wrap
https://github.com/PrismJS/prism/issues/1237
In case this is helpful for anyone else, I have a textarea that updates a code block as you type, and this worked for me:
<textarea onkeyup="this.onchange();" onchange="document.getElementById('query-highlighted').textContent = this.value; Prism.highlightAll();"></textarea>
<pre><code class="language-sql" id="query-highlighted"></code></pre>
Namely, I used .textContent = instead of .innerText = (the latter didn't preserve the line breaks as expected).
I was aided by Sever van Snugg's answer and the issue he linked.
1. Activate normalize whitespace plugin
I suggest you activate normalize whitespace plugin and set the break-lines property instead of manipulating prism.css file to using white-space: pre-wrap like this:
Prism.plugins.NormalizeWhitespace.setDefaults({
'remove-trailing': true,
'remove-indent': true,
'left-trim': true,
'right-trim': true,
'break-lines': 60, //max number of characters in each line before break
});
I'm using the above approach in my blog, and it works like a charm. You can adjust the break-lines value according to your preferences of course.
2. Insert a line break tag <br> to break a line at will
Now that you set the break-line property after a certain maximum number of characters, you probably want to break some lines at will for cleaner code. To do so you need to insert a <br> tag where you want to have a break line.
NOTE: if you're using an html parser to parse dynamic content with prism
If you're using a parser to parse you dynamically generated html code as a string (from a database for example) and prims is not parsing your <br> tags you'll have to use before-sanity-check prism hook like this:
Prism.hooks.add('before-sanity-check', function (env) {
env.element.innerHTML = env.element.innerHTML.replace(/<br>/g, '\n');
env.code = env.element.textContent;
});
before highlighting, what the above code does is replacing <br> tags with \n since prism can't parse <br> as a line break.
Similar to the answer by Sever van Snugg, I use the following solution where the forEach loop highlights all the code nodes according to the style rules of the Prism CSS stylesheet used (because I have several code tags on a single page). I locate these scripts in the bottom of my HTML body:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/prism.min.js" data-manual></script>
<script>
Prism.hooks.add("before-highlight", function (env) {
env.code = env.element.innerText;
});
code = document.getElementsByTagName('code');
Array.from(code).forEach(el => { Prism.highlightElement(el) });
</script>
I tried to mixed Markdown and Prismjs the trick is to replace '\n' with '\r\n' to keep breaklines.
from bs4 import BeautifulSoup
...
code_tag = soup.new_tag('code class="lang-%s"' % lang)
code_tag.string = code.string.replace('\n','\r\n')
code.replaceWith(code_tag)

Simple Add class with Javascript

I've this code :
jQuery(document).ready(function($) {
document.getElementById('HAVEATESTHERE').className = "newClass";
}
I want to add a class to #HAVEATESTHERE in javascript, it does not work
Am I missing something ?
You can use classList.add method:
document.getElementById('HAVEATESTHERE').classList.add('first','second', ... );
Also, please make sure you add your class after DOM is rendered.
Take into account, that element.className = 'someClass' will override existing classes with someClass.
elementid is your element`s id and yourclass is that what class do you want add this element.
jQuery(document).ready(function($) {
$('#elementid').addclass('yourClass');
}
Code is fine, see this demo
Ensure that it is either
Added in the window.onload section
window.onload = function(){
document.getElementById('HAVEATESTHERE').className = "class1";
};
if there are already some classes for this element (as suggested by your updated OP), then use classlist to add a new class to that list
document.getElementById('HAVEATESTHERE').classList.add("class1");
- Or the script section is added at the end of body after all the markup is already loaded.
make sure you don't have duplicate IDs for divs. Check this:
function myFunction() {
document.getElementById("myDIV").className = "myclass";
}
.myclass {
width: 200px;
height: 100px;
background-color: blue;
text-align: center;
color: white;
margin-bottom: 10px;
}
<!DOCTYPE html>
<html>
<head>
<style>
.mystyle {
width: 300px;
height: 100px;
background-color: coral;
text-align: center;
font-size: 25px;
color: white;
margin-bottom: 10px;
}
</style>
</head>
<body>
<p>Click the button to add a class for div.</p>
<div id="myDIV">
Sample div
</div>
<button onclick="myFunction()">Add Class</button>
</body>
</html>
Basically you are trying to mix JavaScript inside jQuery function. Please take care of that. And if you are only using jquery then please use your code
As in this formate
$(document).ready(function(){
$('#HAVEATESTHERE').addclass('newClass');
}
use addclass() function to add class to your div.
with simple js please try to use anonymous function like this
(function(){
var d = document.getElementById("HAVEATESTHERE");
d.className = " newClass";
})();

jQuery 'on' click not checking for updated selector?

I'm creating a simple button (sort of) for a user to iterate through a number of selections when clicking "up" or "down".
I'm using jQuery to check after each click that there are more things up (or down) and updating the classes / styles / selections accordingly. However if I change the class of the element that is triggering the "on" function, it is still triggering (on click) even though all the classes specified in the selector are not there (in the DOM) any more.
In this simplified example if you click the "i.up.enabled" element then it's class switches ".up.disabled" and the visible field changes. Fine so far. However, if you click it again then it updates again, which it shouldn't(?) as the selector used to call the 'on' function is "i.up.enabled" and not "i.up.disabled". It's reasonably simple to work round this but I wondered why this is?
Does "on" read from the source rather than the DOM & is there a more accepted way doing this?
HTML
<div class="wrapper">
<div data-state="1">Number 1</div>
<div data-state="0">Number 2</div>
<i class="up enabled">up</i>
</div>
CSS
i {
cursor: pointer;
}
div[data-state="0"] {
display: none;
padding: 0 2rem;
border: 1px solid gray;
}
div[data-state="1"] {
padding: 0 2rem;
border: 1px solid gray;
}
.wrapper > * {
display: inline-block;
font-size: 90%;
}
i.disabled {
color: gray;
cursor: default;
}
i.enabled {
color: blue;
cursor: pointer;
}
JavaScript / jQuery
$('.wrapper i.enabled.up').on('click', function(){
var $current = $(this).siblings('div[data-state="1"]');
var $next = $(this).siblings('div[data-state="0"]');
$current.attr('data-state', 0)
$(this).addClass('disabled').removeClass('enabled');
$next.attr('data-state', 1);
});
And the fiddle is here
N.B. I appreciate that .data() is better for manipulating data-* elements, but due to restrictions I have to use attr("data-*", [value])
Currently what you are using is called a "direct" binding which will only attach to element that exist on the page at the time your code makes the event binding call.
Its does't matter even if selector is modified, Event will still be attached with these elements when using "direct" binding.
You need to use Event Delegation using .on() delegated-events approach, when generating elements dynamically or manipulation selector (like removing and adding classes).
General Syntax
$(staticParentElement).on('event','selector',callback_function)
Example
$('.wrapper').on('click', 'i.enabled.up', function(){
});
DEMO
You can remove the event inside the on function using $(this).off("click");:
$('.wrapper i.enabled.up').on('click', function(e) {
var $current = $(this).siblings('div[data-state="1"]');
var $next = $(this).siblings('div[data-state="0"]');
$current.attr('data-state', 0)
$(this).addClass('disabled').removeClass('enabled');
$next.attr('data-state', 1);
$(this).off("click");
});
i {
cursor: pointer;
}
div[data-state="0"] {
display: none;
padding: 0 2rem;
border: 1px solid gray;
}
div[data-state="1"] {
padding: 0 2rem;
border: 1px solid gray;
}
.wrapper > * {
display: inline-block;
font-size: 90%;
}
i.disabled {
color: gray;
cursor: default;
}
i.enabled {
color: blue;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div data-state="1">Number 1</div>
<div data-state="0">Number 2</div>
<i class="up enabled">up</i>
</div>

Capitalizing the first letter of a label element

I am getting some external html page where all the data is coming in lowercase. with css, i tried to capitalize the first intial of the complete label tag but i am unable to do it, it makes complete uppercase like this:
.fontmodal {
text-transform:capitalize !important;
}
but that did not worked...
<table><fieldset><div><label>DATA</label></div></fieldset></table> - This is the current Structure
Now i am trying to same in jquery, i am not sure what and how to proceed.
Here is my code what i am trying:
$('#Container2').find("table>label").css(textTransform,'capitalize');
See below:
label {
text-transform: lowercase;
}
div::first-letter {
text-transform: uppercase;
}
<table>
<fieldset>
<div>
<label>DATA</label>
</div>
</fieldset>
</table>
If you can't change the HTML and need to apply the capital letter on the first letter, you need to change the default display property of the <label> tag :
:first-letter :
has only an effect on elements with a display value of block,
inline-block, table-cell, list-item or table-caption. In all other
cases, ::first-letter has no effect. (source MDN)
label {
display: inline-block;
text-transform: lowercase;
}
label::first-letter {
text-transform: capitalize;
}
<table>
<fieldset>
<div>
<label>DATA</label>
</div>
</fieldset>
</table>
You simplify it and do something like below.
$(document ).ready(function() {
$("label").addClass("capitalizer"); // Adjust specificity as needed
});
.capitalizer {
font-weight: bold;
font-size: 72px;
display: inline-block;
color: red;
}
.capitalizer::first-letter {
text-transform: capitalize;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<label>data</label>
</div>
Note: I prefer .addClass because .CSS adds inline css to your HTML and that's not advisable.
You can achieve this using the CSSS selector :first-letter.
The subtly I have found is that it doesn't appear to be supported on the <label/> tag (didn't work in my demo code, anyhow)
But we can get round that:
label {
text-transform: lowercase;
}
div:first-child:first-letter {
text-transform: uppercase;
color: red;
}
DEMO: http://jsfiddle.net/30trmm3w/1
I don't get what's wrong a simple CSS rule should do the trick :
#Container2 label {
text-transform: capitalize;
}

Categories