How can I force AngularJS to serialize empty form fields - json

As far as I can tell, AngularJS does not serialize a form field if it is empty. But, I need this fields to be in the JSON that is generated, even if they are empty. I am trying to query that JSON, and it will fail if the fields descriptors are not there. Any tips on how to get AngularJS to do this?
In the example below, if you entered "John" into the name field, and nothing in the optionalval field, the json that is formed is this {name: John}. But I would like it to be like this {name:'John', optionalval:''}. This is in the case of a "create new" form where optional fields might not have any values. But, the fields need to be sent whether they have values or not.
<!doctype html>
<html>
<head>
<title>Serialize Test</title>
<script src="js/angular.min.js"></script>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.addnew = function(){
$http.put('/newthing.json', JSON.stringify($scope.item))
.success(function(){
})
.error(function(){
});
};
});
</script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<label for="name">Name:</label>
<input type="text" id="name" ng-model="item.name" required>
<label for="optionalval">Don't put anything here:</label>
<input type="text" id="optoinalval" ng-model="item.optionalval">
<button ng-click="addnew()">Serialize</button>
</body>
</html>

One way is to preinitialize model with empty string. For example, by setting model value in controller:
$scope.item = {optionalval: ''};
Here is a demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$scope.item = {optionalval: ''};
$scope.addnew = function() {
$http.put('/newthing.json', JSON.stringify($scope.item))
.success(function() {})
.error(function() {});
};
});
<script src="https://code.angularjs.org/1.4.3/angular.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<label for="name">Name:</label>
<input type="text" id="name" ng-model="item.name" required>
<label for="optionalval">Don't put anything here:</label>
<input type="text" id="optionalval" ng-model="item.optionalval">
<button ng-click="addnew()">Serialize</button>
<pre>{{item | json}}
</div>

Related

ng-disabled in Angular is not working immediately

I am editing the file, here i can change the filename as well as i can add another file for versions, If I have chosen the file, filename edit field should be disabled immediately. I have tried this following code, but its not get disabled until i type something in filename field.
My View code:
<div class="ipfield">
<label class="plclabel">Choose file</label>
<input type="file" class="txt_box" id="newfile"
onchange="angular.element(this).scope().fileNameChanged()">
</div
<div class="ipfield" >
<label class="plclabel">File Name</label>
<input type="text" class="txt_box" ng-disabled="filechoosen" ng-
model="filenameedit" id="filenameedit">
</div>
My app.js
In my controller I have wrote function:
$scope.filechoosen = false
$scope.fileNameChanged = function() {
$scope.filechoosen= true
}
Is there any mistake in my code.
Can you please try with $scope.$apply() inside the click function
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="ipfield">
<label class="plclabel">Choose file</label>
<input type="file" class="txt_box" id="newfile"
onchange="angular.element(this).scope().fileNameChanged()">
</div
<div class="ipfield" >
<label class="plclabel">File Name</label>
<input type="text" class="txt_box" ng-disabled="filechoosen" ng-
model="filenameedit" id="filenameedit">
</div>
</div>
</body>
</html>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.filechoosen = false
$scope.fileNameChanged = function() {
$scope.filechoosen= true
$scope.$apply()
}
});
</script>
as below
try ng-change insted of onchange
<input type="file" class="txt_box" id="newfile"
onchange="angular.element(this).scope().fileNameChanged()">
to
<input type="file" class="txt_box" id="newfile"
data-ng-change="fileNameChanged()">
The user #sqren (https://stackoverflow.com/users/434980/sqren) has made a custom directive which will help to solve this since angularjs doesn't have any ng-change support for file.
view.html
<input type="file" custom-on-change="uploadFile">
controller.js:
app.controller('myCtrl', function($scope){
$scope.uploadFile = function(event){
var files = event.target.files;
};
});
directive.js:
app.directive('customOnChange', function() {
return {
restrict: 'A',
link: function (scope, element, attrs) {
var onChangeHandler = scope.$eval(attrs.customOnChange);
element.on('change', onChangeHandler);
element.on('$destroy', function() {
element.off();
});
}
};
});
He has also created a JSFiddle which help you to understand this.
The answer credit goes to #sqren, I am just mentioning it over here.
More information on the actual answer can be seen here - https://stackoverflow.com/a/19647381/1723852

