uib-datepicker : minDate doesn't seem to work - angularjs

I don't know how to make the minDate property of my uib-datepicker work.
Here is what I have done:
<div class="form-group">
<div class="col-md-6">
<label class="col-md-4 control-label" for="field_dateDebut">Date Début</label>
<div class="col-md-5">
<div class="input-group">
<input id="field_dateDebut" type="text" class="form-control" name="dateDebut" uib-datepicker-popup="{{dateformat}}" ng-model="vm.mission.dateDebut" is-open="vm.datePickerOpenStatus.dateDebut"
/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="vm.openCalendar('dateDebut')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
</div>
<div class="col-md-6">
<label class="col-md-4 control-label" for="field_dateFinPrevisionnelle">Date Fin Prévisionnelle</label>
<div class="col-md-5">
<div class="input-group">
<input id="field_dateFinPrevisionnelle" type="text" class="form-control" name="dateFinPrevisionnelle" uib-datepicker-popup="{{dateformat}}" ng-model="vm.mission.dateFinPrevisionnelle" is-open="vm.datePickerOpenStatus.dateFinPrevisionnelle" minDate = "vm.mission.dateDebut"
/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="vm.openCalendar('dateFinPrevisionnelle')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
</div>
</div>
When I click on the first date, I want to disable all the dates previous to this date in the second datepicker.
If anyone has any idea...
Thank you.

As jmoreno pointed out, minDate is a property of an object and that object you need to pass through datepicker-options attribute in the element.
vm.dateOptions2 = {
minDate: new Date()
};
<input id="field_dateFinPrevisionnelle" type="text" class="form-control" name="dateFinPrevisionnelle"
ng-model="vm.mission.dateFinPrevisionnelle"
uib-datepicker-popup="{{dateformat}}"
datepicker-options="vm.dateOptions2"
is-open="vm.datePickerOpenStatus.dateFinPrevisionnelle"/>
This is the basic. Now as you want to set the second datepicker's minDate to the first datepicker's selected date, you can use ng-change of the first datepicker element to change the minDate in vm.dateOptions2 object of the second datepicker.
<input id="field_dateDebut" type="text" class="form-control" name="dateDebut"
ng-model="vm.mission.dateDebut"
uib-datepicker-popup="{{dateformat}}"
ng-change="vm.setSecDatepickerMinDate()"
is-open="vm.datePickerOpenStatus.dateDebut" />
vm.setSecDatepickerMinDate = function() {
// to change the minDate of the second datepicker
vm.dateOptions2.minDate = vm.mission.dateDebut;
// updating the current vm.mission.dateFinPrevisionnelle date to vm.mission.dateDebut.
// I don't want any previous date keep setting in vm.mission.dateFinPrevisionnelle
vm.mission.dateFinPrevisionnelle = angular.copy(vm.mission.dateDebut);
}
This plunker will give you more clear idea.

