how in reactjs checkboxes with same name keep values as array - reactjs

do get to point quick
<input type="checkbox" name="name1[]" value="1" />
<input type="checkbox" name="name1[]" value="2" />
note the brackets in name [] - in classic html, posting form with this, the POST body would contain this
{name1:[1,2]}
now building a reactjs, inputs have name, ref, but can i use the brackets there too? does not seem to work... having predefined objects, trough .map() function i output the checkboxes, but how to keep their values qrouped with the shortest code?
actually, its supersimple, if i would write it as
<select ref="name1" name="name1" multiple="true" ....
how simplest way do this with checkboxes, with select i have result in this.refs["name1"], without any overhead hassle, how to do it with checkboxes pls? to avoid any crazy long coding?

The way is to wrap checkbox in a parent div & then access them through its ref as follow:
<div
ref={ref => this.inputs = ref}
>
<input type="checkbox" name="name1" value="1" />
<input type="checkbox" name="name2" value="2" />
<input type="checkbox" name="name3" value="3" />
</div>
const array = this.inputs.children
const name1 = array[0]
const name2 = array[1]
const name3 = array[2]
I hope it help you.

Related

React ignores value attribute of input field

I have a react sign-up form. I want to set up an input (checkbox) that holds the value as some text - e.g:
<form onSubmit={this.validateStepTwo} id="registerForm">
<label htmlFor="short_bio">Tell the users a bit about yourself:</label>
<input type="textarea" name="short_bio" className="textarea-small"/>
<label htmlFor="bio_info">Tell the users who you are</label>
<input type="textarea" name="bio_info" className="textarea-large"/>
<label htmlFor="bio_exp">Tell the users what you did</label>
<input type="textarea" name="bio_exp" className="textarea-large"/>
<input type="checkbox" name="instructor" value="I want to be an instructor" />
<input type="submit" value="Register" className="submit"></input>
{this.state.errors !== null ? (
<h1 className="error">{this.state.errors}</h1>
) : ('')}
</form>
Where
<input type="checkbox" name="instructor" value="I want to be an instructor" />
should have a value of "I want to be an instructor" but it doesnt have anything.
I tried doing it like this:
<input ...>I want to be an instructor</input>
but that threw another error.
Is this a react thing or am i missing something in my code? Ive been on the computer for 13 hours so i wouldnt be surprised if i made a dumb mistake.
Checkbox input value is the one sent in the request and not the text that appears afterwards.
If you want it to be the text then do something like this
<input type="checkbox" name="instructor" value="instructor"> I want to be an instructor

How to get the selected value from a radio button group in React where there are multiple groups?

I have a group of radio buttons like this :
return committees.map((committee) => {
return (
<div>
<input type="radio" name={committee.shortName}
ref={`${committee.shortName}Preference`} defaultChecked="true" value="1" />
<label>1</label>
<input type="radio" name={committee.shortName}
ref={`${committee.shortName}Preference`} defaultChecked="true" value="2" />
<label>1</label>
<input type="radio" name={committee.shortName}
ref={`${committee.shortName}Preference`} defaultChecked="true" value="3" />
<label>1</label>
<input type="radio" name={committee.shortName}
ref={`${committee.shortName}Preference`} defaultChecked="true" value="4" />
<label>1</label>
<input type="radio" name={committee.shortName}
ref={`${committee.shortName}Preference`} defaultChecked="true" value="5" />
<label>1</label>
</div>
);
});
There are multiple groups like this in this page. React ref does not give me the right value. It gives the value as 5 (The last value) for all the groups. If I use getElementsByName it give me 5 elements (5 radio button fields). I need to get the selected value of the group. How can I do this?
You could keep an inner state with a map between commitee.shortName => selectedValue (updating the state onChange), and then add a:
checked={this.state.selectedValues[committee.shortName] === radioValue}
Here is a fiddle: Radio Buttons Example
There is also a library that sugars it off for you:
react-radio-group
If you are using React I don't think it's a correct way to use it jQuery-style, using ref - React works nice as a final-state-machine and you should store your components data in state and do not request it accessing component by ref.
So you should add something like onChange= ()=>this.setState({selectedValue: 'yourValue'}) to pass correctly changed value to the state, and if you want to use "controlled" input value={this.state.selectedValue} or in the case with radio buttons checked={this.state.selectedValue === 'yourValue'}.
But you do not really need use radio checks and groups with react, you could do something like this:
committies.map(committie => (
<button className={this.state.selectedValue === committie.id ? 'selected' : ''}
onClick={() => this.setState({selectedValue: committie.id})}>
{committee.shortName}
</button>
))

