Including style tag in javascript - javascript

I want to include style tag in the javascript. ie., I am printing notices and the number of notices change dynamically. I receive the notices in a JSON object and hence require styles to be applied to each notice separately.
For now I just want the border around each notice or text
function retrive()
{
/*var css = ' { border :2px dashed; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css'; Not working*/
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append(
'<br><br>Currently There are no Notices to be displayed'
);
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append(
'<br><br><strong><center>'+ myObj[i].title+'</center></strong><br>'+myObj[i].introtext
);
}
}
}
I am printing the notices in the else block using for loop by finding the object length and appending it to the heading. This is where I want to print border to be printed around each block
<div>
<ul id="heading" style = "font-size : 16px;">
</ul>
</div>
If I use style here, border is appears to whole block or a single border to all notices.
<div>
<ul id="heading" style = "font-size : 16px; border : 2px dashed">
</ul>
</div>
,which is obvious.
Thanks.

I believe that you could handle this entirely with CSS and applicable classes. If you need to make changes based on the number of items, you could define classes for the different sets of count values that would result in the same CSS settings and simply apply that class to the header. Based on what you have in your code, that doesn't look to be the case and the example below should approximate what you're trying to achieve.
Note: I'm assuming that you're using a standard CSS reset to remove list styles. If not, then I suggest that you should.
<style>
#title p {
padding-top: 1em;
}
#heading {
font-size: 16px;
}
#heading li {
border: 2px dashed;
}
#heading li span.item_title {
font-weight: bold;
display: block;
text-align: center;
}
#heading li span.item_text {
display: block;
}
</style>
function retrive()
{
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append('<p>Currently There are no Notices to be displayed</p>' );
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append('<li><span class="item_title">'+ myObj[i].title+'</span><span class="item_text"'+myObj[i].introtext+ "</span></li>" );
}
}
}

If you use CSS classes you will be able to change the design more easily later, by modifying the CSS, rather than the JavaScript and HTML.
<style>
.heading
{ font-size : 16px; border : 2px dashed; }
</style>
<div>
<ul id="heading" class="heading">
...
</ul>
</div>
You can put the HTML in your JavaScript as you already have it, and use as many classes as you need.
In addition, try to avoid using <strong> and <br> and use CSS to control the layout.

You can apply a css style to each notice inside of #heading.
Something like this should work fine (place this in your css file or inside of a style tag) :
#heading strong {
border: 2px dashed;
}
I would recommend surrounding each notice in a span and append this to your #heading inside of an li and then applying this style:
#heading li {
list-style:none;
margin: 0 auto;
text-align: center;
}
#heading li span {
border: 2px dashed;
font-weight: bold;
}
you html would look something like this:
<ul id='heading'>
<!-- your newly inserted notice -->
<li><span>text</span></li>
</ul>
This will remove the need for the center and br tags.

Related

How to restrict the div with a css badge when the content overflows

