Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm a relative JavaScript / jQuery newbie.

I'm working on exporting (to a file on the server) a dynamically-generated <svg> from within a dynamically-generated <iframe>. I've succeeded in extracting the relevant data with jQuery (i.e., I can produce an object whose contents is the <svg>...</svg>

Relevant snippit of my JavaScript parser:

<script type="text/javascript">
function chart_export(svg_id) {
    var svg_data = $('iframe:first').contents().find('svg');
    svg_data = svg_data[0]; // Unwrap the [], only one element.
    console.log(svg_data); // Looks right (but perhaps it's not).
    console.log(svg_id); // Also right

    // POST svg
    $.post("chart_export.php", {'svg_post' : svg_data, 'chart_name' : svg_id}, function(data){
        alert(data); // Quick view of $_POST, no var_dump();
    });
}
</script>

Relevant snippit of my PHP parser:

  <?php
  $path = "module/" . "post.txt";
  $svg_data = $_POST['svg_post'];
  file_put_contents($path, $svg_data); // Same output as below
  echo json_encode($_POST); // Hack return to JS's alert() callback.
  ?>

for the moment, has been replaced with simply echo json_encode($_POST);

If I don't unwrap the svg_data object, PHP receives it as a (JavaScript?) [object Object] which I am unable to iterate across within PHP (such as with $svg = $_POST['svg_data']; which again returns [object Object].

If I do unwrap svg_data within JavaScript before I post it to PHP (as in the example code above) I get [object SVGSVGElement].

I caught the fix found in jQuery Object to string, and Post value pairs from jQuery to php file and save data in database but don't believe they apply to my situation (despite Cipi's comment). I also attempted var svg_string = new String('svg_data'); to no avail (it creates a string "[object Object]".

Clearly, my understanding of JavaScript data objects and jQuery selectors requires improvement.

What do I need to do, either within JavaScript/jQuery or PHP to allow me to access the raw contents of the entire <svg>...</svg>? I imagine it's simple and I'm missing it.

And here's the sample SVG just for good measure:

<svg id="chart" width="1292" height="636"><defs id="defs"><clipPath id="_ABSTRACT_RENDERER_ID_0"><rect x="214" y="122" width="865" height="393"></rect></clipPath></defs><g><text text-anchor="start" x="214" y="91.5" font-family="Arial" font-size="30" font-weight="bold" stroke="none" stroke-width="0" fill="#000000">Test</text></g><g><g><text text-anchor="start" x="1127" y="139" font-family="Arial" font-size="20" stroke="none" stroke-width="0" fill="#000000">5</text></g><rect x="1099" y="122" width="20" height="20" stroke="none" stroke-width="0" fill="#64a8d1"></rect><g><text text-anchor="start" x="1127" y="171" font-family="Arial" font-size="20" stroke="none" stroke-width="0" fill="#000000">4</text></g><rect x="1099" y="154" width="20" height="20" stroke="none" stroke-width="0" fill="#3d9ad1"></rect><g><text text-anchor="start" x="1127" y="203" font-family="Arial" font-size="20" stroke="none" stroke-width="0" fill="#000000">3</text></g><rect x="1099" y="186" width="20" height="20" stroke="none" stroke-width="0" fill="#03436a"></rect><g><text text-anchor="start" x="1127" y="235" font-family="Arial" font-size="20" stroke="none" stroke-width="0" fill="#000000">2</text></g><rect x="1099" y="218" width="20" height="20" stroke="none" stroke-width="0" fill="#245a7a"></rect><g><text text-anchor="start" x="1127" y="267" font-family="Arial" font-size="20" stroke="none" stroke-width="0" fill="#000000">1</text></g><rect x="1099" y="250" width="20" height="20" stroke="none" stroke-width="0" fill="#0969a2"></rect></g><g><rect x="214" y="122" width="865" height="393" stroke="none" stroke-width="0" fill-opacity="0" fill="#ffffff"></rect><g clip-path="url(#_ABSTRACT_RENDERER_ID_0)"><g><rect x="214" y="514" width="865" height="1" stroke="none" stroke-width="0" fill="#cccccc"></rect><rect x="214" y="416" width="865" height="1" stroke="none" stroke-width="0" fill="#cccccc"></rect><rect x="214" y="318" width="865" height="1" stroke="none" stroke-width="0" fill="#cccccc"></rect><rect x="214" y="220" width="865" height="1" stroke="none" stroke-width="0" fill="#cccccc"></rect><rect x="214" y="122" width="865" height="1" stroke="none" stroke-width="0" fill="#cccccc"></rect></g><g><g><rect x="270" y="319" width="177" height="195" stroke="none" stroke-width="0" fill="#0969a2"></rect><rect x="269.5" y="318.5" width="178" height="196" stroke="#000000" stroke-width="1" stroke-opacity="0.3" fill-opacity="1" fill="none"></rect><rect x="268.5" y="317.5" width="180" height="198" stroke="#000000" stroke-width="1" stroke-opacity="0.15" fill-opacity="1" fill="none"></rect><rect x="267.5" y="316.5" width="182" height="200" stroke="#000000" stroke-width="1" stroke-opacity="0.05" fill-opacity="1" fill="none"></rect></g><rect x="558" y="319" width="177" height="195" stroke="none" stroke-width="0" fill="#0969a2"></rect><rect x="846" y="319" width="177" height="195" stroke="none" stroke-width="0" fill="#0969a2"></rect><rect x="270" y="123" width="177" height="195" stroke="none" stroke-width="0" fill="#245a7a"></rect><rect x="558" y="123" width="177" height="195" stroke="none" stroke-width="0" fill="#245a7a"></rect><rect x="846" y="123" width="177" height="195" stroke="none" stroke-width="0" fill="#245a7a"></rect><rect x="270" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#03436a"></rect><rect x="558" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#03436a"></rect><rect x="846" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#03436a"></rect><rect x="270" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#3d9ad1"></rect><rect x="558" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#3d9ad1"></rect><rect x="846" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#3d9ad1"></rect><rect x="270" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#64a8d1"></rect><rect x="558" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#64a8d1"></rect><rect x="846" y="514.5" width="177" height="0" stroke="none" stroke-width="0" fill="#64a8d1"></rect></g><g><rect x="214" y="514" width="865" height="1" stroke="none" stroke-width="0" fill="#333333"></rect></g></g><g></g><g><g><text text-anchor="middle" x="358.5" y="538.6" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#222222">One</text></g><g><text text-anchor="middle" x="646.5" y="538.6" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#222222">Two</text></g><g><text text-anchor="middle" x="934.5" y="538.6" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#222222">Three</text></g><g><text text-anchor="end" x="198" y="520.1" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#444444">0.0</text></g><g><text text-anchor="end" x="198" y="422.1" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#444444">0.5</text></g><g><text text-anchor="end" x="198" y="324.1" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#444444">1.0</text></g><g><text text-anchor="end" x="198" y="226.1" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#444444">1.5</text></g><g><text text-anchor="end" x="198" y="128.1" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#444444">2.0</text></g></g></g><g><g><path d="M438.5,303.5A1,1,0,0,1,437.5,302.5L437.5,247.5A1,1,0,0,1,438.5,246.5L488.5,246.5A1,1,0,0,1,489.5,247.5L489.5,302.5A1,1,0,0,1,488.5,303.5L479.5,303.5L447.5,319.5L463.5,303.5Z" stroke="none" stroke-width="0" fill-opacity="0.4" fill="#cccccc" transform="translate(2, 2)"></path><path d="M438.5,303.5A1,1,0,0,1,437.5,302.5L437.5,247.5A1,1,0,0,1,438.5,246.5L488.5,246.5A1,1,0,0,1,489.5,247.5L489.5,302.5A1,1,0,0,1,488.5,303.5L479.5,303.5L447.5,319.5L463.5,303.5Z" stroke="none" stroke-width="0" fill-opacity="0.6" fill="#cccccc" transform="translate(1, 1)"></path><path d="M438.5,303.5A1,1,0,0,1,437.5,302.5L437.5,247.5A1,1,0,0,1,438.5,246.5L488.5,246.5A1,1,0,0,1,489.5,247.5L489.5,302.5A1,1,0,0,1,488.5,303.5L479.5,303.5L447.5,319.5L463.5,303.5Z" stroke="#cccccc" stroke-width="1" fill="#ffffff" transform="translate(0, 0)"></path><text text-anchor="start" x="447" y="269.6" font-family="Arial" font-size="16" font-weight="bold" stroke="none" stroke-width="0" fill="#000000">One</text><text text-anchor="start" x="447" y="290.6" font-family="Arial" font-size="16" stroke="none" stroke-width="0" fill="#000000">1:</text><text text-anchor="start" x="465" y="290.6" font-family="Arial" font-size="16" font-weight="bold" stroke="none" stroke-width="0" fill="#000000">1</text></g></g></svg>
share|improve this question

2 Answers 2

up vote 1 down vote accepted

Your problem is about not getting the real HTML structure of the <svg/> element, that's the reason why you got [object SVGSVGElement] and [object SVGSVGElement] as representation strings of it. You should do something like

$("<div/>").html(svg_data).html()

to get a string with the HTML contents of the element. I am not sure whether there another way to do it, but I think this will do fine.

share|improve this answer
    
That did it! I knew I wasn't properly acquiring the HTML from the object; I just didn't know how to get to it. For future reference, what does the initial $("<div/>") do: create a new DOM element and stick my svg_data_object's jQuery selector into it, then grab the HTML from it? And why the trailing /? –  msanford Feb 1 '12 at 19:58
1  
@msanford, <div/> is a shorthand for <div></div> which both are empty elements. Then add your <svg>...</svg> as a content and request the contents of it as a string. Basically .html() will get the HTML of the contents of the element, which is the reason I am enclosing it before to get the HTML of the element itself. –  Alexander Feb 1 '12 at 20:17

Use javascript's escape function to make it portable. I have a personal preference for json encoding when communicating between javascript and PHP.

Here's the reference for escape:

http://www.w3schools.com/jsref/jsref_escape.asp

and this one's for json encoding:

http://www.openjs.com/scripts/data/json_encode.php

Good luck!

share|improve this answer
    
Thanks for your suggestion! Unfortunately, escaping the string doesn't work. I assume because JavaScript's svg_data variable is an object, I simply get an escaped version of its name: %5Bobject%20Object%5D or %5Bobject%20SVGSVGElement%5D (depending on whether I choose svg_chart_obj or svg_chart_obj[0] respectively). When I attempted to implement array2json(), I actually get a stack overflow ;) (Uncaught RangeError: Maximum call stack size exceeded). –  msanford Feb 1 '12 at 19:31
    
You could try serialize as well –  dabito Feb 1 '12 at 20:06

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.