0

I have a dynamically-generated list of plants that I have gotten from a MySQL query. In each row of the resulting list, I have a select dropdown list of plant sizes to allow users to change the size of each plant.

I would like to warn the user upon clicking on the dropdown list that they need to click the submit button to update when they change the size any given plant. The current JavaScript I have plugged in displays the correct message only in the first row of results, no matter which row I click the select dropdown in.

Here is the code that currently works and will only appear the first row of the list. I realize this is old syntax, but I see so much diverse information out there, that I'm having a hard time sorting out what to do. I am much better at php than JavaScript.

$(document).ready(function() { 
$(".plantSize").click(function() { 
    $("#reCalc").css({ color:"red" }).html("Click button to update after making changes.").width(400); 
});});



echo '<td>

            <select class="plantSize" name="size_' . $row_count . '" value="' . $size . '">
                  <option value=".5"' . ($size == .5 ? ' selected="selected"' : '') . '>.5 feet</option>
                  <option value="1"' . ($size == 1 ? ' selected="selected"' : '') . '>1 foot</option>
                  <option value="2"' . ($size == 2 ? ' selected="selected"' : '') . '>2 feet</option>
                  <option value="3"' . ($size == 3 ? ' selected="selected"' : '') . '>3 feet</option>
                  <option value="4"' . ($size == 4 ? ' selected="selected"' : '') . '>4 feet</option>
                  <option value="5"' . ($size == 5 ? ' selected="selected"' : '') . '>5 feet</option>
                  <option value="6"' . ($size == 6 ? ' selected="selected"' : '') . '>6 feet</option>
                  <option value="7"' . ($size == 7 ? ' selected="selected"' : '') . '>7 feet</option>
                  <option value="8"' . ($size == 8 ? ' selected="selected"' : '') . '>8 feet</option>
                  <option value="9"' . ($size == 9 ? ' selected="selected"' : '') . '>9 feet</option>
                  <option value="10"' . ($size == 10 ? ' selected="selected"' : '') . '>10 feet</option>
            </select>
    </td>

    <td>'; 
              $peak_water = $peak_et * $etaf * 0.7854 * 1 * .623;
              echo number_format($peak_water,1) . ' gal./wk.</td>'; 
    </td>

    <td><input type="submit" name="Submit" value="Calculate" />
                <span class="recalcwarning" id="reCalc"></span>
    </td>

    </tr>'; 
Lori
  • 59
  • 2
  • 8
  • 1
    Please post an example of your HTML. – j08691 Aug 18 '14 at 16:26
  • I agree with j08691, we need to see some HTML – jwatts1980 Aug 18 '14 at 16:28
  • 1
    Are you adding elements to the list dynamically with Javascript, e.g. using AJAX? Then you need to use event delegation, see http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Barmar Aug 18 '14 at 16:30
  • The jQuery code looks syntactically fine. You are matching elements with a class named "plantSize", then then sending some HTML to an element (div?) with id "reCalc". So that looks fine, but it is not enough to troubleshoot the issue in this case. – jwatts1980 Aug 18 '14 at 16:30
  • I have hesitant to provide the html because it's about 150 lines of code. These rows of plant results are in a while loop. – Lori Aug 18 '14 at 16:48
  • @Lori the HTML helped. I think I found the problem. – jwatts1980 Aug 18 '14 at 18:02

1 Answers1

1

The ID field is supposed to be unique for ENTIRE DOCUMENT. Not just on each row. JQuery is matching all of the #reCalc ID in the whole table, then is only applying the HTML text only to the first matched #reCalc which is the one in the first row. Here are a couple of ways to fix it.

1) If you can't modifiy the ID, look for the reCalc ID in only the row of the click.

$(".plantSize").click(function() { 
    //finds the closest TR up-DOM of the clicked object, then finds the span with ID reCalc within that TR.
    var span = $(this).closest("tr").find("span#reCalc"); 
    span.css({ color:"red" }).html("Click button to update after making changes.").width(400); 
});

2) But really, you shouldn't use the ID field for this. ID's are really meant to be unique. Instead, use the class name then employ the above code again, but a slightly modified selector.

<span class="recalcwarning"></span>

$(".plantSize").click(function() { 
    //finds the closest TR up-DOM  of the clicked object, then finds the span with class recalcwarning within that TR.
    var span = $(this).closest("tr").find("span.recalcwarning"); 
    span.css({ color:"red" }).html("Click button to update after making changes.").width(400); 
});

update

On further review, I did notice a potential invalid HTML issue. In the line echo number_format($peak_water,1) . ' gal./wk.</td>' I see that the TD tag is ended there, but then on the next line, you have another end TD tag.

Here is a link to a workin JSFiddle example based on your sample code. http://jsfiddle.net/7v90kj9p/

jwatts1980
  • 7,254
  • 2
  • 28
  • 44
  • Thank you so much @jwatts1980. This is a very good explanation and solution. I can't get it to work yet, but I will keep trying. The span is actually in the same row as the clicked element, so I tried it using .closest("td") instead. – Lori Aug 18 '14 at 18:38
  • 1
    @Lori: `td` represents the column in the row. `tr` is whole row and all of it's columns. Based on your HTML sample, `tr` should be the correct option. I have updated my answer with a link to a working example based on your code. – jwatts1980 Aug 18 '14 at 18:50
  • YES!!! It works great now!! Thank you so much, @jwatts1980. Thank you for setting up the jsfiddle, too. The funky HTML you saw was just the resul of my slicing and dicing the HTML I provided here, to not show a ton of code. Thank you for sticking it out with me. I love the generosity and good graces of people on this site. I hope I can return the favor and start answering questions too someday. – Lori Aug 18 '14 at 23:05