set state in onClick function - javascript

I have 2 submit buttons in my react form.
I am trying to use an onClick function to get the id of the clicked button, so I can then specify how to handle each accordingly.
My onClick function is returning undefined for the setState of the id.
How can I properly grab the id of the button and set the state?
handleClick() {
var buttons = document.getElementsByTagName("button");
var buttonsCount = buttons.length;
for (var i = 0; i < buttonsCount; i++) {
buttons[i].onclick = (e) => {
this.setState({clickedSubmit: this.id});
console.log(this.state.clickedSubmit); //returns undefined
};
}
}
//in the render
<button id="formSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick}>Submit</button>
<button id="hashSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick}>Generate Hash</button>

You will find your element id in the event of the onClick handler that is e.target.id
handleClick = (e) => {
this.setState({ clickedSubmit: e.target.id },() => {
console.log(this.state.clickedSubmit)
});
}
//in the render
<button id="formSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick}>Submit</button>
<button id="hashSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick}>Generate Hash</button>

I recommend changing how you invoke handleClick slightly, by passing in an argument for buttonId.
In your render function:
<button onClick={() => this.handleClick('formSubmit')}>Submit</button>
In handleClick:
handleClick(buttonId) { ... }
As I posted in my comment, you have an option to separate the button out into it's own component. In that case, you would be able to use simple like this.props.id to get the value of id.

I would suggest you to go for a simpler approach, something like this
handleClick1() {
var buttons = document.getElementsByTagName("button");
var buttonsCount = buttons.length;
let id = 1;
for (var i = 0; i < buttonsCount; i++) {
buttons[i].onclick = (e) => {
this.setState({clickedSubmit: id});
console.log(this.state.clickedSubmit); //returns undefined
};
}
}
handleClick2() {
var buttons = document.getElementsByTagName("button");
var buttonsCount = buttons.length;
let id = 2;
for (var i = 0; i < buttonsCount; i++) {
buttons[i].onclick = (e) => {
this.setState({clickedSubmit: id});
console.log(this.state.clickedSubmit); //returns undefined
};
}
}
//in the render
<button id="formSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick1}>Submit</button>
<button id="hashSubmit" className="btn btn-info" name="submitButton" onClick={this.handleClick2}>Generate Hash</button>
The benefit of this approach is, in future when your button count increases, then at that time, your code should be modular so that it is easy to add new functionality to your app.
Hope this helps!

You can get id of your buttons by using event.target, like below:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
clickedId: -1,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(event) {
const id = event.target.id;
this.setState({
clickedId: id,
});
}
render() {
return (
<div>
<h1>Clicked id: {this.state.clickedId}</h1>
<button id="asd" onClick={this.handleClick}>Asd</button>
<button id="qwe" onClick={this.handleClick}>Qwe</button>
</div>
);
}
}
DEMO: http://jsbin.com/yiqavav/1/edit?html,js,output

You can try this, even change id to other parameter you want to pass in to the your function.
<button onClick={(e) => this.handlefunction(id, e)}>Delete Row</button>
<button onClick={this.handlefunction.bind(this, id)}>Delete Row</button>
This article helps a great deal:
https://reactjs.org/docs/handling-events.html

Related

Diable the button , enable button after another button clock

