I am facing an issue with using ng-init and assign it model inside my html.
The following code works fine. The following code is for Add/Edit functionality. For example, when row is is opened in Edit mode than it persist existing value and shows it in textbox.
<div>
<div ng-if="title == 'Add Student'">
<input type="text" name="name"placeholder="Student Name" data-ng-model="registration.Student.FirstName" maxlength="50">
</div>
<div ng-if="title == 'Edit Student'">
<input type="text" name="name"placeholder="Student Name" data-ng-model="student.Student.FirstName" maxlength="50">
</div>
</div>
However, the following code which is short version of above code does not work. I mean when the row is opened in edit mode it shows text field but does not show existing value (first name) in it. Why?
<div ng-init="model = (title == 'Add Student' ? registration.Student : student.Student)">
<input type="text" name="name" placeholder="Student Name" data-ng-model="model.FirstName" maxlength="50">
</div>
Please suggest whether ng-init can't be used in this way or some issue in my code?
thanks
Controller
var currentState = $state.current.name;
if if (currentState == "Add")
{
$scope.registration = {
Student: {
FirstName: '',
}
var _init = function () {
}
$scope.title = " Add Student";
}
else
{
$scope.student= {};
$scope.student= response[0];
var _init = function () {
$scope.title = " Edit Student";
}
}
You are ng-init block is wrong currently it is returning true or false, you are messing with brackets.
Markup
<div ng-init="model = (title == 'Add Student') ? registration.Student : student.Student">
<input type="text" name="name" placeholder="Student Name" data-ng-model="model.FirstName" maxlength="50">
</div>
Update
In your current case you ng-init is getting executed while element rendered on the DOM, at that instance on time registration.Student & student.Student doesn't have any value. Evaluation of ng-init setting null object to the model student. I'd suggest you do set model value from the controller logic that would be more safer.
Code
var currentState = $state.current.name;
if (currentState == "Add")
{
$scope.registration = {
Student: {
FirstName: '',
}
var _init = function () {
}
$scope.title = " Add Student";
}
else
{
$scope.student= {};
$scope.student= response[0];
var _init = function () {
$scope.title = " Edit Student";
}
//shifted logic in controller
$scope.model = (title == 'Add Student' ? registration.Student : student.Student);
}
Markup
<div>
<input type="text" name="name" placeholder="Student Name"
data-ng-model="model.FirstName" maxlength="50"/>
</div>
Other way you could add one more flag like loadedData which will says that ajax response has been fetched & registration.Student & student.Student values are available in the scope.
Markup
<div ng-if="loadedData">
<input type="text" name="name" placeholder="Student Name" data-ng-model="model.FirstName" maxlength="50">
</div>
Code
var currentState = $state.current.name;
if (currentState == "Add")
{
$scope.registration = {
Student: {
FirstName: '',
}
var _init = function () {
}
$scope.title = " Add Student";
}
else
{
$scope.student= {};
$scope.student= response[0];
var _init = function () {
$scope.title = " Edit Student";
}
//set flag
$scope.loadedData = true;
}
Related
Contact form variables are not passing into javascript. basically javascript fail on validation. On debug, I am getting "undefined is not a function." I have several seperators on this page. If i put identical code inside a seperate page like "contact.html" variables pass into javascript.
My understanding is that HTML tag id="contact-form" for some reason does not pass into the function.
Java Script
function code_contactvalidation() {
// Add form.special data (required for validation)
$('form.special input, form.special textarea').each(function() {
this.data = {};
this.data.self = $(this);
var val = this.data.self.val();
this.data.label = (val && val.length) ? val : null;
this.data.required = this.data.self.attr('aria-required') == 'true';
});
// Special form focus & blur
$('form.special input, form.special textarea').focus(function() {
with (this.data) {
console.log('focusing');
if ( label && self.val() == label) self.val('');
else return;
}
}).blur(function() {
with (this.data) {
if ( label && self.val().length == 0 ) self.val(label)
else return;
}
});
// initialize captcha
var randomcaptcha = function() {
var random_num1=Math.round((Math.random()*10));
var random_num2=Math.round((Math.random()*10));
document.getElementById('num1').innerHTML=random_num1;
document.getElementById('num2').innerHTML=random_num2;
var n3 = parseInt(random_num1) * parseInt(random_num2);
$('#captcharesult').attr('value', n3);
$('#buttonsubmit').attr('value','Submit');
};
randomcaptcha();
//initialize vars for contact form
var sending = false,
sent_message = false;
$('#contact-form').each(function() {
var _this = this;
this.data = {};
this.data.self = $(this);
this.data.fields = {};
this.data.labels = {};
this.data.notification = this.data.self.find('.notification');
_.each(['name','email','subject'], function(name) {
_this.data.fields[name] = _this.data.self.find(_.sprintf('input[name=%s]', name));
_this.data.labels[name] = _this.data.fields[name].val();
});
}).validate({
errorPlacement: function() {},
highlight: function(element) { $(element).addClass('invalid'); },
unhighlight: function(element) { $(element).removeClass('invalid'); },
submitHandler: function(form) {
if (sending) return false;
if ( sent_message ) { alert('Your message has been sent, Thanks!'); return false; }
var field, valid = true;
with (form.data) {
_.each(fields, function(field, name) {
if ( $.trim(field.val()) == labels[name] ) { valid = false; field.addClass('invalid'); } else { field.removeClass('invalid'); }
});
}
if (valid) {
sending = true;
$('#ajax-loader').show();
form.data.self.ajaxSubmit({
error: function(errorres) {
$('#ajax-loader').hide();
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Unable to send message (Unknown server error)');
form.data.notification.animate({opacity: 100}).fadeIn(500);
},
success: function(res) {
sending = false;
$('#ajax-loader').hide();
if (res == 'success') {
sent_message = true;
form.data.notification.removeClass('error').addClass('success').find('span:first-child').html('Your message has been sent!');
form.data.notification.animate({opacity: 100}).fadeIn(500);
$('#formName').val("");
$('#formEmail').val("");
$('#formSubject').val("");
$('#formMessage').val("");
$('#formcheck').val("");
} else if (res == 'captchaerror') {
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Captcha Error');
form.data.notification.animate({opacity: 100}).fadeIn(500);
} else {
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Unable to send message (Unknown server error)');
form.data.notification.animate({opacity: 100}).fadeIn(500);
}
}
});
}
return false;
}
});
}
HTML
<section id="contact">
<div class="container">
<div class="row text-center">
<div id="principal" data-align="left">
<div class="form_group_contact">
<script type="text/javascript" src="js/jquery.validate.pack.js"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>
<form class="contactForm special validate" id="contact-form" action="sendmsg.php" method="post">
<p><input id="formName" name="name" type="text" value="Name" class="required" /></p>
<p><input id="formEmail" name="email" type="text" value="Email" class="required email" /></p>
<p><input id="formSubject" name="subject" class="last required" type="text" value="Subject" /></p>
<p><textarea id="formMessage" name="message" class="required margin20" rows="4" cols="83"></textarea></p>
<div class="form_captcha margin20">
<p>Captcha Recognition (<span id="num1"></span> * <span id="num2"></span>) =
<input type="hidden" id="captcharesult" name="captcha_result" value=""/>
<input type="text" class="required number" maxlength="3" size="3" id="formcheck" name="captcha" value=""/>
</p>
</div>
<p class="notification" style="display: none;"><span></span> <span class="close" data-action="dismiss"></span></p>
<p><input type="submit" value="" class="margin20" id="buttonsubmit" /><img id="ajax-loader" alt="" src="./images/ajax-loader.gif" /></p>
</form>
</div>
</div>
</div>
</div>
</section>
if ( label && self.val().length == 0 ) self.val(label)
There needs to be a semicolumn (;) to end that line ;)
Also, you call "each" on the contact-form which makes me think you expect more than one contact-form. You will need to set the identifier as "class" rather than "id" in the HTML and use "." in the jQuery selector rather than "#".
Now you got those little things fixed, please try it out in Firefox. Google is very vague with javascript errors, Firefox will give you a better error message. Please share it with us so I can edit this post with a final solution.
I'm trying to pass localStorage to input field, but i'm not able to pass the values, i not getting where i'm going wrong, please help me with this, 1 thing more how can i call the angularjs function outside the controller. thanx for any help guys.
html
<div class="modal__content" ng-controller="joinctrl">
<form novalidate>
<input type="email" placeholder="Email" ng-model="email"><br />
<input type="password" placeholder="Password" ng-model="password"><br />
<input type="password" placeholder="Confirm Password" ng-model="cpassword"><br />
<input type="submit" value="Create" class="creat" ng-click="create()">
</form>
</div>
js
preauth();
function preauth() {
var user_login = window.localStorage.getItem('email');
var pass_login = window.localStorage.getItem('password');
if(user_login != undefined && pass_login != undefined) {
alert(user_login);
document.getElementById("email").value=user_login;
document.getElementById("password").value=pass_login;
angular.element(document.getElementById('loginctrl')).scope().Login();
}
}
var app = angular.module('contol', ['onsen']);
app.controller('loginctrl', function($scope, $http){
$scope.login=function(){
if (!$scope.email || !$scope.password){
alert("Please Fill Email & Password");
}
else{
var request=$http({
method:"post",
url:"http://www.example.com/login.php",
dataType: "json",
data:{
email:$scope.email,
password:$scope.password
},
headers:{'Content-Type':'application/x-www-form-urlencoded'}
});
request.success(function(retmsg){
if(parseInt(retmsg.status)==0)
{
alert(retmsg.txt);
}
else if (parseInt(retmsg.status)==1)
{
window.localStorage.setItem('email', $scope.email);
window.localStorage.setItem('password', $scope.password);
myNavigator.pushPage('home.html');
}
});
}
};
});
This may be useful,store it in variable and use it and only id name not #password
var x = document.getElementById("password").value = "Password";
alert ("The value was changed to: " + x);
In Angular applications, you should write ALL code inside modules. Otherwise, you don't use one of the useful feature of Angular: modularity.
For example:
app.factory("LocalStorage", function() {
var LS = {};
LS.getItem = function(key) {
return localStorage[key];
};
LS.setItem = function(key, value) {
localStorage[key] = value;
return value;
};
return LS;
});
app.controller('loginctrl', function($scope, $http, LocalStorage) {
$scope.email = LocalStorage.getItem('email');
$scope.password = LocalStorage.getItem('password');
$scope.login = function() {
// code...
// I'd rather to create another service "Api" or "Request", like this:
return Api.doAuth($scope.login, $scope.password).then(function(res) {
// For example, service `Request` write to `LocalStorage` status of current authentication.
if(res) {
myNavigator.pushPage('home.html');
}
});
};
});
You should not to call function in outside application (it's incorrect from the point of view Angular's philosophy). However, it's possible, you wrote right:
// get our scope:
var scope = angular.element(document.getElementById('loginctrl')).scope();
// and call our function in the scope:
scope.login();
But it's code you need to execute after Angular's bootstrap.
Also, you may to execute any function with Angular's services.
//find the `ng:app` element and get injector.
var injector = angular.element('body').injector();
//execute our own function with any services
injector.invoke(function($rootScope, $http, LocalStorage) {
$http.get('/foo.php').then(function(res) {
LocalStorage.setItem('answer', res);
});
$rootScope.bar = 1;
});
I have an object with multiple observables. Is there a way in a computed to know which observable changes, therefore which observable fired the computed?
Thank you in advance
Matthew
Without details of exactly what you are trying to achieve, I'll post this in the hope it might help.
A simple way to track changes is to use the .subscribe method on an observable you want to track. Each time the observable gets updated, this method will fire.
self.myValue = ko.observable('initial value');
self.myValue.subscribe(function (item) {
alert('myValue has changed to: ' + item);
});
The item passed in to the subscribe function is optional, so you can use the new value if required.
Here's a simple example of it in use with a computed:
Sample JSFiddle
JS:
var viewModel = function () {
var self = this;
self.firstName = ko.observable('Mod');
self.lastName = ko.observable('dinu');
self.valueChanged = ko.observable('');
self.fullName = ko.computed(function () {
var val = '';
if (self.valueChanged() !== '') {
val = ' (' + self.valueChanged() + ' Changed)';
}
return self.firstName() + ' ' + self.lastName() + val;
});
self.firstName.subscribe(function () {
self.valueChanged('First Name');
});
self.lastName.subscribe(function () {
self.valueChanged('Last Name');
});
};
ko.applyBindings(new viewModel());
HTML:
<div>
<label for="fname">First Name:</label>
<input id="fname" data-bind="value: firstName" />
</div>
<div>
<label for="lname">Last Name:</label>
<input id="lname" data-bind="value: lastName" />
</div>
<hr />
<div>Hello <span data-bind="text: fullName"></span></div>
<hr />
<div>Value Changed: <span data-bind="text: valueChanged"></span></div>
What I'm trying to do here is when I type in a text in the MainField, I want DateField and NumberField to be enabled. I want the $scope.enableSubFields to be generic so it can be used as a utility. ( The controller does not work, Im only trying to show what I kind of like want :) )
Here's my HTML :
<div>
<label>IF THIS HAS TEXT THEN ENABLE DATE AND NUMBER FIELD</label>
<input type="text" ng-model="MainField" ng-change="enableSubFields('MainField','Subfield')"/>
</div>
<div>
<label>DATE FIELD</label>
<input type="text" ng-model="DateField" ng-disabled="Subfield"/>
</div>
<div>
<label>NUMBER FIELD:</label>
<input type="text" ng-model="NumberField" ng-disabled="Subfield"/>
</div>
Heres my Controller
$scope.Subfield= true;
$scope.enableSubFields = function (mainField, subfield) {
if ($scope + '.' + mainField != "") {
$scope + '.' + subfield = false;
} else {
$scope + '.' + subfield = true;
}
};
You need to use a bracket notation to access dynamic properties of an object. So your code should be:
$scope.enableSubFields = function(mainField, subfield) {
if ($scope[mainField] !== "") {
$scope[subfield] = false;
} else {
$scope[subfield] = true;
}
};
or shorter:
$scope.enableSubFields = function(mainField, subfield) {
$scope[subfield] = $scope[mainField] == "";
};
Demo: http://plnkr.co/edit/IbVzrPFEf624JiG6hIrC?p=preview
How do you have conditional binding based on other properties?
Example..
var ViewModel = {
IsAdded = ko.observable(),
AddedBy = ko.observable()
}
When I display it.. I don't want to show AddedBy if IsAddedBy is null or false
Something like this..
<input type="text" data-bind="value: if (IsAdded != null && IsAdded) { AddedBy }"/>
I know that isn't right, but something like that...
What I would do is this;
var ViewModel = function() {
this.IsAdded = ko.observable('True');
this.AddedBy = ko.observable('Test');
this.AddedByText = ko.computed(function(){
if ( this.AddedBy() != null && this.IsAdded() ) return this.AddedBy()
return "";
}, this);
}
Then your input would be
<input type="text" data-bind="value: AddedByText" />
This way you are keeping the logic contained within your ViewModel and separate from the HTML.
This question is old but it might help someone else looking
<input type="text" data-bind="value: IsAdded ? AddedBy : "" "/>
Basically if IsAdded is not null then set the value to AddedBy, else do nothing