ExtJS DateField - initialising date - extjs

I have an ExtJS Date field. During some operation in the application, min value and max value get assigned to the date field. The min value and max value are 4 years prior to the current dat, but when the date picker opens up, it opens to the disabled current dates. The user has to manually scroll back 4 years to select a date. Anyways I can update the datepicker to open up by showing the date between the min value and max value ?
Adding code:
cmpDt.setMinValue(new Date(2000, 0, 1));
cmpDt.setMaxValue(new Date(2004, 0, 1));
this sets the min and max value. I cant use setValue() because it inialises/changes the textfield. I want the textfield to get value only on selection from the datepicker.
Thanks

You have to set an initial value using the value property of the Ext.form.field.DateView:
{
...,
minValue: new Date(2000, 0, 1),
maxValue: new Date(2004, 11, 31),
value: new Date(2002, 5, 15),
...
}
EDIT after more info from the OP:
You may override the onExpand method that initializes the value on the picker. The original one looks like (given that you use ExtJS 4 - but 3 should not be that much different):
...,
onExpand: function() {
var value = this.getValue();
this.picker.setValue(Ext.isDate(value) ? value : new Date());
},
...
You could override the method to read:
...,
onExpand: function() {
var value = this.getValue(),
myDefaultDate = /* do some processing to determine the default date*/;
this.picker.setValue(Ext.isDate(value) ? value : myDefaultDate);
},
...
Just add the override to the initial form field configuration.

For anyone interested in an EXTJS 3 solution to this problem, I've made the following code.
This allows you to pass initialDateToShowOnPicker as a config to the Ext.DatePicker when declaring it, if needed.
It also allows you to call setInitialDateToShowOnPicker(initialDateToShowOnPicker) on the datepicker component to set it dynamically.
Both require a Date() type to be used, and there cannot be a value already set on the datepicker.
if (Ext.versionDetail && Ext.versionDetail.major == 3) {
Ext.form.DateField.prototype.setInitialDateToShowOnPicker = function (initialDateToShowOnPicker) {
this.initialDateToShowOnPicker = initialDateToShowOnPicker;
};
Ext.form.DateField.override({
onTriggerClick: function() {
if(this.disabled){
return;
}
if(this.menu == null){
this.menu = new Ext.menu.DateMenu({
hideOnClick: false,
focusOnSelect: false
});
}
this.onFocus();
Ext.apply(this.menu.picker, {
minDate : this.minValue,
maxDate : this.maxValue,
disabledDatesRE : this.disabledDatesRE,
disabledDatesText : this.disabledDatesText,
disabledDays : this.disabledDays,
disabledDaysText : this.disabledDaysText,
format : this.format,
showToday : this.showToday,
startDay: this.startDay,
minText : String.format(this.minText, this.formatDate(this.minValue)),
maxText : String.format(this.maxText, this.formatDate(this.maxValue)),
initialDateToShowOnPicker: this.initialDateToShowOnPicker // Date() type
});
this.menu.picker.setValue(this.getValue() || this.initialDateToShowOnPicker || new Date());
this.menu.show(this.el, "tl-bl?");
this.menuEvents('on');
}
}); }

Related

Validate formly angularjs fields are not the same

I have dynamically added fields on click.
addNewFiled() {
let parent = this;
this.scope.fields.push({
key: 'field-'+parent.scope.fields.length,
type: 'horizontalInput',
templateOptions: {
placeholder :'Enter Field',
label: 'Filed',
required: false
},
validators: {
fieldFormat: function($viewValue, $modelValue, scope) {
let value = $viewValue;
if(value.length != 12){
scope.to.message = "Field should be 12 characters";
return false;
}
return true;
}
}
});
}
What I need is to validate the the value entered is not in another field in the validator, I tried looping through the model but its not efficient, any help is appreciated.
I have encountered this case once, I solved the issue using 2 maps
Basically, you will have 2 maps, one which will contain the index of the field mapped to the value of it, the second map will contain the value of the field mapped to the number of the repetitions of that value
In your validator, you decrement the number of repetitions for the previous value ( after done with other validations) and increase the number of repetitions of the new value and check if it's more than 1 then it's repeated.
In your Dialog define the two maps
private valuesMap: any = [];
private keysArray:any = [];
In your field, you inject a controller to save the index of the current field
controller: function ($scope) {
$scope.index = parent.scope.fields.length-1;
parent.keysArray[$scope.index] = $scope.index;
},
then in your validator
if(value) {
if(angular.isDefined(parent.valuesMap[parent.keysArray[scope.index]])) {
parent.valuesMap[parent.keysArray[scope.index]]= parent.valuesMap[parent.keysArray[scope.index]] -1;
}
parent.keysArray[scope.index] = value;
if(angular.isDefined(parent.valuesMap[value]) && parent.valuesMap[value] > 0) {
parent.valuesMap[value] = parent.valuesMap[value]+1;
scope.to.message = "Value is already entered";
return false;
}
parent.valuesMap[value] = 1;
}
Hope this works with your scenario
You don't need a validator on this, there is already default validation for field length through the minlength and maxlength properties in the templateOptions.
Simply do this:
templateOptions: {
placeholder :'Enter Field',
label: 'Filed',
required: false,
minlength: 12,
maxlength: 12
},

