Adding a check box using MERN - javascript

I am form where i am trying to add a check box for gender selection. I have tried everything but with no result.
Here is my code about the checkbox and a picture of my form
<div className="input-field col s12">
<input
onChange={this.onChange}
value={this.state.gender}
error={errors.gender}
id="gender"
type="checkbox"
className={classnames("", {
invalid: errors.amka
})}
/>
<label htmlFor="gender"><b className="black-text text-darken-1">Gender:</b></label>
<span className="red-text">{errors.gender}</span>
<br></br>
</div>
enter image description here

Okay, first of all you should not use chekckbox for gender selection unless there is very specific reason for that.
Here is the code for checkbox.
<div>
<input
type="checkbox"
name="checkbox"
id="checkbox"
checked={value}
value={value}
onChange={e => {
// perform the function onChange
}}
/>
<label for="checkbox">My Checkbox</label>
</div>
Here is the demo: https://stackblitz.com/edit/react-f5q3n8?file=src/App.js

Related

Display alert message pop up the to the user when user checked or unchecked the checkbox using angular

Scenario 1: User has initially checked the value for "Automated" and updates the value to unchecked state
Display alert message pops up to the user if at least one of the following accordions is in the "Completed" state.
HTML
<div class="col-md-12 col-sm-12 filter-opn">
<form #checkboxfilt="ngForm" (ngSubmit)="onapplyfilter(checkboxfilt)">
<div >
<div>
<input type="checkbox" name="Success" value="1" ngModel selected ><br>
<label for="Success"> Success</label><br>
</div>
<div>
<input type="checkbox" name="Pending" value="2" ngModel ><br>
<label for="Pending"> Pending</label><br>
</div>
<div>
<input type="checkbox" name="Canceled" value="3" ngModel ><br>
<label for="Canceled"> Canceled</label><br>
</div>
<input type="submit" value="Apply">
<br>
</div>
</form>
</div>
TS
onapplyfilter(checkbox:NgForm){
if((checkbox.value.Success ==''|| checkbox.value.Success==false)
&&(checkbox.value.Pending ==''|| checkbox.value.Pending==false)
&&(checkbox.value.Canceled ==''|| checkbox.value.Canceled==false))
{
alert('CheckBox is Empty');
}
}
}

eventListener always fires on first element

