checkbox checked attribute not working in reactJS - reactjs

I have a radio button that I am rendering dynamically, But the checked property is not working.
Below is my code.
case "6":
var vchky = "";
var vchkn = "";
if(item.answer === "Yes"){
vchky= true;
vchkn = false;
}
else if(item.answer === "No"){
vchky= false;
vchkn = true;
}
console.log("vchky : ", vchky);
console.log("vchkn : ", vchkn);
return (
<li key={key}>
<div class="custom-selection ml-0 pl-0">
<p>{item.questionText}</p>
<span class="ml-10">
<input type="radio" class="custom-control-input" id="customRadio1-11" name="ques-1"
disabled="disabled"
checked = {vchky}
value = "Yes"
/>
<label class="custom-control-label" for="customRadio1-11">Yes</label>
</span> <span>
<input type="radio" class="custom-control-input" id="customRadio2-22" name="ques-1"
checked = {vchkn}
disabled="disabled"
value = "No"
/>
<label class="custom-control-label" for="customRadio2-22">No</label>
</span> </div>
</li>
);
break;
I debugged and checked that item.answer = "Yes" , but radiobutton for Yes is notting getting checked.
when I inspected the element, there too the checked attribute is present but not getting rendering.
check below screenshot.
What am I missing? thanks.

Related

Form name could not identify on Angular JS validation

