Angular expression in text input "value" - angularjs

I have a form that user will have to fill in. Some fields are dates and i don't want user to have to type in today's date.
My Form
<div class="row" ng-controller="JobOrderController as jOrder">
<form class="form-inline" ng-submit>
<div class="form-group">
<label for="todaysDate"><h4><span class='glyphicon glyphicon-flag'></span> Date</h4>Date </label>
<input type="text" class="form-control" id="todaysDate" ng-model="jOrder.orderData.date" value="{{ 2 + 4 }}" >
</div>
......... more code .........
My Controller
angular.module('jobOrderCtrl', ['jobOrderService'])
.controller('JobOrderController', function(Jobs, socketio) {
var vm = this;
vm.createOrders = function() {
vm.message = '';
Jobs.createOrders(vm.orderData)
.success(function(data) {
vm.orderData = '';
vm.message = data.message;
});
};
});
I try out using js to write to that date input field, but is not showing due to angular data binding.
So what i want is the date input value field to be today's date. So how do i go about and do this?

Where do you set the date?
orderData should be an object with the form fields - NOT a string
initialize the orderData:
var vm = this;
vm.orderData = { date : new Date()};
and remove the value property form the html input field. Also set type to date
<input type="date" class="form-control" id="todaysDate" ng-model="jOrder.orderData.date" >

Related

issue with converting date and time to millisecond format in angularjs

I am working on an angularjs web application which uses REST layer to communicate with the backend. I have to display the date and time of a job but I receive it in milliseconds format. How do I convert the value to display the date and time on the UI.
1479982860000 // input
11/24/16 //output date
10:21 AM //output time
Both have to be stored in DataModel.date and DataModel.time.
Also the user enters a date and a time which I have to combine and send it in the same milliseconds format to the REST layer. How do I do that?
<input type="time" id="exampleInput1" ng-model="DataModel.time"
placeholder="HH:mm:ss" required/>
<input type="date" id="exampleInput2" ng-model="DataModel.date"
placeholder="yyyy-mm-dd" required/>
I have to combine the two and send it as Datamodel.date in the controller. Please help.
According to the documentation, you can convert the value in your controller.
$scope.date = new Date($scope.DataModel.time);
$scope.date= $filter('date')(new Date($scope.DataModel.time), 'yyyy-mm-dd');
and the view:
<input type="date" id="exampleInput2" ng-model="date" placeholder="yyyy-mm-dd" required/>
Don't forget to add $filter in your dependencies:
app.controller('YourController', ['$scope','$filter', function($scope, $filter) {
}]);
[This may work for your issue]
https://docs.angularjs.org/api/ng/filter/date
Here is a simple example to achieve what you need,
use
(new Date($scope.milli_seconds)) to get the full date.
(new Date($scope.milli_seconds)).toDateString() to get the date from it
(new Date($scope.milli_seconds)).toTimeString() to get the time from it
(new Date($scope.milli_seconds)).getTime() to convert bact to milliseconds
<!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">
"milliseconds" : {{milli_seconds}} <br>
"full_date" : {{full_date}} <br>
"date" : {{date}} <br>
"time" : {{time}} <br>
"millisecondsreverse" : {{milli_seconds_reverse}} <br>
<br><br>
<input type="time" id="exampleInput1" ng-model="DataModel.time"
placeholder="HH:mm:ss" required/>
<input type="date" id="exampleInput2" ng-model="DataModel.date"
placeholder="yyyy-mm-dd" required/>
<input type="submit" ng-click="submit_values()" value="getmilliseconds"/> <br>
<span ng-if="milli">Your milliseconds: {{milli}}</span>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.DataModel = {}
$scope.milli_seconds = 1479982860000;
$scope.full_date = (new Date($scope.milli_seconds))
$scope.date = $scope.full_date.toDateString()
$scope.time = $scope.full_date.toTimeString()
$scope.milli_seconds_reverse = $scope.full_date.getTime();
$scope.submit_values = function()
{
date = new Date($scope.DataModel.time).toTimeString()
time = new Date($scope.DataModel.date).toDateString()
date_time = (new Date($scope.DataModel.date).toDateString())+" "+ (new Date($scope.DataModel.time).toTimeString())
alert(new Date(date_time).getTime());
$scope.milli = new Date(date_time).getTime();
}
});
</script>
</body>
</html>
Please run the above snippet
You can just convert it into different formats you like, using the filters.
Here is a fiddle
Have a look at moment.js
Add configuration in your JS file
/*Configuration to change the date format*/
angular.module('myapp')
.config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
return date ? moment(date).format('DD/MM/YYYY') : '';
};
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, 'DD/MM/YYYY', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
})
Change the format which ever way you want
var newFormatDate =moment(oldFormatDate).format();
EDITS
If you want to set specific timezone,
moment().tz("America/Los_Angeles");
MOMENT.JS DOCS
Also look at timezone identifier

