CreatordotJS
CreatordotJS

Reputation: 63

Escape/Special Characters from user input to HTML5 data-attributes using URL Encode/Decode

This is my first question on stackoverflow - needing help from all you experts. Our web app allows the user to input escape/special characters. We are doing some testing for extreme cases. I'm able to pass the escape characters through ajax/json.

var test = JSON.stringify({
  typeName: $("#typeName").val(),
  invoiceType: 'NewTypeArea'
});
$.ajax({
  type: "POST",
  url: "BackEnd/WebService.php",
  data: {
    newInvoice: test
  },
  dataType: 'json'
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

My backend developer does their thing with escape/special characters. When I make another call I get the following JSON data

[{"propName":"Special '\"'\\","typeName":"type'\"\\"}]

This data returned is correct. For simplicity - I have only one object for this example - I take this data and put it into a dropdown list.

$.each(data, function(i, val) {
var output = '<option class="type" id="' + this.qfInvoiceNum + '" value="' + this.typeName + '">' + this.typeName +'</option>';
$('select#typeList').append(output);

});

It displays all the escape/special characters correctly. For instance: "type'\"\" displays as type'\"\

The user then selects one of the list items. I've tried capturing the typeName numerous ways with data-attributes, value, etc. Here is one example:

$( '.selectChange1').change(function() {
typeGrab = $('select option.type:selected').val();
pullArea();
});

But this is where the problem comes in. If they select a list item with special/escape characters the value from the console returns

"type'"

not

"type'\"\\"

So of course when I pass in the var typeGrab for the JSON/AJAX call it is wrong.

Is there a good solution on on how to get escape/special characters from a dropdown? Or maybe I'm going wrong with $.each when I loop through the data? Or, quite possibly, I'm missing something very simple. Any help or insight would be great.

Thank you.

Additional Info. The first solution does work. However, I didn't use this initially due to the fact that there are a couple of times where the displayed text is not what I want to grab - which is why I was trying data*-attributes.

For example:

$.each(data, function(i, val) {
var output = '<option id="' + this.qfInvoiceNum + '" class="type" data-index="' + this.typeName + '" >' + this.typeName +' | #' + this.qfInvoiceNum +'</option>';
$('select#typeList').append(output);
}); 

If I want the value of this.typeName with escape/special characters the provided solution does not work. I can't use data-attributes or the html option value.

However, after much research, I found a great solution for this problem if you are looking to pass in values to data-attributes that have escape/special characters. Please my answer below.

Upvotes: 3

Views: 2502

Answers (2)

CreatordotJS
CreatordotJS

Reputation: 63

After much research I found the solution I was looking for. If you want to use escape/special characters in html5 data-attributes than a great solution would be to use encodeURI()/decodeURI(): http://www.w3schools.com/jsref/jsref_decodeuri.asp

Solution for this question:

Encoded url version of the value and set the value for select:

$.each(data, function(i, val) {
     var uri = val.typeName;
     var res = encodeURI(uri);
     var output = '<option id="' + this.qfInvoiceNum + '" class="type" data-name="' + res + '" >' + this.typeName +' | #' + this.qfInvoiceNum +'</option>';
     $('select#typeList').append(output);
    }); 

On select, grab the encoded uri, then decode uri

$('.selectChange2').change(function() {
    uriTypeGrab = $('select option.type:selected').data('name');
    typeGrab = decodeURI(uriTypeGrab);
});

typeGrab is now in the correct format with all of the escape/special characters and ready to pass to JSON.stringify() for the ajax call.

Upvotes: 3

cFreed
cFreed

Reputation: 4474

Not pretty sure to have really understood the whole question. Anyway, here is what I point out as perforce causing some issues.

When you create an <option> like this one:

'<option class="type" id="' + this.qfInvoiceNum + '" value="' + this.typeName + '">' + this.typeName +'</option>'

then this.typeName is used to populate both value attribute and node content.

In the latter case all is fine, as you reported, since the current typeName content has nothing special here, at the HTML point of view.

But in the value attribute, the content goes inside of quotes, and here it cannot be neutral as well.

Without more deeper analyzing and testing I can't be strictly affirmative, but a first, quite simply, attempt would be not to populate value attribute at all, using the HTML capability to transparently infer option value from its node content when no value has been given.

This way, the content should escape the constraints of the formulation in writing value. Let me know if it worked...

Upvotes: 2

Related Questions