I have a problem on my code. After submitting the form I have a function for validation checking but it seems that the condition on my function won't identify my form name. Here's my code:
Template form part:
<div class="modal-body">
<form name="form.addeditcoursewareModal">
<div class="row">
<div class="small-12 medium-12 large-12 columns">
<label class="stacked">
Question
<input name="question" type="text" class="form-field" placeholder="Question" ng-model="$ctrl.question.data.attributes.question" >
</label>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 large-6 columns">
<label class="stacked">
Question Type: {{ $ctrl.question.data.attributes.question_type }}
<select name="question_type" class="form-field" id="questionType" ng-model="$ctrl.question.data.attributes.question_type" ng-change="$ctrl.getSelectedQuestionType()">
<option value="single">Single</option>
<option value="multiple">Multiple</option>
<option value="true_or_false">True or False</option>
<option value="free_text">Free Text</option>
</select>
</label>
</div>
Validation part:
validateForm(){
this.validatingForm = true;
if (this.question.data.attributes.question_type === 'true_or_false'){
this.question.data.attributes.choices.data[0].attributes.choice = 'True';
this.question.data.attributes.choices.data[1].attributes.choice = 'False';
}
if (this.modalOptions.actionType == 'duplicate'){
this.question.data.attributes.choices.data.forEach((value) => {
delete value.id;
});
}
if (this.modalOptions.type === 'multiple'){
this.validateCheckbox();
}
console.log(this);
if (this.form.addeditcoursewareModal.$invalid || this.invalidMultiple) { // ERROR DETECTED
// Check for an invalid field
angular.forEach(this.form.addeditcoursewareModal.$error, (field) => {
angular.forEach(field, (errorField) => {
if (errorField.$name === 'dynamicForm'){
errorField.dynamicInput.$setTouched();
} else {
// Set field as touched to display invalid field message
if (errorField.$name === 'single') {
this.invalidRadio = true;
}
errorField.$setTouched();
}
});
});
this.validatingForm = false;
} else {
Here's the error I got:
angular.js:14791 TypeError: Cannot read property 'addeditcoursewareModal' of undefined
I already tried renaming my form but the error is the same.
It seems that you are using the controller as syntax. You would need to add $ctrl in front of form.addeditcoursewareModal.
<form name="$ctrl.form.addeditcoursewareModal">

While using "onChange" event on input type="checkbox", it is not working on single click and working on doubleclick

on using onChange event on input type="checkbox", it is not working on a single click and working on double-click
<input
type="checkbox"
name="category[]"
id={listItems.id}
ref="category"
value={listItems.id}
onChange={this.formValueChange}
defaultChecked={creatorFormData.category[index]}
/>
and on using onClick event, checkbox is not checked at all.
<input
type="checkbox"
name="category[]"
id={listItems.id}
ref="category"
value={listItems.id}
onClick={this.formValueChange}
defaultChecked={creatorFormData.category[index]}
/>
What can I use there?
Try this
<input type="checkbox" name="category[]" id={listItems.id} ref="category"
value={listItems.id} onChange={this.formValueChange.bind(this}
defaultChecked={creatorFormData.category[index]}/>
I am using an array of category,
` let category = [];
if(this.props.stateValues.creatorData != undefined && this.props.stateValues.creatorData != ''){
creatorFormData = this.props.stateValues.creatorData;
if(creatorFormData.categories != undefined && creatorFormData.categories != ''){
category = creatorFormData.categories;
} else if( creatorFormData.category == null) {
creatorFormData.category=[];
}
}
const categoryList = category.map((listItems,index) =>
<div className="col-12 col-md-3" key={listItems.id}>
<div className="selectmultibtn">
<input type="checkbox" name="category[]" id={listItems.id} ref="category" value={listItems.id} onChange={this.formValueChange} defaultChecked={creatorFormData.category[index]}/>
<label htmlFor={listItems.id}>{listItems.name}</label>
</div>
</div>
)`
You can easily do it using state value and checked attribute,
First set the default states,
this.state = {
checkboxStatuses:[],
}
Now the change handler will be,
formValueChange(index){
let checkboxStatuses = [...this.state.checkboxStatuses];
checkboxStatuses[index] = !checkboxStatuses[index]
this.setState({checkboxStatuses:checkboxStatuses})
}
While updating the category, you will have to update the state with the number of checkbox as equivalent to the number of categories,
let category = [];
if (this.props.stateValues.creatorData != undefined && this.props.stateValues.creatorData != '') {
creatorFormData = this.props.stateValues.creatorData;
this.setState({checkboxStatuses:[...creatorFormData].fill(false)});
if (creatorFormData.categories != undefined && creatorFormData.categories != '') {
category = creatorFormData.categories;
} else if (creatorFormData.category == null) {
creatorFormData.category = [];
}
}
And the component should be like,
const categoryList = category.map((listItems,index) =>
<div className="col-12 col-md-3" key={listItems.id}>
<div className="selectmultibtn">
<input type="checkbox" name="category[]" id={listItems.id} ref="category" value={listItems.id} onChange={(e)=>this.formValueChange(index)} defaultChecked={creatorFormData.category[index]}/>
<label htmlFor={listItems.id}>{listItems.name}</label>
</div>
</div>

How can I do event on text box in Angular?

I have a text box that show when I click on checkbox and I need to make an event on it that can make me bind it to object from DB
HTML:
<div ng-repeat="feture in featureEnumArray">
<input id="txtchkFet" type="checkbox" ng-model="feture.IsChecked" />
{{feture.DisplayText}}
<div ng-show="feture.IsChecked" >
<input class="form-control" type="text" ng-model="feture.Value" ng-change="getFeatureID(feture)" id="txtValue" placeholder="Type Feature Value" />
</div>
<div class="label label-danger" ng-show="feture.IsChecked && !feture.Value">
Type Value
</div>
</div>
And in Angular controller I did Like this :
$scope.getFeatureID = function (feture) {
if (feture.IsChecked) {
$scope.Planfeature = angular.copy(feture);
$scope.PlanFeatureTemp.FeatureID = $scope.Planfeature.ID;
$scope.PlanFeatureTemp.Value = $scope.Planfeature.Value;
$scope.Planfeature = [];
}
else {
var index = $scope.JAdminPlan.PlanFeatureValues.indexOf(feture);
$scope.JAdminPlan.PlanFeatureValues.splice(index, 1);
}
if (!$scope.$$phase) $scope.$apply();
};

setting a button disabled if there is some error for ng-repeat

I am generating some rows using ng-repeat, I am showing error for each row based on certain condition. Upto that my code is working fine. Now If I got any error I want to make a button disabled that is outside the scope of ng-repeat. How can I do that?
html code
<div ng-repeat="item in itemList">
<input type="text" ng-model="item.name" />
<input type="text" ng-model="item.phone" />
<div ng-if="validateRow(item)">Here is my error</div>
</div>
<button ng-disabled="I want to disabl this if there is some error for the above ng-repeat">Click </button>
js code
$scope.validateRow = function(item) {
return true or false based on item values
}
This example should be enough
<div ng-repeat="item in itemList">
<input type="text" ng-model="item.name" />
<input type="text" ng-model="item.phone" />
<div ng-show="validateRow(item)">Here is my error</div>
</div>
<button ng-disabled="isDisabled">Click </button>
function MyCtrl($scope) {
$scope.itemList = [{"name": "", "phone": "123"},{"name": "", "phone": "456"},{"name": "", "phone": "789"}];
$scope.disable= false;
$scope.validateRow = function(item) {
$scope.disable= false;
for(var c =0; c < $scope.itemList.length; c++){
if($scope.itemList[c].name != "abc"){
$scope.disable = true;
break;
}
}
return item.name != 'abc';
}
}
Update with the link working
http://jsfiddle.net/LXAt7/125/
In view
<button ng-disabled="disable">Click </button>
In controller,
$scope.disable= false;
$scope.validateRow = function(item) {
if(true based on item values) // if your going to return true
$scope.disable= true;
}
return true or false based on item values
}

Using a group of checkboxes in Angularjs

Im having the following problem:
i have a group of checkboxes and an indifferent check too, in the database if indifferent is checked then an empty array is saved.
I have 2 use cases:
1) if indifferent is checked, the rest is not, as soon as i check another checkbox indifferent is unchecked (This is actually working)
2) if i select all checkboxes (except indifferent), all should be unchecked and indifferent should be checked. (This is not working)
Here is an extract of my code
http://jsfiddle.net/ngbYW/
1) To test first use case:
Indifferent is checked, as soon as you click Married, indifferent is unchecked, if u click again on Married to uncheck, indifferent is checked.
2) click on Single, Relationship and Married to get them checked, then indifferent is checked AND the last one where u clicked is checked too!
Hope im clear enough.
What im doing wrong? Any help or suggestion will be appreciated.
Here is my code
HTML
<div ng-app="">
<div ng-controller="MyCntrl">
<label class="control-label">Family status</label>
<div class="controls">
<label class="checkbox inline" ng-repeat="item in familystatus"><input type="checkbox" ng-click="addToSearchedProfile(item.id,'familystatus')" ng-checked="isChecked(item,'familystatus')" >{{item.text}}</label>
<label class="checkbox inline"><input type="checkbox" value="" ng-click="addToSearchedProfile(undefined,'familystatus')" ng-checked="userSearchedProfile.familystatus.length=='0'">indifferent</label>
</div>
<label class="control-label">Sexuality</label>
<div class="controls">
<label class="checkbox inline" ng-repeat="item in sexuality"><input type="checkbox" ng-click="addToSearchedProfile(item.id,'sexuality')" ng-checked="isChecked(item,'sexuality')" >{{item.text}}</label>
<label class="checkbox inline"><input type="checkbox" value="" ng-click="addToSearchedProfile(undefined,'sexuality')" ng-checked="userSearchedProfile.sexuality.length=='0'">indifferent</label>
</div>
</div>
</div>
CONTROLLER
function MyCntrl($scope) {
$scope.familystatus = [{id:1,text:'Heterosexual'},{id:2,text:'Bisexual'},{id:3,text:'Homosexual'}];
$scope.sexuality = [{id:1,text:'Single'},{id:2,text:'Relationship'},{id:3,text:'Married'}];
$scope.userSearchedProfile = {
familystatus : [1],
sexuality : []
};
$scope.isChecked = function(item, type) {
return $scope.userSearchedProfile[type].indexOf(item.id)!==-1;
};
$scope.addToSearchedProfile = function(id, item) {
if (angular.isUndefined(id)) {
$scope.userSearchedProfile[item].length=0;
return;
}
if ($scope.userSearchedProfile[item].indexOf(id) === -1) {
$scope.userSearchedProfile[item].push(id);
} else {
$scope.userSearchedProfile[item].splice($scope.userSearchedProfile[item].indexOf(id), 1);
}
if ($scope[item].length === $scope.userSearchedProfile[item].length){
$scope.userSearchedProfile[item].length=0;
}
};
}
inter-restricting / counter acting form elements are very confusing
to me too.
I usually attack this kind of problem by defining a view model
which represents the form state and let javascript code to handle
the coordination rather than reacting to the indivisual events.
here is the simplified example: http://jsfiddle.net/4TBFn/
in template:
<label class="checkbox inline" ng-repeat="item in sexuality">
<input type="checkbox" ng-model="item.selected"/>{{item.text}}
</label>
<label class="checkbox inline">
<input type="checkbox" ng-model="indifferent"/>indifferent
</label>
in controller:
$scope.$watch('indifferent', function(v) {
if (!v) return;
for ( var i = 0; i < $scope.sexuality.length; ++i ) {
$scope.sexuality[ i ].selected = false;
}
});
$scope.$watch('sexuality', function(arr) {
var selected = arr.reduce(function(s, c) { return s + (c.selected ? 1 : 0); }, 0);
if ( selected === arr.length ) {
$scope.indifferent = true;
} else if ( selected > 0 ) {
$scope.indifferent = false;
}
}, true );

Resources