How to set value to SCSS variables from HTML? - html

I have gone through this link and it doesn't answer my questions.
Passing values from HTML to SCSS
I am building a web application wherein an admin can go and set custom properties such as
1) changing global font size
2) changing the panel background colors
3) changing button color
4) changing button dimensions etc.
I have looked at PrimeNg designer API and I see that they have a list of about 500 variables in their scss file.
What I would like to do is create a form so that user can set the values on the UI.
Scenario 1-->
Example -->
<p-fieldset legend="Global Font Size">
<input type="text" pInputText placeholder="Enter the global font size">
</p-fieldset>
once the user enters a value here, I want the value of the following variable that's contained inside of scss file to be updated with what the user entered above.
$fontSize:14px;
Scenario 2 -->
Example -->
<p-fieldset legend="Global Font Size">
<input type="text" pInputText placeholder="Enter the global font size">
<button (onClick)="saveGlobalFontSize(fontSize)"> OK </button>
</p-fieldset>
1) How can I accept a value on the UI and update the value of scss variable as asked in scenario 1?
2) How can I accept a value on the UI, pass it to a typescript function and then update the value of scss variable as asked in scenario 2?
Here is the documentation that I am referring -->
https://www.primefaces.org/designer-ng/#/documentation

I really appreciate the folks who took time to answer my question but unfortunately that wasn't what I was looking for.
The simplest answer is -->
1. Create css variables in your styles.css file.
Example :
:root {
--body-color: yellow;
--text-color: red;
--font-size: 50px;
}
Then assign those variables to the properties such as -->
input {
color: var(--text-color);
}
Then in your HTML -->
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-g-12">
<div class="ui-g-3">
<p-fieldset legend="Global Font Size">
<input type="text" placeholder="Enter the global font size">
<button pButton label="Save"></button>
</p-fieldset>
</div>
</div>
</div>
</div>
In your TS file -->
import { Component, Input, OnInit } from '#angular/core';
import { TableBody } from 'primeng/table';
#Component({
templateUrl: './miscdemo.component.html'
})
export class MiscDemoComponent implements OnInit {
input = document.querySelector('input');
body = document.querySelector('body');
fontSize = document.querySelector('input');
button = document.querySelector('button');
constructor() {
}
ngOnInit() {
if (this.input) {
this.input.addEventListener('change', () => {
this.body.style.setProperty('--body-color', this.input.value);
this.fontSize.style.setProperty('--body-color', this.input.value);
} );
}
this.input = document.querySelector('input');
this.button = document.querySelector('button');
if (this.input) {
this.button.addEventListener('click', () => {
this.body.style.setProperty('--body-color', this.input.value);
this.body.style.setProperty('--font-size', this.input.value + 'px');
} );
}
}
}
A great working example is here -->
https://jsfiddle.net/btg5679/9e22zasm/5/

For changing font size, you can use relative font sizes and just set the main font size when you want to change the font size scale. You can see how to do it here.
For changing colors and other values, you can use CSS values as described here.

SCSS is compiled down to CSS so by the time the browser is running it you cannot change the values assigned to SCSS variables.
However using CSS custom properties, also called CSS variables you can. https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties

Related

Using Angular 8 to change the attribute value of a div

In Angular 8, I'm trying to change the value of an element so that I can mask and unmask a text field at the click of a button. The way it is now, the UI has admin controls that when turned on (the showOTP input), it allows a user to have an 'eye' icon to mask and unmask the text. The HTML for this div is here:
OTP HTML
<div class="toggle-otp">
<toggle-otp [showOTP]="toggleOTPEnabled">
<mat-form-field>
<input matInput type="text" fontName="passwordFont">
</mat-form-field>
</toggle-otp>
</div>
The CSS is configured to have the font be a masked version of the text, or be normal text depending if the user hit the button to mask/unmask the field
OTP CSS
toggle-otp input[fontName=passwordFont] {
font-family: passwordFont;
}
toggle-otp input[fontName=unmask] {
font-family: plaintext;
}
Where I'm getting tripped up with this is the OTP TypeScript isn't what is handling the fontName being changed, it's being exported to a separate input component called toggle-otp that holds the button that is displayed for when the admin controls have password masking/unmasking enabled.
OTP TS
export * from ./lib/toggle-otp
TOGGLE-OTP HTML
<div class="toggle-otp-button *ngIf="showOTP">
<button id="toggle-otp" type="button" (click)=otpField.fontName = togglePasswordFont(passwordField.fontName)
</button>
</div>
TOGGLE-OTP TS
#Component({
selector: 'toggle-otp'
})
export class ToggleOTPComponent {
#ContentChild(MatInput) otpField;
togglePasswordFont(font) {
let togglePasswordFont;
font === 'unmask' ? (togglePasswordFont = 'passwordFont') : (togglePasswordFont = 'unmask')
return togglePasswordFont;
}
}
Every thing is working as expected except that the fontName of the OTP HTML is not being updated with the value of 'unmask' to change the font styling, and I'm not sure how I can accomplish this when using an input component.
I have tried using [attr.fontName] in the OTP HTML, but I don't think it's actually binding to the input component TOGGLE-OTP, and thus I can't get the fontName to change it's value.

Can a HTML color picker remember the selected color?