As you can see on docs (https://angular-ui.github.io/bootstrap/#/datepicker) minDate is a property of a config Javascript object passed in datepicker-options to datepicker directive.

Related

Sharing controllers in angularjs

I have two date-pickers, one text field and a button in one form as below:
<div class="form-group">
<label class="control-label">Date End </label>
<div class="controls">
<p class="input-group" ng-controller="datePickerCtrl">
<input type="text" name="endDate" class="form-control" uib-datepicker-popup="{{format}}" ng-model="dt" is-open="popup1.opened" datepicker-options="dateOptions" ng-required="true" close-text="Close" alt-input-formats="altInputFormats" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<div class="form-group">
<label class="control-label">Staff </label>
<div class="controls">
<input type="text" name="name" class="form-control" ng-model="staff.name">
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4">
<div class="btn-group" role="group" aria-label="Close">
<button type="button" class="btn btn-primary" ng-click="userClickedCancel()">Filter</button>
</div>
</div>
<div class="col-md-4"></div>
</div>
As can be seen, each date-picker has the same controller: datePickerCtrl. I would like to have one controller attached to the whole form that will utilise the dates returned by the date-pickers and the text field. However, I'm not sure how to do it since both date-pickers are returning the date as ng-model=dt.
I do not want to copy paste the datePickerCtrl code in multiple places with a different variable to dt in each instance. I also don't want to create one controller and copy the datePickerCtrl into it since I would like to keep the code for date-picker separate. What's the best way to do this? Thanks.

Toggle class on input depending on input's value

I am still new to Angular but I have an existing application that uses Angular 1.5 pretty heavily.
I have a basic form that I need to add a class to depending on the following criteria:
The form can only have an End Date value or an Active for value. It cannot have both. I was thinking I need to disable the input box of the input not being used.
Ex. If a user inputs a date into the End Date input, then the Active for input will become disabled.
I looked into ng-if but every example I came across was for checking if the entered input variable was empty or equal to a value in a .js controller, not checking if the current entered variable was equal to another entered variable in the form.
<div class="form-group">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Here is a screenshot of my modal where this happens. Ignore the other inputs as they are not affected by the conditions I've laid out.
Thanks
Form Screen Shot
You can use ng-disabled.
//initialize your dates with null
$scope.updatePatientLabel = {};
$scope.updatePatientLabel.active_end_date = null;
$scope.updatePatientLabel.expiration_time_number = null;
HTML:
<input id="endDate" ng-disabled="updatePatientLabel.expiration_time_number !== null" ng-model="updatePatientLabel.active_end_date" />
<input id="activeDate" ng-disabled="updatePatientLabel.active_end_date !== null" ng-model="updatePatientLabel.expiration_time_number" />
You have a few options. Classes, as you mentioned, or ng-if. The ng-if seems more elegant, like so:
<div class="form-group" ng-if="updatePatientLabel.active_end_date != ''">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group" ng-if="updatePatientLabel.expiration_time_number > 0">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
Otherwise, you could do an inline conditional outputting "hidden" inside the class attribute only if the value is not present. Something like this:
<div class="form-group {{updatePatientLabel.active_end_date != '' ? '' : 'hidden'}}">
<label>End date:</label>
<div class="input-group">
<input type="text" class="form-control" is-open="endDateOpened" uib-datepicker-popup="MM/dd/yyyy" ng-model="updatePatientLabel.active_end_date"/>
<span class="input-group-btn">
<button type="button" class="btn btn-search" ng-click="openEndDate($event)"><i class="fa fa-calendar"></i></button>
</span>
</div>
</div>
<div class="form-group {{updatePatientLabel.expiration_time_number > 0 ? '' : 'hidden'}}">
<label>Or will be active for:</label>
<input name="expirationTimeNumber" type="number" class="form-control time" ng-model="updatePatientLabel.expiration_time_number"/>
</div>
I use both in my projects, and either way is perfectly acceptable. Though, ng-if does seem more elegant and a bit more suited for this scenario.

howto use ui.bootstrap.datepickerPopup with html form

I'm using ui.bootstrap.datepickerPopup with angular forms, but i also want to use it with ASP.Net html forms. If i use an MVC EditorTemplate as below
//Date.cshtml
#{
var prop = ViewData.ModelMetadata.PropertyName;
var required = ViewData.ModelMetadata.IsRequired;
<p class="input-group" >
<input type="text" uib-datepicker-popup="dd/MM/yyyy" id="#prop" name="#prop" ng-model="#prop" #required class="form-control" ng-required="true" is-open="#(prop)Open" init-date="new Date()" value="#ViewData.Model"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="#(prop)Open = !#(prop)Open"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
}
I can select a date and it correctly posts. However when i try and edit a form with an existing Date value, i cannot get it to pre populate the date. Can the init-date be passed inline? I've tried to test this in a plunkr here. http://plnkr.co/edit/glVfsqNVst11IxRvF3tJ?p=preview
You have to set it through datepicker-options as shown below.
<input type="text" uib-datepicker-popup="dd/MM/yyyy" id="#prop" name="#prop" ng-
model="#prop" #required class="form-control" ng-required="true" is-
open="#(prop)Open" datepicker-options="{minDate:'#ViewData.DateOptions'}" value="#ViewData.Model"/>
try this instead ... bootstrap 3 datepicker version 4. You can set the default value as well
https://eonasdan.github.io/bootstrap-datetimepicker/
code snippets from the site ...
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker5'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker5').datetimepicker({
defaultDate: "11/1/2013",
disabledDates: [
moment("12/25/2013"),
new Date(2013, 11 - 1, 21),
"11/22/2013 00:53"
]
});
});
</script>
</div>
</div>
datepicker init has a bug... see this forum..
https://github.com/angular-ui/bootstrap/issues/2331

