Trigger NgChecked in Angular JS - javascript

I need to work out a way of triggering NgChecked to re-evaluate it's expression after a user submits a form (which reloads the data). Ideally the trigged would be after the data has been reloaded, so the checkbox state is in line with that of the data and the amendments that have been made.
I've tried calling the expression directly after loadData() is called, however to no avail.
Do I instead need to use something like NgUpdate?
Any suggestions would be very much appreciated. Please see my code below:
view.html
<form ng-submit="updateinfo(item.downloadID); showDetails = ! showDetails;">
<input class="form-control" style="margin:5px 3px;" type="text"
ng-model="item.title" value="{{item.title}}"
placeholder="{{item.title}}"/>
<div class="checkbox" style="margin:5px 3px;">
<label for="downloadLive">
<input name="downloadLive" type="checkbox" ng-model="item.dlLive" ng-checked="liveCheckBoxState(item.dlLive);" ngTrueValue="1" ngFalseValue ="0"> Download live
</label>
</div>
<input class="btn btn-default form-control" style="margin:5px 3px;" type="submit"/>
</form>
controllers.js
// a scope function to edit a record
$scope.updateinfo = function(downloadID) {
id = downloadID
var result = $scope.items.filter(function( items ) {
return items.downloadID == id;
});
updatedata = $scope.items
$http({
method : 'PUT',
url : '/view1/downloadedit/'+id,
data : result
});
$scope.loadData();
};
//return correct state checkbox for downloadlive
$scope.liveCheckBoxState = function(dlLive) {
console.log(dlLive);
if (dlLive == 1) {
return true;
} else {
return false;
};
};
// a scope function to load the data
$scope.loadData = function () {
$http.get('/view1/downloadData').success(function (data) {
$scope.items = data;
});
};
$scope.loadData();

Related

Form does not update on view and server in AngularJS?

I have this bug in my web app. So, I have a form where when I edit the form it does not update on view and server. What I want to solve is when I edit my form, I want to update the view and the server. So, here is my code below. Please, check out my code if somethings wrong. Thanks in advance. Any Help?
here is my code.
var app = angular.module("MyApp", ['ngRoute', 'ui.bootstrap']);
app.controller('MyCtrl', function($scope, $window, people) {
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
});
$scope.inactive = true;
$scope.updateUser = function(person) {
people.updateUser(person);
};
$scope.confirmedAction = function(person) {
var index = $scope.userInfo.lawyers.map(function(e) {
return e.id;
}).indexOf(person.id);
people.confirmUser(person.id).then(function(data){ });
$scope.userInfo.lawyers.splice(index, 1);
console.log($scope.userInfo.lawyers);
$window.location.href = '#/lawyer';
};
});
});
about
<div ng-controller="MyCtrl">
<div ng-repeat="person in userInfo.lawyers | filter : {id: lawyerId}">
<a class="back" href="#/lawyer">Back</a>
<button type="button" class="edit" ng-show="inactive" ng-click="inactive = !inactive">
Edit
</button>
<button type="submit" class="submit" ng-show="!inactive" ng-click="updateUser(person)">Save</button>
<a class="delete" ng-click="confirmedAction(person);" confirm-click>Confirm</a>
<div class="people-view">
<h2 class="name">{{person.firstName}}</h2>
<h2 class="name">{{person.lastName}}</h2>
<span class="title">{{person.email}}</span>
<span class="date">{{person.website}}</span>
</div>
<div class="list-view">
<form>
<fieldset ng-disabled="inactive">
<legend>Info</legend>
<b>First Name:</b>
<input type="text" ng-model="person.firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="person.lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="person.email">
<br>
<b>Website:</b>
<input type="text" ng-model="person.website">
<br>
</fieldset>
</form>
</div>
</div>
</div>
services to my backend
app.factory('people', function ($http) {
var service = {};
service.getUserInfo = function () {
return $http.get('https://api-dev.mysite.com/admin/v1/lawyers');
};
service.confirmUser = function (lawyerId) {
return $http.put('https://api-dev.mysite.com/admin/v1/lawyers/'+lawyerId+'/confirm');
};
service.updateUser = function (person) {
return $http.put('https://api-dev.mysite.com/admin/v1/lawyers/'+ person.id, person);
};
return service;
});
HomeController
var isConfirmed = false;
app.controller('HomeController', function($scope, people) {
if (!isConfirmed) {
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
}, function (error) {
console.log(error)
});
}
});
There are a couple of problems here.
Data from the server is not bound to the controller which means it will not display in your view.
The inputs to your form are binding to aliases and not any members of an actual scope
After you submit changes to your data, you need to get updates from your server
The inactive scope value is not updated after you save your data
which means your 'Save' button won't hide after a form is submitted.
First step is populating your $scope.userInfo in your MyCtrl controller. When you set $scope.userInfo in your HomeController only HomeController has access to $scope.userInfo and not MyCtrl.
You need to change your code such that MyCtrl sets $scope.userInfo in it's own scope so that it has access to the data like so:
app.controller('MyCtrl', function($scope, $window, people) {
// This function will now be called so that it can get the userInfo
// from the server and populate into the scope and give the controller
// access.
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
});
// ...
});
Now you need to actually bind the input of your form to the data in your scope.
<form>
<fieldset ng-disabled="inactive">
<legend>Info</legend>
<b>First Name:</b>
<input type="text" ng-model="userInfo.lawyers[$index].firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="userInfo.lawyers[$index].lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="userInfo.lawyers[$index].email">
<br>
<b>Website:</b>
<input type="text" ng-model="userInfo.lawyers[$index].website">
<br>
</fieldset>
</form>
It's important to remember that Angular needs to bind to data in $scope before it will render changes in the DOM and using person from the person in userInfo.lawyers ng-repeat directive references an alias to a person and not to the actual data in the userInfo scope.
After you submit your changes you're going to want to update your list with new data from the server so include:
app.controller('MyCtrl', function($scope, $window, people) {
// ...
$scope.updateUser = function(person) {
people.updateUser(person)
// Now get the new data.
.then(function() {
return people.getUserInfo();
}).then(function (response) {
// Apply the new data to the scope.
$scope.userInfo = response.data;
});
};
// ...
});
Finally for the Save button issues you need to be sure that isactive value of the scope is set appropriately for when you do and don't want it to appear in the DOM. Setting the value to true hides it while setting to false reveals it. The edit button already toggles this value for you but you can also toggle this value when the function you want it to execute completes. You can do this in the updateUser function:
app.controller('MyCtrl', function($scope, $window, people) {
// ...
$scope.updateUser = function(person) {
// Hide the save button
$scope.inactive = true;
people.updateUser(person)
.then(function() {
return people.getUserInfo();
}).then(function (response) {
$scope.userInfo = response.data;
});
};
// ...
});
Additional resources for AngularJS scopes can be found here.

Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters

