0

I'm using Jquery $.post to get string array from SQL based on selection from a drop-down that I'm then reading into an HTML table. Each time they change selection on drop down, it clears all but the header row from the table and reloads new values. That is working fine.

It is just a basic 3 row table; a unique identifier, a value and a count shown as string. Every record has all 3, so I'm just using for loop with counters to control start/end of rows. In my form it's header is defined as such:

    <div class="col-md-10">
            <table id="attEditTable" style="width:100%" cellpadding="0" cellspacing="0" border="1" class="row">
                <tbody>
                    <tr style="background-color: #F0F8FF;">
                        <th></th>
                        <th>Attribute Value</th>
                        <th>Item Count</th>
                    </tr>
                </tbody>
            </table>
        </div>

I'm now trying to change the 1st cell of each row to a radio button with the value set to the value I was displaying in that cell.

Currently when the view displayed it is showing [object Object] in the first cell of every row instead of a radio button.

Sorry I am a newb at this with no training on Java or MVC - so hoping just a simple syntax issue...

Trying this basic one returned syntax error on input:

    <input type="radio" name="SelERow" value='+editValues[i]+' />

I've also tried (both had same result of [object Object]):

    $("input:radio[name=\"SelERow\"][value="+editValues[i]+"]")
    $('<input type="radio" id="ERow" name="SelERow" value='+editValues[i]+' />')

Per David's suggestions I've now also tried (both resulted in no data and no error):

    '<input type="radio" name="SelERow" value='+editValues[i]+' />'
    var tblCell = $('<td />');  // create an empty <td> node
    if (x == 1 || (x - 1) % 3 == 0) {
        var input = $('<input />', { type: 'radio', id: 'ERow', name: 'SelERow', value: editValues[i] });
        tblCell.append(input);  // append an <input> node to the <td> node
     } else {
        tblCell.text(editValues[i]);  // or just set the text of the <td> node
     }

With the 2nd one I also changed the line: tblRow = tblRow + ""; to instead be tblRow = tblRow + tblCell + "";

Current Script

<script>
    $(function () {
        $("#EditAttributeName").change(function () {
            var selectedName = $(this).val();

            // Delete all but first row of table
            $("#attEditTable").find($("tr")).slice(1).remove();

            var url2 = "EditDD2changed?selectedName=" + selectedName;

            $.post(url2, function (editValues) {

                var x = 0;
                var tblRow = "<tr>";
                for (var i=0; i < editValues.length; i++)
                {
                    x++;
                    if (x == 1 || (x - 1) % 3 == 0) {
                        tblRow = tblRow + "<td>" + $('input:radio[name="SelERow"][value="' + editValues[i] + '"]');
                    }
                    else {
                        tblRow = tblRow + "<td>" + editValues[i] + "</td>";
                    }

                    if (x % 3 == 0)
                    {
                        tblRow = tblRow + "</tr>";
                        $("#attEditTable").append(tblRow);
                        tblRow = "<tr>";
                    }
                }
            })
        });
    });
</script>

Console is showing no error messages.

Bert
  • 35
  • 1
  • 1
  • 9
  • Wondering if you're sure that `editValues[i]` contains the value you need (inside the object). – wazz Oct 26 '19 at 20:55
  • Yes it does, as mentioned in my post... Prior to changing it to use radio buttons I ran the code and the table is perfect, every row1 cell1 contains the string value that I want passed back to controller if they choose that radio button. – Bert Oct 27 '19 at 15:15

1 Answers1

1

Looks like it's close. To start, there's an important difference in the two attempts. This is a jQuery selector syntax:

$('input:radio[name="SelERow"][value="' + editValues[i] + '"]')

So it's not creating an <input/>, but looking for an <input/>. Which isn't what you want in this case. Your other attempt uses the syntax for creating an element:

$('<input type="radio" id="ERow" name="SelERow" value=editValues[i] />')

Though an issue here (which may have just been a copy/paste error in posting the question? but for completeness and for future readers it may as well be addressed...) appears to be that the editValues[i] is just part of the string. You want to concatenate it into the string. There are a couple ways to do that. Either direct concatenation:

$('<input type="radio" id="ERow" name="SelERow" value="' + editValues[i] + '" />')

Or string interpolation (take note of the different overall quotes, using back-ticks this time):

$(`<input type="radio" id="ERow" name="SelERow" value="${editValues[i]}" />`)

The latter is newer syntax but should be widely enough supported by now. (Though in any given business environment who knows what ancient browsers one may need to support.) Could just be personal preference between the two.

it is showing [object Object]

