1

I've run into a problem with a plugin I'm working on. I'm allowing users to pass some text to the plugin like so:

data-plugin='{ "setting" : "hello world" }'

no problems there, until a special character is introduced:

data-plugin='{ "setting" : "hello world, it's been awhile." }'

The apostrophe just halts everything and doesn't throw any errors. I'm not sure how I would go about allowing users to type this as they normally would?

EDIT: Here's the exact attribute that is causing the problem:

data-plugin='{
   "foreground":"1_foreground.png", 
   "horizon":"50,120",
   "subtitle":"Hello world. It's been awhile.",
   "subtitle_speed":"3500,2000",
   "subtitle_color":"#ff5b00",
   "subtitle_pos":"bottom"
}'

EDIT 2:

When \' is used in the setting, this is logged before merging objects inside the plugin:

{
       "foreground":"1_foreground.png", 
       "horizon":"50,120",
       "subtitle":"Hello world. \

Directly after that I'm using $.extend to merge this then apply it as data.

THIS IS HOW IT IS SETUP:

Call a plugin on a ton of elements:

$('.el').plugin({ "setting1" : "value" });

Modify those settings by using them here:

<div class="el"></div>
<div class="el" data-plugin='{ "setting1" : "special value" }'></div>

Anyways, that isn't the issue. The issue is trying to plug an apostrophe into the value. Single quotes on any HTML element is valid.

Thanks!

Aaron
  • 2,482
  • 1
  • 26
  • 56
  • I'd need to know how the data is being saved and written for a complete answer, but this will help: http://stackoverflow.com/a/1219983/1173601 – James L. May 07 '14 at 23:19
  • I assume `data-plugin='{ "setting" : "hello world" }'` is an HTML attribute? – Felix Kling May 07 '14 at 23:38
  • Yes it is an HTML attribute – Aaron May 07 '14 at 23:38
  • You have to properly HTML encode all `'` before you generate the HTML. See http://jsfiddle.net/t9qv4/. – Felix Kling May 07 '14 at 23:39
  • The html isn't being generated - but will be typed in by users for plugin settings. – Aaron May 07 '14 at 23:42
  • Then how does `data-plugin` get its value? If it isn't generated, then the quotation mark should't be an issue. Please provide a complete example that reproduces the issue. See http://stackoverflow.com/help/mcve for guidance. – Felix Kling May 07 '14 at 23:43
  • Or are you saying that if the users use `data-plugin='{ "setting" : "hello world, it's been awhile." }'` in their HTML, it doesn't work as expect? That's the user's problem, not yours. The user has to create valid HTML to begin with. – Felix Kling May 07 '14 at 23:46
  • Just like plugin settings $('#el').plugin({ same thing here }); – Aaron May 07 '14 at 23:47
  • You said `data-plugin` is an **HTML attribute**. How does this relate to `$('#el').plugin({ same thing here });` now? As I said, you should provide a complete example. It's completely unclear for me now where exactly you have the issue. – Felix Kling May 07 '14 at 23:53
  • Hey Felix, single quotes on an attribute is valid. It relates because you're passing Javascript plugin settings into both of them the exact same way. – Aaron May 07 '14 at 23:59

1 Answers1

1
data-plugin='{ "setting" : "hello world, it's been awhile." }'

Since you're wrapping your JSON string with apostrophes, you need to escape apostrophes inside of your string.

Change it to:

data-plugin='{ "setting" : "hello world, it\'s been awhile." }'

EDIT: Ok I think I have an idea what you're trying to do based on data-plugin being an html attribute:

I tried a JSFIDDLE to reproduce and here's what I get:

<input type='hidden' data-plugin='{
   "foreground":"1_foreground.png", 
   "horizon":"50,120",
   "subtitle":"Hello world. It\'s been awhile.",
   "subtitle_speed":"3500,2000",
   "subtitle_color":"#ff5b00",
   "subtitle_pos":"bottom"
}'>

and javascript

alert($('input').data('plugin'));

and it causes the error you noted in your question.

Per the first comment on your question, I escaped the apostrophe to &apos; and when I run

alert($('input').data('plugin'));

and I get a proper response. This will alert to a JSON object, so

alert($('input').data('plugin').foreground);

alerts "1_foreground.png". To turn it back into JSON if that's what you're trying to do you need to:

var jsonPluginSettings = JSON.stringify($('input').data('plugin'));
Gary Schreiner
  • 902
  • 5
  • 14
  • This was the first thing I tried, and oddly enough it doesn't work? – Aaron May 07 '14 at 23:21
  • Once that apostrophe is escaped it's a sound string, such as: alert('te'st'); vs. alert('te\'st'); ... Just to confirm, you're getting NO console errors? If not, then I would need to see more code to diagnose what's going on within your plugin, and more of a description about what problem you're happing. Are you trying to create a JSON object, and it's undefined? What happens if you put an alert before and after the data-plugin line? – Gary Schreiner May 07 '14 at 23:25
  • Hey Gary, just added to the question so you can see it in context. I was pretty sure escaping it as usual would do the trick, but no luck - and no console errors. I'll try alerting. – Aaron May 07 '14 at 23:30
  • Can't type this on the main question yet because I don't have 50 rep, but I missed part of the original question, that users will be typing this in. I agree with James L. that we need more info on where the data's coming from and how it's getting into the JSON string you're using. – Gary Schreiner May 07 '14 at 23:32
  • yeah, is this a "user" typing data into a form field or a "developer" adding a data attribute to an element? – James L. May 07 '14 at 23:34
  • it's a user - which is why it could be an issue. I've added the alerts and something interesting came up... I'm updating the question now. – Aaron May 07 '14 at 23:34
  • Just noticed something, you're not escaping newlines on your data-plugin string. If you're going to run a string across multiple lines you need to. I'll update my answer with an example. – Gary Schreiner May 07 '14 at 23:51
  • Line breaks are irrelevant in HTML. – Felix Kling May 07 '14 at 23:54
  • Agreed, however based on his question, he's creating a Javascript string. To be honest, I'm not sure what he's trying to do so I'm grasping at straws. Don't think there's much more I can help with unless he adds more context per your comment in the question. – Gary Schreiner May 07 '14 at 23:58
  • Correction, I see what he said reference an HTML element, not a javascript string. I will look at it from that perspective now. – Gary Schreiner May 07 '14 at 23:59
  • Lol, I'll update this again - sorry guys I didn't think it was confusing. – Aaron May 08 '14 at 00:00
  • I just found that I can actually escape the apostrophe using \u0027 – Aaron May 08 '14 at 00:07
  • just updated my answer with using `'` as an escaped apostrophe .. Only thing that was confusing for me was whether this was a JS variable or an HTML element.. I was working under the idea it was javascript. – Gary Schreiner May 08 '14 at 00:09
  • Awesome, now it's just a bit awkward for users to type ' inside their settings so I just have to figure out how to swap those out for real-life apostrophes :) Thanks Gary!!!! – Aaron May 08 '14 at 00:17
  • Thanks for marking it as an answer! I can finally comment on questions lol. We can tackle the other problem if you wish, I still need to know where the users are typing this in, is it an input? or in another application? how is the data getting into the data-plugin attribute? – Gary Schreiner May 08 '14 at 00:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/52245/discussion-between-gary-schreiner-and-aaron) – Gary Schreiner May 08 '14 at 00:32
  • Also, the reason why `\'` doesn't work is because HTML doesn't have the concept of ``\`` as an escape character. – Felix Kling May 08 '14 at 00:48