Home > Net >  bold tags don't take effect in span element in html
bold tags don't take effect in span element in html

Time:02-02

I'm totally new to html, css and javascript.

I'm trying to create a simple interest rate calculator and I want to style the result so that the numbers in the result message are highlighted like this:

Interest : If you deposit 10,
at an interest rate of 10.25.
You will receive an amount of 11.025,
in the year 2023.

What I get is the <b> elements rendered as text, for example:

Interest : If you deposit <b>10</b>,
at an interest rate of <b>10.25</b>.
You will receive an amount of <b>11.025</b>,
in the year <b>2023</b>.

My code is this:

function compute()
{
    var principal = document.getElementById("principal").value;
    var rate      = document.getElementById("rate").value;
    var years     = document.getElementById("years").value;
    var interest  = principal * (rate / 100) * years;
    // add amount to principal
    let amount    = interest   parseInt(principal);
    var year      = new Date().getFullYear()   parseInt(years);

    var interestString = "If you deposit "   principal.bold()   ",\n at an interest rate of "   rate   ".\n You will receive an amount of "   amount   ",\n in the year "   year   ".";
    document.getElementById("result").innerText = interestString
}
body {
    background-color:black;
    font-family: arial;
    color:white
}

h1 {
    color: grey;
    font-family: verdana
}

.maindiv {
    background-color: white;
    color:black;
    width:300px;
    padding: 20px;
    border-radius: 25px;
    margin: auto;
}
<div >
    <h1>Simple Interest Calculator</h1>
    Amount <input type="number"  id="principal">  
    <br/>
    Rate <input type="range" id="rate" min="1" max="20" step="0.25" value="10.25"  oninput="this.nextElementSibling.value = this.value">
    <output>10.25</output>   
    <br/>
    No. of Years 
    <select id="years">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>
    <button onclick="compute()">Compute Interest</button>
    <br>
    <br>
    Interest : <span id="result"></span>
</div>

I would be happy for a way to solve this. Thank you!

CodePudding user response:

Change innerText to innerHTML.

CodePudding user response:

  • The String.prototype.bold() method (which wraps any JavaScript string value in a <b> element) is deprecated and should not be used - unless you suddenly found yourself time-warped back to 1995.
  • Instead, I recommend making your "template" into normal HTML, and use <output> elements as placeholders, and use CSS to make all <output> elements bold.

Something like this:

  • My code uses Intl.NumberFormat to format monetary-amounts and percentages appropriately
    • When formatting percentages, remember that number percentage values have to be normalized to 0-1.0; so 10% is 0.1 and 250% is 2.5, and 1.25% is 0.0125.
  • Because JavaScript doesn't have compile-time (or parse-time) type-checking, my code employs defensive-programming techniques to preemptively fast-fail if anything goes wrong by doing throw new Error, including:
    • Verifying that HTML elements referenced by getElementById or querySelector actually exist (with function getElement).
    • Precondition validation that verifies parameter argument value types and other value things (e.g. numeric range bounds-checking).
    • JSDoc (/** @param */, etc) is used to document parameter types in a machine-readable format.
  • I cleaned-up the HTML and wrapped related form fields in <div >) and added a currency-symbol to the <input id="principal" /> field.

const fmtUsd  = new Intl.NumberFormat( 'en-US', { style: 'currency', currency: 'USD' } );
const fmtPerc = new Intl.NumberFormat( 'en-US', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2 } );

function compute( e ) {

  const errorOutput     = getElement( 'errorOutput'    , 'div' );
  const outputContainer = getElement( 'outputContainer', 'div' );
  
  try {
    
    const principalInput = getElement( 'principal', 'input[type="number"]' );
    const rateInput      = getElement( 'rate'     , 'input[type="range"]' );
    const yearsSelect    = getElement( 'years'    , 'select' );
    
    const principalAmount = getNumberValue( principalInput );
    const ratePercDbl     = getNumberValue( rateInput ) / 100.0;
    const yearsCount      = getNumberValue( yearsSelect );
    
    computeInner( principalAmount, ratePercDbl, yearsCount );
    
    // No errors, so show the output div and hide any previous error messages:
    outputContainer.hidden = false;
    errorOutput    .hidden = true;
  }
  catch( err ) {
    // Something went wrong! So hide the normal output <div> and show the error details:
    errorOutput.hidden = false;
    errorOutput.textContent = ( err || "(Unknown error)" ).toString()   "\r\n\r\n"   ( err.stack );
    outputContainer.hidden = true;
  }
}

