1

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>
Community
  • 1
  • 1
msanford
  • 11,803
  • 11
  • 66
  • 93

2 Answers2

1

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.

Alexander
  • 23,432
  • 11
  • 63
  • 73
  • 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 `$("
    ")` 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 01 '12 at 19:58
  • 1
    @msanford, `
    ` is a shorthand for `
    ` which both are empty elements. Then add your `...` 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 01 '12 at 20:17
0

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!

dabito
  • 586
  • 1
  • 7
  • 14
  • 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 01 '12 at 19:31
  • You could try serialize as well – dabito Feb 01 '12 at 20:06