Clicking Separate Div Causes Radio Button To Change - javascript

I'm having a problem where clicking anywhere inside a separate div is causing the radio button to change to the first radio button. I don't know why this is happening as the panel div for adding payments is completely separated from the radio label.
Basically, I have a bunch of cards in a list, clicking the radio button selects the cards. When I try to fill out the fields to add a payment method, clicking anything within the box causes the radio button to go back to the first card. How is the handleRadioChange method propagating to the panel div?
<div id="payment_methods" style={{margin: '10px'}}>
<div className="group">
{methods.map((method, key) => {
return (
<label>
<span>
<input type="radio"
name={method.id}
value="saved-card-1"
style={{verticalAlign: 'middle', margin: '0px'}}
checked={radio == method.id}
onChange={handleRadioChange}
/>
</span>
</label>
)
})}
<label>
<span>
<input type="radio"
name="add-card"
value="add-card"
style={{verticalAlign: 'middle', margin: '0px'}}
checked={radio == 'add-card'}
onChange={handleRadioChange}
/>
</span>
<div className="box-root hideIfEmpty">
<div className="box-root">
<div className="box-root flex flex-row flex-justify-flexstart flex-wrap">
<div className="flex flex-align-baseline flex-row">
<div className="flex align-baseline flex-row flex-justify-flexstart">
<span className="button-link-label text-proportional text-typeface text-wrap-nowrap text-gray">
<span> Add Payment Method </span>
</span>
</div>
</div>
</div>
</div>
</div>
</label>
</div>
</div>
<CSSTransition
classNames="method"
in={radio === 'add-card'}
timeout={100}
unmountOnExit>
<div className="panel panel-primary">
</CSSTransition>
This is my handleRadioChange method
const handleRadioChange = async (e) => {
console.log(e.target);
setRadio(e.target.name)
if (e.target.name == 'add-card') {
console.log('Creating payment fields')
}
}

The event on your input is propagating to the label, which contains everything else inside your card. Try adding e.preventDefault() to your handler, or moving non-input elements outside of your label element. You're also using a unique name attribute for each payment method in your array. That would prevent them from acting as a single radio group.

Related

click button to toggle show one component and hide another component in reactjs

I have two separate button like grid and list button:
<button
onClick={() => setClassName('jsGridView')}
title="Grid View"
>
<IoGrid className="active" size="25"/>
</button>
<button
onClick={() => setClassName('jsListView')}
title="List View"
>
<BiAlignLeft size="25"/>
</button>
const [cName, setClassName] = useState('jsGridView');
So when i click Grid view button it will show this component:
<GridCard className={cName}/>
and when i click list view button it will show
<ListCard className={cName}/>
with this mentioned className..
class is changed button but show hide component is not working.
You can display different components depending on the value of cName.
<div className="row mt-4 book-div">
<div className={cName}>
{ cName === 'jsGridView' ? <BooksGridCard/> : <BooksListCard/> }
</div>
</div>

GET http://localhost:8080/undefined 404 - when dynamically adding html

