I'm new to AngularJS and am trying to hide a div when a button is clicked. What I'm doing works fine until I put the button in the div I'm trying to hide (the button is using a different controller). The button works as expected when taken out of the controller so I assume it's an issue with scope. Any help would be appreciated.
<form action="" name="signUpForm" class="heroForm" >
<div ng-hide="signUpB">
<span id="signUpFormA">
<input required type="email" />
<input required type="password"/>
<span ng-controller="checkEmailCtrl">
<input type="button" ng-click="signUpB=true">
</span>
</span>
</div>
<div ng-show="signUpB">
<span id="signUpFormB">
<input required type="text">
<input required type="text">
<input type="submit">
<span>
</div>
</form>
Yes, you are setting signUpB=true on the scope of checkEmailCtrl. You can do something like this:
<form action="" name="signUpForm" class="heroForm" ng-init="signUpB={value:false}">
<div ng-hide="signUpB.value">
<span id="signUpFormA">
<input required type="email" />
<input required type="password"/>
<span ng-controller="checkEmailCtrl">
<input type="button" ng-click="signUpB.value=true">
</span>
</span>
</div>
<div ng-show="signUpB.value">
<span id="signUpFormB">
<input required type="text">
<input required type="text">
<input type="submit">
<span>
</div>
</form>
By wrapping the signUpB in an object, the signUpB.value=true statement will look up the signUpB object in the outer scope, and set it's value property to true, no modification will be made on checkEmailCtrl's scope.
ng-controller creates its own scope. So, within ng-click="signUpB=true", you are modifying the signUpB in this new scope.
You can fix this by using a object to hold the state of signUpB. Basically, replace all signUpB occurrences with state.signUpB. And, define state object in your outer controller's scope.
$scope.state = {signUpB: false // defaults to false}
Even better approach would be to use controllerAs syntax. Let's say your outer controller is OuterController. You define it as
ng-controller="OuterController as outerCtrl"
and,
replace all occurrences of signUpB with outerCtrl.signUpB to ensure you are using/modifying outerCtrl's model.
Related
When I click the button it works, but when I try to add "quantity" and click the arrows to do it - it immediately runs the function. How do I avoid it?
<form ng-click="ctrl.launch(quantity, someOtherInfo)">
<div class="quantity">
<input type="number" ng-model="quant" ng-init="quant=1" min="1" step="1">
</div>
<button class="hit_it_button" >LAUNCH!</button>
</form>
I tried to place ng-click right in the button, but it just doesn't work at all.
You should change ng-click to ng-submit.
Here is helpful link
your script should look like this I think:
<form>
<div class="quantity">
<input type="number" ng-model="quantity" ng-init="quant=1" min="1" step="1">
</div>
<button class="hit_it_button" ng-click="ctrl.launch(quantity)>LAUNCH!</button></form>
ngClick does not submit the form.You should change ng-click to ng-submit.
<form ng-submit="ctrl.launch(quantity, someOtherInfo)">
<div class="quantity">
<input type="number" ng-model="quant" ng-init="quant=1" min="1" step="1">
</div>
<button class="hit_it_button" >LAUNCH!</button>
</form>
I've this basic form implemented using AngularJS and Bootstrap:
http://jsfiddle.net/dennismadsen/0stwd03k/
HTML
<div ng-controller="MyCtrl">
<form class="well" name="formTest" ng-submit="save()">
<div class="form-group">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" required />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
JavaScript
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.save = function () {
};
}
Result
The Name input field is required. When I click the submit button, I need the input field to have a red border if it's invalid. How can this be done?
Alternatively, if I unfocus the input field and it's still not valid, it would be great that the red corder is shown on that time, instead of waiting for the form submit.
Twitter Bootstrap has an has-error class, so I would use this in conjunction with ng-class for the form group, then a label with the label and label-danger classes for good measure:
<div class="form-group" ng-class="{'has-error': errors.Name }">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" required />
<span class="label label-danger" ng-if="errors.Name">{{errors.Name}}</span>
</div>
Then in your controller, have an errors object, and set the Name property of this to a string when the name is invalid.
The first thing you were missing was adding ng-model='name' to input field, then only will the form become invalid once you click submit, otherwise the form will always be valid since it considers that there is no field present.
Then I'd add the submitted class on the submit click button, then put the border css like .submitted would be the parent and .ng-invalid would be the child so we can put the style on .submitted .ng-invalid
HTML
<div ng-controller="MyCtrl">
<form class="well" name="formTest" ng-class="{'submitted': submitted}" ng-submit="save()" >
<div class="form-group">
<label for="name">Name*</label>
<input type="name" class="form-control" id="name" placeholder="Enter name" ng-model="name" required />
</div>{{submitted}}
<button type="submit" class="btn btn-default" ng-click="submitted= true;">Submit</button>
</form>
</div>
CSS
.submitted .ng-invalid{
border: 1px solid red;
}
Working Fiddle
Hope this could help you, Thanks.
Basically you need angular to take over validation, so add novalidate to form. Also add ng-class to input field to determine wether to add error css
<form name="myForm" novalidate ng-submit="test()">
<input type="text" name="user" ng-model="user" required ng-class="myForm.user.$invalid && myForm.user.$dirty ? 'error' : ''">
<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
<span ng-show="myForm.user.$error.required">Username is required. </span>
</span>
<p>
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
</p>
</form>
Good luck..
I can not get Angular.js required or ng-required to work. I want it to where if the user hits ok, they have to have some text in the textbox.
<div class="modal-body">
<p>Your change will be logged. Please provide a ticket number or comment for reference</p>
<div class="row">
<div class="span4">
<textarea type="text" class="form-control"
ng-model="commentBox.text"
ng-required="commentBox.text">
</textarea>
</div>
</div>
</div>
Scratching my head.....
two things:
make sure that value you are passing to ng-required is boolean (to be technically correct, it should evaluate to boolean)
<textarea type="text" class="form-control"
ng-model="commentBox.text"
ng-required="commentBox.textRequired">
</textarea>
//somewhere in your controller
$scope.commentBox.textRequired = true
you would need form.$invalid on your button
<button type="submit" ng-disabled="formname.$invalid" ng-click="onsubmit()"></button>
so to complete it
<ng-form name="exampleForm">
<textarea type="text" ng-model="commentBox.text" ng-required="true"></textarea>
<button ng-disabled="exampleForm.$invalid" ng-click="onsubmit()"></button>
</ng-form>
also without adding another prop, you could set it to
ng-required="!!commentBox.text"
I am working on a QA app where i need to add multiple answers to a question as per requirement dynamically. for this in my form I have a question field , an answer field and a Boolean correct field to tell if the answer choice is correct or not. I have given a button add another answer which create a new answer field when clicked.I want to give ng-model name dynamically so that I can easily retrieve the value of ng-model.
For this I have created a controller which is like
app.controller('questionsCtrl', function ($scope) {
$scope.question={};
$scope.question.answers=[];
$scope.answer_choices=[];
var choice=1;
$scope.addAnswerField=function(){
$scope.answer_choices.push(choice);
choice++;
}
$scope.addAnswerChoice=function(){
$scope.question.answers.push({});
}
});
My HTML code is:
<div class="container">
<form ng-submit="createQuestion()">
<textarea class="form-control" ng-model='question.question_text'></textarea>
<textarea class="form-control" ng-model="question.answer_choice_1"></textarea>
<label class="checkbox-inline">
<input type="radio" name="correct" ng-model="question.correct_1" />
Correct
</label>
<div ng-repeat="choice in answer_choices">
<textarea class="form-control" ng-model="question.answers.$index[answer]">
</textarea>
<label class="checkbox-inline">
<input type="radio" name="correct" ng-model = "question.answers.$index[correct]" />
</label>
</div>
<button class='btn btn-primary' type="submit">Submit</button>
</form>
<button class="btn btn-default" ng-click="addAnswerChoice()">Add Answer</button>
</div>
I want to do something like when i add a new answer choice a new empty object is pushed in the question.answers array and this objects first key answer hold the value of question field and second key ` like
question.answers=[
{'answer':'',correct:''},
{'answer':'',correct:''},
{'answer':'',correct:''},
{'answer':'',correct:''},
]
Suggest me how can i do this . There is only one error that using $index i am unable to assign value to the array object at the same index in question.answers array.
Or if there is any other better way suggest me.
Help will be appreciated.
You are making just a small mistake. Correct your syntaxes and it will work fine
replace your ng-repeat div with this code
<div ng-repeat="choice in choices">
<label class="checkbox-inline"> Choice</label>
<textarea class="form-control" ng-model="question.answers[$index].answer">
</textarea>
<label class="checkbox-inline">
<input type="radio" name="correct" ng-model="question.answers[$index].correct_answer" value="1" />
Correct
</label>
</div>
And assign values to the radio buttons or these will not show in your object.
I have a $rootScope variable:
$rootScope.register_data = {};
I have a view which contains a form:
<form name="register_data">
<div class="popup signup">
<div class="social">
<a ng-controller="FacebookCtrl" ng-click="login()" href="javascript:void(0)" class="facebook fb-login-button">Sign up with Facebook</a>
<div class="clear"></div>
</div>
<div class="userinfo">
<div class="left"><input type="text" ng-model="register_data.firstname" placeholder="First Name" tabindex="1" required></div>
<div class="right"><input type="text" ng-model="register_data.email" placeholder="Email Address" tabindex="4" required></div>
<div class="left"><input type="text" ng-model="register_data.lastname" placeholder="Last Name" tabindex="2" required></div>
<div class="right optional"><div class="tip">optional</div><input type="text" ng-model="register_data.dob" tabindex="5" placeholder="DoB (dd/mm/yyyy)"></div>
<div class="left"><input type="text" ng-model="register_data.phone" placeholder="Phone Number" tabindex="3" required></div>
<div class="right password"> <input type="password" ng-model="register_data.password" placeholder="Password" tabindex="6" required></div>
<div class="clear"></div>
</div>
<div class="control">
<span class="terms">I agree to the terms & conditions</span>
Sign up
</div>
</div>
</form>
The form has a name register_data and each field is bound to that via ng-model. It seems to overwrite my $rootScope.register_data variable as when I update that none of the form controls update. Though if I remove the form name then it works. However i need the form name to do proper form validation.
Anyone know how I can bind the form controls to a scope object but also keep the form validation?
Change the form name to be something else other than the name used as model, since the form controller will be published into related scope, under this name.