Binding an Angular boolean to a Bootstrap Radio Button Group - angularjs

I have a model like this:
$scope.user = { is_active: true }
I'm currently displaying that in my template like this:
<form class="form-horizontal">
<!-- ... -->
<div class="form-group">
<label class="col-sm-2 control-label">Is Active</label>
<div class="btn-group col-sm-5" data-toggle="buttons">
<label class="btn btn-default">
<input type="radio" ng-selected="{{ user.is_active }}" name="is_active">
Active
</label>
<label class="btn btn-default">
<input type="radio" ng-selected="{{ user.is_active }}" name="is_active">
Inactive
</label>
</div>
</form>
This looks like this in practice:
How can I bind the value of {{ user.is_active }} to this button group in Bootstrap? I'd like the correct button to be depressed based on what's selected in the model.

You may also want to look at the buttons in Angular's bootstrap ui- these are designed to work cleanly with Angular and so they use ngModel directly.
If you go this route you'll need to use ngModel by adding it to your buttons like this:
<input type="radio" ng-model="user.is_active" name="is_active">
Sticking with the default Twitter Bootstrap- it uses the class active to define which label is active. To set this you can use ngClass. For instance on the label you want active when is_active is true you'll want this:
ng-class="{active:user.is_active==true}
And to control the value you'll need to use 'ngClick' on the label to toggle the value.
<label class="btn btn-default" ng-class="{active:user.is_active==true}" ng-click="setActive(true)">
<input type="radio">
Active
</label>
<label class="btn btn-default" ng-class="{active:user.is_active==false}" ng-click="setActive(false)">
<input type="radio">
Inactive
</label>
And the new function:
$scope.setActive = function(val) {
$scope.user.is_active= val;
};
demo fiddle

Related

Angularjs form scope bug

I have a Angularjs form with a list with names.
When I click on a name the form will change with here profile.
When I change one input and don't save it and I click on a other profile every thing change except the one input that has changed.
<form class="form-horizontal bordered-row" >
<div class="form-group">
<label class="col-sm-4 control-label">Naam</label>
<div class="col-sm-6">
<input type="text" class="form-control" id="" value="{{gegevens.naam | capitalize}}">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">Categorie</label>
<div class="col-sm-6">
<select class="form-control">
<option ng-repeat="x in producten_categorie" value="{{x.value}}" ng-selected="gegevens.categorie == x.value">{{x.name}}</option>
</select>
</div>
</div>
<div class="form-group pad25L">
<button class="btn btn-info" ng-click="productAlgemeen_update(gegevens.naam);">Save</button>
</div>
</form>
And the change scope:
$scope.productGegevens = function(product){
$http.post("php/producten-locatie.php", {'id':product.id}).then(function(response){
$scope.producten_locatie = response.data.records[0];
$scope.gegevens = {
id:product.id,
naam:product.naam,
categorie:product.categorie,
straatnaam:$scope.producten_locatie.straatnaam,
huisnummer:$scope.producten_locatie.huisnummer,
postcode:$scope.producten_locatie.postcode,
stadsnaam:$scope.producten_locatie.stadsnaam
};
});
}
Please note that input data needs to bind with ng-model whereas you are entering your input with value tag. it means the value is rendered in html not in model, so when you click on other profile UI can not detect the change. Please use ng-model for input value not value tag of input box.

ng-required not working as expected if parent div is hidden conditionally

