2
votes

I'm running into this weird and wonderful issue with the xAxis.labels.formatter function within highcharts JS.

I wanted to add a lightbox icon to the xAxis labels of the chart as following:

return '<div class="label">'
         +'<a class="lightbox" href="http://www.google.com" data-lightbox="iframe" data-plugin-options=\'{"type":"iframe"}\'>ICON</a>'
       +'</div>';

However when rendering this chart the html code shows me the following output:

<div class="label">
  <a class="lightbox" href="http://www.google.com" data-lightbox="iframe" data-plugin-options="{"type":"iframe"}">ICON</a>
</div>

The problem is with the single quotes being rendered into double quotes

data-plugin-options="{"type":"iframe"}"

instead of

data-plugin-options='{"type":"iframe"}'

No matter what I try, I can't seem to prevent this from happening.

Things I have tried:

  1. use simple escaping with \'
  2. created a var and passing it into the return string
  3. used .replace(/['"]+/g, '')

Could someone please point me in the right direction as it's driving me slowly crazy, thanks all

UPDATE AFTER FEEDBACK

thank you for your reply, the problem is not the actually single quotes inside of the data-plugin-options attribute but around it, so for example it renders: data-plugin-options="{"type":"iframe"}" instead of data-plugin-options='{"type":"iframe"}', I have found out that even if I would add a fake html element e.g foo=bar, it will render this as foo="bar", so it automatically adds the double quotes, within the xAxis label formatter.

Please see my modified JSFiddle (http://jsfiddle.net/g6yehxeo/1/), and inspect the element of the icon label on the xAxis, you will find that it renders with quotes, even while there are none in the original code ? Any idea of how to prevent this, as the lightbox does not seem to work without these.

Thanks all

1

1 Answers

1
votes

You need to properly escape the string that goes into the data-plugin-options attribute. More info: https://stackoverflow.com/a/9189067/1869660

formatter: function () {
    function escapeAttr(str) {
        var div = document.createElement('div');
        div.setAttribute('data-dummy', str);
        return /\"(.*)\"/.exec(div.outerHTML)[1];
    }

    var options = { type: 'iframe'},
        optionsAttr = escapeAttr(JSON.stringify(options));

    return '<div class="label">'
         +   '<a class="lightbox" href="http://www.google.com" data-lightbox="iframe" data-plugin-options="' + optionsAttr + '">ICON</a>'
         + '</div>';
},

http://jsfiddle.net/g6yehxeo/

You can also use the built-in escape() method instead of our homemade escapeAttr(), but then whoever reads the attribute later needs to unescape() the value first to get valid JSON.