Angular translate - format dates - angularjs

I am using Angular translate for my app localization. I'd like to dynamically change the date format depending on the user's locale.
If the locale is French : format is dd/mm/yyyy
If the locale is English/US : format is mm/dd/yyyy
...and so on depending on the locale's default date format
How can I achieve this (cleanly) with Angular translate ?

I finally ended using moment.js and Angular moment.
Dates can be formatted to locale default with this:
<td>{{user.lastLogin | amDateFormat:'l LT'}}</td>
To change the moment locale, use the following:
amMoment.changeLocale(language);
Don't forget to import the moment locale files for the languages you wish to support:
<script src="assets/global/plugins/moment.min.js"></script>
<script src="jslib/angular-moment.min.js"></script>
<script src="jslib/moment/de.js"></script>
<script src="jslib/moment/es.js"></script>
<script src="jslib/moment/fr.js"></script>
<script src="jslib/moment/it.js"></script>
<script src="jslib/moment/pl.js"></script>
<script src="jslib/moment/ru.js"></script>
<script src="jslib/moment/zh-cn.js"></script>
And add angular moment module in your app:
var myapp = angular.module('myapp', ['angularMoment']);

Maybe I am out of date, but I don't think angular-translate has anything to do with localization. So here are my solution (yet it very clean)
If you are loading it only once per page reload use angular-i18n will be enough. Install and put js file into your HTML
bower install angular-i18n
<script src="/bower_components/angular-i18n/angular-locale_YOUR-LOCALE.js"></script>
If you want to load it dynamically angular-dynamic-locale :
bower install angular-dynamic-locale
<script src="myPath/tmhDynamicLocale.js"></script>
your js:
angular.module('myApp', ['tmh.dynamicLocale', ...])
angular.module('myApp').controller('myController', [..., 'tmhDynamicLocale',
function… {
tmhDynamicLocale.set('en');
}
])
NOTE, made sure you check the repo's readme for usage of localeLocationPattern(string)

Yeah there is a very easy way to do it..
Not sure if it's clean but can be made clean.
you can use interpolation provided by angular-translate, the problem is you can't use function inside interpolation string, but you can do something cool..
pass a function inside the object you're interpolating and call that function while interpolation
say you need to put in date
{{ 'date' | translate:{date:"28/01/2016"} }}
//instead of this
{{ 'date' | translate:'{date:"28/01/2016",func: func}' }}//func comes from scope.
and in your $translateProvider.translations
$translateProvider.translations('en',{
'date': "{{func(date)}}"
});
here is the plnkr

Related

Angular - Pikaday date format not working

I am using pikaday-angular directive wraper.
I wanted to show date in MM/DD/YYYY format in inputbox, hence supplied format in directive.
<input pikaday="example.myPickerObject" format="MM/DD/YYYY">
When i click on any date it shows up in inputbox in its default date format and not in my supplied format.
Here is the Demo: http://plnkr.co/edit/mFyTVKeGgUm6wz553hOB
Am i missing something?
Thanks in advance.
In order to use the format option, you need to import moment.js first:
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.2/moment.min.js"></script>
<script src="pikaday.js"></script>
<script src="pikaday-angular.js"></script>
<script src="app.js"></script>
See this plunker.

How to translate a date object using angular-translate?

I have a list of date in my view, powered by my controller. I am using angular-translate to manage localisation in my all application but do not know how to deal with date object.
My HTML looks like this :
<div ng-repeat="date in nextDates">
<div class="day">{{date | date: 'EEEE'}}</div>
</div>
This code display a list a day : Monday, Tuesday, ... based on date which is a date object.
My first try was to use moment.js which is already used in this project, and deal really well with i18n. It works, but I had a lot of difficulty to update it when lang is changed by user since moment.js is not related to angular-translate.
I tried to implement it on my controller using an event to update my variable but didn't worked well. I would like to keep the object date in my view instead of having a moment object, I am sure there is a way not implementing it manually.
$scope.$on('translationChanged', function(event, lang) {
...
});
I would like to know if there is an easy way to solve this issue, my only idea is to generate a key for translation like DAY.0 for Monday, DAY.1 and translate it by myself but it sounds cheap. moment.js seems perfect for the job, but then how to link it with angular-translate ?
Thanks for reading.
OK so after some research I found a library on github called angular-moment which work fine for me.
First I import both js files + locale
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/angular-moment/angular-moment.js"></script>
<script src="bower_components/moment/locale/fr.js"></script>
<script src="bower_components/moment/locale/de.js"></script>
<script src="bower_components/moment/locale/it.js"></script>
Then I set up momentjs locale variable during my app mode config
var core = angular.module('app.core').config(configLang);
configLang.$inject = ['moment'];
/* #ngInject */
function configLang(moment) {
moment.locale('en');
}
I then can start using in my templates amFormat directive directly on my Date object
<div ng-repeat="date in nextDates">
<div class="day">{{date | amDateFormat:'dddd'}}</div>
</div>
If I want to change language in my app, I just use moment.locale(String); and my view is automatically updated.
$rootScope.$on('$authenticationStateChanged', function(event, userData, isAuthenticated) {
moment.locale(userData.currentLanguage.toLowerCase());
});
$scope.$on('translationChanged', function(event, lang) {
moment.locale(lang.toLowerCase());
});
I can then access all the power of moment.js in my angular app :D.

