-1

When I return the value from the javascript function on the onClick event, it is getting inserted but the form refreshes again and I lose the selection and the values that I have inserted. Why does this happen and how can i avoid it?

Below is a sample of my code:

<form id="lengthConvert">
    <p><b>Enter a value : </b></p><input type="number" name="inputValue" />
    <p><b>Convert from : </b></p>
        <select name="fromUnit">
            <option value="Centimeter">Centimeter</option>
            <option value="Meter">Meter</option>
            <option value="Kilometer">Kilometer</option>
            <option value="Miles">Miles</option>
        </select>
    <p><b>Convert to : </b></p>
        <select name="toUnit">
            <option value="Centimeter">Centimeter</option>
            <option value="Meter">Meter</option>
            <option value="Kilometer">Kilometer</option>
            <option value="Miles">Miles</option>
        </select>
        <br/><p id="Output"></p>
    <button type="submit" form="lengthConvert" value="Submit" onclick="getElementById('Output').innerHTML=convert()">Convert</button>
</button>
</div>

</body>
</html>
<script>
    function convert(){
        var value = document.getElementsByName('inputValue')[0].value;
        var fromUnit= document.getElementsByName('fromUnit')[0].value;
        var toUnit= document.getElementsByName('toUnit')[0].value;
        if(fromUnit==toUnit){
            return value;
        }
    }
</script>

when I am returning the value from the javascript method on onclick event, it is getting inserrted but the form refreshes again and I am loosing all the selection and values which i have inserted. Why? and how can i avoid that?

i alarmed alien
  • 9,412
  • 3
  • 27
  • 40

3 Answers3

3

When you click the button you're submitting your form because you're not doing anything to stop the default behavior. Change

<button type="submit"...

to

<button type="button"...

As a side note, your HTML needs to be fixed as you have an extra </button>, no closing </form>, and an unopened </div>. Also, your function doesn't appear to do any actual conversion.

j08691
  • 204,283
  • 31
  • 260
  • 272
1

You need to do two things:

  1. Pass event object from onclick() function
  2. Prevent form submission inside convert function by using preventDefault();

function convert(e) {
  e.preventDefault();
  var value = document.getElementsByName('inputValue')[0].value;
  var fromUnit = document.getElementsByName('fromUnit')[0].value;
  var toUnit = document.getElementsByName('toUnit')[0].value;
  if (fromUnit == toUnit) {
    return value;
  }
}
<form id="lengthConvert">
  <p><b>Enter a value : </b></p><input type="number" name="inputValue" />
  <p><b>Convert from : </b></p>
  <select name="fromUnit">
    <option value="Centimeter">Centimeter</option>
    <option value="Meter">Meter</option>
    <option value="Kilometer">Kilometer</option>
    <option value="Miles">Miles</option>
  </select>
  <p><b>Convert to : </b></p>
  <select name="toUnit">
    <option value="Centimeter">Centimeter</option>
    <option value="Meter">Meter</option>
    <option value="Kilometer">Kilometer</option>
    <option value="Miles">Miles</option>
  </select>
  <br/>
  <button type="submit" form="lengthConvert" value="Submit" onclick="getElementById('Output').innerHTML=convert(event)">Convert</button>
  <div id='Output'></div>
</form>
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
  • This form isn't being used to submit data anywhere, so having a submit button that needs to prevent its default behavior makes no sense. A regular button should be used. – Scott Marcus Aug 09 '18 at 15:11
0

You are submitting your form, which causes the page to reload, thus wiping out whatever was updated on it prior to the submit. Instead, you'll want to use a regular button (<button type="button">).

But, beyond that, your code is very outdated and inefficient. .getElementsByName() is generally not recommended for performance reasons, but in your case it's even worse because you only want one element, so you're scanning the entire DOM, getting a set of matching elements and then throwing away all but one of them. Use the modern .querySelector() and .querySelectorAll() for most of your DOM searches.

Your HTML is also invalid because you have an extra closing button tag an no closing form tag.

Also, the use of inline event attributes (onclick) should not be used. This is a 25+ year old technique that just won't die because it's easy and people just copy/paste other code they've found that seems to work. There are a lot of reasons not to do this.

There are a number of other concerns in your code as well. Here's your solution, cleaned up and modernized (make sure to see the HTML, CSS, and JS comments):

/* We can style the rows any way we want: */
div.row { margin-top:1em; margin-bottom:1em; font-weight:bold; }
<form id="lengthConvert">
    <!--
      The us of <p> elements here is really not correct as they mean paragraph, which
      itself means "thought or idea". You are just using them for vertical spacing, and
      we should not be using HTML for presentation, that's for CSS. Along the same vein,
      <b> isn't appropriate here either because you are just using it for presentation.
    
      Instead, a semantically neutral tag like <div> should be used for rows. 
      CSS classes can be added to control the presentation
    -->
    <div class="row">Enter a value : </div>
    <div class="row">
      <!-- 
        Don't use self-termination syntax <tag />.
        That syntax is very old an only applies to XHTML, which is not used
        very much these days. Adding that syntax buys you nothing.
      -->
      <input type="number" name="inputValue">
    </div>
    <div class="row">Convert from :</div>
    <div class="row">
        <!-- You don't need to set a value for an <option> when
             you want the value of an <option> to be the same as 
             the text of the <option>. The text of the selected 
             <option> will become the value of the <select> by default.
        -->
        <select name="fromUnit">
            <option>Centimeter</option>
            <option>Meter</option>
            <option>Kilometer</option>
            <option>Miles</option>
        </select>
    </div>
    <div class="row">Convert to :</div>
    <div class="row">
        <select name="toUnit">
            <option>Centimeter</option>
            <option>Meter</option>
            <option>Kilometer</option>
            <option>Miles</option>
        </select>
    </div>
    <div class="row" id="Output"></div>
    
    <!-- The form attribute is only used when a form element is placed outside of the 
         form it relates to. 
         
         Also, don't use inline HTML event attributes. 
         
         And, there is no need to add a value attribute unless you want the value
         to be something different than the text of the element.
    -->
    <button type="button">Convert</button>
</form>
<script>
   // Get all the element references you know you'll need
   let btn = document.querySelector("button[type='button'");
   let output = document.getElementById('Output');
   
   // You only have one element with a name of "inputValue". Use 
   // .querySelector() with a valid CSS selector as an argument
   // to find the first item that matches the selector.
   
   // Also, don't assign variables to properties of an element because
   // if you ever want to get a second property value, you'll have to
   // scan the document all over again for the element. Just store a
   // reference to the element itself, then you can access that as often
   // as you like.
   let input = document.querySelector("input[name='inputValue']");
   let fromUnit = document.querySelector("select[name='fromUnit']");
   let toUnit = document.querySelector("select[name='toUnit']");  
   
   // Set up your event handling in JavaScript, not HTML
   btn.addEventListener("click", convert);
   
    function convert(){
      console.log(fromUnit.value, toUnit.value);
        if(fromUnit.value == toUnit.value){
           // Use .textContent when getting/setting text that
           // does not contain any HTML. Its's quicker and
           // safer.
           output.textContent = input.value;
        }
    }
</script>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71