Simple javascript function fails in Framework7 v7

This is driving me crazy!
I have a simple weight conversion function (kgs <–> lbs) I have used in my App successfully since Framework7 v3 thru v5, core. It automatically converts the weights oninput and onchange.
I am now updating to v7 and it fails with no errors. Typing in either input never changes the other input.
I have tried loading it in app.js, on the page with both $on('pageInit', () => {}) and $on('pageAfterIn', () => {}) with no luck. Hopefully it is obvious to others what I am missing!

The function:

 function weightConverter(source, valNum) {
    valNum = parseFloat(valNum);
    var inputPounds = document.getElementById("inputPounds");
    var inputKilograms = document.getElementById("inputKilograms");
    if (source == "inputPounds") {
        inputKilograms.value = (valNum / 2.2046).toFixed(2);  
    }
    if (source == "inputKilograms") {
        inputPounds.value = (valNum * 2.2046).toFixed(2);
        
    }
}

The html:

<div class="w-1/3 poundInput">
              <div class="item-content item-input">
                <div class="item-inner">
                  <div class="item-title item-label">Pounds</div>
                  <div class="item-input-wrap">
                    <input id="inputPounds" class="form-control appearance-none" name="inputPounds" type="number" placeholder="lbs" 
@input="${(e) => weightConverter(e.target.id,e.target.value)}"
@change="${(e) => weightConverter(e.target.id,e.target.value)}"/>
                  </div>
                </div>
              </div>
            </div>
            <div class="w-1/3 kgw">
              <div class="item-content item-input">
                <div class="item-inner">
                  <div class="item-title item-label">Kilograms</div>
                  <div class="item-input-wrap">
                    <input id="inputKilograms" class="form-control appearance-none" name="inputKilograms" type="number" placeholder="kgs" @input="${(e) => weightConverter(e.target.id,e.target.value)}"@change="${(e) => weightConverter(e.target.id,e.target.value)}"/>
                  </div>
                </div>
              </div>
            </div>

I realize I never use quotes around @… shorthands. So instead of this:

@input="${(e) => weightConverter(e.target.id,e.target.value)}"

Have you tried this?

@input=${(e) => weightConverter(e.target.id,e.target.value)}

Thanks.
Yes, and it still fails.

I should have noted that these inputs are not inside

${items.map((item) => $h
)}

I tried to use oninput="weightConverter(this.id,this.value)" onchange="weightConverter(this.id,this.value)" instead but it still fails:

eventHandler is not a function. (In 'eventHandler(...arguments)', 'eventHandler' is "weightConverter(this.id,this.value)")

Obviously I am missing something in this function or how to call it within an input in v7

Would be good to see the whole code related, where is that helper function definitions, what is the full code of the component with HTML, etc.

I use the weightConverter code on a number of pages but here is an example template page:

The similar code I use for Temperature conversion works fine function Converter(source, valNum) {...}

