0

I want to use the var s for the value-field of an option-element. How to escape correctly in the sense to contain user input used for key and value?

var key='highway'; var value='track';
var s = JSON.stringfy({ [key]:value }, undefined,'');
s = s.replace(/'/g,'\\\'').replace(/"/g,'\\"');
var h = '<option type="text" value="' + s + '">'+key+'</option>';
// ...
document.getElementById('aSelectElement').innerHTML = h;

Edit: Actually I use it for an option-Element instead of an input element as mentioned first.

If I select the result in the browser, and let it me show the generated html, it shows something like:

<option value="{\" highway\":\"track\"}"="">highway track</option>

Which adds the question, why there is a whitespace in front of the highway?

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
John
  • 57
  • 8
  • The var declaration `var value:'test';` is invalid syntax. Should be `var value='test';` – Steve Nov 05 '19 at 01:21
  • The code `{ [key]:value }` should be `{ key: value }`. You can't use an array as a key in a Javascript object, nor in a JSON object. When you use a key which is not a string, Javascript silently converts it to a string. – kaya3 Nov 05 '19 at 01:30
  • @kaya3 Starting with ES6 this is working: https://stackoverflow.com/questions/11508463/javascript-set-object-key-by-variable – John Nov 05 '19 at 01:54
  • Oh, you are right. I remember seeing that syntax before but I don't write for ES6 myself. – kaya3 Nov 05 '19 at 01:57

2 Answers2

1

I also recomment using DOM elements rather than building HTML as a string, as in the other answer. But if you really don't want to do that, you can convert any double quotes in the JSON to the HTML entity &quot;, so they won't terminate the value attribute.

var key = 'first';
var value = 'test';
var s = JSON.stringify({
  [key]: value
}, undefined, '').replace(/"/g, '&quot;');
var h = '<input type="text" value="' + s + '">';
document.getElementById('aDiv').innerHTML = h;
<div id="aDiv"></div>
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • With `'"'` in the replace instead of `'\\"'`, which I used first, it does work. Ty! – John Nov 05 '19 at 01:37
  • Naturally. HTML doesn't use backslashes for escaping. – Barmar Nov 05 '19 at 01:38
  • Now that you say it, it's so obvious. :) Another question: Which editor for html, javascript and php would you suggest or are you using? – John Nov 05 '19 at 01:44
0

There's no need to build HTML as a string; you can create an input element and set its value programmatically:

// ...
var inputElem = document.createElement('input');
inputElem.type = 'text';
inputElem.value = s;
// ..
document.getElementById('aDiv').appendChild(inputElem);

Note that this isn't quite equivalent because setting innerHTML removes all the existing content from the div, but calling appendChild doesn't. If you do need to replace the existing content, you can do this by removing the existing child nodes first.

kaya3
  • 47,440
  • 4
  • 68
  • 97
  • I'm not very fond of appendChild-syntax. Worst was that it triggered Firefox (I believe it was version 30-something) to let the loading animation on the top beside the http-adress run. People would have thought the program would connect to the internet, whereas it is a 100% offline application. – John Nov 05 '19 at 01:16
  • OK, well if you absolutely must avoid `appendChild` for some reason, you could create the input element as an HTML string with a blank value, but give it some id so you can do `document.getElementById('the_input').value = s`. The solution is still to set `.value` programmatically. – kaya3 Nov 05 '19 at 01:21
  • Another question: Which editor for html, javascript and php would you suggest or are you using? – John Nov 05 '19 at 01:44