AngularJS Directive to modify URL - angularjs

In my templates i am able to display an image from my data using
ng-style="{'background-image':'url({{f.flower.imageURL}})'}"
The imageURL always returns a hi-res image with URL such as
https://s3.amazonaws.com/images/FlowerImages/Rose_1920.jpg
However the endpoint also has smaller images such as
https://s3.amazonaws.com/images/FlowerImages/Rose_320.jpg
https://s3.amazonaws.com/images/FlowerImages/Rose_480.jpg
https://s3.amazonaws.com/images/FlowerImages/Rose_1024.jpg
How would i create a directive to traverse back through the URL up to the underscore and pass in a size i want (depending on the view) to update between the underscore and the .jpg?

Based on you example, I don't think you need a directive. Just add a function to your controller.
Instead of
ng-style="{'background-image':'url({{f.flower.imageURL}})'}"
do
ng-style="{'background-image':'url({{generateImageUrl(f.flower.imageURL, 320)}})'}"
And your controller would have standard javascript to manipulate the url:
function generateImageUrl(url, size) {
var n = url.lastIndexOf("_");
var beforeUnderscore = url.substring(0, n);
var afterUnderscore = url.substring(n+1);
var suffix = afterUnderscore.split('.')[1];
return beforeUnderscore + "_" + size + "." + suffix;
}
The same function could work for image as well
<img ng-src="{{generateImageUrl(f.flower.imageURL, 320)}}">
Note: ng-src is used instead of src to prevent the browser from requested the url before angular has bootstrapped.

Related

Angular ui grid tooltip not working

I am having a problem to display header tooltip on angular-ui-grid.
Here is plunker demo.
Any idea how to make it work?
I have not been able to figure out how to make the directive work properly internally by setting the headerTooltips as strings. The directive developers are making it work using a different implementation than yours that can be seen in this Plunker.
This solution will patch the problem until a better or more permanent one can be found. Place it at the end of your service call inside of your controller like the following.
upareneStavkePromise.then(function(upareneStavkeData){
$log.debug(upareneStavkeData);
$scope.ucitaniUpareniPodaci = true;
$scope.gridOptionsUpareniPodaci.data = upareneStavkeData.grupe;
upareneStavkeTotals = upareneStavkeData.totals;
/*
* Patch for possible bug:
* Description: Setting headerTooltip property
* value as a string doesn't render the value at
* runtime.
*
*/
//class for the header span element
var headerClass = ".ui-grid-header-cell-primary-focus";
//the column definitions that were set by the developer
var colDefs = $scope.gridOptionsUpareniPodaci.columnDefs;
//Get the NodeList of the headerClass elements.
//It will be an array like structure.
var headers = document.querySelectorAll(headerClass);
//loop through the headers
angular.forEach(headers,function(value,key){//begin forEach
//Set the title atribute of the headerClass element to
//the value of the headerTooltip property set in the columnDefs
//array of objects.
headers[key].title = colDefs[key].headerTooltip;
});//end forEach
/****************END PATCH********************/
});

Angular method for querySelectorAll and getElementsByTagName