<template>
    <div class="page" data-name="convert" data-page="convert">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner">
      <div class="left"> <a href="#" class="link back color-white"> <i class="far fa-chevron-left fa-lg fa-fw"></i> </a> </div>
      <div class="title mb-2 pb-1 text-align-center color-white"> Unit Conversion</div>

    </div>
  </div>


  <div id="convertPage" class="page-content hide-bars-on-scroll">


    <div class="wtHelp mx-1 py-1 card">
      <form class="form-store-data flex flex-wrap mb-2 py-1 card-content card-content-padding print:mb-0" form="true" formstoredata="true" id="convertFormBSA">
        <div class="w-full text-md font-semibold bg-gray-100 my-1 p-2 dark:bg-gray-700">
          <span class="px-2 py-1 h-6 w-6 rounded-full text-black text-md font-bold shadow-solid bg-gray-400"><i class="fad fa-inverse fa-weight fa-lg fa-fw hidden-print"></i> </span>
          Weight and Body Surface Area
        </div>
        <div class="w-1/2 poundInput">
          <div class="item-content item-input">
            <div class="item-inner">
              <div class="item-title item-label">
                Pounds
              </div>
              <div class="item-input-wrap">
                <input id="Pounds" class="form-control patient appearance-none" name="Pound" type="number" data-id="#weightPounds" placeholder="lbs" @input=${(e) => weightConverter(e.target.id, e.target.value)} @change=${(e) => weightConverter(e.target.id, e.target.value)}  />
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/2">
          <div class="item-content item-input">
            <div class="item-inner">
              <div class="item-title item-label">
                Kilograms
              </div>
              <div class="item-input-wrap">
                <input id="Kilograms" class="form-control patient appearance-none " name="Kilogram" type="number" placeholder="kgs" data-id="#weightKgs" @input=${(e) => weightConverter(e.target.id, e.target.value)} @change=${(e) => weightConverter(e.target.id, e.target.value)}  />
              </div>
            </div>
          </div>
        </div>
        <div class="w-full flex flex-wrap text-center mt-2">


          <div class="w-1/2">
            <div class="item-content item-input item-input-with-info">
              <div class="item-inner">
                <div class="item-title item-label text-lg">
                  <i class="fas fa-cat fa-lg fa-fw hidden-print"></i>
                  Feline BSA
                </div>
                <div class="item-input-wrap">
                  <span class="bsaCat "></span>
                  <div class="pt-2 text-black">
                    (10.0 x kg <sup>0.67</sup>)/100
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="w-1/2">
            <div class="item-content item-input item-input-with-info">
              <div class="item-inner">
                <div class="item-title item-label text-lg">
                  <i class="fas fa-dog fa-lg fa-fw hidden-print"></i>
                  Canine BSA
                </div>
                <div class="item-input-wrap">
                  <span class="bsaDog "></span>
                  <div class="pt-2 text-black">
                    (10.1 x kg <sup>0.67</sup>)/100
                  </div>
                </div>
              </div>
            </div>
          </div>

        </div>
      </form>
    </div>


    <div class="wtHelp mx-1 py-1 card">
      <form class="form-store-data flex flex-wrap mb-2 py-1 card-content card-content-padding print:mb-0" form="true" formstoredata="true" id="convertFormTemp">
        <div class="w-full text-md font-semibold bg-gray-100 my-1 p-2 dark:bg-gray-700">
          <span class="px-2 py-1 h-6 w-6 rounded-full text-black text-md font-bold shadow-solid bg-gray-400"><i class="fad fa-inverse fa-thermometer fa-lg fa-fw hidden-print"></i> </span>
          Temperature Conversion
        </div>
        <div class="w-1/3">
          <div class="item-content item-input">
            <div class="item-inner">
              <div class="item-title item-label">
                Temp ℉
              </div>
              <div class="item-input-wrap">
                <input id="tempF" class="form-control patient appearance-none" name="tempF" type="number" placeholder="Enter Temp ℉" 
                @input=${(e) => Converter(e.target.id, e.target.value)} @change=${(e) => Converter(e.target.id, e.target.value)} />

              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3">
          <div class="item-content item-input">
            <div class="item-inner">
              <div class="item-title item-label">
                Temp ℃
              </div>
              <div class="item-input-wrap">
                <input id="tempC" class="form-control patient appearance-none" name="tempC" type="number" placeholder="Enter Temp ℃" @input="${(e) => Converter(e.target.id, e.target.value)}" @change="${(e) => Converter(e.target.id, e.target.value)}" />
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3">
          <div class="item-content item-input">
            <div class="item-inner">
              <div class="item-title item-label">
                Temp °K
              </div>
              <div class="item-input-wrap">
                <input id="tempK" class="form-control patient appearance-none" name="tempK" type="number" placeholder="Enter Temp °K" @input="${(e) => Converter(e.target.id, e.target.value)}" @change="${(e) => Converter(e.target.id, e.target.value)}" />
              </div>
            </div>
          </div>
        </div>
      </form>
    </div>
    <div class="wtHelp mx-1 py-1 card">
      <form class="form-store-data flex flex-wrap mb-2 py-1 card-content card-content-padding print:mb-0" form="true" formstoredata="true" id="convertFormVolume">
        <div class="w-full text-md font-semibold bg-gray-100 my-1 p-2 dark:bg-gray-700">
          <span class="px-2 py-1 h-6 w-6 rounded-full text-black text-md font-bold shadow-solid bg-gray-400"><i class="fad fa-inverse fa-flask fa-lg fa-fw hidden-print"></i></span> Volume Conversion
        </div>
        <div class="w-1/3  print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Enter Number
              </div>
              <div class="item-input-wrap">
                <input id="ConvertV" class="form-control patient appearance-none" name="inputConvert" type="number" placeholder="" />
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3  print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert From
              </div>
              <div class="item-input-wrap">
                <select id="selectedVol" class="volume dark:text-white dark:bg-black form-select" name="selectedVolume">
                  <option value="fl-oz">
                    oz
                  </option>
                  <option value="cup">
                    cup
                  </option>
                  <option value="pnt">
                    pint
                  </option>
                  <option value="qt">
                    quart
                  </option>
                  <option value="gal">
                    gallon
                  </option>
                  <option value="ml">
                    ml
                  </option>
                  <option value="l">
                    Liter
                  </option>
                  <option value="tsp">
                    tsp
                  </option>
                  <option value="Tbs">
                    tbs
                  </option>

                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3  print:w-1/4 text-center">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert To
              </div>
              <div class="item-input-wrap">
                <select id="selectedVol2" class="volume dark:text-white dark:bg-black form-select" name="selectedVolume2">
                  <option value="ml">
                    ml
                  </option>
                  <option value="l">
                    Liter
                  </option>
                  <option value="tsp">
                    tsp
                  </option>
                  <option value="Tbs">
                    tbs
                  </option>
                  <option value="fl-oz">
                    oz
                  </option>
                  <option value="cup">
                    cup
                  </option>
                  <option value="pnt">
                    pint
                  </option>
                  <option value="qt">
                    quart
                  </option>
                  <option value="gal">
                    gallon
                  </option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="hideandsort w-3/4  print:w-1/4 mx-auto md:w-1/2 text-center print:w-1/6 print:px-1 print:text-black">
          <div class="item-title item-label text-lg mt-2">
            Result <span class="resultVol inline-flex items-center"></span>
          </div>
        </div>
      </form>
    </div>
    <div class="wtHelp mx-1 py-1 card">
      <form class="form-store-data flex flex-wrap mb-2 py-1 card-content card-content-padding print:mb-0" form="true" formstoredata="true" id="convertFormMass">
        <div class="w-full text-md font-semibold bg-gray-100 my-1 p-2 dark:bg-gray-700">
          <span class="px-2 py-1 h-6 w-6 rounded-full text-black text-md font-bold shadow-solid bg-gray-400"><i class="fad fa-inverse fa-balance-scale fa-lg fa-fw hidden-print"></i> </span> Mass Conversion
        </div>
        <div class="w-1/3  print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Enter Number
              </div>
              <div class="item-input-wrap">
                <input id="ConvertM" class="form-control patient appearance-none" name="ConvertM" type="number" placeholder="" />
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3  print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert From
              </div>
              <div class="item-input-wrap">
                <select id="selectedMass" class="mass dark:text-white dark:bg-black form-select">
                  <option value="kg">
                    kg
                  </option>
                  <option value="oz">
                    oz
                  </option>
                  <option value="lb">
                    lb
                  </option>
                  <option value="mcg">
                    mcg
                  </option>
                  <option value="mg">
                    mg
                  </option>
                  <option value="g">
                    gram
                  </option>

                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3  print:w-1/4 text-center">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert To
              </div>
              <div class="item-input-wrap">
                <select id="selectedMass2" class="mass dark:text-white dark:bg-black form-select">
                  <option value="mcg">
                    mcg
                  </option>
                  <option value="mg">
                    mg
                  </option>
                  <option value="g">
                    gram
                  </option>
                  <option value="kg">
                    kg
                  </option>
                  <option value="oz">
                    oz
                  </option>
                  <option value="lb">
                    lb
                  </option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="hideandsort w-3/4  print:w-1/4 mx-auto md:w-1/4 text-center print:w-1/6 print:px-1 print:text-black">
          <div class="item-title item-label text-lg mt-2">
            Result <span class="resultMass inline-flex items-center"></span>
          </div>
        </div>
      </form>
    </div>
    <div class="wtHelp mx-1 py-1 card">
      <form class="form-store-data flex flex-wrap mb-2 py-1 card-content card-content-padding print:mb-0" form="true" formstoredata="true" id="convertFormLength">
        <div class="w-full text-md font-semibold bg-gray-100 my-1 p-2 dark:bg-gray-700">
          <span class="px-2 py-1 h-6 w-6 rounded-full text-black text-md font-bold shadow-solid bg-gray-400"> <i class="fad  fa-inverse fa-ruler fa-lg fa-fw hidden-print"></i> </span> Length Conversion
        </div>
        <div class="w-1/3 print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Enter Number
              </div>
              <div class="item-input-wrap">
                <input id="ConvertL" class="form-control patient appearance-none" name="ConvertL" type="number" placeholder="" />
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3 print:w-1/4">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert From
              </div>
              <div class="item-input-wrap">
                <select id="selectedLength" class="length dark:text-white dark:bg-black form-select">
                  <option value="in">
                    inch
                  </option>
                  <option value="yd">
                    yard
                  </option>
                  <option value="ft-us">
                    foot
                  </option>
                  <option value="mi">
                    mile
                  </option>
                  <option value="mm">
                    mm
                  </option>
                  <option value="cm">
                    cm
                  </option>
                  <option value="m">
                    meter
                  </option>
                  <option value="km">
                    km
                  </option>

                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="w-1/3 print:w-1/4 text-center">
          <div class="item-content item-input item-input-with-value">
            <div class="item-inner">
              <div class="item-title item-label">
                Convert To
              </div>
              <div class="item-input-wrap">
                <select id="selectedLength2" class="length dark:text-white dark:bg-black form-select">
                  <option value="mm">
                    mm
                  </option>
                  <option value="cm">
                    cm
                  </option>
                  <option value="m">
                    meter
                  </option>
                  <option value="km">
                    km
                  </option>
                  <option value="in">
                    inch
                  </option>
                  <option value="yd">
                    yard
                  </option>
                  <option value="ft-us">
                    foot
                  </option>
                  <option value="mi">
                    mile
                  </option>
                </select>
              </div>
            </div>
          </div>
        </div>
        <div class="hideandsort w-3/4 print:w-1/4 mx-auto md:w-1/4 text-center print:w-1/6 print:px-1 print:text-black">
          <div class="item-title item-label text-lg mt-2">
            Result <span class="resultLength inline-flex items-center"></span>
          </div>
        </div>
      </form>
    </div>






  </div>
