Angular 2 datepicker two way data binding - javascript

I have the following code:
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right input-sm" id="datepickerTo" [ngModel]="dateTo | date:'yyyy-MM-dd'" (ngModelChange)="dateTo = $event" name="nameTo">
</div>
I have component class and declared dateTo parameter.
public dateTo: Date;
constructor() {
this.dateTo = new Date();
this.dateTo.setDate(this.dateTo.getDate() + 30);
}
When I load page it shows date properly, but when I change date on picker choose different date, value in component class does not change. Any idea how to fix this problem?

Related

JavaScript / jQuery - calculate number of days, receiving input data and output data

I have two fields of data entry, date of entry and date of out, which receive data using a datepicker. Is it possible to calculate the number of days, take into account the values of the date of entry and date of out, and save it in the field number of nights? How can I do this?
HTML
<div class="form-group">
<label class="col-md-4 control-label">Date Entry</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span>
<input name="DateEntry" id="DateEntry" class="form-control" type="text">
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">DateOut</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span>
<input name="DateOut" id="DateOut" class="form-control" type="text">
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">NÂșNights</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-list-ol"></i></span>
<input name="Nights" class="form-control" type="text">
</div>
</div>
</div>
var start = $('#DateEntry').val();
var end = $('#DateOut').val();
// end - start returns difference in milliseconds
var diff = new Date(end - start);
// get nights
var days = diff/1000/60/60/24;
//set nights
$('#Nights').val(days)
This is client side code. You have to call this from document.load or may be onchange event of both entry and out dates.
Here's a similar approach with the hook to handle the text changing.
<html>
<head>
<title>Date Diff in Nights</title>
</head>
<body>
<div id="container">
<span class="input-group-addon"><i class="glyphicon glyphicon-time">entry</i></span>
<input name="DateEntry" id="DateEntry" class="form-control" type="text" >
<span class="input-group-addon"><i class="glyphicon glyphicon-time">out</i></span>
<input name="DateOut" id="DateOut" class="form-control" type="text" >
<span class="input-group-addon"><i class="fa fa-list-ol">nights</i></span>
<input name="Nights" id="Nights" class="form-control" type="text">
</div>
<script type="text/javascript">
var input = document.getElementById('DateEntry');
input.addEventListener('input', calcNights);
var input2 = document.getElementById('DateOut');
input2.addEventListener('input', calcNights);
function calcNights() {
try {
var nightsout = document.getElementById('Nights');
var element = document.getElementById('DateEntry');
var entryDate = new Date(element.value);
var out = document.getElementById('DateOut');
var outDate = new Date(out.value);
// Set to noon to avoid any DST errors
outDate.setHours(12, 0, 0);
entryDate.setHours(12, 0, 0);
var difference = outDate - entryDate;
var nights = Math.round(difference / 8.64e7);
if (isNaN(nights) || nights < 0) {
nightsout.value = '';
return;
}
nightsout.value = nights;
}
catch (ex) {
//ignore
}
}
</script>
</body>
</html>
Here is working code with your update of date format being DD/MM/YYYY:
jQuery
I highly suggest using Momentjs. It is user friendly and very powerful when working with dates & times! That is what my solution will use. Otherwise you will have to do a bunch of parsing in order to match your date format. Just make sure that your format doesn't change or else you will have to edit this!
$(document).ready(function() {
$('#TestOne').datetimepicker({
format: 'DD/MM/YYYY HH:mm:ss',
});
$('#TestTwo').datetimepicker({
format: 'DD/MM/YYYY HH:mm:ss',
});
$("#DateOut").blur(function() {
var str1 = $("#DateEntry").val();
var str2 = $("#DateOut").val();
var dateEntry = moment(str1, "DD/MM/YYYY");
var dateOut = moment(str2, "DD/MM/YYYY");
var range = dateOut.diff(dateEntry, 'days');
$("#NightsBetween").val(range);
});
});
UPDATED FIDDLE
Here is a working JSFiddle
Hope this helps

Angular2 datepicker input data-binding

