How to programmatically ng-bind a property on an svg element? - javascript

I'd like to bind a background color to an svg element. I have an external svg file that I'm referencing, myfile.svg, inside of this file there's a circle with the id 'mycircle'.
So my html looks like:
<div ng-controller="MyCtrl">
<embed src="myfile.svg" id="mySvg"/>
</div>
I have a controller that looks like:
function MyCtrl($scope) {
$scope.myfill = 'yellow';
}
Now I'd like to set up the binding programmatically, this is what I do:
var mySvg = document.getElementById("mySvg");
mySvg.addEventListener("load", function() {
var svg = mySvg.getSVGDocument();
var mycircle = svg.getElementById("mycircle");
//this works:
//mycircle.setAttribute("fill", "yellow");
$(mycircle).attr('ng-bind','myfill');
});
However, this doesn't set the fill. I'm thinking I might need to use angular "compile" or something in order to get this to work (?) can anyone clue me in on how to do this?

Yes you need to compile. Should bind as an exp and compile against the scope. Below snippet should work.
var mySvg = document.getElementById("mySvg");
mySvg.addEventListener("load", function() {
var svg = mySvg.getSVGDocument();
var mycircle = angular.element(svg.getElementById("mycircle"));
mycircle.attr('fill', '{{myfill}}');
$compile(mycircle)($scope);
});

Related

I am trying to trim the output of a jQuery function