angular material date picker field value empty

I want to get date of birth of a user, with predefined min and max date which is working fine.
And the date format i want is DD-MM-YYYY, for this i have defined following in config;
app.config(['$mdDateLocaleProvider', function ($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
return moment(date).format('DD-MM-YYYY');
}}]);
and the controller has
$scope.user = {};
$scope.user.dob = new Date();
$scope.maxDate = new Date(
$scope.user.dob.getFullYear() - 10,
$scope.user.dob.getMonth(),
$scope.user.dob.getDate()
);
$scope.minDate = new Date(
$scope.user.dob.getFullYear() - 120,
$scope.user.dob.getMonth(),
$scope.user.dob.getDate()
);
and the HTML is;
<md-datepicker
ng-model="user.dob"
md-placeholder="Enter date of birth"
md-min-date="minDate"
md-max-date="maxDate">
</md-datepicker>
with this code the field shows current date by default, which i don't want,
i want the date field to be empty by default.
Also i want to get values in both ways as follows
1) date-month-year
And
2) date-month-year hour-minutes-seconds
When i tried to get the value it shows this "09-11-2016T18:30:00.000Z"
i want either "09-11-2016" or "09-11-2016 18:30:00"
Your mdDateLocaleProvider doesnt check for null values.
Your Problem is:
app.config(['$mdDateLocaleProvider', function ($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
return moment(date).format('DD-MM-YYYY');
}}]);
it needs to be something like:
$mdDateLocaleProvider.formatDate = function(date) {
var m = moment(date);
return m.isValid()? m.format('DD-MM-YYYY') : '';
};
Then you can set
$scope.user.dob=null;
And get an empty Datepicker.
The problem is your ng-model. You're initializing it with the current date:
$scope.user.dob = new Date();
Simply empty this variable and you'll be good ;)

How to make a bootstrap date picker to have the certain dates selected

I am using angular bootstrap datepicker in my code. Problem with my requirement is that I want to have certain dates to be selected in the datepicker on which deliveries will be made. I am new to angular JS and have no Idea how to do that. Can someone help me in this ?
PS:I do not require the calendar to take input It is just needed to show the selected dates.
You can use the custom-class attribute to do this.
From the documentation
custom-class (date, mode) (Default: null) : An optional expression to
add classes based on passing date and current mode (day|month|year).
Here is a sample of the relevant handler adapted from the Angular UI Bootstrap example
...
$scope.events =
[
{
date: new Date(2015, 9, 1),
status: 'delivered'
},
{
date: new Date(2015, 9, 5),
status: 'delivered'
},
{
date: new Date(2015, 9, 15),
status: 'delivered'
}
];
$scope.getDayClass = function(date, mode) {
if (mode === 'day') {
var dayToCheck = new Date(date).setHours(0,0,0,0);
for (var i=0;i<$scope.events.length;i++){
var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);
if (dayToCheck === currentDay) {
return $scope.events[i].status;
}
}
}
return '';
};
...
Plunker - http://plnkr.co/edit/vJl8hDUfsBOJsLXFNKWQ?p=preview

Date Picker not populating after override Expand method in Extjs

