Dynamically and conditionaly changing css of a button in reactJs - css

In a react application how to dynamically change css of a button when a form input validation fails(There are lot of input fields which accept marks)

You can do it like this
<button style={{backgroundColor: this.state.error ? 'red' : 'green'}}>Save</button>
or change the class based on the error state and style in the css file like this
<button className={this.state.error && 'error'}>Save</button>
Hope this helps
PS this.state.error assumes you are using a class component

Also you can give className conditionally. If you don't want to set anything when condition is false, then just leave as empty string ''
<button className={ this.state.something ? 'first-class' : 'second-class' }>Clicker</button>
If you want to add a className attribute conditionally, then
<button { ...(booleanValue && { className: 'some-class' }) }>Clicker</button>

Related

React conditional class name setting for styling

I am trying to make a quiz app using React.
I am currently working on the main quiz page where I have 4 buttons, and each of the buttons denotes an answer I'm importing from a question bank.
I want the current selected button to be highlighted, and for this I am currently using a state for each button. Is there any way to just use one state and deal with all four of the buttons, as this way is too tedious and cannot be used for a large number of such buttons? Also, I want only one button, the one the user selects finally, to be highlighted. So for this reason I need to set the state of all the other buttons to null, which makes the task even more tedious.
Here is the div containing the buttons
<div>
<button className={selected1} onClick={() => dealingWithOptions("A")}>{questions[currentQuestion].optionA}</button>
<button className={selected2} onClick={() => dealingWithOptions("B")}>{questions[currentQuestion].optionB}</button>
<button className={selected3} onClick={() => dealingWithOptions("C")}>{questions[currentQuestion].optionC}</button>
<button className={selected4} onClick={() => dealingWithOptions("D")}>{questions[currentQuestion].optionD}</button>
</div>
Here is the function dealing with the options clicking
const [selected1,setSelectedButton1] = useState("")
const [selected2,setSelectedButton2] = useState("")
const dealingWithOptions = (op) => {
setOptionChosen(op);
if (op=="A") {
setSelectedButton1("selected1");
setSelectedButton2("")
setSelectedButton3("")
setSelectedButton4("")
} else if (op=='B') {
setSelectedButton1("");
setSelectedButton2("selected2")
setSelectedButton3("")
setSelectedButton4("")
} else if (op=='C') {
setSelectedButton1("");
setSelectedButton2("")
setSelectedButton3("selected3")
setSelectedButton4("");
}
else if (op=='D') {
setSelectedButton1("");
setSelectedButton2("")
setSelectedButton3("")
setSelectedButton4("selected3");
}
}
It can be solved and optimized in many ways. I am trying to give what suit your current code most.
I assume you have a state that stores choosen option.
Now update all the button like this
<button className={choosen == "A" ? "selected" : "" } onClick={() => dealingWithOptions("A")}>{questions[currentQuestion].optionA}</button>
Here choosen is the state where the selected option is being stored.
Explanation: Here what we are doing is, we are matching for each button that if it is the selected button then add the selected class else add nothing.
I would suggest having one state, that stores the chosen option (so either A, B, C or D) and then in your JSX part you have a condition that assigns the classname "selected" to the appropiate button.
If the selection changes so will the state, which triggers a rerender (so you don't even have to take away the "selected" class, since it will just be assinged to (and only) the right one on rerender
I'd suggest you set one piece of state to maintain the selected button.
setSelectedButton('A')
Or undefined if none is selected
Then,
<button className={selectedButton === 'A' ? 'selected1' : ''}>...
That said for conditional classes I'd use something like clsx rather than building class strings manually
e.g.
<button className={clsx({selected1: selectedButton === 'A'})}>...
Several ways to achieve this. You can set one state: const [selectedId, setSelectedId] = useState("")
Define the function: const selectHandler = (e) => setSelectedId(e.target.name)
On your buttons call the function and set the state to the Id: <button className={selectedId === "a" && "selected"} name="a" onClick={() => setSelectedId("a")}>Button A</button> For the rest of the buttons, change the name as well as the parameter passed to the function. Also the string inside the className comparison

How can I remove a CSS class based on condition

Hi I am writing a react code for a button. Here is the code:
<Button
block={true}
className={`sc-pc-action-button ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>
There is a condition in which I dont need this sc-pc-action-button css.
Now this class sc-pc-action-button is hardcoded.
How can I write a CSS which tells me to ignore the contents of sc-pc-action-button and take fresh CSS I am giving.
I need a CSS solution to remove the properties. I don't need JS Solution
<Button
block={true}
className={`${someCondition ? "sc-pc-action-button" : ""} ${className}`.trim()}
disabled={disabled}
onClick={onClick}
> Click me
</Button>

How do I use ternary operator for classnames with css modules?

I am facing some difficulty effecting a styling with the ternary operator in an element's className.
I created three buttons to render to a particular component when any of them are clicked, and I also intend to use a background color change on the buttons when each component assigned to it is rendered to denote which button was clicked.
The issue I face is that while the components are successfully rendering, the background color for the button doesn't change.
<div className="App">
<div className ="App-btns">
<button onClick = {fPro} className = {`${styles[{pro ? "active" : null}]}`}>Profile</button>
<button onClick = {fSec} className = {`${styles[{sec ? "active" : null}]}`}>Security</button>
<button onClick = {fVer} className = {`${styles[{ver ? "active" : null}]}`}>Verification</button>
</div>
<div className = "App-render">
{pro && <Profile/>}
{sec && <Security/>}
{ver && <Verification/>}
</div>
</div>
I created three variables; pro, sec and ver. I set all to false except pro which was set to true, which renders the component, Profile as the default. Then, I created three functions also, which sets its corresponding variables to true and others to false and they are activated when a button Is clicked.
I also used the variables in the ternary operator to assign a classname, when a particular variable is true. The class name should be set to active and a corresponding styling change should come with it, but this doesn't seem to work.
.active{
background-color: purple;
border: 1px solid purple;
}
When pro is truthy, styles[{pro ? "active" : null}] gets resolved to styles[{"active"}] which makes no sense.
Instead conditionally add className like this
<button onClick = {fPro} {...(pro && { className: "active" })}>Profile</button>
OR
<button onClick = {fPro} className= {pro?"active":null}>Profile</button>
Do the same for other buttons.
<div className="App">
<div className ="App-btns">
<button onClick = {fPro} className = {`${pro ? styles.active : null}`}>Profile</button>
<button onClick = {fSec} className = {`${sec ? styles.active : null}`}>Security</button>
<button onClick = {fVer} className = {`${ver ? styles.active : null}`}>Verification</button>
</div>
<div className = "App-render">
{pro && <Profile/>}
{sec && <Security/>}
{ver && <Verification/>}
</div>
</div>

How to make autosuggest field look like bootstrap input?

How can I make the <vue-autosuggest> input look like the input from BootstrapVue (<b-input>)?
To apply the form-control class to vue-autosuggest's inner <input>, as required for the Bootstrap <input> styles, you could use the inputProps prop (automatically applied to the <input>):
<template>
<vue-autosuggest :input-props="inputProps">
...
</vue-autosuggest>
</template>
<script>
export default {
data() {
return {
inputProps: {
class: 'form-control',
}
}
}
}
</script>
Interestingly, that class used to be added by default in vue-autosuggest 1.x, but was removed in 2.x.
demo
You need to modify the the <input> tag of the vue-autosuggest component to include the class form-control from Vue-Bootstrap.
You will not be able to add this class directly to the component as the component wraps the input within a div block. Bootstrap CSS requires the the element to be of type input to properly match the CSS selectors.
If we look here https://github.com/darrenjennings/vue-autosuggest/blob/master/src/Autosuggest.vue at the component itself we see
<input
:type="internal_inputProps.type"
:value="internalValue"
:autocomplete="internal_inputProps.autocomplete"
:class="[isOpen ? `${componentAttrPrefix}__input--open` : '', internal_inputProps['class']]"
v-bind="internal_inputProps"
aria-autocomplete="list"
:aria-activedescendant="isOpen && currentIndex !== null ? `${componentAttrPrefix}__results-item--${currentIndex}` : ''"
:aria-controls="`${componentAttrIdAutosuggest}-${componentAttrPrefix}__results`"
#input="inputHandler"
#keydown="handleKeyStroke"
v-on="listeners"
>
This must be modified in your local version to include the bootstrap class.

button disabled background color inline style attribute jsx

I have a case where I can only pass the property to the jsx component but I cannot use standard css class (component is not reachable, only can be styled by passing the attributes to its parent component). Is there a way to set the background-color for a disabled button using inline style attribute?
EDIT
the closest I get is style: {[disabled=true]:{backgroundColor: "red"}} but I get Uncaught ReferenceError: disabled is not defined
Yes. Something like this should work:
define your style:
const disabled = {
backgroundColor: "red"
};
Then wherever your button component occurs:
<Button style={disabled}>
Example Button
</Button>
Goodluck!
Can I ask if you are passing disabled into the component as a prop?
If so you can do below
const isDisabled = {
backgrondColor: 'red'
};
<button style={disabled ? isDisabled : null}>
Button 1
</button>

Resources