I have use the below link to make a filter on select option based on input text :
1. http://jsfiddle.net/tyrsius/67kgm/
2. http://www.knockmeout.net/2011/04/utility-functions-in-knockoutjs.html
3. Using Knockout to Filter ViewModel Data Using Multiple Fields/Columns and Controls
Faced a Error: Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.
Did some research and found the below link to solve
1. Possible Bug: Breeze.js 1.5 -- Cannot write a value to a ko.computed unless you specify a 'write' option
2. Cannot write a value to a ko.computed unless you specify a 'write' option
But still facing the error not able to find out the solution. Can anyone please help me I know this question has been ask most of the time . Ironically I am not able to find the solution.Where is the mistake??.
function AccessLevelVM() {
var self = this;
self.AccessLevel_nameSearch = ko.observable();
self.PositionTypeJobDesc = ko.computed(function () {
var filter = self.AccessLevel_nameSearch();
if (!filter) {
return self.PositionTypeJobDesc();
} else {
return ko.utils.arrayFilter(self.PositionTypeJobDesc(), function (item) {
return ko.utils.stringStartsWith(PositionTypeJobDesc.PositionByDept.toLowerCase(), filter.toLowerCase());
});
}
});
}
$(document).ready(function () {
ko.utils.stringStartsWith = function (string, startsWith) {
string = string || "";
if (startsWith.length > string.length) return false;
return string.substring(0, startsWith.length) === startsWith;
};
var Model = new AccessLevelVM()
ko.applyBindings(Model, document.getElementById('AccessLevelForm'));
});
HTML
<div class="panel-body">
<div class="row">
<div class="col-md-12">
<div class="input-group">
<input type="text" name="SearchAccessLevel" class="form-control" placeholder="search" data-bind="value: AccessLevel_nameSearch, valueUpdate: 'afterkeydown'" />
<span class="input-group-addon glyphicon glyphicon-search"></span>
</div>
</div>
</div>
<div class="well" style="max-height: 300px;">
<select class="form-control input-sn" style="width: 94%;" size="4" name="sometext"
data-bind="options: PositionTypeJobDesc, optionsText: 'PositionByDept', optionsValue: 'PositionDepartmentRelId', optionCaption: ' Choose Job Position ... ', value: selectedPositionType, validationElement: selectedPositionType, event: { change: OnChangeJobPosition } " data-required="true">
</select>
</div>
</div>
You should try something like this
View:
<input type="text" data-bind="value:search" />
<div data-bind="foreach:filteredArray">
<span data-bind="text:name"></span>
</div>
ViewModel:
$(function() {
ko.applyBindings(new ViewModel());
});
var ViewModel = function () {
self.array=ko.observableArray([{'name':'charlie'},{'name':'sheen'}]);
self.search=ko.observable();
self.filteredArray= ko.computed(function () {
var filter = self.search();
if (!filter) {
return self.array();
} else {
return ko.utils.arrayFilter(self.array(), function (item) {
return ko.utils.stringStartsWith(item.name.toLowerCase(), filter.toLowerCase());
});
}
});
};
Working fiddle here