There are 3 <input type="file"> elements on a page.
Each element has a "change" event listener.
When I click on the 2nd or 3th element, the label of the first is logged to the console.
What am I doing wrong?
Sandbox: https://jsfiddle.net/x01e4kgu/3/
HTML
<form action="">
<div class="input--upload">
<label for="attachment">Upload 1</label>
<input type="file" name="attachment[]" id="attachment">
</div>
<div class="input--upload">
<label for="attachment">Upload 2</label>
<input type="file" name="attachment[]" id="attachment">
</div>
<div class="input--upload">
<label for="attachment">Upload 3</label>
<input type="file" name="attachment[]" id="attachment">
</div>
</form>
JS
const fileInputs = document.querySelectorAll('.input--upload input')
fileInputs.forEach(input => {
input.addEventListener('change', function(e) {
const label = e.target.parentNode.querySelector('label')
console.log(label)
})
})
this way
ID must be UNIQUE (you don't need any one in your code)
all your label elements use the same for attribute pointing on the same id which all concern only the first element having this id (the others are ignored)
use onchange to use an arrow function,
it's allow you to bypass e.target...
because it's allows you to stay within the scope of your local variable(s) (actualy only inEl)
<form action="">
<div class="input--upload">
<label>
Upload 1
<input type="file" name="attachment[]" >
</label>
</div>
<div class="input--upload">
<label>
Upload 2
<input type="file" name="attachment[]" >
</label>
</div>
<div class="input--upload">
<label >
Upload 3
<input type="file" name="attachment[]" ">
</label>
</div>
</form>
const fileInputs = document.querySelectorAll('div.input--upload input')
fileInputs.forEach( inEl =>
{
inEl.onchange = e =>
{
let el_Lb = inEl.closest('label')
console.log( el_Lb.textContent )
}
})
This is happening because they all have the same ids. The for attribute in labels tells that which input they are for. All of the 3 labels are for one input with id attribute attachment and the first occurrence of that is triggered. So in order to get what you need, you will have to assign different ids for each input and change the for in the labels accordingly. Its a common thing to NOT use the same id for more than 1 html element. So the updated code would be:
<form action="">
<div class="input--upload">
<label for="attachment1">Upload 1</label>
<input type="file" name="attachment[]" id="attachment1">
</div>
<div class="input--upload">
<label for="attachment2">Upload 2</label>
<input type="file" name="attachment[]" id="attachment2">
</div>
<div class="input--upload">
<label for="attachment3">Upload 3</label>
<input type="file" name="attachment[]" id="attachment3">
</div>
</form>

How to hide updated state from the URL

I have created a form in using React and maintain state for storing form data. The form contains only text fields and radio buttons. There is a 'Proceed' button at the end whose onClick function goes like this :
handleClick(event){
console.log(this.state);
var userID = 1;
firebase.database().ref('registrations/'+userID).set(this.state);
}
There is another function to handle input change like so :
handleInputChange(event){
const target=event.target;
const name=target.name;
var value;
if((target.type==="radio"&&target.checked)||target.type!=="radio") value=target.value;
this.setState({
[name]:value
});
}
I want the console to log the updated state after filling the form and clicking the Proceed button. But when I fill the form and click the button, the state is briefly displayed on the console before disappearing (console goes back to how it was initially) and I see the form data in the URL instead. How do I stop the data being displayed in the URL and log the state data in the console?
I am relatively a beginner in React. So please bear with me if I don't know something very basic.
Thanks in advance.
Edit: Here's render(), and please note that I also updated the click handler.
render() {
return(
<div>
<div className="State">
<div className="Head">
State
</div>
<div className="StateField">
<input
name="state"
type="text"
onChange={this.handleInputChange} />
</div>
<hr />
</div>
<div className="Age">
<div className="Head">
Age
</div>
<div className="AgeField">
<input
name="age"
type="number"
onChange={this.handleInputChange} />
</div>
<hr />
</div>
<div className="Ethnicity">
<div className="Head">
Ethnicity
</div>
<div className="EthnicityField">
<input name="ethnicity" type="radio" value="Hispanic or Latino" onClick={this.handleInputChange} defaultChecked /> Hispanic or Latino
<input name="ethnicity" type="radio" value="Non-Hispanic or Non-Latino" onClick={this.handleInputChange} /> Non-Hispanic or Non-Latino
</div>
<hr />
</div>
<div className="Race">
<div className="Head">
Race
</div>
<div className="RaceField">
<input name="race" type="radio" value="American Indian" onClick={this.handleInputChange} defaultChecked /> American Indian
<input name="race" type="radio" value="Asian" onClick={this.handleInputChange}/> Asian
<input name="race" type="radio" value="Native Hawaiian or Other Pacific Islander" onClick={this.handleInputChange}/> Hawaiian or Other Pacific Islander
<input name="race" type="radio" value="Black or African American" onClick={this.handleInputChange}/> Black or African American
<input name="race" type="radio" value="White" onClick={this.handleInputChange}/> White
</div>
<hr />
</div>
<div className="Sex">
<div className="Head">
Sex
</div>
<div className="SexField">
<input name="sex" type="radio" value="Male" onClick={this.handleInputChange} defaultChecked /> Male
<input name="sex" type="radio" value="Female" onClick={this.handleInputChange}/> Female
</div>
<hr />
</div>
<div className="Height">
<div className="Head">
Height
</div>
<div className="HeightField">
<input name="height" type="number" placeholder="In inches" onChange={this.handleInputChange}/>
</div>
<hr />
</div>
<div className="Weight">
<div className="Head">
Weight
</div>
<div className="WeightField">
<input name="weight" type="number" placeholder="In pounds" onChange={this.handleInputChange}/>
</div>
<hr />
</div>
<div className="ProceedButton">
<button name="Proceed" onClick={this.handleClick} >Proceed</button>
</div>
</div>
);
And now I also realized that when I add the state to firebase realtime database, height, sex and weight fields are empty. Please point out if anything's wrong.
The default type of a button element is "submit". If you don't do anything to prevent it, clicking a button will submit a form that is an ancestor element of the button.
All the symptoms you describe are consistent with the button being inside a form that has not been shown in the post.
Try addding `type="button" to the button definition:
<button name="Proceed" type="button" onClick={this.handleClick} >Proceed</button>

Adding multiple <Fields /> in redux-form

I should have both question input and answer input in a <Field/>. Because of that redux-form docs tells me to use <Fields/>.
<Fields names={['question1', 'answer1']}
component={this.renderInputGroupField} />
<Fields names={['question2', 'answer2']}
component={this.renderInputGroupField} />
<Fields names={['question3', 'answer3']}
component={this.renderInputGroupField} />
rendering fields with this
renderInputGroupField(fields){
return(
<div className="form-group d-block">
<div className="form-group input-group">
<select className="form-select" >
<option>Multiple-Choice</option>
<option>Open-Ended</option>
</select>
<input {...fields.question1.input}
type="text"
className="form-input"
placeholder="Type your question..."/>
</div>
<div className="form-group">
<input {...fields.answer1.input}
type="text"
className="form-input"
placeholder="Comma-separated answer choices" />
</div>
</div>
);
}
To make renderInputGroupField work, I should add {...fields.answer1.input} into <input /> as above. Here is the problem. Names that are passed into fields are different and I can't find a way to change ...fields.answer1.input to ...fields.answer2.input dynamically.
I am not sure if I was able to explain it properly. Thanks for your help.
So, it seems you want to use the renderInputGroupField as a reusable component. Quickly testing, it looks like redux-form also sends back that list of names you originally gave it. You should be able to access those properties of fields that you listed in the names array using their index in that array, like below.
return(
<div className="form-group d-block">
<div className="form-group input-group">
<select className="form-select">
<option>Multiple-Choice</option>
<option>Open-Ended</option>
</select>
<input {...fields[fields.names[0]].input}
type="text"
className="form-input"
placeholder="Type your question..."/>
</div>
<div className="form-group">
<input {...fields[fields.names[1]].input}
type="text"
className="form-input"
placeholder="Comma-separated answer choices" />
</div>
</div>
);

jQuery - Uncheck other checkboxes if a specific checkbox is selected by user

I would like to uncheck all the checkboxes that are presently selected if a specific checkbox is selected by the user.
Example:
<div>
<label for="foo">
<input type="checkbox" name="meh" id="foo" checked> foo
</label>
</div>
<div>
<label for="bar">
<input type="checkbox" name="meh" id="bar" checked> bar
</label>
</div>
<div>
<label for="foobar">
<input type="checkbox" name="meh" id="foobar"> foobar
</label>
</div>
<div>
<label for="barfoo">
<input type="checkbox" name="meh" id="barfoo" checked> barfoo
</label>
</div>
<div>
<label for="omgwtfbbq">
<input type="checkbox" name="meh" id="omgwtfbbq"> omgwtfbbq
</label>
</div>
If the user selects "omgwtfbbq" checkbox, I would like all the other boxes that might be checked to be unchecked and have the "omgwtfbbq" be the only one checked.
for the label instead of id I think you need for
<div>
<label for="foo">
<input type="checkbox" name="foo" id="foo" checked /> foo
</label>
</div>
<div>
<label for="bar">
<input type="checkbox" name="bar" id="bar" checked /> bar
</label>
</div>
<div>
<label for="foobar">
<input type="checkbox" name="foobar" id="foobar" /> foobar
</label>
</div>
<div>
<label for="barfoo">
<input type="checkbox" name="barfoo" id="barfoo" checked /> barfoo
</label>
</div>
<div>
<label for="omgwtfbbq">
<input type="checkbox" name="omgwtfbbq" id="omgwtfbbq" /> omgwtfbbq
</label>
</div>
then
var $others = $('input[type="checkbox"][name="meh"]').not('#omgwtfbbq')
$('#omgwtfbbq').change(function () {
if (this.checked) {
$others.prop('checked', false)
}
});
$others.change(function () {
if (this.checked) {
$('#omgwtfbbq').prop('checked', false)
}
})
Demo: Fiddle
Note: I'll add a common class to all the input elements which has to be affected by omgwtfbbq and change var $others = $('#foo, #bar, #foobar, #barfoo') to var $others = $('.myclassoninput')
Live demo (click).
$('#omgwtfbbq').click(function() {
$('input:checkbox').not(this).attr('checked', false);
});
Also note that you're re-using id's. Id's should only be used once in a document.
If you choose not to give each checkbox a sequential IDs so that you can use an array, here's a solution:
Place all your controls in a div, with an ID "checkgroup".
Then the JavaScript function goes:
function checkone(d){
if (!d.checked) return; //if it's unchecked, then do nothing
var group=document.getElementById('checkgroup');
var os=group.getElementsByTagName('input');
for (var i=0;i<os.length;i++){
if (os[i].checked&&os[i]!=d) os[i].checked=false;
}
}
Now you can call this function in each checkbox
<div id="checkgroup">
<input id="abcd" onclick="checkone(this);">
<input id="xyz" onclick="checkone(this);">
...
</div>
Note how you don't even need to bother with the name, because the object passes in itself.

Categories