/**
 * @param {number} principalAmount
 * @param {number} interestRatePerc
 * @param {number} yearsCount
 */
function computeInner( principalAmount, interestRatePerc, yearsCount ) {

  // Preconditions:
  if( typeof principalAmount != 'number' ) throw new Error( "Expected `principalAmount` to be `number` but encountered "   typeof principalAmount );
  if( typeof interestRatePerc != 'number' ) throw new Error( "Expected `interestRatePerc` to be `number` but encountered "   typeof interestRatePerc );
  if( typeof yearsCount != 'number' || yearsCount <= 0 ) throw new Error( "Expected `yearsCount` to be a positive `number` but encountered "   ( typeof yearsCount )   " \""   yearsCount.toString()   "\" instead." );
  
  //
  
  const interest    = principalAmount * interestRatePerc * yearsCount;
  const totalAmount = interest   principalAmount;
  const endYear     = new Date().getFullYear()   yearsCount;
  
  //
  
  setOutput( 'principal', principalAmount , fmtUsd  );
  setOutput( 'rate'     , interestRatePerc, fmtPerc );
  setOutput( 'years'    , endYear                   );
  
  const amountOut = getElement( 'receiveAmountOut', 'output' );
  amountOut.value = fmtUsd.format( totalAmount );
}

/**
 * @param {string} outputFor
 * @param {number} value
 * @param {Intl.NumberFormat} formatter
 */
function setOutput( outputFor, value, formatter ) {
   
  const formattedValue = formatter ? ( formatter.format( value ) ) : ( value.toString() );
   
  const selector = 'output[for~="'   CSS.escape( outputFor )  '"]';
  const outputs  = document.querySelectorAll( selector );
  for( const outputEl of outputs ) {
    outputEl.value = formattedValue;
  }
}

/**
 * @param {string} id
 * @param {string} validationSelector
 * @returns {HTMLElement}
 */
function getElement( id, validationSelector ) {
  const el = document.getElementById( id );
  if( el === null ) throw new Error( "No element with `id=\""   id   "\"` was found." );
  if( !el.matches( validationSelector ) ) throw new Error( "The element with `id=\""   id   "\"` does not match selector \""   validationSelector   "\"." );
   
  return el;
}

/**
 * @param {HTMLInputElement | HTMLSelectElement} input
 * @returns {number}
 */
function getNumberValue( input ) {
   
  // Preconditions:
  if( !( input instanceof HTMLElement ) ) throw new Error( 'Expected `input` to be a HTML element.' );
  if( !( input.tagName === 'SELECT' || input.tagName === 'INPUT' ) ) throw new Error( 'Expected `input` to be a HTML <input /> or <select> element.' );
   
   //
   
  let valueNumber;
  if( input.tagName === 'SELECT' ) {
     valueNumber = parseInt( input.value, /*radix:*/ 10 );
  }
  else if( input.type === 'number' ) { // Can't use valueAsNumber with type="range", grr.
     valueNumber = input.valueAsNumber;
  }
  else {
     valueNumber = parseFloat( input.value );
  }
   
  if( isNaN( valueNumber ) ) {
    throw new Error( "Form <input> or <select> has invalid value: \""   input.value   "\"." );
   }
   
   return valueNumber;
}
body {
    background-color: black;
    font-family: sans-serif;
    color: white
}
.maindiv {
    background-color: white;
    color: black;
    width: 300px;
    padding: 20px;
    border-radius: 25px;
    margin: auto;
}