Making a directive that can group radio options

I'm trying to create a input radio element as angular directive with 3 possible options; none, single and double.
I also want the user to be able to select only from none to single, from single to double and from double to none.
In this case my element will looks like this :
<tribox id="{{id}}" name="{{name}}" type="{{type}}" />
Also sometimes I need to be able to group bunch of them together in which case I would add group attribute into it like so :
<tribox id="{{id}}" name="{{name}}" type="{{type}}" group="cheese" />
Tribox gets generated from the following template:
<div class="tribox">
<input id="{{id}}-none" type="radio" name="{{(group)?group:name}}" ng-model="val" value="0" />
<label for="{{id}}-none" ng-show="val == 2" class="none">{{name}}</label>
<input id="{{id}}-single" type="radio" name="{{(group)?group:name}}" ng-model="val" value="1" />
<label for="{{id}}-single" ng-show="!val || val==0" class="single">{{name}}</label>
<input id="{{id}}-double" type="radio" name="{{(group)?group:name}}" ng-model="val" value="2" />
<label for="{{id}}-double" ng-show="val == 1" class="double">{{name}}</label>
</div>
Question
The problem I am having is that when I choose to group bunch of elements together my program is not really grouping it. is this because of the tribox element that I'm using? or is it because of the ng-show attributes that I have used! what's the clean logical workaround !
Click here for example

Multiple checkboxes, comma separated get request?

I have this form with get set as method.
<form method="get" action="index.html">
<input type="checkbox" name="item" value="1" />
<input type="checkbox" name="item" value="2" />
<input type="submit" />
</form>
When I submit, i end up with the url
index.html?item=1&item=2
I wonder if it is possible to make a more neat format like comma-seperation, for instance
index.html?item=1,2
I have been searching for a while, but I cannot find how to obtain this. Do I really need to implement this with javascript?
function submitForm(){
var name=document.getElementsByName('item[]');
var str="";
for(i=0;i<(name.length);i++){
if(name[i].checked){
str+=name[i].value+",";
}
}
if(str.length>0){str=str.substring(0,str.length-1)};// remove the last comma
var url="actionpage.html?item="+str;
document.getElementById('formid').action=url;
document.getElementById('formid').submit();
}
Please rename the checkbox to item[], this will create an array. Then call this function in your button click event.

Angularjs dynamic binding for ng-model

Here is the Plunker that describe my problem with dynamic binding in Angularjs.
http://plnkr.co/edit/fGgtOZ5IrJVo9QasQALc?p=preview
Before using Angularjs, I am used to using the input name/value like the following to generate desirable data structure for back end processing
<input type="text" name="computer[details][][purchaseddate]" />
<input type="text" name="computer[details][][warrantyperiod]" />
With Angularjs ng-model, it is possible to bind a complex data structure like
<input type="text" ng-model="computer.parts[0].name" />
However it does not work with dynamic property like the following:
<input type="text" ng-model="computer.details[0].name" />
Angular keeps telling me that I am trying to set property 'name' to undefined 'details[0]', I am aware of that but are there any ways to get the same behavior with previous input's name/value where I can specify dynamic property without having to declare it first?
Thank you,
Binding to attributes that don't exist yet works. You can bind to a.b.c even if $scope.a does not exists. Angular creates the objects and attributes on-the-fly.
<input type="text" ng-model="a.b.c" />
But you are trying to bind to an array element that does not exist yet:
<input type="text" ng-model="a.b[0].c" />
Angular would have instantiate the array and then push an empty object in it and then assign it's name. Apparently this does not work.
I ran into the same situation and tried everything.
This is how I was able to get dynamic values inside 2 deep ng-repeat:
JS:
$scope.newContact = {
name: [],
phone: [],
email: [],
notes: []
};
$scope.saveNewContact = function (idx) {
console.log($scope.newContact.name[idx]);
};
HTML:
<input type="text" ng-model="newContact.name[$index]" />
<input type="text" ng-model="newContact.phone[$index]" />
<input type="text" ng-model="newContact.email[$index]" />
<input type="text" ng-model="newContact.notes[$index]" />
<button ng-click="saveNewContact($index)">Save</button>

Resources