4

I have a textarea in a form that I'm trying to send via ajax with jQuery. My problem is when the textarea contains linebreaks and ampersand (&).

I get the value of the textarea with the following js code:

// Find all the fields with class dirty
$('#customer .dirty').each(function() {

    fieldName = $(this).attr('id');
    fieldValue = $(this).val();

    // Create an object of dirty field names and values             
    var fields = { 'fieldName' : fieldName, 'value' : fieldValue }; 

    // Add the object of field names and values to the custRecordToUpdate array                 
    custRecordToUpdate.push(fields);  // note: this was initialized before  

});


var arrayToSend = {
    customer : custRecordToUpdate
};

var dataToSend = JSON.stringify(arrayToSend);

With the textarea value as follows:

1/8 CLEAR MIRROR  
3/8 CLEAR GLASS

If I console.log(dataToSend), I get the following:

{"customer":[{"fieldName":"cust_note","value":"1/8 CLEAR MIRROR\n3/8 CLEAR GLASS"}]} 

On the PHP script, I json_decode the posted data and it works correctly.

If I then change the textarea to include an ampersand as follows:

1/8 CLEAR MIRROR  
3/8 CLEAR GLASS & GLASS  

the json_decode fails. The console.log(dataToSend) displays the following:

{"customer":[{"fieldName":"cust_note","value":"1/8 CLEAR MIRROR\n3/8 CLEAR GLASS & GLASS"}]}

json_last_error() displays Syntax Error

If I change the js code above to this:

fieldValue = encodeURIComponent($(this).val());

Then console.log(dataToSend) displays:

{"customer":[{"fieldName":"cust_note","value":"1%2F8%20CLEAR%20MIRROR%0A3%2F8%20CLEAR%20GLASS"}]}  

and json_decode fails with both data cases with a syntax error.

So, how can I send textarea data that contains linebreaks and ampersands via ajax to a php backend, and have json_decode not fail?

Solution:

Based on some of the comments below, I decided to change the ajax code that sends the data, and this solved the problem, although I'm not sure why.

Anyway, here is the code, in case it can help anyone else.

var returnedHTML = $.ajax({
   type: "POST",
   url: 'index.php/customer/save_edit_customer',
   //data : "data="+dataToSend, // This is how I was sending it before 
   data : { "data" : dataToSend }, // This is the new code that works!
   async: false,
   cache: false
}).responseText;
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
Julio
  • 41
  • 1
  • 3
  • I get an object as expected when I do a `print_r(json_decode($your_bad_sample_here))` on my PHP install (5.3.2-1). I'd suggest dumping out the string you receive on the PHP-side immediately before calling json_decode(). Most likely you've got something mungeing the data there, like magic_quotes and the like. – Marc B Jun 03 '11 at 16:41
  • 1
    @Marc B, this comment, and the one below got me thinking about the way I was sending the data, instead of focusing on the data itself. I changed the ajax code, and it suddenly works. I updated the post to reflect the changes I made. So yes, it looks like something was "mungeing" the data, but I'm still not sure what... – Julio Jun 08 '11 at 20:05

2 Answers2

2

assuming your text is saved in the variable textareaText do this

var val = textareaText.replace('&', '__and__');

send this as the ajax

and on the server side

assuming your json_decode`d value is saved in a variable named $data do this:

$val = str_replace( '__and__', '&', $data['value'] );

this way you will be able to keep the ampersands without letting your json_decode fail

you can use something else instead of and as a place holder

though it is confusing why it breaks.

shaheer
  • 376
  • 2
  • 6
  • 16
  • It's a workaround, but doesn't solve the root problem - Javascript doesn't consider an `&` inside a string as a metacharacter, so there's no reason the json_decode should fail. Something else is mungeing the OP's data. – Marc B Jun 03 '11 at 17:01
  • exactly, something is changing the $_GET or $_POST array, or something is happening with the data before the user tries to json_decode that value – shaheer Jun 03 '11 at 17:06
  • It'd be better to figure out what/why is changing the data, rather than papering over it with a string manipulation. No guarantees it won't munge the sentinel characters you're using into something else either. – Marc B Jun 03 '11 at 17:22
  • Just a note to say that replacing the ampersand in the client and then switching it back server side as per this suggestion worked for me with a similar problem where I was creating a javascript array containing text from tinymce text areas. The object was packed with stringify and sent to the server via ajax, if the text contained an ampersand it broke the array which was empty server side, uriencoding also did not help, replacing the ampersand as suggested here solved the problem. – paj Jun 27 '14 at 07:09
2

I'm not sure what the shape of your object is supposed to be, but it works for me if I change:

{"customer":[{"fieldName":"cust_note","value":"1/8 CLEAR MIRROR\n3/8 CLEAR GLASS & GLASS"}]}

To

{"customer":{"fieldName":"cust_note","value":"1/8 CLEAR MIRROR\n3/8 CLEAR GLASS & GLASS"}}

i.e. Remove the array-syntax from the json object.

Here is my test...

    var customer = {"customer":{"fieldName":"cust_note","value":"1/8 CLEAR MIRROR\n3/8 CLEAR GLASS & GLASS"}};
    alert(customer.customer.fieldName);
    alert(customer.customer.value);

This suggests that the & is not your problem, but the [] are.

Fenton
  • 241,084
  • 71
  • 387
  • 401