Getting hardcoded value from input tag into angular controller

I am using angularjs in my application.I am trying to pass hardcoded value from input tag into angularjs controller.Here i am not taking any dynamic values.User just clicks the input area.Based on clicked area i am passing value into angular controller.
Here is my html
<div class="first-hour">
<input type="text" value="12:00am - 12:30am" readonly>
</div>
<div class="second-hour">
<input type="text" value="12:30am - 01:00am" readonly>
</div>
If the user select first input text box value is 12:00am - 12:30am and if second means value is 12:30am - 01:00am.I need to get these values inside angular controller.Can anyone tell how to get the input hardcoded values directly into angularjs controller?
Here is an example of how you can select a specific filed. Both ranges have to be initialised in the Controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.range1 = "12:00am - 12:30am";
$scope.range2 = "12:30am - 01:00am";
$scope.select = function(val) {
$scope.display = angular.copy(val);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="first-hour">
<input type="text" ng-model="range1" ng-click="select(range1)" readonly>
</div>
<div class="second-hour">
<input type="text" ng-model="range2" ng-click="select(range2)" readonly>
</div>
Selected: {{display}}
</div>
(value was replaced with ng-model)
You can try like this,
create one object and initialize value in controller itself. then bind the object in html,
$scope.client = {};
$scope.client.start = "12:00am - 12:30am";
in html page,
<div class="first-hour">
<input type="text" ng-model="client.start" readonly>
</div>
please let me know if u have any quires.

I want to set ng model's value with value attribute's value

<input type="text" value="{{id}}" class="form-control" id="pid" ng-model="user.id" readonly />
if text box's value is 1 i want to set the user.id value as 1
You can add dynamic attribute binding, using angular's directive.
<div ng-app="myApp" ng-controller="ctrl">
<input type="text" ng-attr-value="{{title}}" class="form-control" id="pid" ng-model="title" readonly />
</div>
JS
var app = angular.module('myApp', []);
function ctrl($scope){
$scope.title = "I 'm a tooltip!";
}
Fiddle
Try Following code,
var app = angular.module("app", []);
app.controller("InputController", function($scope) {
$scope.user={"id":1};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="InputController">
<input type="text" value="{{user.id}}" class="form-control" id="pid" ng-model="user.id" readonly />
</body>

How to send data from a text box from one form to the other in angularjs?

I am using this sample form to send data. I currently watch under the console. But I really need to send these information to another page called result.html and I want to know how to do that. Currently I am using the following code in the main page... Here is the code
<!-- File: chapter4/two-forms-databinding.html -->
<html ng-app="notesApp">
<head><title>Notes App</title></head>
<body ng-controller="MainCtrl as ctrl">
<form ng-submit="ctrl.submit1()">
<input type="text" ng-model="ctrl.username">
<input type="password" ng-model="ctrl.password">
<input type="submit" value="Submit">
</form>
<form ng-submit="ctrl.submit2()">
<input type="text" ng-model="ctrl.user.username">
<input type="password" ng-model="ctrl.user.password">
<input type="submit" value="Submit">
</form>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.js">
</script>
<script type="text/javascript">
angular.module('notesApp', [])
.controller('MainCtrl', [function() {
var self = this;
self.submit1 = function() {
// Create user object to send to the server
var user = {username: self.username, password: self.password};
console.log('First form submit with ', user);
};
self.submit2 = function() {
console.log('Second form submit with ', self.user);
};
}]);
</script>
</body>
</html>
I want to know how should be the code in the result.html page to grab the parameters sent by these forms. Please help me I am really new to angularjs.
<!-- File: chapter4/two-forms-databinding.html -->
<html ng-app="notesApp">
<head><title>Notes App</title></head>
<body ng-controller="MainCtrl as ctrl">
<form ng-submit="ctrl.submit1()">
<input type="text" ng-model="ctrl.username">
<input type="password" ng-model="ctrl.password">
<input type="submit" value="Submit">
</form>
<form ng-submit="ctrl.submit2()">
<input type="text" ng-model="ctrl.user.username">
<input type="password" ng-model="ctrl.user.password">
<input type="submit" value="Submit">
</form>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.js">
</script>
<script type="text/javascript">
angular.module('notesApp', [])
.controller('MainCtrl', [function() {
var self = this;
self.submit1 = function() {
// Create user object to send to the server
self.user = {username: self.username, password: self.password};
console.log('First form submit with ', self.user);
};
self.submit2 = function() {
console.log('Second form submit with ', self.user);
};
}]);
</script>
</body>
</html>

ng-model vs ngModel - breaks form

New to angular, new to life:
I have a small email form.
This works:
<form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
<p ng-show="success"><b>We received your message</b></p>
<p ng-show="error">Something wrong happened!, please try again.</p>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" ng-model="input.name" required><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" ng-model="input.email" required><br>
<label for="messsage">Message:</label><br>
<textarea id="messsage" name="message" ng-model="input.message" ngMaxlength='2000' required></textarea><br>
<button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
</form>
This does not work:
<form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
<p ng-show="success"><b>We received your message</b></p>
<p ng-show="error">Something wrong happened!, please try again.</p>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" ngModel="input.name" required><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" ngModel="input.email" required><br>
<label for="messsage">Message:</label><br>
<textarea id="messsage" name="message" ngModel="input.message" ngMaxlength='2000' required></textarea><br>
<button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
</form>
for the 2 inputs and the textarea if I use 'ng-model' the email sends, but when the page loads, the form loads invalid.
If i use 'ngModel' the form loads clean, but the email wont submit.
controller here:
app.controller("contactForm", ['$scope', '$http', function($scope, $http) {
$scope.success = false;
$scope.error = false;
$scope.sendMessage = function( input ) {
$http({
method: 'POST',
url: 'processForm.php',
data: input,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.success( function(data) {
if ( data.success ) {
$scope.success = true;
$scope.input.name="";
$scope.input.email="";
$scope.input.message="";
} else {
$scope.error = true;
}
} );
}
You can see it live here:
http://smartestdiner.com/Bethel/indexx.html#/contact
Warning:
There is some annoying red background
.ng-invalid{
background-color:red;
}
}]);
That's how we know it is loading invalidly.
The annoying red background is the form, since you have a very generic rule set by .ng-invalid, the class will be set on the form as well. You would need to make it more specific for the inputs and controls within the form.
Example:
input.ng-invalid,
textarea.ng-invalid {
background-color:red;
}
Or just reset rule for form.ng-invalid
To add on there is nothing called ngModel it is ng-model. using the former one doesn't do anything but adds a dummy attribute on the element, it has no effect. It is angular way of directive naming, since html is case insensitive the one way angular can identify the directive from attribute or element name (based on the restriction). It converts it to camelCasing to evaluate and process respective directive (or directives attribute bindings). When you do not have ng-model specified and if the form or control does not have novalidate attribute, then the browser's HTML5 validation kicks in that is what you see as inconsistency. Using HTML5 novalidate attribute makes sure no native validation happens on the form.
ng-model is when u write the view (html part).
ngModel is used when one write a custom directive. It is placed in the "require:" param so that u can access,
variables like ngModel.$modelValue
ngModel.$modelValue will have the latest content which has been typed by the user at realtime. So, it can be used for validations, etc.
View code:-
<!doctype html>
<html ng-app="plankton">
<head>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/scripts/emailing/emailing.directive.js"></script>
</head>
<body ng-controller="EmailingCtrl">
<div>
<label>Enter Email: </label>
<emailing id="person_email" ng-model="email_entered"></emailing>
</div>
</body>
</html>
Custom directive:-
(function() {
'use strict';
angular.module('plankton', [])
.directive('emailing', function emailing(){
return {
restrict: 'AE',
replace: 'true',
template: '<input type="text"></input>',
controllerAs: 'vm',
scope: {},
require: "ngModel",
link: function(scope, elem, attrs, ngModel){
console.log(ngModel);
scope.$watch(function(){ return ngModel.$modelValue;
}, function(modelValue){
console.log(modelValue);//awesome! gets live data entered into the input text box
});
},
};
})
.controller('EmailingCtrl', function($scope){
var vm = this;
});
})();
This has been plunked here:- here