JSFiddle - React, Tailwind, and code Playground

by jun68ykt

HTML

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<table>
  <tr>
    <th></th>
    <th>平米数(㎡)</th>    
    <th class="result">坪数</th>
    <th>坪単価(円/坪)</th>
    <th class="result">金額(円)</th>
  </tr>

 <tr>
  <td><input type="text" class="se01_a" value=""></td>
  <td><input type="text" value="" class="se01_b"></td>
  <td class="result"><span class="tsubo"></span></td>
  <td><input type="text" value="" class="se01_c"></td>
  <td class="result"><span class="kingaku"></span></td>
 </tr>
 
 <tr>
  <td><input type="text" class="se01_a" value=""></td>
  <td><input type="text" value="" class="se01_b"></td>
  <td class="result"><span class="tsubo"></span></td>
  <td><input type="text" value="" class="se01_c"></td>
  <td class="result"><span class="kingaku"></span></td>
 </tr>
 
 <tr>
  <td><input type="text" class="se01_a" value=""></td>
  <td><input type="text" value="" class="se01_b"></td>
  <td class="result"><span class="tsubo"></span></td>
  <td><input type="text" value="" class="se01_c"></td>
  <td class="result"><span class="kingaku"></span></td>
 </tr>
 
 <tr>
  <td><input type="text" class="se01_a" value=""></td>
  <td><input type="text" value="" class="se01_b"></td>
  <td class="result"><span class="tsubo"></span></td>
  <td><input type="text" value="" class="se01_c"></td>
  <td class="result"><span class="kingaku"></span></td>
 </tr>
 
 <tr>
  <td><input type="text" class="se01_a" value=""></td>
  <td><input type="text" value="" class="se01_b"></td>
  <td class="result"><span class="tsubo"></span></td>
  <td><input type="text" value="" class="se01_c"></td>
  <td class="result"><span class="kingaku"></span></td>
 </tr>
 
 
</table>

CSS

table, th, td { border: solid 1px #000000; border-collapse: collapse; }

th { background-color: #aaa; }
th.result { width: 150px; }
td { padding: 5px; }
td.result { text-align: right; }
input { font-size: 16pt; }

input { width: 100px; }
input.se01_a { width: 30px; }

input.error { background-color: #dc143c; }

JavaScript

var inputs = document.getElementsByTagName('input');

for (var i=0; i < inputs.length; i ++ ) {
  inputs[i].addEventListener('input', inputHandler);
}

function inputHandler(e) {
   
   var value = 0;   
   var row = e.target.parentNode.parentNode;         
   var pos = e.target.className.split(/\s/)[0];
      
   switch(pos) {
     case 'se01_b':
       e.target.value = e.target.value.replace(/[^0-9.]/,'');
       if (/^[0-9]*(\.[0-9]*)?$/.test(e.target.value)) {
         value = Number(e.target.value);         
         e.target.className = e.target.className.replace(' error','');         
         price({ se01_b: value, row });
       } else {
         if (e.target.className.indexOf('error') < 0)
           e.target.className += ' error';
         row.getElementsByClassName('tsubo')[0].innerHTML = '';
         row.getElementsByClassName('kingaku')[0].innerHTML = '';
       }
       break;
     case 'se01_c':
       value = Number(e.target.value.replace(/[^0-9]/g,''));
       e.target.value = value > 0 ? value.toLocaleString('ja-JP') : '';
       price({ se01_c: value, row });
       break;
     default:
       break;
   }  
}

function price({se01_b, se01_c, row }) {
    if (!row) return;
    
    var se01bNode = row.getElementsByClassName('se01_b')[0];
    var se01cNode = row.getElementsByClassName('se01_c')[0];
    
    se01_b = (se01_b >= 0 ? se01_b : Number(se01bNode.value));   
    se01_c = (se01_c >= 0 ? se01_c : Number(se01cNode.value.replace(/[^0-9]/g,'')));
            
    var tsubo = se01_b * 0.3025;
    var kingaku = tsubo * se01_c;
    
    tsubo = Math.floor(tsubo * 100.0) / 100.0;  // 少数点第3位以下を切り捨て
      
    var tsuboNode = row.getElementsByClassName('tsubo')[0];
    var kingakuNode = row.getElementsByClassName('kingaku')[0];
    
    tsuboNode.innerHTML = (tsubo > 0 ? `<b>${tsubo} 坪</b>` : '');
    kingakuNode.innerHTML =  (kingaku > 0 ? `<b>${kingaku.toLocaleString('ja-JP')} 円</b>` : "");
}