ng-click not sending updated value - angularjs

I have following code:
<div class="input-field col s3" ng-repeat="data in content.data">
<input class="updatable mcq"
ng-disabled="!viewMode"
type="checkbox"
id="mcq{{data.surveyPropertyId}}"
ng-click="updateMCQ(data.surveyPropertyId,data)"
ng-model="data.value"/>
<label for="mcq{{data.surveyPropertyId}}">{{data.name}}{{data.value}}</label>
$scope.updateMCQ = function(surveyPropertyId,newValue){
console.log(newValue);
}
problem is that it in updateMCQ function it shows right value of data.value
but if i trigger a click event on this input element it shows previously selected value. for example if checkbox is checked it would send false.
Also {{data.name}}{{data.value}} is evaluating and changing correctly as check / uncheck this element
What can be the problem
UPDATE:
I have found the problem and its a silly one. when I call $('.updatable.mcq.ng-dirty').trigger('click') or for change, it actually changes and now the element value has been changed.!!!.
Now can anyone guide me on how to create a custom directive which would act like an event same as click or change in angularjs?

You should use ng-change like:
ng-change="updateMCQ(data.surveyPropertyId,data)"

You can use ng-change and it will work for you as said by #Jenny.
Here is the code,
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="input-field col s3" ng-repeat="data in content">
<input type="checkbox" ng-model="data.value" ng-change="updateMCQ('data.surveyPropertyId',data)"> click and check console
{{data}}
</div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = "John";
$scope.content =[{ value: false },{ value: false },{ value: true }]
$scope.updateMCQ = function(surveyPropertyId,newValue){
console.log(newValue);
}
});
</script>
</body>
</html>
Please run the above code.
Check this demo

I have found the problem and its a silly one. when I call $('.updatable.mcq.ng-dirty').trigger('click') or for change, it actually changes and now the element value has been changed.!!!.

Related

Checkbox to button ngmodel - which way to change my value