I am having a scenario where the selected items are overflowing the div.
But I have managed to wrap it by css properties.
Now I am planning to put a css badge if the content width is crossing the parent div to transform from image 1 to image 2:
.
<div class="list-view">
<div class="item-box">
<h4>select Cities</h4>
<ul>
<li *ngFor="let item of cityList" (click)="selectedCity(item)">{{item}}</li>
</ul>
</div>
</div>
I have a sample code from this link https://stackblitz.com/edit/angular-uatw5p.
I tried to achieve this but couldn't find a way. Can anyone let me know how to achieve this??
Slice the list of array for the number of items you want to display. I used three items to display. And minus three from the total length of array. Use the CSS to format it the way you want.
<div class="container-fluid">
Cities
<a *ngFor="let item of selectedItems.slice(0, 3)" href="javascript:void(0)">{{item}}</a>
<div *ngIf="selectedItems.length > 3">+{{selectedItems.length - 3}}</div>
<button (click)="selectedItems=[]">Reset</button>
</div>
The above will give you the following result:
Edit:
Use the following with the CSS provided in the another answer:
<a href="javascript:void(0)" class="selection">
<p>Cities {{selectedItems.length? ' : ' + selectedItems.slice(0, 3): '' }}</p>
<span *ngIf="selectedItems.length > 3">+{{selectedItems.length - 3}}</span>
</a>
It is the problem with text "Chennai,Mumbai,Pune,Bangalore" without spaces. If there is space, there would be on overflow of tex outside div
If you still require badge based on the text overflow, you need to add or remove css class based on parentDiv.offsetWidth and textDiv.offsetWidth. Css will dictate to show or hide the badge including ellipsis of text.
Try the following html for the anchor tag, manipulate the content by checking array length:
Cities {{selectedItems.length? (selectedItems.length < 3 ? ' : ' + selectedItems : ' : ' + selectedItems.slice(0,3) + '+' + (selectedItems.length-3) ): '' }}
Output
I would use a combination of overflow, overflow-wrap and white-space to make the text break correctly.
Then I would use a pseudo element to render the item count after the container.
By putting it absolute, we can align ther element relative to the container, no matter how many extra nodes we add to the container.
Since we use a pseudo-element, we can easily use the content css rule to bind the data-items attribute of the HTML container as the content of our little counter.
The big advantage is that by positioning the counter absolutely, we can keep using relative units to position everything else and we can put the counter anywhere we want, including putting overflow back on hidden and have the counter overlap the border.
const cities = [
"amsterdam",
"belize",
"calcutta",
"dortmund",
"egmond aan zee",
"frankfurt",
"gotenburg"
];
const render_list = list => content => {
const items = content.map( text => `<li>${ text }</li>` ).join( '' );
list.innerHTML = items;
return list;
};
const add_city = list => event => {
const item = event.target;
if ( event.target.nodeName === 'LI' ) {
list.appendChild( item.cloneNode(true));
list.setAttribute( 'data-items', list.childElementCount );
}
};
const options = document.querySelector( '#options' );
const selections = document.querySelector( '#selections' );
options.addEventListener( 'click', add_city( selections ));
render_list( options )( cities );
#selections {
background-color: steelblue;
border: 1px solid grey;
list-style: none;
margin: 4px;
max-width: 50%;
min-height: 1.1em;
overflow-wrap: break-word;
position: relative;
width: 50%;
}
#selections:after {
background-color: white;
border: 1px solid grey;
content: '+' attr(data-items);
position: absolute;
left: 100%;
top: -1px;
}
#selections > li {
display: inline;
margin-left: 2px;
}
#options {
border: 1px solid grey;
margin-top: 20px;
}
<ul data-items="0" id="selections"></ul>
<ul id="options"></ul>
I would ellipsis the text to always allow space for the badge:
p {
display:block;
text-overflow: ellipsis; /* will make [...] at the end of only ONE LINE!*/
-webkit-line-clamp: 2; // experimental only! would allow ellipsis on 2nd line
width: 370px; /* change to your preferences */
white-space: nowrap; /* paragraph to one line */
overflow:hidden; /* older browsers */
}
If it helps, one simple css fix as overflow-wrap: break-word; by using word-break property
a{
text-decoration: none;
color: black;
background: skyblue;
display: block;
width: 20em;
margin: 20px auto;
padding: 1.2em;
font-size: 18px;
max-width: 16em;
overflow-wrap: break-word;
}

vaadin-combo-box / vaadin-combo-box-overlay change background color / Polymer API