I have angular2 app where I have used datepicker.In which I am binding value initially from json(01.01.9999 01:00) and some other setting.
It works fine but there one button which sets specific date (01.01.2099 00:00).
It works fine as well but in datepicker input value is getting unchanged.
How can I fix this problem.
<div class="form-group">
<label class="col-sm-3 control-label">End Date :</label>
<div class="col-md-6" style="bottom: 22px">
{{break.EndDate | amDateFormat:'DD.MM.YYYY HH:mm'}}
<date-time-datepicker [Id]="'endDate'" (dateSelected)="endDate = $event" initValue="{{break.EndDate | amDateFormat:'YYYY-MM-DD HH:mm'}}" viewformat="DD.MM.YYYY HH:mm" postformat="YYYY-MM-DD HH:mm" caption=""></date-time-datepicker>
</div>
<div class="col-sm-3">
<button type="button" class="btn btn-warning" (click)="setMaxBreakEndDate()">MAX</button>
</div>
</div>
setMaxSelectedBreakValidTo() {
this.break.EndDate = moment(new Date(2099, 0, 1, 0, 0, 0)).format('YYYY-MM-DD HH:mm');
}

Vue-js removed selected date from textbox when add new element

Vue-js remove selected date from textbox when add new element. if i entered any text instead of date and add new element text is display as is it. but date is removed.
below is my HTML code
<div class="dateAvailabilityContainer">
<div class="dateAvailability" v-for="(date, index) in dates">
<div class="form-group date">
<input type="text" v-model='date.date' class="form-control date" v-bind:class="'datepicker_'+index" placeholder="Date">
</div>
<div class="form-group">
<input type="text" v-model='date.from' class="form-control from" placeholder="From">
</div>
<div class="form-group">
<input type="text" v-model='date.to' class="form-control to" placeholder="To">
</div>
<a href="#" v-if="index == 0" class="btn btn-success" v-on:click="addNewDate">
<i class="fa fa-plus"></i>
</a>
<a href="#" v-if="index > 0" class="btn btn-danger" v-on:click="removeThisDate(index)">
<i class="fa fa-minus"></i>
</a>
</div>
</div>
and below is my vue-js code
var addAvailability = new Vue({
el: '#addAvailability',
data: {
dates : [{
date : '',
from : '',
to : '',
}],
},
mounted: function () {
this.addDatePicker( this.dates.length - 1 );
},
methods: {
addNewDate: function () {
this.dates.push({
date: '',
from: '',
to: '',
});
this.addDatePicker( this.dates.length - 1 );
},
removeThisDate : function(index){
this.dates.splice(index, 1);
},
addDatePicker : function( id ){
setTimeout(function(){
console.log('.datepicker_'+id);
$('.datepicker_'+id).datepicker({
autoclose: true,
});
},500);
}
}
});
please help where i create a mistake.
please check in fiddle : https://jsfiddle.net/renishkhunt/bod4ob5y/19/
Thanks
Bootstrap (js) and jquery aren't friendly working with vue.
I think that it is because they modify DOM directly while vue also has a virtual DOM and works in a more data driven way.
Make them work together requires extra logic, I could only fix datetimepicker, I never haven't work with clockpicker before
First I change addNewDate function
//Save new date in a variable
var dateModel = {
date: '',
from: '',
to: '',
};
this.dates.push(dateModel);
var elementId = "datepicker_"+(this.dates.length - 1);
//pass new date to initDate function
this.initDate( elementId, dateModel );
In initDate we need to listen for date changes and update model
$('#'+id).datepicker({
...
}).on('changeDate', function(e){
dateModel.date = e.format();
});
Please see this partially working fiddle
As alternative you could use vue-flatpickr, at this moment is the best "vue's way" that I have found to handle date time inputs

AngularJS datepicker using date-set