I am very new in Angular. I need a beginner's guide on the best way to define functions to get the length or count of tag (such as div) and Id/Class (#blah or .blah) via querySelectorAll and getElementsByTagName, so it can be called on html template and get current count of the particular elements on page.
function countTag(value1, value2) {
var top_level_div = document.getElementById(' + value1 + ')
top_level_div.document.getElementsByTagName(' + value2 + ’).length
}
function countElem(value) {
document.querySelectorAll(' + value + ’).length
}
How to angularize the above 2 functions, so they can be call on html template anywhere inside the app? If directive may be a method to do so, can anyone help with a plnkr example?
If your're using a directive in your 'DDO' (Directive Definition Object) you have access to jQuery object as 'element' attribute (if jQuery is referenced before loading angular.js file).
In your link function (or compile.post method) just interact with element attribute.
Ex.
.directive('sampleDrv', function () {
return {
...
link: function (scope, element) { // + other attributes
// Just use your jQuery logic/function provider in an example
// Only difference is now syntax ex. document == angular.element(document)
function sampleFn() {
var sampleElementText = angular.element(document).find('p').text();
console.log(sampleElementText);
}
sampleFn();
}
})
You also have $element object available on controller but it's not recommended to interact with element that way.
Also you may want to have a look at that brief explanation from Scott Allen - http://odetocode.com/blogs/scott/archive/2014/05/28/compile-pre-and-post-linking-in-angularjs.aspx
Also
https://docs.angularjs.org/api/ng/function/angular.element

populate a form with a bookmarklet doesn't work in angularjs

I have a bookmarklet that just does some simple form input population but the angular form is still in an invalid state. Like nothing was ever changed.
I tried calling el.onchange() but that doesn't seem to do anything.
javascript:populate();
function populate(){
var name = document.querySelector('input[name=name]');
name.value = 'Fred';
name.click();
name.onchange();
}
Since I already have jQuery loaded, I was able to fix the issue by triggering the input event.
$('input[ng-model]').trigger('input');
I used something similar to the code below to create my bookmarklet.
Couple of things to consider.
Write your function (see example below)
Before creating your bookmarklet, test your function in the chrome console
Function tested, now remove the endlines (e.g. "replace all" in intellij (with regex enabled), replace "\n" with ""
create a new bookmark in the browser
edit the url, the url should begin with "javascript:", paste your one line url after that... you'll end up with something like "javascript:(function(){..." etc...
//nb: This function is not written to work in this page
(function () {
//get the scope object for your controller
var sc=angular.element("[ng-controller=myController]").scope();
//grab your model
var m=sc.mymodel;
//some 'dodgy' date strings :)
var today=new Date();
var todayAsString=today.toLocaleDateString("en-GB");
today.setDate(today.getDate()-183);
var sixMonthsAgoStr=today.toLocaleDateString("en-GB");
today.setDate(today.getDate()+365);
var sixMonthsLaterStr=today.toLocaleDateString("en-GB");
//pick a random oz state
var states=["WA", "VIC","SA", "NT","NSW", "ACT", "QLD"];
var ozState=states[Math.floor(Math.random()*(6)+1)];
//update the model with some semi random values
m.actionDate=todayAsString;
m.ausstralianState=ozState;
m.streetNum=Math.floor((Math.random() * 1000) + 1);
m.ID="CR" + Math.floor((Math.random() * 10000) + 1);
m.manufactureYear="" + Math.floor(Math.random()*(2016-1960+1)+1960); //approx... between 1960 and 2016...
m.endDate=sixMonthsLaterStr;
m.startDate=sixMonthsAgoStr;
//MUST call $scope.apply() at the end.
sc.$apply();
})();

Angularjs appended $resource paramDefaults with special charaters

I have the following code
var resource = $resource('https://api.mongolab.com/api/1/databases/' + DB_NAME + '/collections/' + collectionName + '/:id',
{ apiKey:API_KEY, id:'#_id.$oid'},{update:{ method:'PUT' } }
);
when i call
$scope.projects = Project.query({q:"+"});
referencing
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
I append the Get request with the string in the {}. I cannot however include special charaters. Is this a feature and how can I implement special characters?
I believe you should urlencode values as long as you are sending them in url query

AngularJs - QueryString value & ng-include

I am trying to capture the querystring and apply the value to my ng-include.
My querystring: http://mydomain.com/?target=W7ROP175T5TEHW2
My MainCtrl: $scope.target = $location.search()['target'];
$scope.target is picking up the value.
Doing a simple text write, ie {{target}} works.
This does not work: <div ng-include="'/_UserSession/{{target}}/assets/menu.html'"></div>
Any ideas?
You need to escape the value, it is an expression.
ng-include="'/_UserSession/' + target + '/assets/menu.html'"
Also if you want to make sure that target is set before it attempts to include the template, you can add ng-if ="target". This way it will avoid a bad request.
OK, I solved it, I hope this helps others as well:
HTML
<ng-include src="session()"></ng-include>
Controller
$scope.target = $location.search()['target'];
$scope.session = function() {
return "/_UserSession/" + $scope.target + "/assets/menu.html";
};

Resources