using $watch in angularjs

I have a form with 2 input fields and requirement is that once user enters valid data into these
fields, I need to pass the input data to the factory function and get the data from server.To achieve this I thought of using $watch function but stuck at how to know if form is valid in $wathc function and then call the factory function to get data from the server.Here is the code.
Any help would be highly appreciated.
//html
<html>
<body ng-app="myModule">
<div ng-controller="myCtrl">
Product Id: <input type="text" ng-model="myModel.id" /><br/>
Product Name: <input type="text" ng-model="myModel.productname" /><br/>
</div>
</body>
</html>
//js
var myModule = angular.module('myModule',[]);
myModule.controller('myCtrl',['$scope', function($scope){
$scope.myModel = {};
var getdata = function(newVal, oldVal) {
};
$scope.$watch('myModel.id', getdata)
$scope.$watch('myModel.productname', getdata)
}]);
Wouldn't you just watch myModel, since the same function is called in both cases?
You could do this with ng-change just as easily.
<html>
<body ng-app="myModule">
<form name="productForm" ng-controller="myCtrl">
<div>
Product Id: <input type="text" name="idModel" ng-model="myModel.id" ng-change="validateID()" /><br/>
Product Name: <input type="text" ng-model="myModel.productname" ng-change="validateProduct()" /><br/>
</div>
</form>
</body>
And your JS would look like this:
var myModule = angular.module('myModule',[]);
myModule.controller('myCtrl',['$scope', 'myFactory',
function($scope, myFactory){
$scope.myModel = {};
$scope.validateID = function(){
//things that validate the data go here
if(your data is valid){
myFactory.get(yourParams).then(function(data){
//whatever you need to do with the data goes here
});
}
};
$scope.validateProduct = function(){
//things that validate the data go here
if(your data is valid){
myFactory.get(yourParams).then(function(data){
//whatever you need to do with the data goes here
});
}
};
}
]);
Using ng-change saves you from having to add a $watch to your scope (they are expensive) and will fire when the user leaves the input box. If you need to catch each keystroke, I would recommend that you use UI-Keypress and run the same functions.
To know if form is valid you have to add a form tag and inside your controller check $valid, on your example the form is always valid becaus you do not have any required field.
See the below example on codepen
The HTML
<div ng-app="myModule">
<div ng-controller="myCtrl">
<form name="myform" novalidate>
Product Id:
<input type="text" ng-model="myModel.id" />
<br/>
Product Name:
<input type="text" ng-model="myModel.productname" />
<br/>
</form>
<br/>
<div>{{result}}</div>
<div>Form is valid: {{myform.$valid}}</div>
</div>
</div>
The JS
var myModule = angular.module('myModule', []);
myModule.controller('myCtrl', ['$scope', function ($scope) {
$scope.myModel = {};
$scope.result = "(null)";
var getdata = function (newVal, oldVal) {
var valid = null;
if ($scope.myform.$valid) {
valid = "is valid";
} else {
valid = "is INVALID";
}
$scope.result = "Changed value " + newVal + " form " + valid;
};
$scope.$watch('myModel.id', getdata);
$scope.$watch('myModel.productname', getdata);
}]);

How to pass value of textbox to a method in controller?