I'm trying to override the background color present in vaadin-combo-box-overlay element.
Here is the css that I want to override, more specifically the background property, source taken from (https://github.com/vaadin/vaadin-combo-box/blob/master/vaadin-combo-box-overlay.html)
:host {
position: absolute;
#apply(--shadow-elevation-2dp);
background: #fff;
border-radius: 0 0 2px 2px;
top: 0;
left: 0;
.......
}
So I've tried something like:
:root ::content vaadin-combo-box-overlay.vaadin-combo-box-overlay {
background: red !important;
background-color: red !important;
}
Also I've tried with :host but I guess it should be used :root because I use this dropdown in a dialog, and the overlay component doesn't seem to be a child of the dialog. I've tried different combinatons as the one mentioned above without any success.
Also I'm wondering why the background is not parameterized as the text color is:
#selector .item {
cursor: pointer;
padding: 13px 16px;
color: var(--primary-text-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Specifying a different value for --primary-text-color I'm able to change the text color..
Thanks.
you can do it with javascript like that.
ready: function() {
var domElem=Polymer.dom(this).node.$.YOUR-VAADIN-ELEMENT-ID.$.overlay.style.backgroundColor="red";
}
OR
ready: function() {
var css = '#selector .item { background-color:red; }';
var style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
Polymer.dom(this).node.$.tourSelector.$.overlay.$.selector.appendChild(style);
}
Would like to have a working CSS selector, but i cant set breakpoints in CSS to find out the right selectors!
You should use dom-module for styling vaading parts see example below:
<dom-module id="combo-box-overlay-styles" theme-for="vaadin-combo-box-overlay">
<template>
<style>
[part~="content"] {
background-color: red;
}
</style>
</template>
</dom-module>
Read more here https://github.com/vaadin/vaadin-themable-mixin/wiki
Thanks Patrick !!
I wasn't thinking about to do try it this way.
Here's what I did, a hacky solution though.
ready : function(){
var combo = this.$$('#comboid');
combo.addEventListener('vaadin-dropdown-opened'', function() {
var overlay = Polymer.dom(this.root).querySelector('#overlay');
overlay.style.backgroundColor = primaryBackground;
});
},
I only have access to the overlay when the combo is expanded, so in the value change listener the combo would be expanded.

Dynamically add !important to all CSS properties

How can I dynamically add !important for all CSS properties?
For example in my <head></head> section I have:
<style>
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.main-container {
border: 3px solid yellow;
padding: 10px 5px;
margin: 3px;
}
</style>
I need:
<style>
.text-center {
text-align: center !important;
}
.text-left {
text-align: left !important;
}
.main-container {
border: 3px solid yellow !important;
padding: 10px 5px !important;
margin: 3px !important;
}
</style>
I tried to use Window.getComputedStyle(), but I must provide to this method the element for which I want to get the computed style. In my case I can't provide these elements.
I was having an issue with printing (with css styling) in Chrome and Firefox..
even adding -webkit-print-color-adjust: exact!important; didnt work in my case
until i figured out that the style need to have !important attribute. When working with WYSWYG Editor, this could be a problem for printing. So I need to add !important to every css style attribute found in every element.
Here's how I solved it using jQuery
//add !important rule to every style found in each element
//so the browser print render the color/style also
var el = $('.content *');
if (el.length) {
el.each(function(item) {
var _this = $(this);
var attr = _this.attr('style');
var style = '';
if (typeof attr !== typeof undefined && attr !== false) {
if (attr.split(';').length) {
attr.split(';').forEach(function(item) {
if (item.trim() != '') {
style += item.trim() + '!important;-webkit-print-color-adjust: exact!important;';
}
});
_this.attr('style', style);
}
}
});
}
Here's the result in Printing Preview before and After adding the Code Hack
I run into this problem with pandas DataFrame Styler. It generated a <style> tag element with all the styling info. But the styling is overridden by linked css files.
So my solution is to replace all ; with !important; using JavaScript
CSS:
<style type="text/css" >
#T_195822c0_1b0f_11e9_93d2_42010a8a0003row10_col4 {
background-color: yellow;
} #T_195822c0_1b0f_11e9_93d2_42010a8a0003row73_col5 {
background-color: yellow;
} #T_195822c0_1b0f_11e9_93d2_42010a8a0003row100_col2 {
background-color: yellow;
}</style>
Javascript:
var st = document.getElementsByTagName("STYLE")[0];
st.innerHTML = st.innerHTML.replace(/yellow;/g,'yellow !important;')
You can adapt replace rules to your need.