I wanted to set different date in Extjs date picker by replacing default date of date picker that comes system date.
for that I override Date field - below is my code -
Ext.override(Ext.form.field.Date, {
expand: function() {
var value = this.getValue();
var customDate = '07/08/2013';
var myDate = new Date(customDate );
this.getPicker().setValue(Ext.isDate(value) ? value : myDate);
}
});
Now I was expecting myDate as default in picker.
But picker is not populating when I click on picker to select date.
Thanks
I fixed the issue myself. Here is the code to do that. Hopefully it will help someone and will save precious time.
Ext.override(Ext.form.field.Date, {
expand: function() {
var myDate = new Date('07/08/2017');
var value = this.getValue();
this.getPicker().setValue(Ext.isDate(value) ? value : myDate);
var me = this, bodyEl, picker, collapseIf;
if (me.rendered && !me.isExpanded && !me.isDestroyed) {
bodyEl = me.bodyEl;
picker = me.getPicker();
collapseIf = me.collapseIf;
me.isExpanded = true;
me.alignPicker();
bodyEl.addCls(me.openCls);
me.mon(Ext.getDoc(), {
mousewheel: collapseIf,
mousedown: collapseIf,
scope: me
}); Ext.EventManager.onWindowResize(me.alignPicker, me);
me.fireEvent('expand', me);
}
}
});

search field in a dataview in extjs

Am trying to put a search field with respect to a data view. There is a toolbar on top of the data view, which consists of a text field. On entering some text in the field, i want to call a search functionality. As of now, i have got hold of the listener to the text field, but the listener is called immediately after the user starts typing something in the text field.
But, what am trying to do is to start the search functionality only when the user has entered at least 3 characters in the text field.How could i do this?
Code below
View
var DownloadsPanel = {
xtype : 'panel',
border : false,
title : LANG.BTDOWNLOADS,
items : [{
xtype : 'toolbar',
border : true,
baseCls : 'subMenu',
cls : 'effect1',
dock : 'top',
height : 25,
items : [{
xtype : 'textfield',
name : 'SearchDownload',
itemId : 'SearchDownload',
enableKeyEvents : true,
fieldLabel : LANG.DOWNLOADSF3,
allowBlank : true,
minLength : 3
}],
{
xtype : 'dataview',
border : false,
cls : 'catalogue',
autoScroll : true,
emptyText : 'No links to display',
selModel : {
deselectOnContainerClick : false
},
store : DownloadsStore,
overItemCls : 'courseView-over',
itemSelector : 'div.x-item',
tpl : DownloadsTpl,
id : 'cataloguedownloads'
}]
Controller:
init : function() {
this.control({
// reference to the text field in the view
'#SearchDownload' :{
change: this.SearchDownloads
}
});
SearchDownloads : function(){
console.log('Search functionality')
}
UPDATE 1: i was able to get hold of the listener after three characters have been entered using the below code:
Controller
'#SearchDownload' :{
keyup : this.handleonChange,
},
handleonChange : function(textfield, e, eOpts){
if(textfield.getValue().length > 3){
console.log('Three');
}
}
any guidance or examples on how to perform the search in the store of the data view would be appreciated.
A proper way would be to subscribe yourself to the change event of the field and check if the new value has at least 3 chars before proceeding.
'#SearchDownload' :{ change: this.handleonChange }
// othoer code
handleonChange : function(textfield, newValue, oldValue, eOpts ){
if(newValue.length >= 3){
console.log('Three');
}
}
Btw. I recommend you to use lowercase and '-' separated names for id's. In your case
itemId : 'search-download'
Edit apply the filter
To apply the filter I would use filter I guess you now the field you want to filter on? Lets pretend store is a variable within your controller than you may replace the console.log() with
this.store.filter('YourFieldName', newValue);
Second param can also be a regex using the value like in the example
this.store.filter('YourFieldName', new RegExp("/\"+newValue+"$/") );
For sure you can also use a Function
this.store.filter({filterFn: function(rec) { return rec.get("YourFieldName") > 10; }});
Thanks you so much sra for your answers. Here is what i did, based on your comments
filterDownloads : function(val, filterWh){
if(filterWh == 1){
var store = Ext.getStore('CatalogueDownloads');
store.clearFilter();
store.filterBy(function (r){
var retval = false;
var rv = r.get('title');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
if(!retval){
var rv = r.get('shortD');
var re = new RegExp((val), 'gi');
retval = re.test(rv);
}
if(retval){
return true;
}
return retval;
})
}
}
i think there is an example of exactly what you are trying to achive .. http://docs.sencha.com/ext-js/4-0/#!/example/form/forum-search.html

Resources