3

I have a website done using AngularJS and all the HTML code is loading from database. So we cannot edit the code. It's loading when the application running. But we can edit the JavaScript files. So I have to edit the img src link. Actually I have to add some main url part to it. How can I do this ?

<img src="/img/logo.png"/> to <img src="http://demo.com/img/logo.png"/>

This is how this has to be done. No id in the img tag too. Can we use Angular Directives ? And we cannot add anything in the HTML files. No directive name too. Please help me on this. Really stuck in here.

update: the reason the html source can't be changed is because it is coming from an external source and is user generated. the users upload text that contains relative links that work when the pages are viewed statically. however when we load the text into our angular site, relative links no longer work, because the angular code and templates are on a different host than the user content and images.

we would like to find a solution in angular.js directly, without resorting to manipulating the DOM using lower level javascript or jquery.

eMBee
  • 793
  • 6
  • 16
Chanaka De Silva
  • 406
  • 1
  • 7
  • 21
  • In the controller itself when you generating the html add the base url in front of image path. – Debug Diva May 22 '16 at 06:06
  • i believe this question is relevant to evaluate directives in the loaded html: http://stackoverflow.com/questions/20623118/rendering-directives-within-sce-trustashtml – eMBee May 23 '16 at 16:02

5 Answers5

2

in your controller you can add field

$scope.image = {src:"your url to the imge"};

and in your html

<img src="image.src"/> 

and you can change the image src anytime

Erez
  • 574
  • 1
  • 6
  • 23
2

Part of this can be accomplished using ng-src to utilize interpolation .

Example :

In your respective controller ...

$scope.linkappend = 'http://demo.com';

in the end your document will end up like this ..

 <img ng-src="{{linkappend}}/img/logo.png"/>

Didn't really understand why you are not able to touch dom but the prototype above can be placed in a directive and the only other option is to grab the name of the file that the user uploads and build your own path name with the name of that file, then append it back to the dom.

KpTheConstructor
  • 3,153
  • 1
  • 14
  • 22
2

notwithstanding the discussion whether it is wise to create an img directive, the actual directive that solves the problem looks like this:

app.directive('img', function() {
  return {
    restrict: 'E',
    replace: false,
    link: function(scope, elem, attr) {
      if (attr.src.slice(0, 7) !== "http://" && attr.src.slice(0, 8) !== "https://") {
        attr.$set("src", "http://demo.com/+ attr.src);
      }
    }
  };
});

the recursion issue discussed in this comment came from trying to use a template to replace the whole <img> tag instead of just changing the src value

furthermore, in order to apply the directive to html snippets that are loaded dynamically they need to be wrapped in a directive that compiles its contents:

app.directive('dynamic', function($compile) {
  return {
    restrict: 'A',
    replace: false,
    transclude: true,
    link: function(scope, ele, attrs) {
      return scope.$watch(attrs.dynamic, function(html) {
        ele.html(html);
        $compile(ele.contents())(scope);
      });
    }
  };
});

applied like this:

<div dynamic="content"></div>

where content is the variable in your scope that contains the dynamic html snipped with your <img> tags.


if you want to avoid a directive named img, one way would be to "fix" the snippet:

content.replace(/<img /g, "<img customimg ")

and then start the directive like this:

app.directive('customimg', function() {
  return {
    restrict: 'A',
...

using replace here seems rather crude, but i can't think of another way. suggestions to improve the answer would be welcome!

Community
  • 1
  • 1
eMBee
  • 793
  • 6
  • 16
0

If you're unable to edit the html file then it would be tricky to add angular directives. Have you thought about using jQuery to manipulate img source?

AranS
  • 1,871
  • 10
  • 22
  • Hey, can we create a directive named "img" ? So we don't need to add directive name on HTML file.... no ? And also can't we try overriding img tag using Angular? – Chanaka De Silva May 22 '16 at 06:42
  • Even if you would have created an Angular directive named `img` (which is not recommended) you would have to place it in your html file. Look at jQuery examples for handling this issue. – AranS May 22 '16 at 06:51
  • why is using an img directive not recommended? and what would have to be in the html file? the tag is obviously in there already. – eMBee May 23 '16 at 09:19
  • When building directives it's better to prefix it with your app identity, for example: image directive will be called `mb-img`, this way you will be able to differentiate between your directives and the html tags. – AranS May 23 '16 at 11:05
  • In addition, you said you cannot alter the HTML file, that means that you cannot place directives in there. Therefore, the best way to manipulate the DOM (your image source in this case) would be to use `jQuery`. Let me know if you'd like a simple example. – AranS May 23 '16 at 11:07
  • of course having directives that have a distinct name is better, but that doesn't mean that directives that match tag names are bad. even angular.js itself uses builtin directives for eg the input tag. – eMBee May 23 '16 at 15:26
  • i don't understand why the html needs to be altered if the directive is img, and the img tags are already present in the files? – eMBee May 23 '16 at 15:27
  • I have never seen such a practice - building components with the same name as HTML tags. How can Angular differentiate between a component and an HTML tag? It can lead to run-time exceptions. – AranS May 24 '16 at 06:00
  • The problem I see here is this: tomorrow another programmer is updating your app, he is unaware of your directive and uses it in a wrong way. This is why, usually, companies tend to build components with a prefix. – AranS May 24 '16 at 06:05
  • it can hardly be used the wrong way, either the image shows up, then it's used right, or it doesn't then the developer will investigate and fix the problem. – eMBee May 31 '16 at 14:47
  • "How can Angular differentiate between a component and an HTML tag?" yes, that appears to be the problem. angular.js doesn't seem to have a way to break the recursion if the output element of a directive is the same as the input. – eMBee May 31 '16 at 14:51
  • jQuery can be very efficient, use it with caution. – AranS May 31 '16 at 14:55
0

You can use .getElementsByTagName('img') to get all img tags

var imgs = document.getElementsByTagName('img');
var src = imgs[x].getAttribute("src");    //x is the index of img tag
imgs[x].src = 'http://demo.com' + src;

If you want to change the src of all img tags, you can use for loop.

Munawir
  • 3,346
  • 9
  • 33
  • 51