0

Okay, i'm completetly stuck. I tried every answer on here but I just can't get it to work.

My Aim: Updating dynamic forms with jQuery & AJAX

What's the problem: When clicking one of the "save" buttons it only saves the first value, I tried to do it with different ID's but as a newbie to jQuery I don't think I'm doing this right.

jQuery

$(document).ready(function() {
    $("textarea").keyup(function(){
        var txtArea = $('.txta').val();
        var scriptString = $('.button').attr("url");
        $(".button").click(function(){  
            $.ajax({
              method: 'get',
              url: '../wp-content/plugins/custom-text-editor/writefile.php',
              data: {
               'myString': scriptString,
               'txt': txtArea,
                'ajax': true
              },
              success: function(data) {
                $('#'+myString).text(data);
            return false;
              }
            });
        });
    });
});

writefile.php

$file = fopen("files/tab1.txt","w");
$txt = $_GET['txt'];
fwrite($file,$txt);
fclose($file);
echo "OK!";

Generated HTML

<table class=bordered>
    <tr>
        <th>Filename</th>
        <th></th>
        <th></th>
    </tr>
    <tr class=header>
        <td class='plus'>+</td>
        <td><p>tab1.txt</p></td>
        <td><span id='ss' class='data'></span></td>
    </tr>
    <tr>
        <td colspan="3" class="nopad">
            <p><textarea cols="80" class="txta" rows="12" id="tab1.txt">asdasd</textarea>
            <span id='tab1.txt' class='button' rel='qyz' url=tab1.txt>Save</span></p>   
        </td>
    </tr>
    <tr class=header>
        <td class='plus'>+</td>
        <td><p>tab2.txt</p></td>
        <td><span id='ss' class='data'></span></td>
    </tr>
    <tr>
        <td colspan="3" class="nopad">
            <p><textarea cols="80" class="txta" rows="12" id="tab2.txt">This is file 2</textarea>
            <span id='tab2.txt' class='button' rel='qyz' url=tab2.txt>Save</span></p>
        </td>
    </tr>
    <tr class=header>
        <td class='plus'>+</td>
        <td><p>tab3.txt</p></td>
        <td><span id='ss' class='data'></span></td>
    </tr>
    <tr>
        <td colspan="3" class="nopad">
            <p><textarea cols="80" class="txta" rows="12" id="tab3.txt">And File 3</textarea>
            <span id='tab3.txt' class='button' rel='qyz' url=tab3.txt>Save</span></p>
        </td>
    </tr>
    <tr class=header>
        <td class='plus'>+</td>
        <td><p>tab4.txt</p></td>
        <td><span id='ss' class='data'></span></td>
    </tr>
    <tr>
        <td colspan="3" class="nopad">
            <p><textarea cols="80" class="txta" rows="12" id="tab4.txt">It works!</textarea>
            <span id='tab4.txt' class='button' rel='qyz' url=tab4.txt>Save</span></p>
        </td>
    </tr>
</table> 
2
  • Can you post the generated HTML please (instead of the lines and lines of echo)? Commented Dec 22, 2013 at 23:42
  • Added it, i'm sorry for the messy code. Commented Dec 22, 2013 at 23:50

1 Answer 1

1

This should resolve your problem:

   $(document).ready(function () {
        $(".button").click(function () {
            var txtArea = $(this).closest('tr').find('.txta').val();
            var scriptString = $(this).closest('tr').find('.button').attr("url");
            $.ajax({
                method: 'get',
                url: '../wp-content/plugins/custom-text-editor/writefile.php',
                data: {
                    'myString': scriptString,
                        'txt': txtArea,
                        'ajax': true
                },
                success: function (data) {
                    $('#' + myString).text(data);
                    return false;
                }
            });
        });
    });

How it works:

  1. $(this) gives access to an element being clicked. Even "this" (without dollar sign and without quotes) gives such access, but it is not a jquery object, we need jquery object for further manipulations.

  2. closest('tr') iterates the chain of parent elements until it finds an element satisfying the specified selector (in this case it searches for closest tr-element).

  3. find('.txta') iterates the descendants (of the current element) until it finds an element satisfying the specified selector (in this case it searches for any element having "txta" class, within the tr element).

  4. The rest of code is unchanged.

Further notes:

Event handlers within event handlers (like $("textarea").keyup(function(){ ... $(".button").click(function() { ... ) should be avoided, since the effect is: each time an outer event is handled, a new handler for the inner event is created and attached.

Think of jquery as being kind of "navigation system" over DOM-tree. With functions like "closest", "find", "next", "prev" you navigate around and get to the desired element dynamically, at runtime.

When the desired object has ID and is unique, address it with "#ID" syntax.

When the desired object is repeated (like a row/cell within the table or an element within the cell), then use css-classes and DOM-traversal functions in order to address it.

If you need more information on DOM-traversing:

http://learn.jquery.com/using-jquery-core/traversing/

http://api.jquery.com/category/traversing/

Sign up to request clarification or add additional context in comments.

4 Comments

Amazing! Works like a charm :)
For the benefit of future readers can you explain why this should resolve the problem, or rather what the problem was?
Yes, this pleasure :)
I expanded my answer with detailed explanation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.