I want that until the Copy List To Below get clicked I want to disable to Save button.
Currently this is the Copy List To Below button
<button type="button" className={classes["copy-btn"] + " btn-cancel mt-3"} onClick={(event) => this.copyData(event)}>Copy List To Below {_.size(this.state.protestList) > 1 ? _.size(this.state.protestList) + " Groups" : 'Group'} </button>
And this is my Save button
<button type="submit" className={classes["save-btn"] + " btn-save"} onClick={(event) => this.saveData(event)}>Save</button>
And below is the respected functions
saveDate = (event, data) => {
if(event) {
//Do something
}
else {
//Return Error
}
}
copyData = (event, data) => {
if(event) {
//Do something
}
else {
//Return Error
}
}
As I said only if Copy is done then only save button should be able get clicked
Give two ids and add click event and toggle button disable property like this. Make it simple. Your buttons has unnecessary attributes, please remove those.
CORE JAVASCRIPT
<button type="button" id="coptBtn" class ="btn-cancel mt-3" >Copy List To Below</button>
<button id="saveBtn" type="submit" class="" >Save</button>
var coptBtn = document.getElementById('coptBtn');
var saveBtn = document.getElementById('saveBtn');
saveBtn.disabled = true;
coptBtn.addEventListener('click', (evt) => {
saveBtn.disabled = false;
});
REACT JS
var App = React.createClass({
getInitialState() {
return {isDisable: false}
},
handleClick(e) {
this.setState({isDisable: true})
},
render() {
return <div>
<button type="button" onClick={this.handleClick} >Copy List To Below</button>
<button type="button" disabled={!this.state.isDisable}>Save</button>
</div>
}
});
Try this code..
copyData() {
//your existing code
this.setState({copied: true})
}
<button type="submit" disable={!this.state.copied} className={classes["save-btn"] + " btn-save"} onClick={(event) => this.saveData(event)}>Save</button>

how i can keep modal open after click?

My question is different and didn't get any solution.Question is when i click on active modal opens for 1 sec and then page refresh and change status active to inactive.
I want to keep modal open when i click on active then after hitting send from modal page reloads and change status to inactive.
My Modal:
<div class="modal fade text-left" id="small" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel19"
aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<form method="post">
<input type="hidden" name="_token" value="{{csrf_token()}}">
<div class="modal-header">
<h4 class="modal-title" id="heading-name">Reason</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<label class="receiver" for="to">To: </label>
</div>
<div class="form-group">
<textarea type="text" class="form-control" name="message" id="message"></textarea>
</div>
</div>
<input type="hidden" name="message_value" id="message_value">
<div class="modal-footer">
<button type="button" class="btn grey btn-outline-secondary" data-dismiss="modal">
Close
</button>
<button type="submit" class="btn btn-outline-primary" data-target="myModalLabel19"
data-toggle="modal">Send
</button>
</div>
</form>
</div>
</div>
</div>
For Loop:
for (var i = 0; i < response.data.length; i++) {
if (response.data[i]['status'] == 1) {
operatorStatus = "Active";
statusColor = "<button class='btn btn-primary' onclick='fn_statusUpdate("+response.data[i]['id']+",0);reason("+response.data[i]['id']+")'>Active</button>";
} else {
operatorStatus = "Active";
statusColor = "<button class='btn btn-danger' onclick='fn_statusUpdate("+response.data[i]['id']+",1)'>Inactive</button>";
}
}
Function:
function reason(id) {
$('.receiver').text('To: ' + id);
$('#message_value').val(id);
console.log((JSON.stringify(id)));
$('#small').modal('show');
}
Pseudo Code
Okay, rather than re-writing the code for you, I'm just gonna write some pseudo code for you, simply because I'm not sure about how it all works or how it all ties together, etc...
So, you want to be able to do some stuff and remember the values prior to the page being refreshed, as far as I'm aware. So, I'd do something like this...
On load
...
if (sessionStorage.getItem('key') != null) {
// Show modal or set state to active or whatever...
} else {
// Hide modal and set state to inactive or whatever...
}
On State Change
....
if (state.active) {
// Do something...
} else {
// Do something else...
}
Explanation
I think you get where I'm going with this? If not it's really quite simple, if you have some value stored in session storage, then you can set the state to active and show the modal. I mean I think that's what you're trying to achieve?
Otherwise, just hide it all and set the state to inactive. I mean if you have many modals, then you could store an object into session storage using something like the code I've written below(keep in mind I've not tested this code):
const Session = {
get: key => {
try {
JSON.parse(sessionStorage.getItem(key));
} catch (e) {
return sessionStorage.getItem(key);
}
},
set: (key, data) => {
try {
sessionStorage.setItem(key, JSON.stringify(data));
} catch (e) {
sessionStorage.setItem(key, data);
}
}
};
So with this, you could just set some object, i.e. modalStates in you JavaScript, and then execute some check on load to check the state of each modal? I mean I'm not sure if you'd want to only allow only one modal to be active at any given time or if you'd want multiple to be active and open, etc...
Edit
Here's a simple demo, it won't work on here if I'm not mistaken, but if you try it on JSFiddle, I believe it should work without a problem. Again, this is just an example, it's merely here to give you an idea of how to solve your problem.
const dhtml = document.getElementById("demo");
const modal = document.getElementById("mdoal");
const btn = document.getElementById("change");
let state = {};
// Simple on error function.
const log = arg => {
console.clear();
console.log(arg);
};
// Simple get state function.
const getState = () => {
try {
if (JSON.parse(sessionStorage.getItem("demo")) != null) {
state = JSON.parse(sessionStorage.getItem("demo"));
} else {
state = {};
}
} catch (e) {
//log(e);
}
return state;
};
// Simple set state function.
const setState = () => {
try {
state = sessionStorage.setItem("demo", JSON.stringify(state));
} catch (e) {
//log(e);
}
};
// A simple on state change function.
const updateState = () => {
if (state.active == null) {
state.active = true;
} else {
state.active = !state.active;
}
setState();
log('State changed.');
};
// A simple render function.
const render = () => {
if (state.active == null || state.active == false) {
dhtml.textContent = 'Inactive';
modal.style.display = 'none';
} else {
dhtml.textContent = 'Active';
modal.style.display = 'block';
}
};
// A simple click handler for the change button.
const clickHandler = () => {
updateState();
getState();
render();
// window.location.reload(); // Simulate a http refresh/redirect.
};
// A simple on load function.
const onLoad = () => {
getState(); // Update the state object.
render(); // Initial render;
btn.onclick = clickHandler;
};
onLoad();
<div id="demo">
<p>Inactive</p>
</div>
<div id="mdoal" style="display: none">
<p>Hello World!</p>
</div>
<button id="change">state change</button>
You can use localStorage to achieve this basically, you don't have full code so I m assuming and and giving you an example:
function reason(id) {
$('.receiver').text('To: ' + id);
$('#message_value').val(id);
console.log((JSON.stringify(id)));
localStorage.setItem('isModalActive', '1'); // Add is modal active
$('#small').modal('show');
}
So now you set isModalActive 1 to users localStorage than you can check onload
$( document ).ready(function() {
if(localStorage.getItem('isModalActive') == '1'){
$('#small').modal('show');
}
});
Than when you closing to modal dont forget to change the value to 0
localStorage.setItem('isModalActive', '0'); // Add is modal not Active
Hope it helps.