In my maze game app (created with vanilla JS), I dynamically remove and then add a 'user input' pop up box which allows the user to select the character they want and to enter their name. The'user input' pop up box is hardcoded in the HTML so that when the app first loads, it appears on the UI immediately.
Once the user has selected their character, entered their name, and pressed the 'start game' button, the pop-up box HTML is removed from the DOM using 'removeChild'.
Once the user has finished the maze, a 'leader board' pop up box is displayed which has a 'play again' button. When the user clicks this button, the 'leader board' pop up box is removed from the DOM and the 'user input' pop up box is displayed again.
The issue I am having is that when the 'user input' pop up box is displayed when the user clicks the 'play again' button, I am being presented with the error 'GET http://localhost:8080/undefined 404' in the console and I am unable to select a character or start another game.
I have a feeling this may do with the fact that I am using Webpack to bundle the code as when the 'play again' button is clicked, the page does not reload and as the HTML has been removed from the DOM and then added again, this is somehow causing the error?
Here is the relevant html:
<div class="container">
//THE BELOW PART OF THIS CODE IS REMOVED FROM THE DOM
<div class="users-input animated slideInUp">
<div class="users-name">
<input
class="users-name-input"
type="text"
name="Name"
placeholder="Enter Name"
required
/>
</div>
<div class="select-character-text">
<p>Select Character</p>
</div>
<div class="character-select">
<ion-icon class="left" name="arrow-dropleft-circle"></ion-icon>
<ion-icon class="right" name="arrow-dropright-circle"></ion-icon>
<img class="character-img trump" src="images/trump.png" />
</div>
<div class="start-button-container">
<input class="start-button" type="button" value="START" />
</div>
</div>
//THE ABOVE PART OF THIS CODE IS REMOVED FROM THE DOM
</div>
This is the relevant code in the gameView.js file:
const popUpContainer = document.querySelector(".container");
export const renderUsersInput = () => {
let html = ` <div class="users-input animated slideInUp">
<div class="users-name">
<input class="users-name-input" type="text" name="Name" placeholder="Enter Name" required>
</div>
<div class="select-character-text">
<p>Select Character</p>
</div>
<div class="character-select">
<ion-icon class="left" name="arrow-dropleft-circle"></ion-icon>
<ion-icon class="right" name="arrow-dropright-circle"></ion-icon>
<img class="character-img trump" src="images/trump.png">
</div>
<div class="start-button-container">
<input class="start-button" type="button" value="START">
</div>
</div> `;
popUpContainer.insertAdjacentHTML("beforeend", html);
};
export const removeUsersInput = () => {
const usersInput = document.querySelector(".users-input");
usersInput.parentElement.removeChild(usersInput);
};
The removeUsersInput method above is called within the main Controller on my app (index.js):
const ctrlStartGame = () => {
gameView.removeUsersInput();
};
This is attached to an event listener:
base.elements.startButton.addEventListener("click", ctrlStartGame);
the renderUsersInput method is attached to this event listener:
base.elements.leaderBoardContainer.addEventListener("click", (e) => {
const newElements = base.getNewElements();
if(e.target === newElements.playAgainBtn) {
gameView.removeLeaderBoard();
gameView.renderUsersInput();
}

How do I make a label for a slider that slides along with the current value?

I want to make a label on top of the slider that moves along with it and updates it's value as it moves.
I can get the label to show but I don't know how to move it with the slider.
Also, I want to make buttons on the sides but if I place them on top of the bar, the slider doesn't work anymore. (code commented out)
function slideBar({ min, max, onChange, value, style, onCLick }) {
return (
<div className="slider-whole">
<div className="labels" style={style}>
<p className="min">{min}</p>
<p className="currentValue" style={style}>{value}</p>
<p className="max">{max}+</p>
</div>
<input
type="range"
name="range"
min={min}
max={max}git
value={value}
className={`slider slider${style.color}`}
id="myRange"
onChange={onChange}
style={style}
/>
{/* <div className="arrow-buttons" style={style}>
<i className="fas fa-chevron-left"></i>
<i className="fas fa-chevron-right"></i>
</div> */}
{/* <output htmlFor="range" onforminput="value = range.valueAsNumber;"></output> */}
</div>
)
}
Set your class slider-name with position:relative and class currentValue with position:absolute; and set the value for left dynamically as the current value changes.

How to access to state of repeated component in ReactJS

i am new to reactjs. I want to access state of a repeated react component. My code is
{Object.keys(this.state.sharing).map((share)=>{
return(<Sharings />)
})}
above component is repeated 3 times
The Sharing Component contains radio buttons and button.
When the radio button is clicked then only button is enabled.
Here is my code
<div className="col-xs-12 col-md-4">
<div className="book-now-card p-b-10" style={{height:height}}>
<div className="single-sharing" style={{height: '180px'}}>
<h3 className="single-sharing-heading">{props.heading}</h3>
</div>
<div className="m-t-20">
{
props.rent.map((rent)=>{
return(
<div className="m-10" key={rent}>
<input type="radio" name={'radio'} className="m-l-20 " onClick={(e)=>{this.handleChange(rent,e)}} /> <span className="m-l-20" style={{color:'#009688'}}>₹ {rent}</span>
<p className="m-l-55 f-s-12" style={{color: '#65747a'}}>{props.details}</p>
</div>
)
})
}
</div>
<div className="m-20">
<button className="btn btn-secondary col-6 select-rent" disabled={true} onClick={(e)=>{this.proceed(e)}} id={'Button'+this.props.num}>SELECT</button>
</div>
</div>
</div>
I want disable button in button in 1st and 3rd sharing component when radio button in 2nd sharing Component is clicked. I tried DOM manipulation with document.getElementById but click function in button stopped working.
Your input component should be controlled component
In your map method you should have something like this:
<input
type="radio"
name={'radio'}
className="m-l-20 "
value={this.state.radiosValues[index]} {/* get radio value from state */}
onClick={()=>{ // We don't need event because we work with booleans
const radiosValues = this.state.radiosValues
radiosValues[index] = !radiosValues[index] // If true we want false, if false we want true
this.setState({ radioValues})
}}
/>

Remove class from buttons on changing values in editable div for dynamically generated divs

I am creating an app using knockout and jquery. There are user generated contents which a user can edit and save. I have a save button which is disabled and gets enabled only when new character is added to the editable div.
Problem:
Save button gets activated for all divs. I want only the respective button to get enabled and remaining should stay in disabled state.
HTML:
<div data-bind="foreach: $root.goals">
<div class="ui padded segment mainCard brdR-S" data-bind="attr:{id:Title()}">
<div>
<div>
<div contenteditable="true" class="heading pdM-TB wordwrap" data-bind="attr:{href:'#'+Title()}, editableText: Title, event: { keyup: $root.ShowButtons }" id="goalTitle">
</div>
<div class="mgXl-T pdM-TB">
<button class="ui disabled tiny primary button" id="btnSave" data-bind="click: $root.putGoal">
<i class="refresh icon"></i>Save
</button>
</div>
</div>
</div>
</div>
Jquery
self.ShowButtons = function (data, e) {
$('.button').removeClass('disabled')
};

Categories