Sunday, April 29, 2018

Calculate input field based on expiry date

Leave a Comment

A form with 50 entries: each with P1-48, E1-48, and X1-48. I want to calculate the Entry Fee "E1" based on the expires date X1. The js date format for the expires date is YYYY.MM.DD, ex. 2018.04.21 and a player pays $3 if his expires date is greater or equal to today's date. He pays $5 if his expires date is older or less than today's date. But if the expires date is blank and the player pays a membership fee, the Entry Fee is waived to zero.

JS:

<script src = "js/moment.min.js"></script> 

I also have this as a "template" starting guide. I think it could be modified and piggyback the target result onto it.

<script> // change expiration date color function getExpireDate(ele) { var i = null; for (i = 0; members.length > i; i++) {     if (members[i].Name == ele.value) {         var exDate = moment(members[i].Expires, 'YYYY.MM.DD');         if (moment().isAfter(exDate)) {         $(ele).closest('.universal').find('.expDate').css('color', "#A3005B");         } else {         $(ele).closest('.universal').find('.expDate').css('color', "#275052");         }         return members[i].Expires;      } } return ''; } </script>  <script>  for (let i = 0; i <= 48; i++) {     $("#P" + i).on("blur", function(){     $("#X" +i).val(getExpireDate(this));     }); } </script>  <script>      var members [     {"Name": "Jones, David", "Expires": "2017.05.03" },     {"Name": "Roth, Bill", "Expires": "2017.03.08" },     {"Name": "Scullin, Kenn", "Expires": "2019.02.20" }     ]  <script> 

HTML:

<div>     <input type = "text" id = "P1"> <!--Player-->     <input type = "text" id = "E1"> <!--Entry Fee-->      <input type = "text" id = "M1"> <!--Membership Fee-->  <input type = "text" id = "X1" onblur="getExpireDate()" class="expDate"> <!--expires--> <div> 

Funny thing is:

<input type = "text" onblur="getClass()" class="text" id="Y1" maxlength = "4" size = "4" disabled /> <!--works even with input disabled -->  <input type = "text" onblur="calcEntryFee(this);" class="expDate" name = "exp" id="X1" maxlength = "10" size = "10" disabled /><!--new code doesn't work -->  <script> // Lookup class or rating  function getClass(ele) { var i = null; for (i = 0; members.length > i; i++) { if (members[i].Name == ele.value) { return members[i].Rating;  } } return; }   for (let i = 0; i <= 48; i++) { $("#P" + i).on("blur", function(){ $("#Y" +i).val(getClass(this)); }); } </script> 

3 Answers

Answers 1

How about this:

(The main function is calcEntryFee().)