How to set Angular UI Bootstrap Datepicker to set empty field by default?

I'm working a date picker using Angular UI Bootstrap Datepicker. My challenge is to set the input field of the date picker to empty field by default.
Let me show u the input field i have used .
<td>
<div>
<input class="form-control" type="text" datepicker-popup="dd/MM/yyyy" id='txtDate' ng-model="personalDetail.date" is-open="personalDetail.isOpen" close-text="Close" ng-click="open($event, personalDetail)" name="datefilter" value="" />
</div>
</td>
And my script
$scope.personalDetails.forEach(function(personalDetail){
personalDetail.date = new Date(personalDetail.date);
});
$scope.open = function($event, personalDetail) {
$event.preventDefault();
$event.stopPropagation();
personalDetail.isOpen = true;
};
I'm using it in the html table with ng-repeat . But what i need is to show the date field empty untill i set the respective date. Please help me from this.
<td>
<div>
<input class="form-control" type="text" datepicker-popup="dd/MM/yyyy" id='txtDate' ng-model="personalDetail.date" is-open="personalDetail.isOpen" close-text="Close" ng-click="open($event, personalDetail)" name="datefilter" value="" />
</div>
</td>
Your controller should be
$scope.personalDetails.forEach(function(personalDetail){
//personalDetail.date = new Date(personalDetail.date);//sets the value to the control
personalDetail.date = !personalDetail.date || new Date(personalDetail.date).toISOString() == new Date('1/1/1900').toISOString()
? '' // Date is null, undeclared, or default value
: new Date(personalDetail.date);
});
$scope.open = function($event, personalDetail) {
$event.preventDefault();
$event.stopPropagation();
personalDetail.isOpen = true;
};
Change from
personalDetail.date = new Date(personalDetail.date);
to
personalDetail.date = "";
like $scope.personalDetail={
date: ""
}

Validate start date and end date on AngularJS Bootstrap date picker?