I'm using a color picker to enable the user to choose a background color. I've implemented that and it works fine, but the problem is that when the user clicks the color picker for a second time, the color picker resets. It doesn't 'remember' what they selected before, essentially.
My code is:
<label className='optionSelectors'>BACKGROUND COLOR: </label><br/>
<input type='color' value='#FFFFFF' onChange={this.handleBgColorChange}/>
So when the user clicks the color picker the first time, it defaults to white. Say the user picks purple, but then on reflection they want to go a shade lighter or darker, so they open the color picker again - it goes back to white.
I also tried removing the value='#FFFFFF attribute but it still just defaults to white?
Edit: I am using React and the function handleBgColorChange() is as follows:
handleBgColorChange(e) {
document.getElementById('Collage').style.backgroundColor = e.target.value
}
The relevant input just sits within vanilla HTML, it's not part of a complex render or anything fancy. The code is literally:
<div>
<label className='optionSelectors'>BACKGROUND COLOR: </label><br/>
<input type='color' value='#FFFFFF' onChange={this.handleBgColorChange}/>
</div>
Please take a look at https://reactjs.org/docs/glossary.html#controlled-vs-uncontrolled-components
And use controlled in most cases. For example:
import React, { useState, useCallback } from 'react';
function App() {
const [color, setColor] = useState('#FFFFFF');
const handleBgColorChange = useCallback(({ target: { value } }) => {
setColor(value);
}, []);
return (
<div>
<label>BACKGROUND COLOR:</label>
<input type='color' value={color} onChange={handleBgColorChange} />
<hr />
<div class="collage" style={{ backgroundColor: color }}></div>
</div>
);
}
https://jsfiddle.net/m9z1dajh/

How to access a dynamically generated id of a HTML element with angular

<div *ngFor="let link of links; let i = index;">
<p>{{link.full}}</p>
<button [id]='i' (click)="copyToClipboard(copy) ">Copy</button>
</div>
How do I access the [id]="i" in my typescript file
Have a look at this demo:
[https://stackblitz.com/edit/angular-irxzeg?file=src%2Fapp%2Fapp.component.ts]
It includes suggestions from #Sam Herrmann
And with Renderer, to add Class
[https://stackblitz.com/edit/angular-mjvvp1?file=src%2Fapp%2Fapp.component.ts]
You don't need to add an id or to change 'manually' the label of button.
You can add a flag to know if link has been copied or not, inside your existing model.
For example:
export type Link = {
full: string,
copied: boolean
}
Then, inside your code you can set this flag to true:
copyToClipboard(link: Link) {
link.copied = true;
...
}
In template, just use this flag to adapt the label of button, and also to set a specific class on button (or elsewhere):
<div *ngFor="let link of links">
<p>{{link.full}}</p>
<button (click)="copyToClipboard(link)" [class.copied]="link.copied">
{{ link.copied ? 'Copied' : 'Copy' }}</button>
</div>
.copied {
background-color: green
}

Electron Get file path from form and display as text

I am creating a simple program in Electron. The program has the option of running several separate functions based on what the user needs. All functions require a file to be inputted and a save location for the resulting output file. This is done using a form. I would like to have it that once the user inputs the locations it is displayed in a div beside the input buttons. Is there a way to do this within electron?
code:
<!-- File Input Section -->
<div class = "individual-input-container-2">
<div class="input-container" >
<div class = "inner-input-container">
<input type="file" id="file-input" class = "input-top" >
<p class = "input-desc-file">File</p>
</div>
<div>
</div>
</div>
<div class="input-container">
<div class = "inner-input-container">
<input type="file" webkitdirectory id="save-input"class = "input-bottom">
<p class = "input-desc-save">Save Location</p>
</div>
</div>
</div>
Here is photo of what I am building
I did something similar a while back and mine looks like this:
HTML:
<button id="choosePath">Choose Folder</button>
JS:
const { dialog } = require('electron').remote;
document.querySelector('#choosePath').addEventListener('click', (e) => {
dialog.showOpenDialog({
title:"Select Directory",
properties: ["openDirectory"]
}, (folderPaths) => {
// folderPaths is an array that contains all the selected paths
if(folderPaths === undefined){
return;
} else {
// Do something with the folderPaths variable
}
});
});
It's basically just an ordinary button opening a Dialog Window where you can select a path.
If you did select one the full Path is passed to a callback function where you can use it to do whatever you have to do with it.
You can try Electron's dialog.showSaveDialog ()/dialog.showSaveDialogSync () functions. They return a Promise<string> or a string representing the file/folder which was selected by the user, respectively. Then you can easily display in your <div>.

Paper-Button always as upper case

I am using Paper-Button but I am facing issue that the button text always gets capitalized instead or normal case.
I do not see any CSS or Javascript property being applied to make it upper case.
How should I resolve this problem?
I had the same issue and I solved the problem via adjusting the default theme. Add the following code to a file (name of your choice).js
import { createMuiTheme } from '#material-ui/core/styles';
const theme = createMuiTheme({
typography: {
button: {
textTransform: 'none'
}
}
});
export default theme;
You can then add the file to your app in index.js. I named it theme.js:
...
import theme from './theme';
...
const app = () => (
<ThemeProvider theme={theme}>
<CssBaseline />
<App />
</ThemeProvider>
);
ReactDOM.render(app, document.getElementById('root'));
As was mentioned in the comments above, the material design spec for buttons specifies that the text should be uppercase, but you can easily override its CSS property:
paper-button {
text-transform: none;
}
Inspired by the the CSS style above here is the inline styling for localized Button text transformation -
import {Button} from '#material-ui/core';
// Begin Component Logic
<Button style={{textTransform: 'none'}}>
Hello World
</Button>
// End Component Logic
If you use Mui 5 then you can use the sx syntax
<Button sx={{textTransform: "none"}}/>