I've been trying out this AngularJS package (https://www.npmjs.com/package/angularjs-datepicker) and was struggling to use the date-set property. In my example I have 2 calendars, 1 that should display yesterdays date and 1 that should display todays date. Could someone please help me set these dates?
Datepicker:
<div class="datepicker-container">
<div class="date-from">
From:
<datepicker date-format="dd/MM/yyyy" selector="form-control" date-set="{{}}" class="date-picker">
<div class="input-group">
<input class="form-control" placeholder="Choose a date"/>
<span class="input-group-addon" style="cursor: pointer">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</datepicker>
</div>
<div class="date-too">
To:
<datepicker date-format="dd/MM/yyyy" selector="form-control" date-set="{{}}" class="date-picker">
<div class="input-group">
<input class="form-control" placeholder="Choose a date"/>
<span class="input-group-addon" style="cursor: pointer">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</datepicker>
</div>
</div>
Setting the date:
$scope.dateFrom = new Date();
$scope.dateTo = new Date();
var date = new Date();
$scope.today = date; //to show today's date
date.setDate(date.getDate() - 1); //to get yesterday's date, Ref:http://stackoverflow.com/questions/5511323/javascript-yesterday
$scope.yesterday = date;
Using date-set:
From the documentation linked above, https://www.npmjs.com/package/angularjs-datepicker . I see you have to pass date object as string to attribute date-set , hence convert the date object to string.
//js
var date = new Date();
$scope.today = date.toString(); //to show today's date
date.setDate(date.getDate() - 1); //to get yesterday's date, Ref:http://stackoverflow.com/questions/5511323/javascript-yesterday
$scope.yesterday = date.toString();
//html
<datepicker date-format="dd/MM/yyyy" selector="form-control" date-set="{{today}}" class="date-picker">
<datepicker date-format="dd/MM/yyyy" selector="form-control" date-set="{{yesterday}}" class="date-picker">
see this plnkr http://plnkr.co/edit/mDHliPweKoUNOAmVv5oo?p=preview
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<pre>Raw date is: <em>{{dt}}</em></pre>
I solved it in a simpler way, just activated the ng-if attribute in the div before the datepicker
pagamentoService.getCronograma(moment().year()).then(function (resp){
var cronogramas = resp.data;
console.log('99',resp.data);
cronogramas.forEach(function (obj){
vm.datasBloqueadas.push(moment(obj.data_limite).format('YYYY-M-D'));
});
}).catch(function (err){
console.log(err);
});
<div class="col-md-4 mt-1">
<label>data vencimento</label>
<div ng-if="Beneficios.datasBloqueadas.length > 0" class="input-control full-size text">
<datepicker date-format="yyyy-MM-dd" date-disabled-dates="{{Beneficios.datasBloqueadas}}" >
<input id="dataVencimento" class="required" type="date" date-converter ng-model="Beneficios.view.data_filter"
data-role="hint" data-hint-background="bg-orang-e"
data-hint-color="fg-white" data-hint-position="bottom" data-hint-mode="2">
<button class="button" onclick="$('#dataVencimento').focus();">
<span class="mif-calendar"></span>
</button>
</datepicker>
</div>

Convert/map inputs of date (day, month, year) into java.time.LocalDate

This is what we have in the interface:
I pasted the parts of the code what I thought that are relevant, but maybe something more is required.
How it works
When the button is pushed, the userController.js save method is invoked. In the controller there is a $resource and the $save method is "connected" with the create method in UserController.java, and there is persisted.
The problem
In the interface I have three inputs (dd, mm, yy) and what I want to persist is a User with a java.time.LocalDate. How and where should I do the map/transformation of these three inputs to convert then in a LocalDate? Because obviously, the way the User is defined in the .js and the way is defined in .java are differents.
In the frontend
user.html
<div class="form-group">
<label class="col-sm-2 control-label">Date of Birth</label>
<div class="col-sm-10">
<div class="form-inline">
<div class="form-group">
<label class="sr-only" for="txt_day">Enter Day</label>
<div class="col-sm-2">
<input type="text" id="txt_day" ng-model="user.birthdate.day" class="form-control" placeholder="DD" required maxlength="2"
data-validation-required-message="Day is required">
</div>
</div>
<div class="form-group">
<label class="sr-only" for="txt_month">Enter Month</label>
<div class="col-sm-2">
<input type="text" id="txt_month" ng-model="user.birthdate.month" class="form-control" placeholder="MM" required
maxlength="2" data-validation-required-message="Month is required">
</div>
</div>
<div class="form-group">
<label class="sr-only" for="txt_year">Enter Year</label>
<div class="col-sm-2 ">
<input type="text" id="txt_year" ng-model="user.birthdate.year" class="form-control" placeholder="YY" required
maxlength="4" data-validation-required-message="Year is required">
</div>
</div>
</div>
</div>
</div>
userController.js
$scope.user = new UserService();
$scope.save = function() {
$scope.user.$save(function() {
$location.path('/');
});
};
UserService.js
return $resource('rest/user/:action', {},....
In the backend
UserController.java
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public User create(User user) {
LOGGER.info("create(): " + user);
return this.userDao.save(user);;
}
Entity
#Column(nullable = false)
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate birthDate;
Well, honestly I see that your application is exposing your domain entities to outside through rest service. I wouldn't suggest to do in order to ensure separation of concern principle. This issue you are now having is because of that. If adding a services/dto layers is a bit cucumber in your application, one workaround could be:
#Entity
public class User{
#Column(nullable = false)
#Convert(converter = LocalDatePersistenceConverter.class)
private LocalDate birthDate;
#Transient
private birthDay
#Transient
private birthMonth
#Transient
private birth birthYear
..
#PrePersist
protected void prePersist()
{
birthDate = new LocalDate(birthDay, birthMonth, birthYear)
}
}
So your entity gets populated from your javascript component and the jpa provider makes the tweaking creating a jodatime object.
Hope this works

Categories