2

I have a page where a user can edit some values (name, description, etc...) which works fine except when a long string is added as a description.

When a user changes the value of an input field, a javascript function is called to check if any values are different from the initial (when the site is first loaded with PHP the initial values are stored as variables). It looks like this:

<script>
    //checks if a field has changed value, if yes, change class
    function check(div, text){
        if(div.val()===text){
            div.parent().removeClass("has-warning");
            return 0;
        } else{
            div.parent().addClass("has-warning");
            return 1;
        }
    }
</script>
*here goes the html stuff*
<script>
    //whenever the form content changes
    $('#horse1').bind('input', function() {
        //the form div
        var horseDiv = $('#horse1');
        //count all the fields with changed value
        var error = check(horseDiv.find($('#name')), 'Rinaldo')
                   +check(horseDiv.find($('#race')),'-')
                   +check(horseDiv.find($('#date')),'1988-01-01')
                   +check(horseDiv.find($('#use')), 'Showpferd')
                   +check(horseDiv.find($('#shortDesc')), 'short Description')
                   +check(horseDiv.find($('#description')),'This can be a long text over multiple lines');

                   //if there is at least one field with a
                   //changed value, display an error message
        var errorDiv = horseDiv.find($('#notSaved'));
        if(error==0){
            errorDiv.hide();
        } else{
            errorDiv.show();
        }
    });
</script>

So firstly if anyone has an idea how to make this behavior more elegant, I am open to suggestions.

But the problem I'm having is that this script completely stops working if the text (the description) is longer than one line. I am not sure why or how to solve this, so any help would be greatly appreciated.

***UPDATE: Compare multiple line texts in javascript

In case anyone has the same problem, here is the solution that worked for me:

var textNew = text.replace(/%0D/g, '');
var divNew = encodeURIComponent(div.val()).replace(/!/g, '%21')
                                          .replace(/'/g, '%27')
                                          .replace(/\(/g, '%28')
                                          .replace(/\)/g, '%29')
                                          .replace(/\*/g, '%2A');

The Variable "text" is the rawlurlencode() String from the php-Script and div.val() is the plaintext read from the textarea. With the above code, textNew===divNew returns true, even if they contain commas, umlaute, new lines and other nasty stuff

Juliette
  • 966
  • 16
  • 35

4 Answers4

1

Try passing the description string into json_encode to properly escape it.

dodopok
  • 868
  • 14
  • 22
  • The question is about JavaScript. But the problem is on the PHP side. The PHP is writing the text, so it needs to be escaped, so the javascript can parse it properly. – dodopok Jul 20 '16 at 20:39
  • hm, follow up question: any idea how I can compare the div.val() to the json string? (the check function obviously isn't working now anymore) – Juliette Jul 20 '16 at 21:00
  • Inside of the check function, if you print the div and text variables, what is showing to you? – dodopok Jul 21 '16 at 10:55
  • 1
    took me quite a while, the solution for the same output ended up looking like this: var textNew = text.replace(/%0D/g, ''); var divNew = encodeURIComponent(div.val()).replace(/!/g, '%21') .replace(/'/g, '%27') .replace(/\(/g, '%28') .replace(/\)/g, '%29') .replace(/\*/g, '%2A'); – Juliette Jul 21 '16 at 18:39
0

Of course it stops working.

On the PHP side you need to correctly connect the strings if there are linebreaks in them.

preg_replace( "/\r|\n/", "", $yourString );
Lemonade
  • 503
  • 2
  • 8
0

Juliette, I think it would be better to use event change instead of input while you don't need to immediately check if text is changed. Browser will do all routine for you.
Also you need to know why your script is stopping, if not already know) You can look at Console tab in dev tools pane in the browser.
If indeed you need to see changes immediately after user pressing a key than I'll recommend you to use String method localeCompare
Here is answer about comparing Optimum way to compare strings in Javascript?
Hope I helped to you!

Community
  • 1
  • 1
Yan Pak
  • 1,767
  • 2
  • 19
  • 15
  • I tried it with change but that didn't work The problem was that I needed to json encode the string so it could be passed as a parameter – Juliette Jul 20 '16 at 20:59
0

I assume that #description is a <textarea> since you mention it may be multiline.

The script as you posted it should have the characters \n instead of an actual newline in the script. You will need to do a replace in PHP to achieve this, but not the one posted by Lemmy as it just removes the newline. You can also just JSON encode as discussed previously.

Also, beware that on Windows, browsers will handle newlines as \r\n instead of just \n. You will also need to do a replace in JS to remove any \r characters before the comparison to handle this.

Also, you can do .find("#selector") instead of .find($("#selector")).

Adam Leggett
  • 3,714
  • 30
  • 24
  • thanks for the tip with the find - the json version from dodopok worked but the check-function isn't working anymore because I can't compare the div.val() to the text which is json encoded now. I tried JSON.stringify in javascript but the compare still doesnt work – Juliette Jul 20 '16 at 21:05