var members = [   // ... fill data here. ];  function getMemberData( name ) {     var a = jQuery.trim( name ).toLowerCase(),         i, b, member;      for ( i = 0; i < members.length; i++ ) {         b = jQuery.trim( members[ i ].Name ).toLowerCase();         if ( a === b ) {             member = members[ i ];             break;         }     }      return member || {}; }  function calcEntryFee( elem ) {     var idx, member, exDate, today, fee;      elem = elem || {};     if ( /^[PEMX](\d+)$/.test( elem.id ) ) {         idx = RegExp.$1;     } else {         return false;     }      member = getMemberData( jQuery( '#P' + idx ).val() );     mmfee = parseFloat( jQuery( '#M' + idx ).val() );     exDate = moment( member.Expires, 'YYYY.MM.DD' );     today = moment();     fee = '';      if ( exDate.isBefore( today ) ) {         fee = 5;     } else if ( exDate.isSameOrAfter( today ) ) {         fee = 3;     } else if ( ! member.Expires && mmfee > 0 ) {         fee = 0;     }      // Updates the entry fee input value.     jQuery( '#E' + idx ).val( fee );      return fee; } 

You'd use calcEntryFee() like this:

<input id="X1" placeholder="X" size="10" onblur="calcEntryFee( this );" /> 

See the full code and try a live demo on https://codepen.io/anon/pen/WJRNVY.

Answers 2

Had to re-read your question a few times. I'm still not sure a fully understand what you're trying to achieve, but I believe this is pretty close:

let getMember = {   index: function(name) {     let index = -1;       $.each(members, function(i, player) {       if (player.Name === name) { index = i; }     });     return index;   },   entryFee: function(memberIndex) {     if (memberIndex === -1) {       return 'waived';     } else {}       let today = new Date();       let expires = new Date(members[memberIndex].Expires.replace(/\./g, '-'));       return today <= expires ? '$3' : '$5';         } };  let members = [   {"Name": "Jones, David", "Expires": "2017.05.03" },   {"Name": "Roth, Bill", "Expires": "2017.03.08" },   {"Name": "Scullin, Kenn", "Expires": "2019.02.20" } ];   let tableHTML = '';  for (let i=0; i < 50; i++) {     tableHTML += `   <div class="row">     <input type="text" class="player" placeholder="player">     <input type="text" class="entryFee" placeholder="entry fee">     <input type="text" class="membershipFee" placeholder="membership fee">     <input type="text" class="expDate" placeholder="expire date">   <div>`; }  $(`<div class="table">${tableHTML}</div>`)   .appendTo('body')   .on('blur', '.player', function() {     if (!this.value) { return false; }     let memberIndex = getMember.index(this.value);     let entryFee = getMember.entryFee(memberIndex);      $(this)       .next().val(entryFee)       .next().val(entryFee === 'waived' ? 'yes' : 'no')       .next()         .val(memberIndex >= 0 ? members[memberIndex].Expires : 'non-member')         .addClass(entryFee === '$3' ? 'currentMember' : 'nonCurrentMember');      $('.player').eq($('.player').index(this) + 1).focus(); }); 

https://jsfiddle.net/ypzjfkxk/

Without an external library to boot! Can't say I have any experience with moment.js, but all of the questions I've come across seem to be solvable in plain javascript. Also, it would be just as fast and easy to generate an alphabetical table for this. Then you wouldn't have to worry about typos in the player input. Unless you're trying to create a log or something?

Answers 3

This works for me:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <!DOCTYPE html>  <html lang="en">    <head>      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js"></script>            <script type="application/javascript">        var members = [          {"Name": "Jones, David", "Expires": "2017.05.03" },          {"Name": "Scullin, Kenn", "Expires": "2019.02.20" },          {"Name": "Peter, Kenn", "Expires": "2018.04.24" },          {"Name": "Chris, Kennx", "Expires": "" }        ];          $(document).ready(function(){          var nUsers = 4; // Number os users            // Fill inputs (tmp: visual purpose)          for (count=1; count<=nUsers; count++){            $("#P"+count).val(members[count-1].Name);            $("#X"+count).val(members[count-1].Expires);          }          $("#M4").val("$20");            /* Get current date. For security purpose you should            get this from the server and not the client side.*/          var date = moment().toDate();            // Go through every input row          for (count=1; count<=nUsers; count++){            var exDate = $("#X"+count).val(); // Get the exire date              // Confirm that date is has the right format            if (moment(exDate, 'YYYY.MM.DD').isValid()){              exDate = moment(exDate, 'YYYY.MM.DD').toDate();              var diff = new Date(exDate - date);              var nDays = parseInt(diff/1000/60/60/24);                console.log(nDays);                if (nDays >= 0){ // If his expires date is greater or equal to today's date                $("#E"+count).val("$3");                $("#X"+count).css('color', "#275052");              }              if (nDays < 0){                $("#E"+count).val("$5"); // If his expires date is older or less than today's date                $("#X"+count).css('color', "#A3005B");              }            }            else{ // If expire date is empty              var mFee = parseFloat($("#M"+count).val().replace(/\$/, ''));              if ((exDate.length == 0) && (mFee > 0 )){ // If the expires date is blank and the player pays a membership fee                $("#E"+count).val("$0");              }            }          }        });      </script>      </head>    <body>        <!-- visual purpose -->      <div>        <input type = "text" id = "P1"> <!--Player-->        <input type = "text" id = "E1"> <!--Entry Fee-->        <input type = "text" id = "M1"> <!--Membership Fee-->        <input type = "text" id = "X1" class="expDate"> <!--expires-->          <br>          <input type = "text" id = "P2"> <!--Player-->        <input type = "text" id = "E2"> <!--Entry Fee-->        <input type = "text" id = "M2"> <!--Membership Fee-->        <input type = "text" id = "X2" class="expDate"> <!--expires-->          <br>          <input type = "text" id = "P3"> <!--Player-->        <input type = "text" id = "E3"> <!--Entry Fee-->        <input type = "text" id = "M3"> <!--Membership Fee-->        <input type = "text" id = "X3" class="expDate"> <!--expires-->          <br>          <input type = "text" id = "P4"> <!--Player-->        <input type = "text" id = "E4"> <!--Entry Fee-->        <input type = "text" id = "M4"> <!--Membership Fee-->        <input type = "text" id = "X4" class="expDate"> <!--expires-->        <div>      </body>  </html>

And a recommendation that I gave to you in the code is you should get the current time from the server side and not from the client side.

I hope that works for you. :)

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment