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>
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>
Share
Improve this question
edited Apr 29, 2018 at 20:48
bcr
9508 silver badges28 bronze badges
asked Apr 20, 2018 at 23:57
verlagerverlager
8765 gold badges26 silver badges49 bronze badges
2
- 2 what have you tried. ? Please e up with at least one of your tries. – Muhammad Usman Commented Apr 21, 2018 at 0:01
- good question, I'll post the reply above. – verlager Commented Apr 21, 2018 at 0:05
3 Answers
Reset to default 4 +50How 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.
UPDATE
Because the expiry date field/input
is disabled, use this instead: (take note of the id
value, which could also be P2
, P3
, etc.)
<input id="P1" placeholder="P" onblur="calcEntryFee( this );" />
I.e. Add the calcEntryFee( this );
to the onblur
attribute of the "Player" field and not the expiry date field. Or add it to any sibling/related fields which is not disabled, or which we can tab to. (So that we can focus and "un-focus" or blur on the field, and the browser would then invoke the calcEntryFee( this );
that was attached to the field's blur
event.)
Try a live demo on: https://codepen.io/anon/pen/xjgQyx
Alternatively, you may add it without using the onblur
attribute of the input
/field: (refer to the code you provided in your question)
for (let i = 0; i <= 48; i++) {
$("#P" + i).on("blur", function() {
$("#X" + i).val(getExpireDate(this));
calcEntryFee(this); // <- add it here
});
}
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/ypzjfkxk/
Without an external library to boot! Can't say I have any experience with moment.js, but all of the questions I've e 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?
This works for me:
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare./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 remendation 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. :)