Why class returned in eventClassNames of V5 is not applied? - html

With fullcalendar v5.7.2 in Alpinejs 2 app I want to set different color for cells depending
on some property and reading here https://fullcalendar.io/docs/classname-input
I catch event :
dayMaxEvents: true,
views: {
dayGridMonth: {
editable: false
}
},
events: function (info, successCallback, failureCallback) { //get data from db for selected dates
self.select_year = parseInt(moment(info.start).format('YYYY'))
self.select_month = parseInt(moment(info.start).format('MM'))
var dataArray = {
'_token': '{{ $csrf_token }}',
'start': moment(info.start).format('YYYY-MM-DD'),
'end': moment(info.end).format('YYYY-MM-DD'),
'ad_categories': self.searchSelectedCategoryIds,
'users': self.searchSelectedUserIds,
'status': self.searchStatus,
'text': self.searchText
}
window.axios.post('/admin/get_ad_events', dataArray).then((response) => {
successCallback(response.data.events);
}).catch((error) => {
console.error(error)
failureCallback(error)
popupAlert('Calendar', 'Run time error : ' + getErrorMessage(error), 'error')
});
}, // events: function(info, successCallback, failureCallback) { //get data from db for selected dates
eventClassNames: function(arg) {
// return 'fullcalendar_nearest_days'; // if to uncomment this line it does not work anyway
if (arg.event.extendedProps.is_past) {
return [ 'fullcalendar_nearest_days' ]
} else {
return [ 'normal' ]
}
I check and see that fullcalendar_nearest_days is returned, but it is's properties are not applied
and checking events code I do not see “fullcalendar_nearest_days” in events styling...
Which way is correct ?
MODIFIED:
fullcalendar_nearest_days is defined as :
.fullcalendar_nearest_days {
background-color: red !important;
color: yellow !important;
font-weight: bold;
}
and looking at generated code I found that fullcalendar_nearest_days is the latest class in "a" tag class definition:
<div class="fc-daygrid-event-harness fc-daygrid-event-harness-abs"
style="visibility: hidden; top: 0px; left: 0px; right: 0px;"><a
class="fc-daygrid-event fc-daygrid-dot-event fc-event fc-event-draggable fc-event-resizable fc-event-start fc-event-end fc-event-past fullcalendar_nearest_days"
data-id="undefined"><span class="flex flex-nowrap"><
Can it be that properties of fullcalendar_nearest_days are not applied as they are overwritten by fc-daygrid-event fc-daygrid-dot-event fc-event fc-event-draggable fc-event-resizable fc-event-start fc-event-end fc-event-past ?
Can I remove all/part of these classes in "a" tag class definition for some dates?
Thanks!

I made a demo using your CSS - https://codepen.io/ADyson82/pen/zYwYxRp . There doesn't seem to be a problem for timed events, the class is applied to the correct events and the colours change as you'd expect.
However on all-day events the yellow colour is not applied. If you use the element inspector in your browser you can see what CSS rules are applied to each element and what is overriding them. You can see that the title is inside another div within the main element, which has fc-event-main class on it, and that class has a rule which overrides the color property again.
Fortunately we can solve this easily by adjusting the CSS rule to deal with that situation specifically:
.fullcalendar_nearest_days, .fullcalendar_nearest_days .fc-event-main {
background-color: red !important;
color: yellow !important;
font-weight: bold;
}
Working demo: https://codepen.io/ADyson82/pen/OJmJPEP

Related

Angular: Changing font-size using css variables is applying but not reflecting in browser for certain fields

I am using CSS variables for a feature where the user has an option to change the font-size to small, medium or large. So for most of the fields, it's working as expected. But for certain fields, the value is applied but not reflected
:host-context(.mediumFont) {
--fontSize: 11px;
}
:host-context(.largeFont) {
--fontSize: 12px;
}
:host-context(.smallFont) {
--fontSize: 10px;
}
refClassArray: RefClassInterface[] = [
{ class: 'font-small', refClass: 'smallFont' },
{ class: 'font-medium', refClass: 'mediumFont' },
{ class: 'font-large', refClass: 'largeFont' },
];
defaultFontSize = 'mediumFont';
changeFontSize(selector: string) {
this.defaultFontSize = selector;
let docBody = document.body;
console.log(document.getElementById(selector));
docBody.classList.add(selector);
this.refClassArray.forEach((refClass: RefClassInterface) => {
if (selector !== refClass.refClass) {
docBody.classList.remove(refClass.refClass);
document.querySelector('#' + refClass.refClass).setAttribute('style', 'font-weight: normal;' + 'pointer-events: auto;');
} else {
document.querySelector('#' + refClass.refClass).setAttribute('style', 'font-weight:' + 'bold;' + 'pointer-events: none;');
}
});
this.ieStyles.iEfont(selector);
}
Above is the logic I am using.
The first pic is from the element which is working fine. When I hover over the --font-size, 11px is reflected. The second one is the one where it's not working as expected and when I hover over the --font-size nothing is appearing. And both these elements are inside <body>
You should not be modifying your html code via direct access. This can open leave your application vulnerable to XSS Attacks for instance.
Instead, the Angular Team recomends the use of the Renderer2.
Taking your code and modifying it to use it, would lead to the following:
refClassArray: RefClassInterface[] = [
{ class: 'font-small', refClass: 'smallFont' },
{ class: 'font-medium', refClass: 'mediumFont' },
{ class: 'font-large', refClass: 'largeFont' },
];
defaultFontSize = 'mediumFont';
changeFontSize(selector: string, indexOfClassToAdd: number) {
this.defaultFontSize = selector;
const el: Element = document.getElementById(selector));
// Iterate each class in the list to remove it.
this.refClassArray.forEach((refClass: RefClassInterface) => {
// Remove the class from the specific element only if its present.
if (el.classList.contains(refClass.refClass) {
this.renderer2.removeClass(el, refClass.refClass);
};
});
this.renderer2.addClass(el, refClassArray[indexOfClassToAdd].refClass);
};
This would imply that you are aware of what is the class to be applied (and it being present in the style.scss or and the appropriate scss file).
Kind regards.
Out of curiosity, why are you doing it this way rather than simply using a class with the desired text size?
Either way, it looks like your value is not being applied because your selector is not specific enough.
To correct for this, you could make an artificially specific selector with something like this:
html > body * { // rules }
Why not use ngClass?
Define three classes
.font-small{
fontSize: 10px
}
.font-medium{
fontSize: 11px
}
.font-large{
fontSize: 12px
}
Bind something to the user select, like userChoice: SizeEnum or something
Then, on your data element, use ngClass to bind
ngClass = "{
'font-small': userChoice === sizeEnum.small,
'font-medium': userChoice === sizeEnum.medium,
'font-large': userChoice === sizeEnum.large
}"
The issue was resolved by moving
:host-context(.mediumFont) {
--fontSize: 11px;
}
:host-context(.largeFont) {
--fontSize: 12px;
}
:host-context(.smallFont) {
--fontSize: 10px;
}
from app.component.scss to styles.scss. Because the pop-ups are not a part of app.compontnet.html they render outside it.

Using CSS Variables on Stripe Elements

I am using Stripe Elements for a credit card checkout. The issue is, that I am not able (or I simply don't know how) to use my own CSS variables on this Stripe Element.
I need to use CSS variables for the sake of changing colors when the user changes the theme. Here is my current implementation:
Variable definitions (I'm using SASS)
.theme1
--color-1: red
--color-2: pink
// ...
.theme2
--color-1: blue
--color-2: lilec
// ...
.theme3
--color-1: orange
--color-2: yellow
// ...
// ...
The CSS variables are defined under the scope of a class, that is put to the body depending which theme is currently selected.
HTML (I am using Angular 6)
<div #stripe></div>
Typescript
#ViewChild('stripe') el: ElementRef;
card: any;
cardHandler = this.onChange.bind(this);
async onSubmit() { /* ... */ }
setupStripe(): void {
this.card = stripeElements.create('card', {
iconStyle: 'solid',
style: {
base: {
iconColor: 'var(--some-var)',
// using css variables here does not work
// ...
},
}
});
this.card.mount(this.el.nativeElement);
this.card.addEventListener('change', this.cardHandler);
}
destroyStripe(): void {
this.card.removeEventListener('change', this.cardHandler);
this.card.destroy();
}
ngAfterViewInit() {
this.setupStripe();
}
ngOnDestroy() {
this.destroyStripe();
}
onChange({ error }) { /* ... */ }
Styles (I am using SASS)
.StripeElement
background-color: var(--dy-bg-1)
// I don't have access to font colors etc here
color: var(--dy-txt-1) !important
// !important also does not work
P.S.: It's important for me, that the variables will change at runtime (which is the reason I'm using CSS variables.
The Stripe documentation says
Elements creates UI components for you that are hosted by Stripe
i.e. their input fields are in a different document, so don't have access to your custom CSS variables.
A 'good enough' solution might be to read the CSS Custom Property values in your setupStripe method, and pass the values over as plain strings:
// Note: document.body is just an example:
const styles = getComputedStyle(document.body);
this.card = stripeElements.create("card", {
iconStyle: "solid",
style: {
base: {
iconColor: styles.getPropertyValue("--some-var")
// ...etc
}
}
});

Different cursor pointers for different html tags

I am trying to render
if(path == "not supported") {
return $('<p>',{"class" : "color-black font13_20"}).text(path);
}
else {
return $('<a>',{"class" : "wrap-text-span getWidthP color-ublue font13_20", "href": path, "target":"_blank"}).text(path);
}
This gives me the desired results where if path is not supported I get a <p> in black colour with no hyperlink while if the path does not have not supported I get a hyperlink in blue colour. But in the both the cases I get cursor of type pointer. I wanted to have default cursor when it goes in if block and pointer cursor if it goes in else.
Add the following rules to your CSS
p.color-black {
cursor: not-allowed;
}
a.color-ublue {
cursor: pointer;
}
For some reason your p tag inherits a cursor style from a parent element. so you need to set it to back to the default behaviour.
p {
cursor:auto;
}
or with a class applied in the p tag:
.reset-cursor {
cursor:auto;
}
Check this if it works for you...
if(path == "not supported") {
return $('<p>',{"class" : "color-black font13_20",/*use inline css style here for cursor -> style="cursor:auto;"*/}).text(path);
}
else {
return $('<a>',{"class" : "wrap-text-span getWidthP color-ublue font13_20", "href": path, "target":"_blank"}).text(path);
}
I dont know the coding convention of language you use .. So do it yourself... I have add where and what to add...... This may solve your problem...

CSS properties for general 'Formatters' in a Google Visualization Table

Google visualization API's include 'Formatters' which allow you to use things like colored text and arrows representing qualities of data. More information on formatters can be found here.
Now, when I edit the CSS values of the table, or use configurtion options (found here), tables that use fomatters seem to have trouble displaying certain CSS properties i.e, width of cells and text size. An example I've noticed where this is the case when the entire tables text is a smaller than default font, and a row is selected. That row which was selected will revert back to a 10pt Arial font when deselected.
Although this specific instance is annoying, I am curious about ALL formatter css properties and their class names. There is no information, to my knowledge, on the Google developer site.
These are my class names:
'headerRow': 'header-cells',
'tableRow': '.even-background all-cells',
'oddTableRow': 'odd-background all-cells',
'selectedTableRow': 'all-cells',
'hoverevenTableRow': '',
'hoveroddrTableRow': '',
'headerCell': 'header-cells white bold darkgreen-background',
'tableCell': 'all-cells'
};
These are the formatters being used.
var changecolor = new google.visualization.ColorFormat();
changecolor.addRange(null, 0, 'red', 'none');
changecolor.addRange(0.000001, null, 'green', 'none');
changecolor.format(dt, 1); // Apply formatter to second column
var parens = new google.visualization.NumberFormat({
prefix: "$",
negativeParens: true
});
parens.format(dt, 1); // Apply formatter to second column
var arrow = new google.visualization.ArrowFormat();
arrow.format(dt, 1); // Apply formatter to second column
var FormatAll = new google.visualization.NumberFormat({
prefix: "$",
pattern: '#.00##'
});
Style properties:
<style>
.all-cells {
border: 0px;
border-collapse: collapse;
font-size: 9px;
padding-right: 0;
}
.header-cells {
border: 0px;
border-collapse: collapse;
font-size: 9px;
padding-right: 0;
color: white;
font-weight: bold;
}
.darkgreen-background {
background-color: #0B3B0B;
}
.odd-background {
background-color: #E6F8E0;
}
.even-background {
background-color: #FFF5E3;
}
.bold {
font-weight: bold
}
.White {
fontcolor: white;
}
</style>
JS fiddle script in action
If you notice, when a cell is selected, the font size changes. This only happens when the google.visualization.ArrowFormat is applied.
I'd like to get rid of the boarder of the table, but that is not affected by classname or class properties (refer to the fiddle),
There is also a conflict with the parens.format and google.visualization.NumberFormat. Decimals places do not display with parentheses.
Not directly shown in code or fiddle: cell width properties become offset with cells that have formatters applied to them.
There are a couple things going on here. First, the ArrowFormat overrides all other classes placed on a cell, so those cells do not have the all-cells class. This is fine, as long as the <tr> has the all-cells class. The <tr>'s lose the all-cells class when you deselect them, because all-cells is part of both the even/odd row and selected row classes (and deselecting a row removes whatever classes you put on it.
If the reason you put all-cells as the selected row class is because you don't want the style from the default class, I suggest changing the class to something that has no styles associated with it, like this:
'selectedTableRow': 'noStyle'
Also, on a side note, you have a typo in the even row classes: there should not be a . before even-background:
'tableRow': 'even-background all-cells'
see it working here: http://jsfiddle.net/asgallant/1q8yk4f5/3/

How to disable a CSS class with javascript on window.load()

I want to disable a CSS class when the page loads. I have the class .rtsULmenuLeft:
.rtsULmenuLeft
{
list-style:none;
margin: 0;
padding: 0;
}
All instances of the style need to be disabled. How can I do this?
In ListStyle Image iam using custom image. It is displaying and again hidden at last. That is, with bullet marks it is displaying again. I need to have that custom image to be present. Thanks.
Here is a working example of what you have requested: http://jsfiddle.net/ALLew/
In the example:
all ULs are yelow
items with class rtsULmenuLeft are red
items with class rtsULmenuRight are blue
As you can see, the rtsULmenuLeft classNames are removed, and the lists are displayed yellow.
// Define a function to run on page load.
var loadCheck = function() {
// Cancel the function if the page isn't loaded...
if(document.readyState !== "complete") {
// ... but call it again in 100 milliseconds.
setTimeout(loadCheck, 100);
return;
}
// From here on, the page is loaded.
// Obtain a list of all elements with the particular class name
var elList = document.getElementsByClassName("rtsULmenuLeft");
// Loop over the elements until there are no longer any with the class.
while(elList.length > 0) {
// For each element, remove the class.
elList[0].className = elList[0].className.replace(
/\brtsULmenuLeft\b/, // RegExp of class name in word boundaries
"" // Replace with empty string - remove it.
);
}
};
loadCheck();
​
Using jquery:
$('.rtsULmenuLeft').removeClass('rtsULmenuLeft');
Add display:none
.rtsULmenuLeft
{
list-style:none;
margin: 0;
padding: 0;
display:none
}