In Angularjs, I'm trying to pass a value from a textbox to method written in controller as below
#Try 1
<input type="text" ng-blur="isExists(this.value)">
and within my controller I have
$scope.isExists = function (theValue) {
alert(theValue);
};
It is not working.
#Try 2
<input type="text" ng-model="username" ng-blur="isExists()">
and within controller
$scope.isExists = function () {
alert($scope.username); // returns undefined
};
How to pass value from ng-blur to a method within a Controller?
Updates:
Any reason why the valueis not seen in the textbox?
<input type="text" ng-model="username" ng-blur="isExists()">
Fiddle
Try2 should not return undefined if the <input type="text"
is filled with at least one character.
You can append {{ username }} on the html page just for debug purporses to make sure it was well binded.
<input type="text" name="userId" id="txtid" />
<script type="text/javascript">
$(document).ready(function () {
$('#txtid').blur(function () {
debugger;
var id = $('#txtid').val();
window.location = "/Home/CreateSupplier/?userid=" + id;
});
});
</script>
In controller
public ActionResult CreateSupplier(string userid)
{
if (userid != null)
{
return Content("Received Username:" + userid);
}
return View(thesupplierList);
}

Not returning a value for some reason

Basically I have a script the function "hola ()" that should return the value of 1 if the radio button value is 1. But for some reason when I try to get the return value in another function i never get it.
The form works perfectly.. the only issue is that it doesnt return the value
Can anyone tell me what i did wrong?? thanks
$(document).ready(function(){
function hola() {
$("form[name=yN]").show("slow");
$('input[type=radio]').click( function (){
var opt = $(this).attr("value");
if (opt == "1") {
this.checked = false;
$("form[name=yN]").hide("slow");
return 1;
}
if (opt == 0) {
$("p").html ("ok");
this.checked = false;
}
})
}
$("#iForm").submit( function(event){
event.preventDefault();
var user = $("input[name=username]").val();
var password = $("input[name=password]").val();
var dbName = $("input[name=dbName]").val();
var server = $("input[name=server]").val();
$.get("1.php",
{username: user, password: password, dbName: dbName, server: server },
function(data){
if (data == "The table PAGE exists" || data == "The table SUBJECTS exists" || data == "The table USERS exists" ) {
// CALLING THE hola () function and expecting a return
var opt = hola();
$("p").html(data + opt);
}
}
)
})
})
HTML
<!-- Yes or No form -->
<form name="yN" style= "display: none; margin-left: auto; margin-right: auto; width: 6em">
<input type="radio" name="yN" value="1">yes</input>
<input type="radio" name="yN" value="0">no</input>
<button id=1 >click me!</button>
</form>
<!-- Login Form -->
<form id="iForm" style= "display: show">
<label id="username" >Username</label>
<input id="username" name="username"/>
<label id="password">Password</label>
<input id="password" name="password" />
<label id="server" >Server</label>
<input id="server" name="server"/>
<label id="dbName" >dbName</label>
<input id="dbName" name="dbName"/>
<input type="submit" value="submit" />
</form>
<p> </p>
Event handlers cannot return values because they're called asynchronously*.
Your existing hola() function will return immediately and the return statements in the click handlers are only called much later, i.e. when the button is clicked.
My approach would be this, using jQuery deferred objects (jQuery 1.6+):
function hola() {
var def = $.Deferred();
// show the popup confirm form
...
$('input[type=radio]').click(function() {
// determine return value
...
// send it back to anything waiting for it
def.resolve(retval);
});
// return a _promise_ to send back a value some time later
return def.promise();
}
$.get("1.php", { ... }).done(function(data) {
if (...) {
hola().done(function(opt)) { // will be called when the promise is resolved
$("p").html(data + opt);
});
}
});
If you prefer, instead of returning the opt value you could use def.reject() to indicate "non-acceptance" and then use a .fail handler to register a handler to be called for that condition.
You return 1 only in the click function of the radiobutton.
If you want to have a function "hola" that returns 1 if the radiobutton is checked, you simply need something like this:
function hola() {
return $("input:radio[name='yN']:checked").val();
}
hola does not even have a return statement. That's the reason for its not returning anything (more precisely: returning undefined always).
A JavaScript function that does not contain a return statement at all or whose all return statements are within nested functions will never return anything but undefined.
Your are tring to return the value from withing the click callback function. Move the return outside that:
function hola() {
var result;
$("form[name=yN]").show("slow");
$('input[type=radio]').click( function (){
var opt = $(this).attr("value");
if (opt == "1") {
this.checked = false;
$("form[name=yN]").hide("slow");
result = 1;
}
if (opt == 0) {
$("p").html ("ok");
this.checked = false;
}
});
return result;
}

Categories