Access $locale in angular.module('xxx').value - angularjs

I'm using angular-ui:s date directive (uiDate) and need to configure it. I can do that like this:
app.value('ui.config', {
date: {
dateFormat: 'yy-mm-dd', // <-- I want to use $locale.shortDateFormat
changeMonth: true,
changeYear: false
}
});
where app is my application module.
What I would like to do is to define the dateFormat from angulars $locale object, which using i18n contains my cultures specific date-formats.
The value property of app does not seem to have access to $locale at that point though, so I'm feeling that this is the wrong way to do it.
How can I provide the dateformat and other stuff from the locale-object to my directives, without having to modify the source code of ui-date (since it's an external dependency of my project).
I can solve this by setting this object in my controllers, but that's not what I want. This is a configuration that should work in all my controllers.

AngularUI is currently undergoing a bit of refactoring which changes this slightly.
Anyway, you can always pass the dateFormat property to uiDate inline, it will be merged with the global configuration. I don't know if it's possible to set .value() from within app.run as was suggested though, but I would think .value() is supposed to be easily overridable. You can even try modifying the object since theoretically the reference would be preserved (depending on when the directive injection function is executed).
Sorry it's not more helpful.

You can use bootstrap to do that. You don't even need to be "inside" angular to use that.
More about bootstrap: http://docs.angularjs.org/guide/bootstrap and http://docs.angularjs.org/api/angular.bootstrap
Just a note ... When navigating on the site, set the version to 1.2 so you can see the comments. It's very helpfull.
HTML
<ul id="result">
</ul>
Javascript
var locale = angular.bootstrap(function ($locale) { }).get('$locale'),
html = '';
for(var i = 0; i < locale.DATETIME_FORMATS.MONTH.length; i++) {
html += '<li>' + locale.DATETIME_FORMATS.MONTH[i] + '</li>';
}
$('#result').html(html);
jsfiddle: http://jsfiddle.net/82aRW/

Related

Which method is good to use for laravel 5 and angularjs tag conflict?

I had print value issue in laravel view, i was trying to print $scope value inside laravel blade. I searched about and find two kind of solution.
1- Change angularjs print tag
By this method i can change angularjs print tag.
var app = angular.module('app', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
app.controller('app', function ($scope, $http) {
$scope.text_print = 'this is text';
});
Now in blade i can print like <% text_print %>
2- Add # for printing angularjs $scope value
I found an up-voted answer in which #Paul A.T. Wilson says that
The easiest way to do this is to simply use # in front of your Angular code
Example #{{text_print}}
Both are working for me, actually i want to make a plugin, so which method should i use? because i'm not sure the second one is compatible with laravel old version. I want my plugin compatible with all version of laravel.
Can anyone guide me about this, i would like to appreciate. Thank You
Changing either interpolation strings for Blade or angular is the best option if you want your plugin to work with older versions of Laravel.
For angularJs you already know how to do it from here.
For Blade, inside your Laravel app's AppServiceProvider.php file add the following code in the boot function:
public function boot() {
Blade::setRawTags("[[", "]]");
// for variables and Blade
Blade::setContentTags('<%', '%>');
// for escaped data
Blade::setEscapedContentTags('<%%', '%%>');
}
Note: In my opinion it's easier to change the interpolation tags for angular as changing the interpolation tags for blade requires you to clear out the storage/framework/views folder.
Apparently there's another way to do this, but I'm not sure if it will work in older versions:
#verbatim
<div>
{{ variableOne }}
{{ variableTwo }}
</div>
#endverbatim
The verbatim annotation indicates that the section is as-is, ie: Blade will leave it out.

Loading angular directives at runtime

I have a service that I call during app.run() and for some reason when I load the files async at that point they don't seem to take.
Here's the service i'm using:
angular.module('nav').service('SubmoduleService', ['submodules_config',
function(config){
this.autoload = function(){
for(var key in config.modules){
for(var i=0; i<config.modules[key].length; i++){
var src = config.modules[key][i].replace(':path', config.path).replace(':name', key);
console.log(src);
var js = document.createElement("script");
js.type = "text/javascript";
js.src = src;
document.body.appendChild(js);
}
}
return true;
};
}]);
Here's the config file:
angular.module('nav').constant('submodules_config', {
path: "scripts/submodules/:name",
modules: {
gallery: [':path/config.js', ':path/directive.js']
}
});
So basically the config defines a module and all the files that need to get loaded for that module.
I see the files get loaded into the DOM, but for some reason when I load the controller that uses that directive, it doesn't work.
NOTE: The directive works when loading the files explicitly.
Any help is appreciated.
E
By default, angular bootstraps the application on the DOM Ready event. When you load scripts asynchronously, this event can be fired before the scripts load, so angular won't know about the directives contained in them when the DOM is $compiled().
There are quite a few ways to work around this, but they all revolve around deferring compilation of the DOM until the required modules are loaded.
On simple (but not the only) way to defer compilation for a fragment of your application is to simply use ng-if. In pseudo code, it would look something like this:
<div ng-if="moduleWithMyDirectiveLoaded" my-directive></div>
This leaves you with the task of figuring out how to determine if a particular script has been loaded and getting that information into your angular application.
Unfortunately, this isn't trivial. You can write this yourself, but others have already done it for you and you'd probably be better off using one of those tested, cross-browser solutions.
require.js comes to mind as an option, but there are many others that would also work.

Sanitize string to using angularjs

I basically want to use tel tag to make a phone call.
<a class="callButton" href="tel: {{phoneno}}"></a>
I am using $compileProvider to remove unsafe tag which comes by default, It works perfectly fine post 1.0.4v of angularjs. However below this version it doesnt work. Can anyone suggest how to implement this feature using angular version 1.0.4 or below?
Here is the sanitizing code which I am using in js file
app.config(['$compileProvider', function ($compileProvider) {
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
}
Assume I have already defined app variable.
P.S. This is an enhancement for particular app which basically works below 1.0.4v
Thanks
Add this to your scripts after angular is loaded.
I asume your on 1.1.5, but change to whatever you need the version to be.
http://code.angularjs.org/1.1.5/angular-sanitize.min.js
Example:
sanitizeSomething = function(string) {
return $sanitize(string);
};
sanitizedString = sanitizeSomething(string);

dijit.byId("").is not defined in Worklight works with Angularjs

I make a project in worklight used dojo mobile 1.8.1 and angularjs 1.0.1,but i got a strange problem.
Here is my html part:
<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props="selected:true" id="id1" ></div>
<div class="full" data-dojo-type="dojox.mobile.View" id="id2"></div>
and my JavaScript part:
require([
"dojo", "dijit/_base/manager","dojo/parser", "dijit/registry",
], function(dojo) {
dojo.ready(function() {
// dijit.byId("id1").performTransition("id2"); //////////place I
});
});
var angularApp = angular.module('app', [])
.run(['$rootScope','$templateCache','$route',
function($rootScope,$templateCache,$route) {
dijit.byId("id1").performTransition("id2");////////place II
}]);
The problem is at place I, it works well, but when I put "dijit.byId("id1")" at place II, it shows:
dijit.byId("").is not defined
The ready function is executed after dojo parsed your document & constructed the widgets you try to get using dijit.byId.
The second part is not placed within the ready function, so dojo can't find your elements yet !
Solution: Access your elements in the ready function OR do not declare them declaratively (like you did, using html code...) !
Lucian
The dojo.ready() function registers an event-handler function (callback) which will be fired after the DOM got completely parsed.
This comes in very handy if you want to be sure that every html element got rerendered as dojo-widget before you perform operations on them.
So, in your example, Code II will be executed before the dijit.byId() function has been made available by loading the necessary modules (dijit/registry, ...). Code II would only work after the dom-ready event got fired and your "dojo.ready()" function did load the required modules.
You should definately invest 5 minutes in reading what dojo.ready() is about:
http://dojotoolkit.org/reference-guide/1.8/dojo/ready.html
Sidenote:
You shouldn't use dijit.byId() any more in Dojo 1.8.1. Try using dijit.registry.byId() (you have to require the dijit/registry module).
http://dojotoolkit.org/reference-guide/1.8/dijit/registry.html#dijit-registry-byid

AngularJS select2 - how create directive?

(sorry for my english :)
I'm using Select2 in my forms with AngularUI ui-select2 directive like this:
<input ng-model="city" type="text" ui-select2="setupCitySelect" />
where setupCitySelect - object with select2 options. I'm setting him up in appropriate scope
$scope.setupCitySelect = {
allowClear: true,
minimumInputLength: 2
...etc, about 50 SLOC
}
All works fine. But when we have, let say, five select2 elements on page (or part of page) - CitySelect, UserSelect, ConditionSelect etc. we get a tons of code, most of them is the same. AngularUI provides "Global Defaults". So we can move repeating code (in directives):
var dirs = angular.module('vipc.directives', ['ui']);
// defaults setting for UI
dirs.value('ui.config', {
select2: {
allowClear: true,
minimumInputLength: 2,
formatInputTooShort: function(term, minLenght) {
var rest = minLenght - term.length;
return "minimum: "+rest;
},
...etc.
But we still need some work in controllers: to set unique properties, such as ajax-url...
And it's come on several pages, several controller. Ough...
Yes, I can put this into one file, say common.js. But I think - it's not best way. Angulas say: "use directive, Luke!". But how? Too complicated docs. I read docs. Three times.
Without success. I wrote some simple dirs, but this...
It should had 'isolated' scope - can be 2 CitySelect on page - in search form and modal form above. compile function? link function?
All i need is just
<myapp-city-select id="city"></myapp-city-select>
<myapp-user-select></myapp-city-select>
...later, same html file
<myapp-city-select id="city2"></myapp-city-select>
Somebody can help?
It should be in the controller. Here is the plunker. showing you that all directives share the same data.
So you can have a directive with common options in the controller and pass specific options into it.
Another option is have a service that defines common options and inject the service into wherever you want.

Resources