</div>
</template>
<script>

import "../js/convert-units.js";
   
   export default (props, {$update, $, $f7, $on, $h }) => {

  

$on('pageInit', () => {
    
  function weightConverter(source, valNum) {
    valNum = parseFloat(valNum).toFixed(5);
    var inputPounds = document.getElementById("Pounds");
    var inputKilograms = document.getElementById("Kilograms");
    if (source == "Pounds") {
        inputKilograms.value = (valNum / 2.2046).toFixed(2);

    }
    if (source == "Kilograms") {
        inputPounds.value = (valNum * 2.2046).toFixed(2);

    }
}

 function Converter(source, valNum) {
    valNum = parseFloat(valNum).toFixed(5);
    var inputFahrenheit = document.getElementById("tempF");
    var inputCelsius = document.getElementById("tempC");
    var inputKelvin = document.getElementById("tempK");
    if (source == "tempF") {
        inputCelsius.value = ((valNum - 32) / 1.8).toFixed(1);
        inputKelvin.value = (((valNum - 32) / 1.8) + 273.15).toFixed(2);
    }
    if (source == "tempC") {
        inputFahrenheit.value = (valNum * 1.8 + 32).toFixed(1);
        inputKelvin.value = ((valNum) + 273.15).toFixed(2);
    }
    if (source == "tempK") {
        inputFahrenheit.value = (((valNum - 273.15) * 1.8) + 32).toFixed(2);
        inputCelsius.value = ((valNum) - 273.15).toFixed(2);
    }
    
}


            function BSA() {
                var kg = round(j$("#Kilograms").val(), 2).toFixed(2);
                var bsaDogs = parseFloat(Math.pow(kg, .6667) * 10.1 / 100).toFixed(3);
                var bsaCats = parseFloat(Math.pow(kg, .6667) * 10 / 100).toFixed(3);
                if (!isNaN(bsaDogs)) {
                    j$("#bsaDog").val(bsaDogs);
                    j$("#bsaCat").val(bsaCats);
                    j$(".bsaDog").text(bsaDogs);
                    j$(".bsaCat").text(bsaCats);
                    //console.log("Dogs "+bsaDogs + "Cats "+bsaCats);
                }
            }
            function convertDataV() {
                var inputValueV = j$("#ConvertV").val();
                var selectedVol = j$("#selectedVol option:selected").val();
                var selectedVol2 = j$("#selectedVol2 option:selected").val();
                var selectedVolText = j$("#selectedVol option:selected").text();
                var selectedVol2Text = j$("#selectedVol2 option:selected").text();
                var volumeResult = Number(convert(inputValueV).from(selectedVol).to(selectedVol2).toFixed(4));
                if (selectedVol === selectedVol2) {
                    j$(".resultVol").html("");
                } else {
                    j$(".resultVol").html(volumeResult + " " + selectedVol2Text);
                }
            }
            function convertDataM() {
                var inputValueM = j$("#ConvertM").val();
                var selectedMass = j$("#selectedMass option:selected").val();
                var selectedMass2 = j$("#selectedMass2 option:selected").val();
                var selectedMassText = j$("#selectedMass option:selected").text();
                var selectedMass2Text = j$("#selectedMass2 option:selected").text();
                var massResult = Number(convert(inputValueM).from(selectedMass).to(selectedMass2).toFixed(4));
                if (selectedMass === selectedMass2) {
                    j$(".resultMass").html("");
                } else {
                    j$(".resultMass").html(massResult + " " + selectedMass2Text);
                }
            }
            function convertDataL() {
                var inputValueL = j$("#ConvertL").val();
                var selectedLength = j$("#selectedLength option:selected").val();
                var selectedLength2 = j$("#selectedLength2 option:selected").val();
                var selectedLengthText = j$("#selectedLength option:selected").text();
                var selectedLength2Text = j$("#selectedLength2 option:selected").text();
                var lengthResult = Number(convert(inputValueL).from(selectedLength).to(selectedLength2).toFixed(4));
                if (selectedLength === selectedLength2) {
                    j$(".resultLength").html("");
                } else {
                    j$(".resultLength").html(lengthResult + " " + selectedLength2Text);
                }
            }
            setTimeout(function() {
                convertDataL();
                convertDataM();
                convertDataV();            
            }, 200);

            j$("select.length").on("change", function() {
                convertDataL();
            });
            j$("#ConvertL").on("input", function() {
                convertDataL();
            });
            j$("select.mass").on("change", function() {
                convertDataM();
            });
            j$("#ConvertM").on("input", function() {
                convertDataM();
            });
            j$("select.volume").on("change", function() {
                convertDataV();
            });
            j$("#ConvertV").on("input", function() {
                convertDataV();
            });
            j$(document).on("input", "#Kilograms, #Pounds", function() {
                BSA();
            });
            
  });
     
    return $render;
   
     }