How to validate required bootstrap date field in angularjs using ng-required

I am unable to validate required bootstrap date field in angularjs using ng-required. Here is my code.
<div class="form-group col-md-12">
<label class="control-label col-md-4" style="text-align: left;" for="Date">Date:<span style="color:red;">*</span></label>
<div class="col-md-8">
<div class='input-group date' id='assignWODate'>
<input type='text' class="form-control" ng-model="woAssignedDate" bs-datepicker ng-required="woAssignedDate" ng-readonly="true" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
You cannot do validation ng-required while it is readonly
see fiddle
<form>
<label class="control-label col-md-4" style="text-align: left;" for="Date">Date:<span style="color:red;">*</span></label>
<div class="col-md-8">
<div class='input-group date' id='assignWODate'>
<input type='text' class="form-control" ng-model="woAssignedDate" bs-datepicker ng-required="woAssignedDateIsRequired" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<input type="submit" value="submit">
</form>
I have solved the above issue by including a forceParse: false attribute in my script tag and making it readonly field. No need for any other validation.
$('#assignWODate').datepicker({
autoclose:true,
format: 'mm/dd/yyyy',
todayHighlight: true,
startDate: dt,
forceParse: false
});

Set a form input to dirty in angularjs?

I have a form that I auto input the current date into an input field. I want to set the input field to dirty because when it tries to sync with firebase, that input field is not included unless you interact with it.
I have tried the following in many different forms...and I am at a loss.
var now = new Date();
$scope.load = function () {
if (!$rootScope.auth) {
$location.path('/a/');
} else {
$scope.logs = Logs.list($scope);
$scope.newDate = now;
$scope.logForm.$setDirty(true);
}
};
<form name="logForm" novalidate class="css-form">
<div class="form-group input-group">
<input class="form-control" name="action" placeholder="Action" type="text" value="{{newAction}}" ng-model="newAction" required />
<div class="input-group-addon">
<i class="fa fa-rocket"></i>
</div>
</div>
<div class="form-group input-group">
<input class="form-control" name="quantity" placeholder="Quantity" type="number" value="{{newQuantity}}" ng-model="newQuantity" ng-pattern="/^[0-9]*$/" />
<div class="input-group-addon">
<i class="fa fa-plus-square"></i>
</div>
</div>
<div class="form-group input-group">
<input class="form-control" name="location" placeholder="Location" type="text" value="{{newLocation}}" ng-model="newLocation" />
<div class="input-group-addon">
<i class="fa fa-map-marker"></i>
</div>
</div>
<div class="form-group input-group">
<input class="form-control" name="date" placeholder="Date" type="datetime" value="{{newDate}}" ng-model="newDate" />
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
</div>
<button class="btn btn-info btn-block" ng-click="create()">Add log</button>
</form>
The form tag creates its own scope, so to have a reliable scope structure, we shouldn't use primitives for the ng-model values.
To ensure, that we have access to the form controller, we have to delay the form initialization into the next digest cycle. This is achieved with the use of the $timeout service.
http://jsbin.com/OvIvIHO/3/
jsbin contains the updated version

Resources