Рассчитать поле ввода на основе срока действия
Форма с 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>
И рекомендация, которую я дал вам в коде: вы должны получать текущее время со стороны сервера, а не со стороны клиента.
Я надеюсь, что это работает для вас.:)