css hover event not working after using javascript?

Here is the code in which i am having the problem-
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p {
font-family: Tahoma;
line-height: 170%;
color: #000;
font-size: 15px;
padding: 5px 0px 5px 0px;
text-align: center;
}
#col1 {
//some propeties
}
#col1:hover ~ p {
color: #f00;
}
#col2 {
//some propeties
}
#col2:hover ~ p {
color: #ff0;
}
</style>
</head>
<body>
<div id="col1"><span>Hover to view and click to select this color.</span></div>
<div id="col2"><span>Hover to view and click to select this color.</span></div>
<p>This is some text.</p>
<script type="text/javascript">
var pElements = document.getElementsByTagName("p");
$('#col1').click(function(){
for(var i = 0; i < pElements.length; i++) {
pElements[i].style.color = "#f00";
}
});
$('#col2').click(function(){
for(var i = 0; i < pElements.length; i++) {
pElements[i].style.color = "#ff0";
}
});
</script>
</body>
</html>
What i actually want is that when i hover a color div, the color of text in p tag changes for only that time when the color div is hovered. When the color div is clicked the color of text should change permanently.
The problem with is that once i click on 1 of the color divs to finalize it for p tag, and then after that the other color is hovered the color change doesnt take place. The color permanently changes on click as it should happen.
When you set the p elements style with pElements[i].style.color = "#f00"; you are setting a more specific style then the one applied by your hover. In CSS, the most specific style get's applied to the element. The CSS hover class you've got defined will never be applied because it is not specific enough to overwrite the inline styles applied by your javascript code.
You could modify your CSS hover class to use the !important tag, this should allow you to apply the hover style even though it is not as specific as the inline style.
#col2:hover ~ p {
color: #ff0 !important;
}
If its not a problem using JQuery, I think is what you want: Live Example
HTML code snippet
<div id="col1"><span>Hover to view and click to select this color.</span></div>
<div id="col2"><span>Hover to view and click to select this color.</span></div>
<p>This is some text.</p>
CSS code snippet
p {
font-family: Tahoma;
line-height: 170%;
color: #000;
font-size: 15px;
padding: 5px 0px 5px 0px;
text-align: center;
}
#col1 {
//some propeties
}
#col1:hover ~ p {
color: #f00 !important;
}
#col2 {
//some propeties
}
#col2:hover ~ p {
color: #ff0 !important;
}​
JS code snippet
$("#col1").click(function () {
$("p").css("color","#f00");
});
$("#col2").click(function () {
$("p").css("color","#ff0");
});
Hope it helps!

Is there a way to reference an existing CSS style from another CSS style using CSS or javascript?