I'd like to edit my checkbox so I get a or an input with type=button instead.
I have for now, properly working :
<label>Afficher</label>
<input type="checkbox" ng-model="isElementVisible">
Simply, with my script-angular.js :
$scope.isElementVisible = false ; //it's working, true when I click on my checkbox.
I haven't been using AngularJS for a looong time cause that's an old project and I don't know how to say to the button that my ng-model needs to change, should I do a function or is there an easier way ?
Thanks in advance to you all :3
You can simply handle it in the html using
ng-click="isElementVisible = !isElementVisible"
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.isElementVisible = false;
}]);
.hlight {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="isElementVisible = !isElementVisible">Click to toggle isElementVisible</button>
<div ng-class="{'hlight':isElementVisible}">isElementVisible is {{isElementVisible}}</div>
</div>

Angularjs Ng-init shows the same retrieved form values when passed through ng-repeat

Am having an issues with angularjs ng-init(). In my table called post, I have 3 rows inserted. For example
insert into post(id,title)values(1,'title1');
insert into post(id,title)values(2,'title2');
insert into post(id,title)values(3,'title3');
Now I have retrieved the records and pass it through ng-repeat and everything works fine.
My problem is the ng-init() function. when I passed the database values into a form inputs with ng-init initialized within the ng-repeat, its shows the last database values all through in the form inputs (Eg. 3, title3)
<input type='text' ng-model='title' ng-model='$parent.title' ng-init="$parent.title=post.title" >
if I add value attribute to the form (Eg. value={{post.id}}) it will show the correct form values on each row but when I click on submit button, the value attribute will not be submitted but it will rather pass the value to ng-init which keeps submitting only the last database records (Eg. 3, title3) irrespective of the form button on each row that was clicked.
I have attached the screenshot that shows how the ng-init displays only the last record in a form values instead of showing all records corresponding to each form rows
but I was expecting to have is the form below or a work around within the angularjs controller or equivalents
below is the code
<!doctype html>
<html>
<head>
</head>
<body ng-app='myapp'>
<div class="content" ng-controller='fetchCtrl'>
<div class="post" ng-repeat='post in posts'>
<form bind-to-scope='$parent' >
post Id<br>
<input type='text' ng-model='pid' ng-model='$parent.pid' ng-init="$parent.pid=post.id" >
<br>
post Title<br>
<input type='text' ng-model='title' ng-model='$parent.title' ng-init="$parent.title=post.title" >
<br>
<input type='button' id='but_save' value='Save' ng-click="submitButton()" >
</form>
</div>
</div>
</div>
<!-- Script -->
<script src="angular.min.js"></script>
<script>
var fetch = angular.module('myapp', []);
fetch.controller('userCtrl', ['$scope', '$http', function ($scope, $http) {
// Add new record
$scope.submitButton = function(){
var pid=$scope.pid;
//alert variables values that is all I want
alert(pid);
// do http thing here if you like
$http({
});
}
// Fetch post data scope goes here
</script>
</body>
</html>
You have few issues in your code: Here are few issues in your question
$parent is not required to bind the data
You have taken ng-model twice in each input which is wrong
Also, ng-model binds the data automatically, ng-init is not required.
Here is the solution:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="post in posts">
<form>
post Id<br>
<input type='text' ng-model='post.pid' >
<br> post Title<br>
<input type='text' ng-model='post.title'>
<br>
<input type='button' id='but_save' value='Save' ng-click="submitButton()">
</form>
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.posts = [
{
"pid" : "1",
"title" : "title1"
},
{
"pid" : "2",
"title" : "title2"
},
{
"pid" : "3",
"title" : "title3"
},
]
$scope.submitButton = function(){
alert(angular.toJson($scope.posts))
}
});
</script>
</body>
</html>
Please run the above snippet
Here is a working DEMO

Lose the focus after inserting a letter

I have written a script which represent a json data in 2 ways: JSBin
<!DOCTYPE html>
<html>
<head>
<script src="https://handsontable.github.io/ngHandsontable/node_modules/angular/angular.js"></script>
</head>
<body ng-app="app">
<div ng-controller="Ctrl">
GUI:
<div ng-repeat="item in data">
<input ng-model="item.val">
</div>
<br><br><br>
Textarea:<br>
<textarea rows=10 cols=20 ng-model="dataString"></textarea>
</div>
<script>
var app = angular.module('app', []);
app.controller('Ctrl', ['$scope', '$filter', function($scope, $filter) {
$scope.data = [{val: "1"}, {val: "2"}];
$scope.$watch('data', function(data_new) {
$scope.dataString = $filter('json')(data_new);
}, true);
$scope.$watch('dataString', function(dataString_new) {
$scope.data = JSON.parse(dataString_new);
}, true);
}]);
</script>
</body>
</html>
Thus, modifying the value in GUI will change the string in the textarea (because of $watch('data'); and modifying the string in the textarea will change the GUI (because of $watch('dataString')).
However, the problem is that when we change the value in GUI, we lose the focus after inserting a letter.
Does anyone know how to amend this?
So the problem is that you are iterating over an array (ng-repeat) and changeing the items of the array. The items are removed from the DOM and new one are inserted because they are strings and thereby compared by value. This makes you loose focus.
It's pretty simple to fix though. Just track by index as the objects are in identical order.
Change:
<div ng-repeat="item in data">
To:
<div ng-repeat="item in data track by $index">

angularjs manual bootstrapping does not update property value when input changes through method call

The problem, I have is AngularJS application is not updating the result when input changes in the input HTML field. If I turn this to auto bootstrapping it does work as expected. I do not know what am i doing wrong?
This is JS file.
angular.module('doublevalue', [])
.controller('DoubleController', ['$scope', function($scope){
$scope.value = 0;
$scope.double = function(value) { $scope.value = value * 2; }
}]);
angular.element(document).ready(function() {
var div3 = document.getElementById('App3');
angular.bootstrap(div3, ['doublevalue']);
});
JSFIDDLE version:
https://jsfiddle.net/as0nyre3/48/
HTML file:
<div id ='App3' ng-controller='DoubleController'>
Two controller equals
<input ng-model='num' ng-change='double(num)'>
<span> {{ value }}</span> </div>
Auto bootstrapping one link:
https://jsfiddle.net/as0nyre3/40/
Please help me!
This is working, with a problem like that you should always check your selectors
<div id="App3" ng-controller="myCtrl">
<input type='text' ng-model='name' ng-change='change()'>
<br/> <span>changed {{counter}} times </span>
</div>
<script>
angular.element(document).ready(function() {
angular.bootstrap(document.getElementById('App3'), ['myApp']);
})
</script>

Change the drop down selected value from an angular controller

I need to change the "selected value" of the drop down from the already saved value in db. How can I do that?
Controller
var app = angular.module('app', []);
app.controller('ctrl', function($scope) {
$scope.months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
$scope.selected='August';//here it's not working ?
});
HTML
<html ng-app="app">
<body ng-controller="ctrl">
<div class="sample" align="center">
<h1>AngularJS Combobox</h1>
<select ng-model="selected" ng-options="opt as opt for opt in months" ng-init="selected='March'"></select>
<h3>You have selected : {{selected}}</h3>
</div>
</body>
</html>
My CODE PEN is here.
Any help would be highly appreciated.
Remove the:
ng-init="selected='March'"
So that your new view code is as follows:
<html ng-app="app">
<body ng-controller="ctrl">
<div class="sample" align="center">
<h1>AngularJS Combobox</h1>
<select ng-model="selected" ng-options="opt as opt for opt in months"></select>
<h3>You have selected : {{selected}}</h3>
</div>
</body>
</html>
To set the initial selected default: set via $scope.selected in the controller - don't use ng-init for this.
To reset the default after a database save, you'll want to use a promise for the save operation and reset the select field in the promise's return function.

Resources