Component didn't re-renders on state change?

I am creating a random quote generator. There is a quote box that displays quote and author names. I created a method to invoke on a button click that may randomize the quote list and display a new quote and a next button to get next quote from my quote list. I can see the first quote but the component didn't re-renders on clicking buttons or something gets wrong that I can't get next quote or can't randomize. Here is the code:
class UI_qoutebox extends React.Component {
constructor(props) {
super(props);
this.state = { qoutes: props.qoutes, authors: props.authors, num: 0 };
this.UI_rq = this.UI_rq.bind(this);
this.UI_next = this.UI_next.bind(this);
}
UI_rq() {
let rnd = Math.floor(Math.random() * this.state.qoutes.length);
this.setState({ num: rnd });
}
UI_next() {
let p = this.state.num + 1;
if (p > this.state.qoutes.length) { p = 0 }
this.setState({ num: p })
}
render() {
const { qoutes, authors, num } = this.state;
return (
<div className="qoute-box">
<span className="qoute">{qoutes[num]}</span>
<span>{authors[num]}</span>
<input type="button" value="Randomize" onClick={() => this.UI_rq} />
<input type="button" value="Next" onClick={() => this.UI_next} />
</div>
)
}
}
I am working on Freecodecamp's project and I need quick help. Thanks in advance.
Change this
<input type="button" value="Randomize" onClick={this.UI_rq}/>
<input type="button" value="Next" onClick={this.UI_next}/>