I am new to Angular JS and I am trying to implement validation for date time picker in my Angular project.
I am using bootstrap date picker.
My HTML is :
<div>
<form id="edit-profile" novalidate name="editReservationForm" autocomplete="off" class="form-horizontal">
<fieldset>
<div class="control-group">
<label class="control-label" for="reservation.reservedFrom">Reserved From<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<input type="text" class="span4" style="width:150px" name="reservedFrom" placeholder="Reserved From" data-ng-model="reservation.reservedFrom"
validator="required" required-error-message="Date is required" valid-method="watch" id="startDate"/>
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
</div> <!-- /controls -->
</div> <!-- /control-group -->
<div class="control-group">
<label class="control-label" for="reservation.reservedTill">Reserved Till<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<input type="text" style="width:150px" class="span4" name="reservedTill" placeholder="Reserved Till" data-ng-model="reservation.reservedTill"
validator="required" required-error-message="Date is required" valid-method="watch" id="endDate" ng-change='checkErr(startDate,endDate)'/>
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
<span>{{errMessage}}</span>
</div> <!-- /controls -->
</div> <!-- /control-group -->
</fieldset>
</form>
</div>
My Controller is :
myApp.controller('editReservationController', ['$scope', '$filter', 'reservationResolved', 'pocResolved', 'accountResolved', 'reservationServices', '$location', '$state',
function ($scope, $filter, reservationResolved, pocResolved, accountResolved, reservationServices, $location, $state) {
$scope.reservation = new Object();
$scope.accounts = accountResolved.data;
$scope.pocs = pocResolved.data;
$scope.reservation.employee = reservationResolved.data;
$scope.updateReservation = function () {
if ($scope.editReservationForm.$valid) {
reservationServices.updateReservation($scope.reservation).then(function (result) {
$scope.data = result.data;
if (!result.data.error) {
$state.transitionTo('employeeTalentPool', {
id: $state.params.id
});
}
});
}
};
$scope.checkErr = function (startDate, endDate) {
$scope.errMessage = '';
var curDate = new Date();
if (new Date(startDate) > new Date(endDate)) {
$scope.errMessage = 'End Date should be greater than start date';
return false;
}
if (new Date(startDate) < curDate) {
$scope.errMessage = 'Start date should not be before today.';
return false;
}
};
$scope.cancel = function () {
$location.path("/reservations");
}
}]);
I am totally new to Angular and I'm trying to understand it by doing projects. Can anyone have a check and provide a solution?
There is no need to pass in the startDate and endDate variables into the ng-change method on your second datepicker; you are already tracking those variables on your $scope with ng-model.
$scope.checkErr = function() {
var start = new Date($scope.reservation.reservedFrom),
end = new Date($scope.reservation.reservedTill);
if (end < start) {
$scope.errorMsg = "End must be after start";
}
... other logic ...
};
Additionally, it may be best to just prevent a user from making bad choices.
The two errors you seem to want to guard against are: 1) the user chooses a startDate before today and 2) the user chooses an endDate before the startDate.
Both of the errors above can be prevented by modifying the minDate option within datepicker-options. Check out the $watch in this plunker -- each time we select a new start date, we can modify the minDate option for the end date and prevent user input issues.
Update (per request)
The plunker shows two datepickers, both of which have their own custom datepicker-options bound as $scope variables -- we'll be able to modify these datepicker-options to change the behavior of each datepicker.
Defaulting startDateOptions "minDate" to today (within the CTRL) makes it impossible for a user to pick a startDate before today (solving the first issue you were trying to prevent).
Placing a $watch on the startDate allows us to update the endDateOptions after any a change of the startDate. This allows us to restrict a users choices for the endDate input by setting minDate to whatever the startDate is (solving the second issue of choosing an endDate before a startDate).
There is also some logic in the $watch to adjust endDate where it makes sense (like if we first selected a valid endDate, but then selected a new startDate that would make that endDate invalid).

Multiple regular expression pattern on one text area in angular js