h1 {
    color: grey;
    font-family: verdana
}

.field {
  padding: 1em;
  margin: 1em 0;
  background-color: #eee;
  border-radius: 5px;
}
  .field > label,
  .field > input,
  .field > div > input {
    display: block;
  }

#principalField.field > div {
  display: flex;
  justify-content: stretch;
  align-items: stretch;
}
  #principalField.field > div > span.symbol {
    display: inline-block;
    
    /* Width is 1em with negative right margin of -1.5em to make the currency symbol appear "inside" the <input />. Also, identical font-size, padding and border as Chrome's default style for <input />: */
    width: 1em;
    margin: 0 -1.5em 0 0;
    border: 1px solid transparent;
    padding: 1px 2px;
    z-index: 10;
    
    pointer-events: none;
    user-select: none;
    color: #999;
    font-size: 90%;
  }


#errorOutput {
  border: 1px solid red;
  border-radius: 7px;
  white-space: pre-line;
}

output {
  font-weight: bold;
}
output:empty {
  display: none;
}

input[type="number"] {
  text-align: right;
}
<div >

    <h1>Simple Interest Calculator</h1>
    
    <div  id="principalField">
      <label for="principal">Principal amount</label>
      <div>
        <span >$</span>
        <input type="number" id="principal" oninput="compute(event)" value="123.00" size="6" />
      </div>
    </div>
    
    <div >
      <label for="rate">Interest rate (<output for="rate">10.25%</output>)</label>
      <input type="range" id="rate" min="1" max="20" step="0.25" value="10.25" oninput="compute(event)" />
    </div>
    
    <div >
      <label for="years">No. of Years </label>
      <select id="years" oninput="compute(event)">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
      </select>
    </div>
    
    <button hidden type="button" onclick="compute(event)">Compute Interest</button>
    
    <div id="outputContainer" hidden>
    
        If you deposit <output for="principal"></output>
        at an interest rate of <output for="rate"></output>
        you will receive an amount of <output id="receiveAmountOut"></output> in the year <output for="years"></output>.
    
    </div>
    <div id="errorOutput" hidden></div>
    
</div>

CodePudding user response:

You can change the interestString to this

  var interestString = `If you deposit  <b>${principal}</b>,<br>
  at aninterest rate of <b>${rate}</b>.<br>
  You will receive an amount of <b>${amount}</b>,<br>
  in the year <b>${year}</b>.`;
  
  document.getElementById("result").innerHTML=interestString

and use innerHTML instead of innerText and it will look exactly like the example you gave above!

CodePudding user response:

you should put innerHTML instead of innerText

function compute()
{
    var principal = document.getElementById("principal").value;
    var rate      = document.getElementById("rate").value;
    var years     = document.getElementById("years").value;
    var interest  = principal * (rate / 100) * years;
    // add amount to principal
    let amount    = interest   parseInt(principal);
    var year      = new Date().getFullYear()   parseInt(years);

    var interestString = "If you deposit "   principal.bold()   ",\n at an interest rate of "   rate   ".\n You will receive an amount of "   amount   ",\n in the year "   year   ".";
    document.getElementById("result").innerHTML = interestString
}
body {background-color:black;font-family:arial;color:white}
h1{color:grey;font-family: verdana}

.maindiv {
    background-color: white;
    color:black;
    width:300px;
    padding: 20px;
    border-radius: 25px;
    margin: auto;
}
<div >
    <h1>Simple Interest Calculator</h1>
    Amount <input type="number"  id="principal">  
    <br/>
    Rate <input type="range" id="rate" min="1" max="20" step="0.25" value="10.25"  oninput="this.nextElementSibling.value = this.value">
    <output>10.25</output>   
    <br/>
    No. of Years 
    <select id="years">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>
    <button onclick="compute()">Compute Interest</button>
    <br>
    <br>
    Interest : <span id="result"></span>
</div>

  •  Tags:  
  • Related