I am modifying a third-party script so that I can style the output.
Here is a segment of the original code:
var tip_content = $('<div>').addClass('tip_content').load(url, function() {
Which produces this output:
<div class="tip_content">
I need to add another class to the output to style it differently on each page. Therefore, it seems like a good solution to add the current html page file name as a class.
But I have no experience with JS.
Here is what I've managed to mangle together:
var tip_content = $('<div>').addClass('tip_content '+elem.attr('href')).load(url, function() {
Which produces this:
<div class="tip_content tickets.php?id=185">
This is almost exactly what I need. But I would be very grateful if someone could demonstrate how to trim the output to:
<div class="tip_content tickets">
You have to split the URL with . and takes the first-value from the splited array and add it to the div as second class.
Do it like below:-
var tip_content = $('<div>').addClass('tip_content '+elem.attr('href').split('.')[0]).load(url, function() {
A hard-coded example:-
var hrefs = "tickets.php?id=185";
$('div').addClass('tip_content '+hrefs.split('.')[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Inspect and check my class</div>
try below code
s = elem.attr('href');
s = s.substring(0, s.indexOf('.'));
var tip_content = $('<div>').addClass('tip_content '+ s).load(url, function() {
I would like to add a modification to be safe. suppose your url is: tickets.sold.php and you want tickets.sold. In this case you should try this:
s = elem.attr('href');
s = s.substring(0, s.indexOf('.php'));
var tip_content = $('<div>').addClass('tip_content '+ s).load(url, function() {

s.substr is not a function

I am using canvg, but when I run this:
jQuery("#print").on("click", function() {
mySvg();
});
function mySvg() {
var svg = jQuery("#map svg");
canvg(document.getElementById('canvas'), svg);
}
I get this in console
canvg.js:58 Uncaught TypeError: s.substr is not a function
Here it is a jsFiddle
Siguza is correct, you want to get the inner HTML of your SVG so (assuming #map is the direct parent of your target svg):
var svg = jQuery('#map');
var txt = svg.innerHTML;
Then you want to pass the txt variable as your second canvg() argument.

how to replace text inside an svg using js?

in this code I am trying to load an svg file into snap paper and then convert it to a group by :
replacing <svg with <g and </svg> with </g> ?
how can I fix this to work please?
var s1 = Snap('#svg1');
Snap.load( "https://dl.dropboxusercontent.com/u/140225334/bicycle.svg", function( frag ) {
var maing = s1.g();
maing.append(frag);
maing.attr({id: 'maing' });
// city_name=city_name.replace(/ /gi,'_');
var maing = maing.replace("<svg", "<maing").replace("</svg>", "</maing>"); // how this can be fixed to work?!
Edit: # dystroy, do you mean something like this?:
var s1 = Snap('#svg1');
Snap.ajax("https://dl.dropboxusercontent.com/u/140225334/bike2.svg", function(request)
{
var svg = Snap(request.responseXML.documentElement);
var maing = svg.selectAll("svg>*");//you can select any elements.
s1.append(maing);
maing.attr({id: 'maing' });
} );
Edit: # dystroy, If I go this way some svg styling is not going to be copied over:
please check to see how these 2 would differ:
copying over the svg nodes to an g:
http://jsbin.com/geyog/1/edit
vs
original svg file:
https://dl.dropboxusercontent.com/u/140225334/bike2.svg
You should add fill-rule attribute to svg element.
Original svg file has fill-rule attribute which value is "evenodd", but svg element described in html has no fill-rule, so browser treats the fill-rule attribute has "nonzero" as default value.
Thus the copied svg graphic looks like its style info was lost.
Snap.ajax("https://dl.dropboxusercontent.com/u/140225334/bike2.svg", function(request)
{
var maing = s1.g();
var svg = Snap(request.responseXML.documentElement);
var maing = svg.selectAll("svg>*");//you can select any elements.
//copy fill-rule attribute.
s1.attr("fill-rule", svg.node.getAttribute("fill-rule"));
s1.append(maing);
maing.attr({id: 'maing' });
// maing.transform('r45');
});

Target child of children with .each() in jQuery

I’m iterating through the elements and grabbing the src attribute of the child of that element. I have this HTML code:
<noscript data-alt="super awesome">
<img src="http://farm9.staticflickr.com/8235/8585847956_39864361e3.jpg" alt="something" />
</noscript>
<noscript data-alt="super awesome">
<img src="http://farm9.staticflickr.com/8235/8585847956_39864361e3.jpg" alt="something" />
</noscript>
and jQuery:
$('body').children().each(function() {
var noscriptTag = $(this)[0];
var imgAlt = noscriptTag.getAttribute("data-alt");
var img_src = noscriptTag.find('img');
var img_regular = img_src.getAttribute("src");
console.log(img_regular);
});
But I’m getting this error:
Uncaught TypeError: Object #<HTMLElement> has no method 'find'
I also tried various other combinations (like $(this).find('img');) without making it work.
Here’s the demo: http://jsfiddle.net/LjWhw/
How do I target the img tag of that element? Thanks!
UPDATE: You can’t target elements which are inside <noscript> with JavaScript.
You are trying to call find jQuery function on DOM object, Use jQuery object instead of DOM javascript object to call find on it.
Change
var noscriptTag = $(this)[0];
To
var noscriptTag = $(this);
Edit: You will also need to change the code accordingly e.g. img_src.getAttribute("src"); to img_src[0].getAttribute("src"); or img_src.attr("src");
I would suggest you to do it this way:
$('body').children().each(function() {
var noscriptTag = $(this).find('noscript').first();
//---------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----this way
var imgAlt = noscriptTag.getAttribute("data-alt");
var img_src = noscriptTag.find('img');
var img_regular = img_src.attr("src");
console.log(img_regular);
});
try this
http://jsfiddle.net/UQJsy/1/
$('noscript').each(function () {
var noscriptTag = $(this);
var imgAlt = noscriptTag.attr("data-alt");
var img_src = noscriptTag.children('img');
var img_regular = img_src.attr("src");
alert(imgAlt);
});

Having problems scripting SVGs

I'm having some trouble with manipulating SVGs through javascript. I'd like to increase the length of a line through clicking a button. I've included this code in the head tag:
<script type="text/javascript">
x=135;
y=135;
var container = document.getElementById("svgbox");
var mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
function svg() {
mySvg.setAttribute("version", "1.2");
mySvg.setAttribute("baseProfile", "tiny");
mySvg.setAttribute("height","300px");
mySvg.setAttribute("width","300px");
container.appendChild(mySvg);
}
function line() {
x=x-10;
y=y-10;
var L1 = document.createElementNS("http://www.w3.org/2000/svg", "line");
L1.setAttribute("x1", "100"); L1.setAttribute("y1", "100");
L1.setAttribute("x2", x); L1.setAttribute("y2", y);
L1.setAttribute("stroke", "#05adc7");
L1.setAttribute("stroke-width", "2px");
mySvg.appendChild(L1);
}
</script>
This is the body text:
<body onload="svg()">
<form>
<input type="button" onClick="line()" />
</form>
<div id="svgbox">
</div>
</body>
But when I click on the button, I get an error telling me that the variable "container" is null. Does anyone know what the problem is?
It works if you put the line var container = document.getElementById("svgbox"); in the svg function.
function svg() {
var container = document.getElementById("svgbox");
mySvg.setAttribute("version", "1.2");
mySvg.setAttribute("baseProfile", "tiny");
mySvg.setAttribute("height","300px");
mySvg.setAttribute("width","300px");
container.appendChild(mySvg);
}
The reason container is null in your code is because the DOM has not loaded yet when the line var container = document.getElementById("svgbox"); gets executed.
You need to declare container after either the DOMContentLoaded event or window.onload event is fired.
This is a common gotcha in DOM scripting, for both SVG and HTML. The problem is that the svgbox element is not yet loaded when the JavaScript executes. The easiest solution is to simply move your script tag so that it is the last element in the document. This is a bit ugly, though, so most JavaScript libraries include a method that accepts a callback to execute after the document has been loaded. For example, if you were using jQuery, then your script tag would look like the following:
<script type="text/javascript">
$(document).ready(function(){
x=135;
y=135;
var container = document.getElementById("svgbox");
var mySvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg = function() {
mySvg.setAttribute("version", "1.2");
mySvg.setAttribute("baseProfile", "tiny");
mySvg.setAttribute("height","300px");
mySvg.setAttribute("width","300px");
container.appendChild(mySvg);
}
line = function() {
x=x-10;
y=y-10;
var L1 = document.createElementNS("http://www.w3.org/2000/svg", "line");
L1.setAttribute("x1", "100"); L1.setAttribute("y1", "100");
L1.setAttribute("x2", x); L1.setAttribute("y2", y);
L1.setAttribute("stroke", "#05adc7");
L1.setAttribute("stroke-width", "2px");
mySvg.appendChild(L1);
}
})
</script>

Categories

Resources