The main issue producing the result you've observing is that you're concatenating the result of that jQuery operation directly as a string:

tblRow + "<td>" + $('<input type="radio" id="ERow" name="SelERow" value="' + editValues[i] + '" />')

(Coincidentally, whether you're creating an element or looking for an element, this observed output would be the same because both operations return an object.)

The result of an $() operation is not itself a string, but a more complex object. When concatenated with a string it has to be interpreted as a string, and unless the object has a meaningful .toString() implementation (this one doesn't appear to) then the default string representation of a complex object is exactly that: "[object Object]"

There are a couple approaches you can take here. One would be to just use strings entirely, you don't necessarily need a jQuery object here:

tblRow + '<td><input type="radio" id="ERow" name="SelERow" value="' + editValues[i] + '" /></td>'

Since you're using jQuery later to append the result to the HTML, you can just build up all the HTML you like as plain strings and let jQuery handle turning them into DOM objects when you send them to .append().

The other option, if you definitely want to "use jQuery" in this situation or are otherwise being instructed to, would be to build the hierarchy of HTML elements as jQuery objects and then pass that hierarchy to .append(). Constructing such a hierarchy can look something like this:

var tblCell = $('<td />');  // create an empty <td> node
if (x == 1 || (x - 1) % 3 == 0) {
    var input = $('<input />', { type: 'radio', id: 'ERow', name: 'SelERow', value: editValues[i] });
    tblCell.append(input);  // append an <input> node to the <td> node
} else {
    tblCell.text(editValues[i]);  // or just set the text of the <td> node
}

Note that each $() operation creates an HTML element node, and you can supply attributes for it as a second argument to the $() function. Then those nodes can be .append()-ed to each other just like you .append() the HTML string to $("#attEditTable").

In your particular case this may get a little more cumbersome because your loop isn't just looping through cells or just through rows, but through both and using a hard-coded count to determine whether it's reached the end of a row or not. So, as part of learning/practicing jQuery, it may be worth the effort to try this approach. But I suspect the shortest path to getting your code working with minimal changes would be the string concatenation approach above.


Side note: This code is using the same id value for the radio buttons created within this loop. The result is that there is expected to be multiple elements on the page with the same id. This is technically invalid HTML. If you ever try to use that id to reference an element, the resulting behavior will be undefined. (It might work in some cases, might not in others, purely coincidentally.) Though if you don't need to use that id to reference the elements, you may as well remove it entirely.

David
  • 208,112
  • 36
  • 198
  • 279
  • Sorry David - I wish it was that easy... To be clear, sorry I didn't mention the 1st of the 4 things I tried in post. I originally tried but that gives a syntax error on – Bert Oct 27 '19 at 15:43
  • @Bert: You may need to elaborate on exactly what you tried. "normal HTML syntax" isn't really a concern in JavaScript, since we're just talking about strings. A syntax error in the JavaScript code would imply that you may have a quoting error or something of that nature in the string you were building. – David Oct 27 '19 at 15:45
  • My bad - re-published wrong project... Your 2nd suggestion is failing completely. It is showing the following error in console "ReferenceError: radio is not defined" – Bert Oct 27 '19 at 15:50
  • @Bert: That was a typo on my part, `radio` should be in quotes (since it's a string). Just updated the answer. – David Oct 27 '19 at 15:51
  • To elaborate on what i meant by "normal HTML" - I copied and pasted your suggestion of tblRow = tblRow + – Bert Oct 27 '19 at 15:53
  • @Bert: That line is missing some quotes. Specifically before the ``. Looks like the entire line wasn't highlighted when you copied. String literals need to be enclosed in quotes. – David Oct 27 '19 at 15:56
  • OK - tried 6 different ways now... Both of your suggestions result in no table and no error. I'll add the other things tried to my post... – Bert Oct 27 '19 at 16:09
  • @Bert: It looks like you're mixing up the two suggested approaches. The first one is simpler, so let's stick with that. Just use this to append a table cell to your `tableRow` variable: `tblRow = tblRow + '';` Inside your first `if` block, that should be all you need to change. – David Oct 27 '19 at 16:19
  • Should mention - there was a 7th attempt I couldn't get to work either... I believe it's how I ended up with the selector syntax as you called it. I was trying to use that selector and .AppendTo('#attEditTable') - But that also didn't work for me. – Bert Oct 27 '19 at 16:22
  • David - thanks that finally did it, was missing or had and extra " or ' from first copy and paste... So really I chased my tail for over a day because I didn't know to enclose my – Bert Oct 27 '19 at 16:35