I have a text area field where it inputs 4 types of personal details separated by commas. I need to validate each of those 4 values using regular expression. This is my approach but it is not much of the angular way to do the validations.
var form = angular.module('form', []);
form.controller('helloController', ['$scope', function($scope){
var submitted = false;
var validNumber = new RegExp('numberRegExp');
var validArea = new RegExp('areaRegExp');
var validCity = new RegExp('cityRegExp');
$scope.submit = function(hello){
$scope.number = false;
$scope.area = false;
$scope.city = false;
if (issue){
$scope.submitted = true;
var splittedDetails = hello.details.split(",");
var trimmedDetails = $.map(splittedDetails, $.trim);
if (!validNumber.test(trimmedDetails[0])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.number = true;
}else if (!validArea.test(trimmedDetails[1])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.area = true;
}else if (!validCity.test(trimmedDetails[2])) {
$scope.inputversion.jiraIssue.$invalid = true;
$scope.city = true;
}else{
alert("Form now submitting");
}
}
};
}]);
<form class="form-horizontal" name="helloForm" ng-controller="helloController" ng-submit="submit(hello)" novalidate ng-app="form">
<div class="form-group" ng-class="{ true:'has-error'}[submitted && helloForm.personal-details.$invalid]">
<label for="helloForm" class="col-sm-2 control-label">Details</label>
<div class="col-sm-10">
<textarea class="form-control" rows="5" ng-model="hello.details" placeholder="number, area, city, details ex: 90********, XYX, XYZ" name="personal-details" required></textarea>
<p ng-show="submitted && helloForm.personal-details.$error.required" class="help-block"> Details are required.</p>
<p ng-show="submitted && number" class="help-block">Please check the format of issue number</p>
<p ng-show="submitted && area" class="help-block">Please check the format of product area</p>
<p ng-show="submitted && city" class="help-block">Please check the format of priority</p>
</div>
</div>
</form>
This approach can validate only one detail at a time. But ideally it should validate dynamically in much of the angular way. Please suggest your ideas.
Thanks
No offense, but this seems like a really bad way to validate 3 bits of expected data. Comma delimiting will only work if and only if the user puts 2 and only 2 commas into the field.
Assuming you want persisted data from the form (transfers from one page to another) you will want a Model for this module. The best way to do this is via the .service (since there is only one instance of each named service in a module in Angular). I'll also be using the format that will actually work with minified code and best practices, careof John Papa.
It also assumes you have declared the module elsewhere (declare uses brackets [] while recall does not).
angular.module('form')
.service("DataService", DataService)
DataService.$inject = ["$rootScope"];
function DataService($rootScope) {
var vm = this; //security in declaring (root)scope objects
vm.phone = {value: '', placeholder: 'Enter your phone number'};
vm.area = '';
vm.city = '';
};
Your controller would have little in it aside from the use of the $scope/$rootScope variables (with 2-way binding to fields and the Model) and your submit function for when the user tries to submit.
angular.module('form')
.controller('FormController', FormController);
FormController.$inject = ['$scope', 'DataService'];
function FormController($scope, DataService) {
var vm = this;
vm.phone = DataService.phone;
vm.area = DataService.area;
vm.city= DataService.city;
function submit() {
//persist the data to the next page/controller/etc.
DataService.number = vm.number;
DataService.area = vm.area;
DataService.city = vm.city;
//do work here
};
You can do all of your validation within your HTML, using Angular's 2-way binding of data. Assuming you're also using BootStrap, each field should look similar to the below:
<!-- phone field (required/validated) -->
<div class="row form-group" ng-class="{'has-warning': helloForm.phone.$invalid && helloForm.phone.$dirty,'has-error': helloForm.phone.$error.required && helloForm.phone.$touched}">
<label for="phone" class="col-md-3 control-label">Phone:</label>
<div class="col-md-9">
<input type="text" id="phone" name="phone" ng-model="vm.phone.value" placeholder="{{vm.phone.placeHolder}}" value="{{vm.phone.value}}" ng-required="true"class="skinny form-control" ng-pattern="/^\+?[-0-9)(]{8,31}[0-9x]{0,6}$/i" />
<p class="required" ng-show="helloForm.phone.$invalid || helloForm.phone.$error.required">*</p>
<p class="good" ng-show="helloForm.phone.$valid">✔</p>
</div>
<p class="help-block" ng-show="helloForm.phone.$error.pattern && helloForm.phone.$dirty">Phone format: +15558675309x52 or (555)867-5309x52</p>
<p class="help-block" ng-show="helloForm.phone.$error.required && helloForm.phone.$touched">Phone is a required field</p>
</div><br />
Rather than my E.164 (for international numbers) and American Standard phone combination validation (regex inside the ng-pattern field), you can use curly braces to declare your variable regex comparable. I hope this helps or at least points you in the right direction.
Thanks for reading,
C§

How to dynamically change input value

I'm trying to show some editable results to the users, so I show them through an input field. This is a basic example of what I'm doing:
<div class="form-group">
<label>First number</label>
<input type="text" ng-model="first" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>Second number</label>
<input type="text" ng-model="second" ng-required="true" class="form-control">
</div>
<div class="form-group">
<label>The sum is: {{first + second }}</label>
<input type="text" ng-model="result" ng-required="true" class="form-control">
</div>
In the result's div, I used a label to test if the result is being obtained correctly, and it is. But if I edit the first or second values, the input's result doesn't update.
This is the controller used (yeah, the form is in a modal):
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.result = $scope.first + $scope.second;
$scope.confirm = function () {
$modalInstance.close(result);
};
$scope.cancelNewBet = function () {
$modalInstance.dismiss('cancel');
};
};
I thought the value was supposed to get automatically updated once I define how it is obtained. But clearly it misses something to change the result through script...
Thanks in advance.
What do you want to happen when the user edits the results input? Do you want the data binding to break (I assume not and ignore this possibility)? Do you want one of the inputs to adjust to the proper value?
If you only want to display the output, do this, in your controller:
$scope.result = function() { return $scope.first + $scope.second; }
And in your view:
{{ result() }}
But if you want the user to be able to edit the result and (let's say) have second be assigned (result - first), then you'd want something like this in your view (by the way, note the type="number"):
<input type="number" ng-change="adjustResult()" ng-model="first">
<input type="number" ng-change="adjustResult()" ng-model="second">
<input type="number" ng-change="adjustInput()" ng-model="result">
And in your controller:
$scope.adjustResult = function() {
$scope.result = $scope.first + $scope.second;
};
$scope.adjustResult(); // initialize result
$scope.adjustInput = function() {
$scope.second = $scope.result - $scope.first;
}

Resources