Months and Days are not being translated

I am trying to translate a FullCalendar using the language file included in the package. To make it simpler with angular, I use the plugin ui-calendar.
To do so, I imported the language script as described in the doc :
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
... //other includes generated by bower
<script src="bower_components/moment/moment.js"></script>
<script src="bower_components/fullcalendar/dist/fullcalendar.js"></script>
<script src="bower_components/jquery-ui/ui/jquery-ui.js"></script>
<script src="bower_components/angular-ui-calendar/src/calendar.js"></script>
<!-- endbower -->
<!-- endbuild -->
<!-- FullCalendar language pack -->
<script src="bower_components/fullcalendar/dist/lang/fr-ca.js"></script>
However, the months and the days are not being translated. I did managed to translate the labels manually using the "monthNames", "dayNames", etc configs, but IMO that's ugly and it doesn't translate the ui.bootstrap.datepicker.
From what I understand, the problem is momentjs who wont take anything I give him. I tried to do a 'moment.lang('fr-ca')' but it doesn't do much. Anyone know a "Mickey Mouse trick" that could help to fix this issue?
Note: ui-calendar uses the v 1.6 of fullcalendar which doesn't include the languages utilities. So I added fullcalendar#2.1.0 to my bower.json. Everything seams to be working properly, I don't see where this could mess up the language since I'm calling fullcalendar directly.
Here is a working plunkr: http://plnkr.co/edit/AFpj79M1C6vOewSWLX8J
You also need to localise angular, you can read the doc here: https://docs.angularjs.org/guide/i18n
To make it work I added the code of i18n/angular-locale_fr-ca.js in the plunkr file ng-fr-ca.js.
Looking at the source of ui-calendar (line 179), you will see it uses anggular $locale service to translate days, month, etc. I have added a console.log to the source so you can see the difference between
var dtf = $locale.DATETIME_FORMATS;
console.log(dtf);
$locale uses engglish by default. If you load one of the i18n locale file, you will have it translated.

What do I need to include that angular bootstrap just simply works

