Node_HW_BMI

In this example below you will see how to do a Node_HW_BMI with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by barbo1942, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright barbo1942 ©

Technologies

  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>Node_HW_BMI</title>
  
  
  <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css'>
<link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'>
<link rel='stylesheet prefetch' href='https://use.fontawesome.com/releases/v5.0.6/css/all.css'>

      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  
<div id="app">
  <div class="row query p-5">
    <div class="col-md-4">
      <div class="logo d-flex justify-content-center align-items-center h-100"><img src="https://firebasestorage.googleapis.com/v0/b/todos-d85a9.appspot.com/o/img%2FBMICLogo.png?alt=media&amp;token=4ae0799e-41ab-4ea2-acf1-c30a9245504b" alt="logo"/></div>
    </div>
    <div class="col-md-4 pt-5 pt-md-0">
      <div class="info d-flex flex-column align-items-center">
        <div class="h d-flex flex-column">
          <label>身高 cm</label>
          <input class="height cursor" type="num" placeholder="請輸入身高" v-model="height" @click="restart" data-field="h"/>
        </div>
        <div class="w d-flex flex-column">
          <label class="mt-3">體重 kg</label>
          <input class="weight cursor" type="num" placeholder="請輸入體重" v-model="weight" @click="restart" data-field="w"/>
        </div>
      </div>
    </div>
    <div class="col-md-4 pt-5 pt-md-0">
      <div class="count h-100 d-flex justify-content-center align-items-center">
        <div class="startCount cursor" @click="countBMI">
          <h2>看結果</h2>
        </div>
        <div class="result d-none align-items-center">
          <div class="circle">
            <div class="num h2">{{ num }} </div>
            <div class="bmi">BMI</div><img class="icon p-2" src="https://firebasestorage.googleapis.com/v0/b/todos-d85a9.appspot.com/o/img%2Ficons_loop.png?alt=media&amp;token=48064fb8-721d-467b-9b23-edd1cf5d2cb0" alt="icon"/>
          </div>
          <div class="text h2 ml-3">{{ text }} 理想</div>
        </div>
      </div>
    </div>
  </div>
  <div class="record p-5">
    <h2 class="text-center mb-3">BMI 記錄  </h2>
    <table class="table h5 table-striped text-center table-responsive-md table-hover">
      <thead>
        <tr class="bg-black text-white">
          <th @click="order('bmiText')">狀態<i class="fas ml-1 text-yellow" :class="{'fa-arrow-circle-up':boolean,'fa-arrow-circle-down':!boolean}" v-if="sortField=='bmiText'"></i></th>
          <th @click="order('bmiNum')">BMI值<i class="fas ml-1 text-yellow" :class="{'fa-arrow-circle-up':boolean,'fa-arrow-circle-down':!boolean}" v-if="sortField=='bmiNum'"></i></th>
          <th @click="order('height')">身高cm<i class="fas ml-1 text-yellow" :class="{'fa-arrow-circle-up':boolean,'fa-arrow-circle-down':!boolean}" v-if="sortField=='height'"></i></th>
          <th @click="order('weight')">體重kg<i class="fas ml-1 text-yellow" :class="{'fa-arrow-circle-up':boolean,'fa-arrow-circle-down':!boolean}" v-if="sortField=='weight'"></i></th>
          <th @click="order('timestamp')">日期     <i class="fas ml-1 text-yellow" :class="{'fa-arrow-circle-up':boolean,'fa-arrow-circle-down':!boolean}" v-if="sortField=='timestamp'"></i></th>
          <th>刪除</th>
        </tr>
      </thead>
      <tbody> 
        <tr v-for="bmi in bmiList">
          <td class="bmiText" :style="{borderColor: bmi.bmiColor}">{{bmi.bmiText}}</td>
          <td class="bmiNum">{{bmi.bmiNum}}</td>
          <td class="height">{{bmi.height}}</td>
          <td class="weight">{{bmi.weight}}</td>
          <td class="bmiDate">{{bmi.bmiDate}}</td>
          <td><i class="fa fa-trash cursor" @click="del(bmi.key)"></i></td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="footer fixed-bottom"></div>
</div>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js'></script>
<script src='https://www.gstatic.com/firebasejs/4.9.1/firebase.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>

  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/barbo1942/node_hw_bmi-GQmZGJ */
.text-yellow {
  color: #FFD366;
}

.bg-black {
  background-color: #424242;
}

.query {
  background-color: #424242;
}

label {
  color: #FFD366;
  font-weight: 100;
  font-size: 1.2rem;
}

input {
  border-radius: 8px;
  padding: 0.5rem;
  padding-left: 0.6rem;
  border: 2px solid #FFD366;
  background-color: rgba(255, 255, 255, 0.3);
  font-size: 1.3rem;
  color: white;
  font-weight: 100;
}
input::placeholder {
  color: white;
  opacity: 0.4;
  font-weight: 100;
}

.startCount {
  width: 123px;
  height: 123px;
  border-radius: 50%;
  background-color: #FFD366;
  color: #424242;
  font-weight: 400;
  position: relative;
}
.startCount h2 {
  position: absolute;
  top: 35%;
  left: 10%;
  font-weight: 300;
}
.startCount:hover {
  box-shadow: 0px 0px 20px #FFD366;
}

.count {
  min-width: 320px;
}

.circle {
  border: 8px solid;
  width: 123px;
  height: 123px;
  border-radius: 50%;
  position: relative;
}
.circle .num, .circle .bmi, .circle .icon, .circle .text {
  position: absolute;
  top: 30%;
  left: 13%;
  font-weight: 300;
}
.circle .bmi {
  top: 60%;
  left: 37%;
}
.circle .icon {
  top: 70%;
  left: 75%;
  border-radius: 50%;
}