In my code I am using ng-show and ng-required in combination. But, ng-required is not working as expected even when the respective $scope variable value is set to false. Please find the code below
<div role="form" name="selectQuestionsForm" id="selectQuestionsForm" ng-form>
<div class="form-group col-sm-12">
<label class="control-label question-answer-label"
for="firstQuestionSelect">First question</label>
<div>
<select class="form-control nopadding">
<option value="">-- Select --</option>
</select>
</div>
<div ng-show="showCustomQuestion.first" >
<input type="text" class="form-control" ng-model="questionsText.first" ng-required="showCustomQuestion.first"
id="firstQuestionInput" name="firstQuestionInput" validation-min-length="3" validation-max-length="100" />
</div>
<label class="control-label question-answer-label"
for="firstAnswerInput">First answer</label>
<div style="padding-bottom: 15px;">
<input type="text" class="form-control" ng-model="answersText.first"
id="firstAnswerInput" validation-min-length="3" validation-field-required="true" validation-max-length="100" required/>
</div>
</div>
</div>
<div id="securityActionBtnContainer" class="visible-md visible-sm visible-lg">
<button id="saveBtn" type="button" ng-disabled="selectQuestionsForm.$invalid" class="btn btn-default btn-xs pull-right" ng-click="saveQuestion(selectQuestionsForm.$valid)">Save</button>
<button id="cancelBtn" type="button" class="btn btn-xs btn-default pull-right" style="margin-right: 10px;" ng-click="redirect['cancel']()">Cancel</button>
</div>
The select element have a logic to display the option and it is working fine. When we select the option 'Write my own question', the hidden input is displayed. If user choose any other question the custom question input is hidden and not part of the form element. But ng-required is still getting applied though the value is set to the false and respective form doesn't validate.
Please let me know what I am missing to make it work. Thanks in advance for your help.
Use ng-if instead of ng-show. Items hidden using ngShow or ngHide still exist in the DOM and will be processed by angular. It's just not visible to a user.

Working with html forms in Ionic

<form ng-submit="update()">
<label class="item item-input item-floatinglabel">
<input type="text" ng-model="word">
</label>
<button class="btn btn-primary"ng-click="OnClick()">Get Words</button>
</form>
This is the current form I have. console logging "word" currently returns the word that's input however for some reason when I attach an <ion-scroll> </ion-scroll> around the form it only returns as "undefined". Is there a work around for this?
You need to create an object in controller and use its properties as models like below.
<label class="item item-input item-floatinglabel">
<input type="text" ng-model="content.word">
</label>
<button class="btn btn-primary" type="submit">Get Words</button>
</form>
In your controller you can get the value like
$scope.content.word
Check the plunker
Hope it helps.

How to select button group item based on true value of another element?

I have a custom directive toggle-switch
<toggle-switch
id="isModule"
ng-model="isModule"
type="checkbox"
switch-active="{{ isActive }}"
switch-on-label="Module"
switch-off-label="Segment"
switch-on="default"
switch-off="default"
switch-animate="true"></toggle-switch>
if isModule is true, then I need my button group to select "Video"
<div class="form-group">
<label class="col-sm-2 control-label">Media Type</label>
<div class="col-sm-10">
<div class="btn-group">
<label class="btn btn-default" ng-model="media.mediaType" btn-radio="0" ng-disabled="(!isModule)">Audio</label>
<label class="btn btn-default" ng-model="media.mediaType" btn-radio="1" >Video</label>
<label class="btn btn-default" ng-model="media.mediaType" btn-radio="2" ng-disabled="(!isModule)">Text</label>
</div>
</div>
</div>
What is the correct way of achieving this? I'm already able to disable the other two items (as you can see), but I don't know how to select the middle one.
well for now I put a watch in the controller. Not sure I like this, but it'll do until a better solution presents it's self.
$scope.$watch('isModule', function (oldValue, newValue) {
if ((oldValue != null) && newValue) {
$scope.media.mediaType = 1;
}
});

Angular.js What is the best way to determine which button caused submit?

