javascript - angular2 - mat_date_locale
Cambiar el formato de md-datepicker en material angular con momentjs (13)
El material angular introdujo un nuevo componente selector de fechas que se encuentra here .
Quiero que la fecha devuelta por este componente tenga el formato
aaa-mm-dd,
pero no estoy seguro de cómo se hace.
Al buscar, descubrí que se puede usar
$mdDateLocaleProvider
, pero no pude encontrar un ejemplo de su uso.
¿Alguien puede mostrarme un ejemplo de cómo formatear la fecha devuelta por
md-datepicker
?
- Cuando usamos md-DatePicker en md-dialog, el servicio $ mdDateLocaleProvider no formatea la fecha como la necesitamos. Tenemos que usar $ mdDateLocale en el controlador de md-dialog para formatear la fecha de md-DatePicker. por ejemplo -
angular.module(''MyApp'').controller(''AppCtrl'', function($scope, $mdDateLocale) {
$mdDateLocale.formatDate = function(date) {
return moment(date).format(''YYYY-MM-DD'');
};
$scope.myDate = new Date(''2015-10-15'');
$scope.minDate = new Date();
$scope.maxDate = new Date();
});
Cambiar el formato de fecha, los nombres de mes y los nombres de semana durante el tiempo de ejecución es perfectamente posible con AngularJS 1.5.9 y el momento 2.17.1.
Primero configure el idioma inicial. (En este ejemplo, la configuración de angular-translate / $ translateProvider es opcional).
angular.module(''app'').config(configureLocalization)
configureLocalization.$inject = [''$translateProvider'', ''$mdDateLocaleProvider'', ''localdb'', ''__config''];
function configureLocalization($translateProvider, $mdDateLocaleProvider, localdb, __config) {
// Configure angular-translate
$translateProvider.useStaticFilesLoader({
prefix: ''locale/'',
suffix: ''.json''
});
// get the language from local storage using a helper
var language = localdb.get(''language'');
if (!language || language === ''undefined'') {
localdb.set(''language'', (language = __config.app.defaultLanguage));
}
// Set the preferredLanguage in angular-translate
$translateProvider.preferredLanguage(language);
// Change moment''s locale so the ''L''-format is adjusted.
// For example the ''L''-format is DD.MM.YYYY for German
moment.locale(language);
// Set month and week names for the general $mdDateLocale service
var localeData = moment.localeData();
$mdDateLocaleProvider.months = localeData._months;
$mdDateLocaleProvider.shortMonths = moment.monthsShort();
$mdDateLocaleProvider.days = localeData._weekdays;
$mdDateLocaleProvider.shortDays = localeData._weekdaysMin;
// Optionaly let the week start on the day as defined by moment''s locale data
$mdDateLocaleProvider.firstDayOfWeek = localeData._week.dow;
// Format and parse dates based on moment''s ''L''-format
// ''L''-format may later be changed
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, ''L'', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
$mdDateLocaleProvider.formatDate = function(date) {
var m = moment(date);
return m.isValid() ? m.format(''L'') : '''';
};
}
Más tarde, puede tener un controlador base que observa una variable de idioma que cambia cuando el usuario selecciona otro idioma.
angular.module(''app'').controller(''BaseCtrl'', Base);
Base.$inject = [''$scope'', ''$translate'', ''localdb'', ''$mdDateLocale''];
function Base($scope, $translate, localdb, $mdDateLocale) {
var vm = this;
vm.language = $translate.use();
$scope.$watch(''BaseCtrl.language'', function(newValue, oldValue) {
// Set the new language in local storage
localdb.set(''language'', newValue);
$translate.use(newValue);
// Change moment''s locale so the ''L''-format is adjusted.
// For example the ''L''-format is DD-MM-YYYY for Dutch
moment.locale(newValue);
// Set month and week names for the general $mdDateLocale service
var localeDate = moment.localeData();
$mdDateLocale.months = localeDate._months;
$mdDateLocale.shortMonths = moment.monthsShort();
$mdDateLocale.days = localeDate._weekdays;
$mdDateLocale.shortDays = localeDate._weekdaysMin;
// Optionaly let the week start on the day as defined by moment''s locale data
$mdDateLocale.firstDayOfWeek = localeData._week.dow;
});
}
Observe cómo no necesitamos cambiar los
$mdDateLocale.formatDate
y
$mdDateLocale.parseDate
, ya que ya están configurados para usar el formato ''L''que se cambia llamando a
moment.locale(newValue)
.
Consulte la documentación de $ mdDateLocaleProvider para obtener más personalización de la configuración regional: https://material.angularjs.org/latest/api/service/ $ mdDateLocaleProvider
Bonificación: así es como se verá el selector de idioma:
<md-select ng-model="BaseCtrl.language" class="md-no-underline">
<md-option
ng-repeat="language in [''en'', ''de'', ''fr'', ''nl'']"
ng-value ="language"
><span
class ="flag-icon flag-icon-{{language ===''en'' ? ''gb'' : language}}"
></span>
</md-option>
</md-select>
Funcionó perfectamente cuando la fecha se escribe desde el keyborard y se devuelve nulo en la iniciación para evitar el masaje ''Fecha inválida'' en la directiva md-datapicker:
$mdDateLocaleProvider.formatDate = function(date) {
return date ? moment(date).format(''DD/MM/YYYY'') : null;
};
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, ''DD/MM/YYYY'', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
Hay una documentación para
$mdDateLocaleProvider
en los documentos de material angular.
angular.module(''app'').config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
return moment(date).format(''YYYY-MM-DD'');
};
});
Si no utiliza moment.js, sustituya el código dentro de
formatDate
por lo que desee utilizar para formatear la fecha.
Here hay un ejemplo de CodePen basado en las muestras de documentos de material angular.
Me gustaría proporcionar mi solución basada 100% en la publicación de Christiaan Westerbeek . Realmente me gusta lo que hizo, pero personalmente quería algo un poco más simplista.
appConfig.js
// config params in global scope that need to be set outside of Angular (due to Angular limitiations)
var appConfig = {
// enables the dynamic setting of md-datepicker display masks (eg. when user changes language from English to Spanish)
date: {
// default mask
format: "MM/dd/yyyy",
// md-datepicker display format
mdFormatDate: function (date) {
if (date && date instanceof Date) {
return date.format(appConfig.date.format);
} else {
return null;
}
}
}
};
app.material.config.js
// set angular material config
app.config([''$mdDateLocaleProvider'', function ($mdDateLocaleProvider) {
// this is a global object set inside appConfig.js
$mdDateLocaleProvider.formatDate = appConfig.date.mdFormatDate;
}]);
algún archivo de servicio que se ocupa de localización / traducciones / etc.
// inside the service where you''d track the language/locale change
service._updateConfigDateFormat = function (theNewDateFormat) {
// where theNewDateFormat is something like ''yyyy/MM/dd'' or whatever
daepConfig.date.format = theNewDateFormat;
};
Cabe señalar que esta solución no volverá a formatear en vivo los valores de visualización de su md-datepicker. Solo funcionará cuando el modelo cambie los valores.
Para
angular-material
> =
5.xx
La forma recomendada de usar otros formatos de fecha personalizados / predefinidos se describe en la documentación del material angular:
Un ejemplo de implementación utilizando moment.js para personalizar y analizar formats visualización de fecha y hora:
...
import { MomentModule } from ''angular2-moment'';
import { MatMomentDateModule, MomentDateAdapter, MAT_MOMENT_DATE_FORMATS } from ''@angular/material-moment-adapter'';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from ''@angular/material/core'';
...
// moment formats explanation: https://momentjs.com/docs/#/displaying/format/
export const MY_FORMATS = {
parse: {
dateInput: ''YYYY-MM-DD'',
},
display: {
dateInput: ''YYYY-MM-DD'',
monthYearLabel: ''MMM YYYY'',
dateA11yLabel: ''YYYY-MM-DD'',
monthYearA11yLabel: ''MMMM YYYY'',
},
};
...
@Component({
...
providers: [
// `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
// `MatMomentDateModule` in your applications root module. We provide it at the component level
// here, due to limitations of our example generation script.
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
// {provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS},
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS}
]
})
...
Dependiendo de su implementación, dentro del componente también puede necesitar usar:
date = new FormControl(moment());
También debe instalar la biblioteca de Moment y el adaptador para Angular:
https://www.npmjs.com/package/angular2-moment
npm install --save angular2-moment
https://www.npmjs.com/package/@angular/material-moment-adapter
npm install --save @ angular / material-moment-adapter
Para abordar también el problema señalado por kazuar:
Lamentablemente no funciona si la fecha se escribe desde el teclado
También debe definir el método parseDate. De los documentos:
$mdDateLocaleProvider.parseDate = function(dateString) {
var m = moment(dateString, ''L'', true);
return m.isValid() ? m.toDate() : new Date(NaN);
};
Para un ejemplo completo, tengo en mi aplicación (usando momento):
$mdDateLocaleProvider.formatDate = function(date) {
return 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);
};
Saludos
Para aquellos que no usan Moment.js, puede formatear como una cadena:
.config(function($mdDateLocaleProvider) {
$mdDateLocaleProvider.formatDate = function(date) {
var day = date.getDate();
var monthIndex = date.getMonth();
var year = date.getFullYear();
return day + ''/'' + (monthIndex + 1) + ''/'' + year;
};
});
Si está utilizando la última versión de angular-material.js, use el servicio $ mdDateLocale. Este ejemplo de código utiliza el filtro de fecha incorporado de angular como alternativa al uso de la biblioteca moment.js. Vea otras opciones de formato de fecha usando el servicio $ filter de angular aquí en este enlace https://docs.angularjs.org/api/ng/filter/date .
// mainController.js
angular.module(''app'').config(function($mdDateLocale, $filter, $scope) {
// FORMAT THE DATE FOR THE DATEPICKER
$mdDateLocale.formatDate = function(date) {
return $filter(''date'')($scope.myDate, "mediumDate");
};
});
Tuve el mismo problema y se me ocurrió esta solución simple con la ayuda de
moment.js
.
ng-change
atributo
ng-change
que se dispara cuando se cambia la fecha.
Dentro de tu HTML:
<md-datepicker ng-model="myDate" ng-change="dateChanged()"></md-datepicker>
Dentro de su controlador:
$scope.dateChanged = function() {
this.myDate = moment(this.myDate).format(''YYYY/MM/DD'');
}
Usando
$filter
lugar de
moment.js
y en referencia a las respuestas de @Ian Poston Framer y @java dev para mí, lo siguiente finalmente funcionó para mí:
angular
.module(''App'', [''ngMaterial''])
.run(function($mdDateLocale, $filter) {
$mdDateLocale.formatDate = function(date) {
return $filter(''date'')(date, "dd-MM-yyyy");
};
})
No pude inyectar
$filter
en
.config
porque no es un proveedor, así que tuve que hacerlo dentro de
.run
con
$mdDateLocale
.
en mi caso, estaba perdiendo el PlaceHolder todo funciona pero el placeHolder estaba desapareciendo cuando uso el formato personalizado. Las siguientes líneas resolvieron mi problema con el marcador de posición.
$mdDateLocaleProvider.formatDate = function (date) {
if(date==null)
return "";
var m = moment(date);
return m.isValid() ? m.format(''L'') : '''';
};
$mdDateLocaleProvider
para formatearlo en el extremo
$mdDateLocaleProvider
.
Si desea formatear la fecha mientras la envía al back-end, lo siguiente funcionó para mí:
$filter(''date'')(this.date, ''MM/dd/yyyy'');
Tengo lo anterior en el controlador.