If I have a style defined
.style1
{
width: 140px;
}
can I reference it from a second style?
.style2
{
ref: .style1;
}
Or is there a way via javascript/jQuery?
--- Edit
To clarify the problem, I am trying to apply whatever style is defined for a #x and #c to .x and .c without altering the CSS as the CSS is going to have updates that are out of my control.
I used width but really the style would be something more complex with font, border and other style elements being specified.
Specifying multiple class names does work when the style is being applied to a class so I'll mark existing responses as answers, but I need to take the style being applied to an id and also apply it to a class style ... if that makes any sense.
There's no way to do it with CSS -- it's an oft-requested feature, but not included in the spec yet. You also can't do it directly with JS, but there's sort of a hacky workaround:
$('.style2').addClass ('style1');
you can achieve the same functionality by allowing elements to inherit multiple styles. ex.
<p class="style1 style2">stuff</p>
and then your css would include, for example:
.style1 {width:140px;}
.style2 {height:140px;}
edit: actually robert's answer might better approximate the method you are trying to achieve
.style1, .style2 {width: 140px;}
.style2 {height: 140px;}
<p class="style2">i will have both width and height applied</p>
One way to use the same code for multiple blocks is the following:
.style1, .style2 { width: 140px; }
Another way is use pre -processing tool, like less and sass. Then after you compile the less/sass file, it will result as normal css.
Here is the documentation of less and sass.
// example of LESS
#header {
h1 {
font-size: 26px;
font-weight: bold;
}
p { font-size: 12px;
a { text-decoration: none;
&:hover { border-width: 1px }
}
}
}
/* Compiled CSS */
#header h1 {
font-size: 26px;
font-weight: bold;
}
#header p {
font-size: 12px;
}
#header p a {
text-decoration: none;
}
#header p a:hover {
border-width: 1px;
}
Some options:
Generate your CSS dynamically, either on the fly or as you're authoring your style sheets (I use a Visual Studio macros to implement constants for fonts, numbers, and colors - and to calculate light/dark tints of colors). This topic has been much discussed elsewhere on this site.
If you have a number of styles that are 140px wide and you want to have the flexibility of changing that dimension for all of those styles, you could do this:
div.FixedWidth {width:140px;}
div.Style1 {whatever}
div.Style2 {whatever}
and
<div class="Style1 FixedWidth">...</div>
<div class="Style2 FixedWidth">...</div>
Are you talking about getting all of the computed styles set on a particular Element and applying those to a second Element?
If that's the case, I think you're going to need to iterate through one Element's computed styles using and then apply those to your other Elements' cssText properties to set them as inline styles.
Something like:
el = document.getElementById('someId');
var cStyle = '';
for(var i in el.style){
if(el.style[i].length > 0){ cStyle += i + ':' + el.style[i] + ';';
}
$('.someClass').each(function(){ this.style.cssText = cStyle; });
If you know that you'll only be dealing with a finite set of CSS properties, you could simplify the above as:
el = $('#someId');
var styleProps = {'border-top':true,'width':true,'height':true};
var cStyle = '';
for(var i in styleProps){
cStyle += styleProps[i] + ':' + el.style(styleProps[i]) + ';';
}
$('.someClass').each(function(){ this.style.cssText = cStyle; });
I'll caveat the above code with the fact that I'm not sure whether or not the IEs will return a CSSStyleDeclaration Object for an HTMLElement's style property like Mozilla will (the first example). I also haven't given the above a test, so rely on it as pseudo-code only.
I was trying this same thing and found this webpage (as well as some others). There isn't a DIRECT way to do this. IE:
<html><head><title>Test</title><style>
.a { font-size: 12pt; }
.b { font-size: 24pt; }
.c { b }
</style></head><body>
<span class='c'>This is a test</span></body></html>
Does NOT work. The problem here is you (like me) are trying to do things in a logical fashion. (ie: A-then-B-then-C)
As others have pointed out - this just does not work. Although it SHOULD work and CSS SHOULD have a lot of other features too. It doesn't so you have to do a work around. Some have already posted the jQuery way to get around this but what you want CAN be achieved with a slight modification.
<html><head><title>Test</title><style>
.a { font-size: 12pt; }
.b,.c { font-size: 24pt; }
</style></head><body>
<span class='c'>This is a test</span></body></html>
This achieves the same effect - just in a different way. Instead of trying to assign "a" or "b" to "c" - just assign "c" to "a" or "b". You get the same effect without it affecting the rest of your code.
The next question that should pop into your mind is "Can I do this for multiple CSS items. (Like font-size, font-weight, font-family?) The answer is YES. Just add the ",.c" part onto each of the things you want it to be a part of and all of those "parts" will become a part of ".c".
<html>
<head>
<title>Test</title>
<style>
.a { font-size: 12pt; }
.b,.c { font-size: 24pt; }
.d { font-weight: normal; }
.e,.c { font-weight: bold; }
.f { font-family: times; }
.g,.c { font-family: Arial; }
</style>
</head>
<body>
<span class='c'>This is a test</span>
</body>
</html>

Categories

Resources