</script>
<script>
export default (_,{ $on }) => {

  function weightConverter(args){ }
  function Converter(args){ }
  // const weightConverter = (args) => { }
  // const Converter = (args) => { }

  $on('pageInit',() => {
    // do not declare funcs here
  });

  return $render; 
}
</script>
1 Like

Thanks. I already tried loading it before pageInit but it failed as well. Still can’t understand why the similar code for Temperature works fine, yet the weight conversion does not.

here => musing-stonebraker-tb5cy4 - CodeSandbox

Thanks for the effort! I see it works in your codeSandbox, just as it has worked in my App for the past number of years, but still not working on my pages within the App. I’ve tried loading it in every way possible and still it fails. Crazy! It’s like a ghost in the code!! :sweat_smile:

did you by any chance add the html dynamically?
if the answer is no, then i dont know what to say.

No, the inputs are not dynamic. It’s making my head explode!

I finally figured out why the function is failing.
I load this function on multiple pages and it seems that using the same id
id="inputKilograms, id="inputPounds"
for the inputs on each page, makes it fail. (to be clear, there is only the 2 unique id’s on each page, no duplicates).
If I change the functions
document.getElementById
and change the input id’s for each page, making them unique, it works as expected.
This is not ideal since I have over 10 pages that use this function and I would have to change a number of other functions that reference the values for these inputs based on the original id’s.

Is there a better way to load this function just once so all the pages can utilize it with the same id’s (on each separate page) for the inputs? I’m guessing it is related to the vdom and having duplicate id’s?