Retrieve unique value of a button

I have several buttons belonging to the same class. I want to retrieve the value of the button I click on.
Here is my code:
var battons = document.getElementsByClassName("converting_video");
var number_of_buttons = battons.length;
function actual_url() {
while (number_of_buttons > 0) {
for (i = 1; i <= number_of_buttons; i++) {
function getting_url() {
battons[i].addEventListener("click", video_url)
}
function video_url(url) {
alert(url);
}
}
}
}
var battons = document.getElementsByClassName("class_btns");
var number_of_buttons = battons.length;
function actual_url() {
while (number_of_buttons > 0) {
for (i = 1; i <= number_of_buttons; i++) {
function getting_url() {
battons[i].addEventListener("click", video_url)
}
function video_url(url) {
alert(url);
}
}
}
}
<button class="class_btns" value='1'> results </button>
<button class="class_btns" value='2'> results </button>
<button class="class_btns" value='3'> results </button>
<button class="class_btns" value='4'> results </button>
This will allow you to get the value of any of the buttons clicked. Using jQuery's .click() event handler and $(this).val() will allow the value of the clicked button to be the value in the alert. Not sure what you are actually looking for with video_url etc, but this should point you in the right direction. You can then use the value from the click to do pass to your function rather than jusrt alerting i eg: ... video_url(btnVal) ...
$(document).ready(function(){
$('.class_btns').click(function(){
var btnVal = $(this).val();
alert(btnVal);
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="class_btns" value='1'>results</button>
<button class="class_btns" value='2'>results</button>
<button class="class_btns" value='3'>results</button>
<button class="class_btns" value='4'>results</button>

React JS reference function in another component

I'm trying to get a button rendered through another component to reference and/or influence the state of a different component.
var Inputs = React.createClass({
getInitialState: function(){
return {count: 1};
},
add: function(){
this.setState({
count: this.state.count + 1
});
},
render: function(){
var items = [];
var inputs;
for (var i = 0; i < this.state.count; i++){
items.push(<input type="text" name={[i]} />);
items.push(<br />);
}
return (
<div className="col-md-9">
<form action="/" method="post" name="form1">
{items}
<input type="submit" className="btn btn-success" value="Submit Form" />
</form>
</div>
);
}
});
I want to write a new component that will be able to access the add function in Inputs. I tried to reference it directly with Inputs.add like this:
var Add = React.createClass({
render: function(){
return (
<input type="button" className="btn" value="Add an Input" onClick={Inputs.add} />
);
}
});
But that didn't work. How would I be able to access a component's functions through another component, or influence the state of a component through another component? Thanks.
You could accomplish this by creating a parent component that is responsible for managing the state and then just push the state down to the sub-components as props.
/** #jsx React.DOM */
var Inputs = React.createClass({
render: function () {
var items = [];
var inputs;
for (var i = 0; i < this.props.count; i++) {
items.push( <input type="text" name={[i]} />);
items.push(<br />);
}
return (
<div className = "col-md-9">
<form action = "/" method = "post" name = "form1">
{items}
<input type="submit" className="btn btn-success" value = "Submit Form" />
</form>
</div>
);
}
});
var Add = React.createClass({
render: function () {
return (<input type = "button" className="btn" value="Add an Input" onClick={this.props.fnClick}/> );
}
});
var Parent = React.createClass({
getInitialState: function(){
return {count:1}
},
addInput: function(){
var newCount = this.state.count + 1;
this.setState({count: newCount});
},
render: function(){
return (
<div>
<Inputs count={this.state.count}></Inputs>
<Add fnClick={this.addInput}/>
</div>
);
}
});
React.renderComponent(<Parent></Parent> , document.body);
jsFiddle
You can call functions on the return value of renderComponent:
var Inputs = React.createClass({…});
var myInputs = React.renderComponent(Inputs);
myInputs.add();
The only way to get a handle to a React Component instance outside of React is by storing the return value of React.renderComponent. Source.

Categories

Resources