0

I am inserting some <input type='text'> elements dynamically with Ajax but when I update them, the value is not actually updated in the DOM.

Let's say if I have a field with the value old and I then update it with a new value of new... if I in my Chrome console writes alert($("input[value='new']").val()); (after the update of course) it just comes with an undefined prompt but I can search on the old value still!?

Please see my JSFiddle demo for my problem. If you don't change the <input type='text'> value but just changes the <select> options everything is working fine and I can see which groups are a member of a certain option but if I change the <input type='text'> then it doesn't work any more.

Do note that the $(document).on("change"... is needed as the elements are coming from an Ajax call.

HTML:

<p>
    <input type="text" value="Group 1" data-id='123' />
    <select multiple>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
</p>
<p>
    <input type="text" value="Group 2" data-id='abc' />
    <select multiple>
        <option>Option 1</option>
        <option>Option 2</option>
        <option>Option 3</option>
    </select>
</p>
<hr>
<ul class="group" data-id='123'> <span>Group 1</span>
    <ul class="item"><span>Item 1</span></ul>
    <ul class="item"><span>Item 2</span></ul>
</ul>
<ul class="group" data-id='abc'> <span>Group 2</span>
    <ul class="item"><span>Item 3</span></ul>
    <ul class="item"><span>Item 4</span></ul>
</ul>
<hr>
<div></div>

jQuery/JS:

// When changing INPUT:TEXT then update the UL>SPAN text based on the "data-id" attribute
$(document).on("change", "input", function () {
    var group = $(this).val();
    var id = $(this).data("id");
    $("ul[data-id='" + id + "'] span:first").text(group);
});

// When changing either INPUT:TEXT or SELECT then update the list of assocuated groups
$(document).on("change", "select, input", function () {

    // Empty the debug DIV text
    $("div").text("");

    // Show all options from the first SELECT
    $("select:first option").each(function () {
        var txtOptionAvailable = $(this).text();

        $("div").append("<p><strong>" + txtOptionAvailable + "</strong></p>");

        // Show all groups
        $(".group > span").each(function () {
            var txtGroup = $(this).text();
            $("div").append("<p>Processing " + txtGroup + "</p>");

            $("input[value='" + txtGroup + "']").next().find("option:selected").each(function () {

                var txtOptionSelected = $(this).text();

                // If the "available option" matches the "selected option"
                if (txtOptionAvailable == txtOptionSelected) {
                    $("div").append("<p>" + txtGroup + " has selected " + txtOptionSelected + "</p>");
                }
            });
        });
    });
});

Can anyone see what I am doing wrong?

Beauvais
  • 2,149
  • 4
  • 28
  • 63

3 Answers3

2

@CBroe - your answer made me look in to this and I figured out that I simply could use the filter method in my selector:

Old string:

$("input[value='" + txtGroup + "']").next().find("option:selected")...

New string:

$("input").filter(function() { return $(this).val() === txtGroup }).next().find("option:selected")...

This question/answer was the real discovery for me, jQuery 1.9.1 property selector

See new JSFiddle demo.

Community
  • 1
  • 1
Beauvais
  • 2,149
  • 4
  • 28
  • 63
1

Your error is here: input[value='new'] – the attribute selector only applies to values as they are given (normally in the HTML code) initially.

Changing the value of an input field that was created using value="old" to new dynamically will not change it in a way that the attribute selector will recognize.

Read what http://api.jquery.com/prop/ has to say about the difference about Attributes vs. Properties, that should make it more clear.

CBroe
  • 91,630
  • 14
  • 92
  • 150
0

See this : DEMO

Assign the value of textbox to a new attribute (here data-val) and use that for filtering ($("input[data-val='" + txtGroup + "']"))...

$(document).ready(function(){
   $("input").each(function() {
     $(this).attr('data-val', this.value);
   });
});

// When changing INPUT:TEXT then update the UL>SPAN text based on the "data-id" attribute
$(document).on("change", "input", function () {
  var group = $(this).val();
  var id = $(this).data("id");
  $(this).attr('data-val', group);
  $("ul[data-id='" + id + "'] span:first").text(group);
});

// When changing either INPUT:TEXT or SELECT then update the list of assocuated groups
$(document).on("change", "select, input", function () {

// Empty the debug DIV text
$("div").text("");

// Show all options from the first SELECT
$("select:first option").each(function () {
    var txtOptionAvailable = $(this).text();

    $("div").append("<p><strong>" + txtOptionAvailable + "</strong></p>");

    // Show all groups
    $(".group > span").each(function () {
        var txtGroup = $(this).text();

        $("input[data-val='" + txtGroup + "']").next().find("option:selected").each(function () {

            var txtOptionSelected = $(this).text();

            // If the "available option" matches the "selected option"
            if (txtOptionAvailable == txtOptionSelected) {
                $("div").append("<p>" + txtGroup + " has selected " + txtOptionSelected + "</p>");
            }
        });
    });
 });
});

UPDATE:

See CBroe's Answer for the reason why your code is not working..

Community
  • 1
  • 1
Anujith
  • 9,370
  • 6
  • 33
  • 48