.text {
  font-weight: 400;
}

.cursor {
  cursor: pointer;
}

.record {
  background-color: rgba(255, 255, 0, 0.1);
}
.record table {
  margin-bottom: 5rem;
  box-shadow: 0 3px 10px 0px rgba(128, 128, 128, 0.2);
}
.record th {
  cursor: pointer;
  font-weight: 300;
  min-width: 120px;
  position: relative;
  transform: translateX(-10%);
}
.record th i {
  position: absolute;
  transform: translateY(3px);
}
.record td {
  padding: 1.2rem;
  border-top: none;
  border-bottom: 10px solid white !important;
}

.footer {
  height: 3rem;
  background-color: #FFD366;
}

.bmiText {
  border-left: 5px solid;
}

i.fa.fa-trash {
  opacity: 0.3;
}


/*Downloaded from https://www.codeseek.co/barbo1942/node_hw_bmi-GQmZGJ */
const bmiStatus =[ {"text": "過輕","color":'#86D73E' },
                   {"text": "理想","color": '#31BAF9'},
                   {"text": "過重","color": '#FF982D'},
                   {"text": "輕度肥胖","color": '#fc7e3f'},
                   {"text": "中度肥胖","color": '#FF6C02'},
                   {"text": "重度肥胖","color": "#FF1200"} ]


const config = {
  apiKey: "AIzaSyDQHIeCZD0ZwXu6HkKL9n-JOCLKZlVmzYY",
  authDomain: "todos-d85a9.firebaseapp.com",
  databaseURL: "https://todos-d85a9.firebaseio.com",
  projectId: "todos-d85a9",
  storageBucket: "todos-d85a9.appspot.com",
  messagingSenderId: "136044664010"
};
firebase.initializeApp(config);
var mybmi = firebase.database().ref('mybmi');
var vueBMI = new Vue({
  el: "#app",
  data: {
    height: "",
    weight: "",
    num: "",
    text: "",
    color: "",
    timestamp: "",
    bmiList: [],
    val: 1,
    boolean: false,
    sortField: "timestamp"
  },
  created: function(){
    var vm = this;
    mybmi.orderByChild('timestamp').on("value",function(snapshot){
      vm.bmiList = vm.objToArr(snapshot).reverse()
      vm.bmiList.map(function(item,index,array){
        item.bmiDate = vm.myDate(item.timestamp)
        let level = vm.showText(item.bmiNum)
        item.bmiText = bmiStatus[level].text
        item.bmiColor = bmiStatus[level].color
        return item
      })
      // console.log(vm.bmiList)
    })
  },
  methods: {
    objToArr: function(obj){
      var vm = this
      let arr = []
      obj.forEach(function (item) {  
        let newObj = item.val()
        newObj.key = item.key
        arr.push(newObj)
      })
      let newArr = arr.map(function(item, index, array){
        item.bmiDate = vm.myDate(item.timestamp)
        return item
      })
      // console.log(newArr)
      return newArr
    },
    myDate: function(time){
      let tt = new Date(time)
      let ty = tt.getFullYear()
      let tm = tt.getMonth() >10 ? tt.getMonth() : "0"+tt.getMonth()
      let td = tt.getDate() > 10 ? tt.getDate() : "0"+tt.getDate()
      let str = tm+"/"+td+"/"+ty
      return str
    },
    countBMI: function(){
      let vm = this

      if(vm.height==""){
            alert('身高為必填欄位')
        }else if(isNaN(parseFloat(vm.height))){
            vm.height=""
            alert('身高請填寫數字')
        }else if(vm.weight==""){
            alert('體重為必填欄位')
        }else if(isNaN(parseFloat(vm.weight))){
            vm.weight=""
            alert('體重請填寫數字')
        }else {
            let countnum = vm.weight/Math.pow(vm.height,2)*10000
            vm.num = countnum.toFixed(2)
            let d = new Date()
            vm.timestamp = d.getTime()
            let level = vm.showText(countnum)
            vm.text = bmiStatus[level].text
            vm.color = bmiStatus[level].color
            $('.startCount').addClass('d-none')
            $('.result').addClass('d-flex').css('color',bmiStatus[level].color)
            $('.icon').css('background-color',bmiStatus[level].color)
            $('.text').text(bmiStatus[level].text)
     
            data = {
                "height": vm.height,
                "weight": vm.weight,
                "bmiNum": vm.num,
                "timestamp": vm.timestamp
            }
            mybmi.push(data)
          
        }
    },
    showText: function(num){
      if (num<=18.5){
        return 0
      }else if(num>18.5 && num<=24 ){
        return 1
      }else if(num>24 && num<=27 ){
        return 2
      }else if(num>27 && num<=30 ){
        return 3
      }else if(num>30 && num<=35 ){
        return 4
      }else if(num>35){
        return 5
      }  
    },
    restart: function(e){
      let vm = this
      let field = e.target.dataset.field
      $('.startCount').removeClass('d-none')
      $('.result').removeClass('d-flex')
      switch(field){
        case "h":
            vm.height="";
            break;
        case "w":
            vm.weight="";
            break;
      }
    
    },
    del: function(key){
      mybmi.child(key).remove()
    },
    order: function(field){
      vm = this
      vm.sortField = field
      vm.val=vm.val*-1
      // console.log(vm.val)
      if (vm.val==1){
           vm.boolean = true
           vm.bmiList = vm.bmiList.sort(function(a,b){  
                       return a[field]>b[field]? 1:-1
                   })
        }else{            
           vm.boolean = false
           vm.bmiList = vm.bmiList.sort(function(a,b){
                      return a[field]<b[field]? 1:-1
                  })
        }   
   
        // console.log(newArr)
      }
  }
})

Comments