I have two buttons on a simple login form in a dropdown on a header bar that is outside of the view/content part of my single page app. There are two buttons on the form:
EDIT: both buttons need to submit the form, but I have two different outcomes; one does new member sign-up, the other login existing members. I do not want to handle this on multiple partials.
My Website
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">
Home
</li>
<li class="divider-vertical"></li>
<li>
<div class="btn-group btn-group-xs navbar-btn btn-pad">
NL
FR
EN
</div>
</li>
<li class="divider-vertical"></li>
<!-- Begin Login Section -->
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Signup/Login <strong class="caret"></strong></a>
<div class="dropdown-menu">
<div class="accountForm">
<!--form action="#" method="post" role="form"-->
<form name="loginForm" ng-submit="login()" ng-controller="homeController">
<div class="form-group">
<label class="control-label" for="username">Username</label>
<input type="text" ng-model="credentials.username" name="username" class="form-control input-sm" placeholder="username" required/>
</div>
<div class="form-group">
<label class="control-label" for="password">Password</label>
<input type="password" ng-model="credentials.password" name="password" class="form-control input-sm" placeholder="password" required/>
</div>
<div class="form-group">
<label class="control-label" for="remember">
<input type="checkbox" class"form-control" name="remember" value="1"/>Remember me</label>
</div>
<div class="form-group btn-group-justified">
<div class="btn-group">
<button button-id="join" type="submit" class="btn btn-default">New? Join us</button>
<input type="hidden" class="btn" />
</div>
<div class="btn-group inline">
<input type="hidden" class="btn" />
<button button-id="login" type="submit" class="btn btn-primary active">Log in</button>
</div>
</div>
</form>
</div>
</div>
</li>
<!-- End Login Section -->
</ul>
</div>
<!--/.nav-collapse -->
</div>
</div>
<div id="page" ng-view>
The first button is intended to send the user to the login process (if they are already registered) and the second button is for new users to register.
The problem I have is that if I use the <form ng-submit="myFunction()"> directive, I haven't yet found a way to determine the button that was pressed.
I can alternatively create my own directive, where I can determine the button that was pressed, but this seems to be a lot of coding effort by comparison, and is this really the Angular way?
app.directive('buttonId', function() {
return {
restrict: "A",
link: function(scope, element, attributes) {
element.bind("click", function(){
// when attributes.buttonId = 'join'
//call the create script
// when attributes.buttonId = 'login'
//call the authenticate script
});
}
}
});
So my question is simply using ng-submit="myfunction()"can i determine which button was pressed?
I know I am answering my own question, but this seems to be the "correct" way to do this:
<form name="loginForm" ng-submit="login()" ng-controller="homeController">
<div class="form-group btn-group-justified">
<div class="btn-group">
<button type="submit" class="btn btn-default" button-id="join">New?Joinus</button>
<input type="hidden" class="btn" />
</div>
<div class="btn-group inline">
<input type="hidden" class="btn" />
<button type="submit" class="btn btn-primary active" button-id="login">Log in</button>
</div>
</div>
</form≥
The above is the section of the form that I'm interested in. Note that both buttons have type="submit"and not type="button" . This is important for two reasons:
1) you can use the standard HTML5 form validation options when you click the buttons
2) it forces the ng-submithandler.
First the controller
app.controller('homeController', function($scope){
$scope.buttons = { chosen: "" };
$scope.login = function (){
// can get the button that was clicked as it is now added to the scope
// by the directive
alert($scope.buttons.chosen);
};
});
... and now the directive.
Next I handle the click on either button using a directive. This has the purpose of allowing me to identify the button, and pass it to the $scope. This was actually the main purpose of the excercise, but I realised that I could now bind this to anything where I suspected a click and pass some data to the scope.
app.directive('buttonId', function() {
return {
restrict: "A",
link: function(scope, element, attributes) {
element.bind("click", function(){
// able to get the name of the button and pass it to the $scope
// this is executed on every click
scope.buttons.chosen = attributes.buttonId;
// alert(attributes.buttonId + scope.buttons.chosen);
});
}
}
});
I am not sure if i have understood your problem correct but you can differential based on
Calling different function for each ng-submit such as ng-submit="myFunction1()" and ng-submit="myFunction2()"
You can also do the same passing in context using a parameter ng-submit="myFunction(from)"
You can also pass in special $event object as parameter ng-submit="myFunction($event)". This object contains the target information.
You can get a handle to the $event in your ng-click, and get its target, and then get its id, but I wouldn't recommend that it is not the angular way of doing things:
<input type="submit" id="test" data-ng-click="showAlert($event)">
Click Me
</button>
$scope.showAlert = function(event){
alert(event.target.id);
}
Another way is to set property dirty for this button and then to check which of the buttons is dirty.
For example if you have a form named "myForm" you can write something like this:
<form name="myForm" id="myForm" ng-submit="save()" ng-model="myForm" novalidate>
<input type="submit" name="save" ng-model="btnSave" ng-click="(frmForm.save.$setDirty())" />
<input type="submit" name="saveOut" ng-model="btnSaveOut" ng-click="(frmForm.saveOut.$setDirty())" />
</form>
In Javascript file you can handle it by:
if ($scope.btnSave.$dirty){
alert("First was clicked)}
else{
alert("First was clicked)}
}

Resources