1

Good morning. I am slowly but surely figuring out jQuery, but this morning I find myself stumped and head-scratching. First, my relevant code:

HTML

<fieldset class="fieldset2">
    <legend>Return Specific Curriculum Information</legend>
    <input type="hidden" id="ccnt" value="0">
    <table class="table" id="retc">
        <thead>
            <tr>
                <th class="th">#</th>
                <th class="th">Year</th>
                <th class="th">Lang</th>
                <th class="th">Week/Packet</th>
                <th class="th">Quantity</th>
                <th class="th">Delete</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    <input type="button" value="Add Curriculum To Return" class="button" id="addcurric">
    <input type="button" value="Remove All Entries" class="button" id="remcurric">
</fieldset>

JavaScript/jQuery

$('#ccnt').data('count', 0);
$('#addcurric').click(function () {
    function getcount() {
        var $this = $('#ccnt'),
            count = $this.data('count') + 1;

        $this.data('count', count);
        return count;
    }

    var mycount = getcount();
    var myyear = 'cyear' + mycount;
    var mylang = 'clang' + mycount;
    var myweek = 'cweek' + mycount;
    var myqty = 'cqty' + mycount;

    alert('mycount: ' + mycount + '; myyear: ' + myyear + '; mylang: ' + mylang + '; myweek: ' + myweek + '; myqty: ' + myqty);

    var tdclass;
    if (mycount % 2 == 1) {
        tdclass = "td1";
    } else {
        tdclass = "td2";
    }

    var chtml = "";
    chtml += "'<tr>";
    chtml += "    <td class=\"" + tdclass + "\">" + mycount + "</td>\n";
    chtml += "    <td class=\"" + tdclass + "\"><select name=\"" + myyear + "\" id=\"" + myyear + "\">\n";
    chtml += "        <option value=\"0\">-- Select --</option>\n";
    chtml += "        <option value=\"1\">Year 1</option>\n";
    chtml += "        <option value=\"2\">Year 2</option>\n";
    chtml += "        <option value=\"3\">Year 3</option>\n";
    chtml += "    </select></td>\\n";
    chtml += "    <td class=\"" + tdclass + "\"><select name=\"" + mylang + "\" id=\"" + mylang + "\">\n";
    chtml += "        <option value=\"0\">-- Select --</option>\n";
    chtml += "        <option value=\"1\">English</option>\n";
    chtml += "        <option value=\"2\">Spanish</option>\n";
    chtml += "    </select></td>\\n";
    chtml += "    <td class=\"" + tdclass + "\"><select name=\"" + myweek + "\" id=\"" + myweek + "\">\n";
    chtml += "";
    chtml += "    </select></td>\n";
    chtml += "    <td class=\"" + tdclass + "\"><input type=\"text\"  name=\"" + myqty + "\" class=\"input\"></td>\n";
    chtml += "    <td class=\"" + tdclass + "\"><button type=\"button\" class=\"dbutton\" title=\"Remove This Row\">X</button></td>\n";
    chtml += " </tr>\n'";

    $('#retc > tbody').append(chtml);

    $(".dbutton").bind("click", Delete);
});

$('#remcurric').click(function () {
    $('#retc > tbody').html("");
    $('#ccnt').data('count', 0);
});

function Delete() {
    var par = $(this).parent().parent();
    par.remove();
}

The Problem/Question

As you can see, in my js/jQ code, I am generating dynamic table rows to handle 1-n records. I also left a blank where option lines should be for id "myweek" - because they should come from my database. Ordinarily, I would do something like this to fill those in:

$('#'+mylang).change(function() {

    var lang = $('#'+mylang).val();
    var year = $('#'+myyear).val();

    $.post("/chairs-dev/jqf/returncurric_processajax.php", {LANG: lang, YEAR: year}, function (data) {
        $('#'+myweek).append(data);
    });
});

This code didn't work, so I went code hunting online. I have tried about every permutation I can think of or find online to solve this issue, but none of it works. I am sure there is something basic I'm missing here, but I just can't see it. Any thoughts on how I can get this to work?

Thanks in advance!!

EDIT: Sorry, jsfiddle link

TheJester1977
  • 155
  • 1
  • 10
  • 1
    Post a [SSCCE](http://sscce.org/) on http://jsfiddle.net/ – steady rain Feb 27 '15 at 14:32
  • 1
    `.change()` will only bind to elements that already exist in the document. You are dynamically creating your form elements, so you will need to change that to [`.on('change', 'selector', function() {})`](http://api.jquery.com/on/), which will delegate the event to matching elements that exist now and in the future. You will likely need to rethink the way you are naming those elements (add a class name or something to use as `selector` in the above). See [one of my other answers](http://stackoverflow.com/a/6658774/74757) on the subject for more explanation. – Cᴏʀʏ Feb 27 '15 at 14:35

2 Answers2

1

Like Corey Mentioned, when you call .change, it only binds to elements that exist currently.

To make it work for elements added to the page later you can bind the change function to the document and add a selector.

Something like this should work for elements added later on...

$(document).on('change', '#' + mylang, function(){
    alert('Element changed');
});
Matt Klooster
  • 717
  • 1
  • 5
  • 13
1

Here's one approach. Step 1 would be to fix the existing Delete click function. You are going to end up assigning multiple click event handlers this way. Step 2 would be to adjust your change method. Here's how I got it working:

// remove your other `.dbutton` click handler
$('#retc').on('click', 'button.dbutton', Delete);

// add a proper change event
$('#retc').on('change', 'select[name^="clang"]', function() {

    var lang = $(this).val();
    var year = $(this).parents('tr').find('[name^="cyear"]').val();

    //alert('lang: ' + lang + ', year = ' + year);

    var $myweek = $(this).parents('tr').find('[name^="cweek"]');

    $.post("/chairs-dev/jqf/returncurric_processajax.php", {LANG: lang, YEAR: year}, function (data) {
        $myweek.html(data);
    });
});

jsFiddle Demo

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • Thanks Cory! I swear, one day I will figure out this jQuery stuff and be able to leave you guys alone!! As a follow-up, I tried to use the same logic after my POST results came back to append to the cweek select with `$(this).parents('tr').find('[name^="cweek"]').append(data);`, but that didn't seem to do the trick. Am I close? :) – TheJester1977 Feb 27 '15 at 15:54
  • 1
    @TheJester1977: I adjusted my answer a little bit. I think `this` is something different in the callback function from your `POST`. So I grabbed a reference to the `myweek` select element before and use that in the callback instead. I also changed `.append` to `.html` so it replaces whatever's there (so you don't end up with a growing list of options on each language change). – Cᴏʀʏ Feb 27 '15 at 16:18
  • Thank you again, Cory! Worked like a champ!! – TheJester1977 Feb 27 '15 at 16:23
  • 1
    @TheJester1977: You're welcome! As far as understanding jQuery, make sure to go back and understand why I chose the selectors I did (`#retc`, the `^=` [starts with]), etc., and why I chose `on()`, `parents()`, etc. and what `this` means in different contexts. Once you understand what jQuery (and JavaScript in general) is thinking, writing it becomes so much easier. – Cᴏʀʏ Feb 27 '15 at 16:31