-1

The following code doesn't work for me although a similar one works (http://85.255.14.137). The CHANGE_ME text should get replaced by a a value on each change of the input field. How can I correct that?

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<html>
<head>

<script>
  $(document).on('change', '.input', (function(){
    var par = $(this);
    var val = $(this).val();

    par.find("span.value").hmtl(val));            
  });

</script>
</head>

<body>
<div class="col-sm-4">
  <div>
    <form id="A" name="do_something" method="POST" action="/do_something">
      <p>
        <input id="A" class="input" type="number" min="5" value="5" step="1" required />
      </p><p>
        <span class="value">CHANGE_ME</span>
      </p>
    </form>
  </div>   
</div>

</body>
</html>
Sphinx
  • 10,519
  • 2
  • 27
  • 45

3 Answers3

1

First: as Taplar said, your supplied code has an extra ) after you call the .html() method. As APAD1 said, you also shouldn't have two elements with the same ID, but that's not causing your issue.

Second: this problem is a great opportunity to think carefully about DOM structure. As it stands, you can't find() from $(this) because $(this) is the input element that fired the change event. The input has no children, so .find() will never return anything. Because your input is inside a paragraph tag and your target span is in a paragraph that is the sibling of that parent, you have to do some complicated traversals up the dom, over, and down, like so:

$(document).on('change', '.input', function() {
  var par = $(this);
  var val = $(this).val();

  par.closest('p').siblings('p').find('span.value').text(val);
});
<!DOCTYPE html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>

<body>
  <div class="col-sm-4">
    <div>
      <form id="A" name="do_something" method="POST" action="/do_something">
        <p>
          <input id="B" class="input" type="number" min="5" value="5" step="1" required />
        </p>
        <p>
          <span class="value">CHANGE_ME</span>
        </p>
      </form>
    </div>
  </div>

</body>

</html>

We can avoid this problem if we approach our DOM structure more meaningfully, and think a bit differently about how we handle the change event.

First, let's use more semantic tags in our form. Inputs need labels; and also keep in mind that the output element is a better tag for displaying content that comes out of using an input:

<form id="A" name="do_something" method="POST" action="/do_something">
  <label for="B">Pick a number</label>
  <input id="B" class="input" type="number" min="5" value="5" step="1" required />
  <output for="B">CHANGE_ME</output>
</form>

With that structure, DOM traversal is a lot easier!

$(document).on('change', 'form', function(e) {
  // the form whose input fired `change`
  const $self = $(e.currentTarget);
  const $output = $self.find('output');
  const val = $self.find('input').val();

  $output.text(val);

(Note that we don't use this to reference the form element. this can be unclear, and we have better ways of referencing the element jQuery is interacting with, like the event.currentTarget or the event.target. The two are subtly different!)

And here's the snippet with these changes together, for the lazy: :)

$(document).on('change', 'form', function(e) {
  // the form whose input fired `change`
  const $self = $(e.currentTarget);
  const $output = $self.find('output');
  const val = $self.find('input').val();

  $output.text(val);
});
* {
  box-sizing: border-box;
}

output {
  display: block;
}
<!DOCTYPE html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <div class="col-sm-4">
    <div>
      <form id="A" name="do_something" method="POST" action="/do_something">
        <label for="B">Pick a number</label>
        <input id="B" class="input" type="number" min="5" value="5" step="1" required />
        <output for="B">CHANGE_ME</output>
      </form>
    </div>
  </div>
</body>
</html>
EJ Mason
  • 26
  • 4
  • Woohoo! Thank you mate for not only the working example but also for the exhaustive explanation. You made my day, mate! Thank you so much! – user1827988 Mar 15 '18 at 17:27
  • You're welcome! Thanks for commenting - I saw a chance to explain myself a bit better. – EJ Mason Mar 15 '18 at 18:41
0

There are a few issues with your code. For one thing you spelled html wrong, another issue is that you are looking for span with the class of value within the input, but it's not inside the input. You can write it like this instead:

$('.input').change(function() {
  var val = $(this).val();

  $("span.value").html(val);            
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-4">
  <div>
    <form id="A" name="do_something" method="POST" action="/do_something">
      <p>
        <input id="A" class="input" type="number" min="5" value="5" step="1" required />
      </p><p>
        <span class="value">CHANGE_ME</span>
      </p>
    </form>
  </div>   
</div>

Another issue, unrelated to this problem, is that you have two elements with the ID of A, which is not valid. IDs must be unique.

APAD1
  • 13,509
  • 8
  • 43
  • 72
-1

In addition to hmtl typo. You're traversing / searching for span with class value using .find method. Unfortunately that's not present there.

Instead of traversing, you can directly access the span with $(".value").html(val);

Veey
  • 216
  • 3
  • 13