Рассчитать поле ввода на основе срока действия

Форма с 50 записями: каждая с P1-48, E1-48 и X1-48. Я хочу рассчитать вступительный взнос "E1" на основе даты истечения срока X1. Формат даты js для даты истечения срока действия YYYY.MM.DD, ex. 2018.04.21 и игрок платит 3 доллара, если его срок действия больше или равен сегодняшней дате. Он платит 5 долларов, если его срок годности больше или меньше, чем сегодняшний день. Но если дата истечения срока не указана и игрок платит членский взнос, вступительный взнос отменяется до нуля.

JS:

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

У меня также есть это в качестве "шаблона", начиная с руководства. Я думаю, что это может быть изменено и добавить целевой результат на него.

<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>

Забавная вещь это:

<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 ответа

Решение

Как насчет этого:

(Главный function является 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;
}

Вы бы использовали calcEntryFee() как это:

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

Посмотрите полный код и попробуйте демо-версию на https://codepen.io/anon/pen/WJRNVY.

ОБНОВИТЬ

Поскольку поле даты истечения срока действия /input отключено, используйте это вместо: (обратите внимание на id значение, которое также может быть P2, P3, так далее.)

<input id="P1" placeholder="P" onblur="calcEntryFee( this );" />

Т.е. добавить calcEntryFee( this ); к onblur атрибут поля "Игрок", а не поле даты истечения срока действия. Или добавьте его к любым родственным / связанным полям, которые не отключены или к которым мы можем перейти. (Так что мы можем сфокусироваться и "не сфокусироваться" или размыть поле, и браузер затем вызовет calcEntryFee( this ); который был прикреплен к полю blur событие.)

Попробуйте демо-версию на: https://codepen.io/anon/pen/xjgQyx

Кроме того, вы можете добавить его, не используя onblur атрибут input/ поле: (см. код, который вы указали в своем вопросе)

for (let i = 0; i <= 48; i++) {
  $("#P" + i).on("blur", function() {
    $("#X" + i).val(getExpireDate(this));
    calcEntryFee(this); // <- add it here
  });
}

Пришлось перечитать ваш вопрос несколько раз. Я до сих пор не уверен, что полностью понимаю, чего вы пытаетесь достичь, но я считаю, что это довольно близко:

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/

Без внешней библиотеки для загрузки! Не могу сказать, что у меня есть какой-то опыт с moment.js, но все вопросы, с которыми я сталкивался, кажутся решаемыми в простом javascript. Кроме того, было бы так же быстро и легко сгенерировать алфавитную таблицу для этого. Тогда вам не придется беспокоиться об опечатках на входе плеера. Если вы не пытаетесь создать журнал или что-то?

Это работает для меня:

<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>

И рекомендация, которую я дал вам в коде: вы должны получать текущее время со стороны сервера, а не со стороны клиента.

Я надеюсь, что это работает для вас.:)

Другие вопросы по тегам