How to include apostrophe in JSON text used in JavaScript for web area?

I have an HTMLViewer that is loaded by creating the page with CSS, JavaScript, and the HTML combined and then displaying. The page includes an HTML form. The JavaScript includes a function called LoadData. When the page load is complete I call a method to call this LoadData function with the JSON data. The problem is that this fails if any of the data includes an apostrophe.

The JavaScript string I build to execute on the HTMLViewer includes apostrophes to enclose the JSON which uses double quotes for the items. (The data for the form is entered in another application. I need to be able to open and display in my Xojo app.)

I have tried escaping the apostrophe that is inside a data item but it hasn’t worked. Any ideas?

Here is what I have tried.

[code] Dim theJS As String
Dim theFormData As String

// escape the \r
characters or the data will not display
theFormData = ReplaceAll(Self.formData, "\r
", "\\r\
")
theFormData = ReplaceAll(Self.formData, “’”, “\’”)

theJS = “LoadData(’” + theFormData + “’);”

if (Len(theFormData) > 0) then
HTMLFormViewer.ExecuteJavaScript(theJS)
end if

// handle any errors
Exception err As HTMLViewerException
NotifyAlert(“HTML JavaScript”, “Error running the LoadData JavaScript.”, Str(err.ErrorNumber)+" “+err.Message)
#if TargetWin32 then
Exception err As OLEException
NotifyAlert(“HTML JavaScript”, “Error running the LoadData JavaScript.”, Str(err.ErrorNumber)+” "+err.Message)
#endif

[/code]

Always get an exception if there is an apostrophe in the data since it is taken as the end of the string.

Can you replace the apostrophe with a curly quote? ( shift + alt + ] ) on Mac - don’t know about Windows

Do you have smart quotes enabled? System Preferences -> Keyboard -> Text -> “Use smart quotes and dashes”.

Windows supports curly quotes as well ; they are accessible through the Character Table accessory.

In Xojo, they are
&u2018 and &u2019 (single)
&u201C and &u201D (double)

First of all, blindly changing things in a JSON string with ReplaceAll can get you into all sorts of trouble.
Could you show us a simple JSON example which fails?

It might also be helpful to see what LoadData does with the passed variable.

I had thought about replacing the apostrophe with something else but only want to do that as a last resort. I was hoping there is a way to escape the apostrophe or use another approach to pass the data to a JavaScript function.

I did not have smart quotes enabled.

I agree that changing things in the JSON string is not ideal, but I have not found a way to make it work otherwise. The HTML form data comes from a 4D application we have written. That 4D application uses a web area, like the HTMLViewer in Xojo, to display the HTML form and when the data is submitted on the form we save it as a JSON string. On the 4D side it automatically changes carriage returns to \r
and back again.

When I take this same form and data into a Xojo app I found the \r
were a problem so I had to escape them. Because I have to build a JavaScript string in Xojo the apostrophe is a problem. But I can’t seem to escape that character. I’ve also tried doubling the apostrophe like you would with double quotes in order to include a double quote in a string.

The data looks like this (simplified):

{"Field1":"791737140","Field2":"","DateField":"2014-12-09","DescField":"Line one.\\r\ Line two, the word don't will cause a problem\\r\ Line three.","formSave":"Save"}
So building the string in Xojo to use HTMLFormViewer.ExecuteJavaScript would result in:

LoadData('{"Field1":"791737140","Field2":"","DateField":"2014-12-09","DescField":"Line one.\\r\ Line two, the word don't will cause a problem\\r\ Line three.","formSave":"Save"}');
This fails because of the apostrophe, the first one in the data matches the first apostrophe used in building the string and therefore the rest must be dropped or treated as bad JavaScript.

The start of the JavaScript LoadData function is:

function LoadData (theData) { var formData = eval('('+theData+')'); ... }
(I had to use eval because JSON.parse does not work on Windows, at least all the ones I tested.)

Closer to being solved. Stupid mistake in my code above. When I was testing the escaping of the apostrophe I used the same Self.formData as the line above it to escape the \r
. Of course this mistake meant I was only escaping the apostrophe so the exception was still happening for the \r
which I was thinking was for the apostrophe.

Anyway, I’m still getting an OLEException on the first load of the form, but the data is loading. If I save it and reopen the OLEException does not happen. So I just need to track down why that is happening.

Thanks for the suggestions.

Never easy. Seems to be fixed when running on Windows, but now it fails on the Mac. More digging…

For anyone who is following along or comes across this at some point, this is what I had to do.

My data load is called from the DocumentComplete event on my HTMLViewer. This seems to be called twice when loading HTML and on Windows it often triggered an OLEException whereas it does not cause an exception on the Mac. I changed my code so that the window property that held the form data to be used would be cleared after it was loaded. There is a check to only execute the load data JavaScript if there is something in the window form data property.

This fixed the problem on Windows, but on the Mac it would cause the form to be displayed without any data. It seems the first time the DocumentComplete was called it was not really complete so the load data was not doing anything. The second DocumentComplete would not do anything since I cleared the property.

I don’t know if this is a bug, but the solution I used was to clear my property when run on Windows but not clear it when run on Mac. Being called twice on the Mac is not throwing any exceptions so for now this works.