I'm using Angular 1.6.2 for a personal project for learning the framework, and I couldn't figure out a way to solve this problem:
I have a variable that gets updated often(like once a second or less) and I have two input text fields in the view. I want the variable to update the input(and another variable) only when it is focused.
For sake of better UX I now updated the view a little bit, so now every Text-Input has a Radio-Button alongside(since sometimes the user might want the value to be updated but he'll need to click outside the field).
Inside the controller:
$interval(function () {
// This gets the updated value from an external source/code.
$scope.updatingValue = updatingValueFunc();
}, 1000);
$scope.fields = [
{ first: 12323, second: 1430,}
];
Html:
<div class="field-wrap">
<input type="radio" name="current-bind" value="answer.end">
<input type="number" ng-model="answer.second">
</div>
<div class="field-wrap">
<input type="radio" name="current-bind" value="answer.start">
<input type="number" ng-model="fields.first">
</div>
Angular has a ng-focus hook you can use to call your update function.
<input type="radio" name="current-bind" value="answer.end" ng-focus="updateValue()"/>
and in your js you can create a function to match it
$scope.updateValue = function(){
$scope.updatingValue = updatingValueFunc();
}
You can also use ng-click if you want the function to run on click instead of on focus.
Related
I am new to Jasmine and Karma
I am testing an AngularJS application using Jasmine+Karma
My Html looks like this:
<div id="form">
<div id="car-type">
<input type="radio" ng-model="$ctrl.carType" ng-change="$ctrl.onTypeChange()" name="carType"
ng-value="true"/>
<span class="label">Honda</span>
<input type="radio" ng-model="$ctrl.carType" ng-change="$ctrl.onTypeChange()" name="carType"
ng-value="false"/>
<span class="label">Mazda</span>
</div>
</div>
However, when I try getting the value of the model bound to the input radio button, true is returned (because of ng-value I believe):
var wrapperForm = element[0].querySelector('#form');
// Returns true
console.log(wrapperForm.querySelector('#car-type input').value);
But, I want the model value bound to the radio button.
I don't know how to retrieve the model value bound to the radio button ($ctrl.carType).
Is there a way to retrieve it using the querySelector?
Can someone please help me out?
Yes:
document.querySelector("#car-type [type=radio]").getAttribute("ng-model")
However, you have two instances, you might want querySelectorAll instead.
what i am trying to do here is, i have an ng-repeat in a form and if i click anyone of those input buttons corresponding all buttons get disabled
<div ng-repeat="question in sinSurCtrl.singleSurvey" ng-show="!$first">
<hr>
<p>Q. {{question.questionText}}</p>
<form >
<div ng-repeat=" option in question.questionOptions track by $index">
<label>
<input name="options" type="radio" value="$index" ng-click="sinSurCtrl.questionId=question.questionId; sinSurCtrl.answer=$index+1; sinSurCtrl.createAnswer()" onclick="this.disabled = true">
<span> {{option}} {{$index+1}} {{question.questionId}} </span>
</label>
</div>
</form>
</div>
here is the view-
as you can see if i select anyone of those option it is getting disabled but what i am trying to do is if i attempt anyone option then options corresponding to the same question get disabled.
for example-
in Q3. which is a better orator ?
if i choose option (a) then it get selected and after that automatically bot options (a) and (b) get disabled.
Note- please try to keep solution completely in angularjs or if you want use affordable amount of javascript other then that please avoid using external libraries like jQuery(i know nobody in his senses will handle trouble of using jQuery and angular together but for the sake of example i have included its name)
Proposed solution with some suggested refactoring...
First change the ng-click directive to point to a new onOptionButtonClicked function on sinSurCtrl which takes in the two parameters question and index (which it needs to carry out it's work):
<div ng-repeat="question in sinSurCtrl.singleSurvey" ng-show="!$first">
<hr>
<p>Q. {{question.questionText}}</p>
<form>
<div ng-repeat="option in question.questionOptions track by $index">
<label>
<input
name="options"
type="radio"
value="$index"
ng-click="onOptionButtonClicked(question, $index)"
ng-disabled="question.disabled">
<span> {{option}} {{$index+1}} {{question.questionId}} </span>
</label>
</div>
</form>
</div>
Also take note of the newly added ng-disabled="question.disabled" directive. This is part of the mechanism that will enable/disable the question's controls.
Now move the variable assignments to the new onOptionButtonClicked function. The controller is generally a better place (than the view) for variable assignments, especially if there are several of them on the same directive.
sinSurCtrl.onOptionButtonClicked = onOptionButtonClicked;
function onOptionButtonClicked(question, index){
sinSurCtrl.questionId=question.questionId;
sinSurCtrl.answer=index;
sinSurCtrl.createAnswer();
question.disabled = true; // <--- This is what disables the option buttons
}
This is where an answered question object gets it's disabled property set to true. This in combination with the ng-disabled directive mentioned previously is what disables the option buttons.
On your controller, create a function that checks if a given questionId has been answered and return truthy if it has. Call that function in ng-disabled in the input tag:
<input type="radio" ng-disabled="sinSurCtrl.questionHasAnswer(question.questionId)" ... />
I'm trying to implement real time search so i have a search for including many input fields
so each and every time when user update input fields search function should be triggered.
i have came up with $watch to track model changes on form field
$scope.$watch('filters.site', function () {
$scope.$broadcast('updateDataTable');
});
$scope.$watch('filters.fname', function () {
$scope.$broadcast('updateDataTable');
});
$scope.$watch('filters.lname', function () {
$scope.$broadcast('updateDataTable');
});
but i'm just wondered is there anyway to get whole form value changes
my form look like
<form name="searchForm">
<label for="">FIRST NAME</label>
<input type="text"
class="form-control"
data-ng-model="filters.fname">
<span></span>
<label for="">LAST NAME</label>
<input type="text"
class="form-control"
data-ng-model="filters.lname">
<span></span>
<label for="">SITE</label>
<input type="text"
class="form-control"
data-ng-model="filters.site">
<span></span>
</form>
thanks
If you pass true as the last argument to $watch, Angular will watch for deep equality instead, and you can watch the entire object at once:
$scope.$watch("filters", function() { ... }, true);
That will incur creating a copy of the object on every digest cycle, but if all your filters object contains is those filters, it's probably not going to be any more inefficient than watching everything separately. If your filters object is expensive to copy for some reason you could also use a $watchGroup for equivalent functionality to your current code except neater:
$scope.$watchGroup(["filters.site", "filters.fname", ...], function() { ... });
$scope.$watch('filters', function () {
$scope.$broadcast('updateDataTable');
});
You can use the ng-change directive that could call your search function just add it on all your input so when one of the input change the search function will be called.
<input type="text" class="form-control" data-ng-change="search()" data-ng-model="filters.fname">
I have a very simple form where I have Yes and No radio buttons. Each radio button is bound to the same item in the scope (I am using AngularJS). The Yes button's value gets set to true on being selected and the No button's value gets set to false when being selected.
When I click the Yes button once, both the model and the html element changes correctly. But when I click the No radio button, the model changes correctly but the html element does not become selected. If I click the No radio button again the html element then changes to it's correct selected state.
The example below is just part of a larger html page and controller but I have kept the Angular model structure the same because this may be where the issue is.
HTML:
<div ng-app="myApp">
<div ng-conroller="MyController">
<div>
<label>
<input type="radio" name="IsBeingPaid" ng-model="item.isBeingPaid" ng-checked="item.isBeingPaid" value="true"/>
Yes
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="IsBeingPaid" ng-model="item.isBeingPaid" ng-checked="!item.isBeingPaid" value="false"/>
No
</label>
<p>{{item.isBeingPaid}}</p>
</div>
</div>
</div>
Controller:
var app = angular.module('myApp', [
'my.controllers'
]);
var controllers = angular.module('my.controllers', []);
controllers.controller('MyController', function($scope) {
$scope.item = {};
});
I have created this fiddle to demonstrate the issue.
http://jsfiddle.net/prajna78/Tdq9n/14/
What am I missing? It seems like such a simple thing.
There are a few problems with your code.
First, use ng-value instead of value in your radio button elements. This makes sure that the value you're binding to is a boolean (true) and not a string ("true"). Also, you don't need ng-checked (ng-model is sufficient).
<input type="radio" name="IsBeingPaidMinimumWage" ng-model="isBeingPaidMinimumWage" ng-value="true"/>
Also, you're binding to item.isBeingPaidMinimumWage, but your $scope variable is just isBeingPaidMinimumWage, so the initial value that you assign in your controller isn't reflected in the view.
Demo
First i have a very basic Question about coupling two input Elements. In my case it is a Slider and an input element:
<div class="userInput">
<input id="slider" type="range" min="0" max="100"/>
<input id="number" type="number" max="100"/>
</div>
js:
$('#slider').corresponding = $('#number');
$('#number').corresponding = $('#slider');
$('#slider').onchange(function(){this.corresponding.value = this.value;});
$('#number').onchange(function(){this.corresponding.value = this.value;});
So this works for me but also seems to me like a dirty hack, extending the jQuery object. The bad feeling even grows when appending the controller to jQuery Objects:
var MYController = new Controller();
$('#slider').controller = MYController;
$('#slider').onchange(function(){
this.corresponding.value = this.value;
this.controller.sliderChange(this.value);
});
I would appreciate any suggestions how this is done "the right way". I couldn't figure out a better way yet because i have a large and changing number of user inputs, each requiring its own controller Object, held in an array in my Mastercontroller Class.
Maybe you can put all the inputs inside a <form></form> tag in jsp and then call the form submit event or the serialize event. With the latter (serialize any value stored against a button would not be stored and it would need the name attribute in the jsp tags as well, so may be submit is a better option).
//jsp page
<form id="myForm" >
<input type="text" value="Enter here">
<input type="submit" value="Submit">
</form>
//js call
( "#myForm" ).submit(function( event ) {
// call the controller
});