I have included these in my index.html because bower is including them:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<!-- bower:js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-animate/angular-animate.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
<!-- endbower -->
Why is the ui-bootstrap.js not included? Because the bower.json from bootstrap and its main property has set "ui-bootstrap-tpls.js" but what about the ui-bootstrap.js?
Even when I include the file outside of the bower:js tags the popover from the datepicker is not visible and I get NO errors in my google chrome.
But when I click on the datepicker button no popover...
UPDATE
Now that I corrected my angularjs modules, now I use just this: 'ui.bootstrap.datepicker'
I get now these errors in google chrome:
Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:9000/template/datepicker/datepicker.html
Error: [$compile:tpload] Failed to load template: template/datepicker/datepicker.html
When I look at the source ui-bootstrap-tpls.js file:
.directive( 'datepicker', function () {
return {
restrict: 'EA',
replace: true,
templateUrl: 'template/datepicker/datepicker.html',
scope: {
datepickerMode: '=?',
dateDisabled: '&'
},
Where are these above path template... ? I have them not here. I just installed the angular-bootstrap bower package. Should there not all be included?
UPDATE2
I get these angularjs error now:
See the parent is null and therefore the parent.InsertBefore can not work and throws the exception...
Official Doc
ui-bootstrap-tpls.js library contains the directives and the directive templates.
ui-bootstrap.js is just the directives and you are expected to supply the directive templates.
Most folks use the predefined directive templates (ui-bootstrap-tpls.js). You do not want to include both and that may be why the popover/datepicker is not working. You would essentially have 2 directives working to show/hide the popover/datepicker. Also, do not load the bootstrap.js library as that will cause the same problems.
UPDATE:
In regards to the template not found error, the datepicker directive is looking for the template 'template/datepicker/datepicker.html' in the $templatecache. The ui-bootstrap-tpls.js injects the templates into the template cache at the very end of the js file.
In the ui-bootstrap-tpls.js file you should see several $templatecache.put lines with 'template/datepicker/datepicker.html' being one of them.
Just in case someone else is having the same issue: I was having problems with the datepicker, and the issue was that I was loading the templates before the base JS:
From:
<script src="/Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>
<script src="/Scripts/angular-ui/ui-bootstrap.min.js"></script>
To:
<script src="/Scripts/angular-ui/ui-bootstrap.min.js"></script>
<script src="/Scripts/angular-ui/ui-bootstrap-tpls.min.js"></script>
I just ran into this issue also, the answers above helped me a lot!
In my instance I was using a yo-angular build, and installed ui-bootsrap with bower. The problem was multiple references to ui-bootrap and bootstrap conflicting with the tpls.js verison
Here is my solution:
Simply put within my index.html
Remove
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
Add
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
Problem:
This questions comes up as a Google result for
Error: [$compile:tpload] Failed to load template: templates/datetimepicker.html
This may not be a direct answer to your specific problem, but I wanted to leave a note for future users encountering similar problems.
The directive daleotts/angular-bootstrap-datetimepicker introduces a breaking change in v1.0.0:
must include datetimepicker.template.js in the page to load the
template.
(b520f515)
Solution:
Users of angular-bootstrap-datetimepicker can either roll back to a previous version (such as v0.40), or choose to include templates file that was previously included in the base .js file:
// Previously this was the needed file
<script type="text/javascript" src="node_modules/angular-bootstrap-datetimepicker/src/js/datetimepicker.js"></script>
// Users who wish to use the default datetimepicker templates must now also include this file
<script type="text/javascript" src="node_modules/angular-bootstrap-datetimepicker/src/js/datetimepicker.templates.js"></script>

How to integrate AngularUI to AngularJS?

Sorry for the silly question, does everyone know how to start using AngularUI? I've downloaded it from Github and read the instruction in README but still don't understand what I have to do.
Steps to integrate:
Include jQuery and jQuery-ui (best served from a CDN)
Include angular (it is the best to include if from a CDN)
Include angular-ui JS / CSS (currently only hosted in the GitHub repository in the build folder)
Include any jQuery plugins for the directives you are planning to use
Declare dependencies on the angular-ui modules (ui.directives or ui.filters depending on what you are planning to use).
Most of the outlined steps are just about including JS/CSS dependencies. The only "tricky" part is to declare dependencies on a ui.* module, you can do it like this:
var myApp = angular.module('myApp',['ui.directives']);
Once all the dependencies are included and a module configured you are ready to go. For example, using the ui-date directive is as simple as (notice the ui-date):
<input name="dateField" ng-model="date" ui-date>
Here is the complete jsFiddle showing how to use the ui-date directive: http://jsfiddle.net/r7UJ2/11/
You might also want to have a look at the sources of the http://angular-ui.github.com/ where there are live examples off all the directives.
As of 3rd of May 2013, here are the steps:
include
<script src="angular.min.js"></script>
<script src="ui-bootstrap-tpls-0.3.0.min.js"></script>
register ui
angular.module('myFancyApp', ['ui.bootstrap']);
make sure myFancyApp is the same as in your <html ng-app="myFancyApp">
Let the magic commence.
I think what is missing is plugins - you've got to add the jquery plugin scripts and css for some angular-ui directives to work. For example the codemirror directive needs:
<script src="http://codemirror.net/lib/codemirror.js" type="text/javascript"></script>
<script src="http://codemirror.net/lib/util/runmode.js" type="text/javascript"></script>
<link rel="stylesheet" href="http://codemirror.net/lib/codemirror.css" type="text/css" />
It's a surprise to me that angular-ui.github.com doesn't mention needing to include plugins.
Hi I wrote an article specifically on how to do this for for PHP syntax highlighting. The article is here: http://neverstopbuilding.net/how-to-integrate-codemirror-with-angular-ui/
The core of things is getting the configuration right:
var myApp = angular.module('myApp', ['ui']);
myApp.value('ui.config', {
codemirror: {
mode: 'text/x-php',
lineNumbers: true,
matchBrackets: true
}
});
function codeCtrl($scope) {
$scope.code = '<?php echo "Hello World"; ?>';
}
For something like the following HTML snippet:
<div ng-app="myApp">
<div ng-controller="codeCtrl">
<textarea ui-codemirror ng-model="code"></textarea>
</div>
</div>
You can see the whole jsfiddle of the set up here: http://jsfiddle.net/jrobertfox/RHLfG/2/
pkozlowski.opensource is right, there are a lot more files that you need to include than it seems from the AngularUI documentation (if you can call it documentation...)
The instructions are in the readme.md file at their official github repository
Angular UI
Alternatively, the way you can find out how to integrate is to open the angular-ui js file (example: ui-bootstrap-tpls-0.6.0.js) and in the first line, you will notice the following statement
angular.module("ui.bootstrap", [...deps...])
Based on the above code, you need to inject 'ui.bootstrap' into your module.
angular.module('myFancyApp', ['ui.bootstrap','other_deps',.....]);

Resources