We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Refs #1847 Closes gh-1854
cab42bb
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
} [data-cart-info] span{ display:inline-block; vertical-align:middle; } .material-icons{ font-size:150px; } [data-credit-card]{ width:435px; min-height:240px; border-radius:10px; background-color:#5d6874 } [data-card-type]{ display:block; width:120px; height:60px; } [data-cc-digits]{ margin-top:2em; } [data-cc-digits] input{ color:white; font-size:2em; line-height:2em; border:none; background:none; margin-right:0.5em; } [data-cc-info]{ margin-top:1em; } [data-cc-info] input{ color:white; font-size:1.2em; border:none; background:none; } [data-cc-info] input:nth-child(2){ padding-right:10px; float:right; } [data-pay-btn]{ position:fixed; width:90%; border:1px solid; bottom:20px; } .mdc-card__primary-action, .mdc-card__primary-action:hover { cursor: auto; padding: 20px; min-height: inherit; } [data-credit-card] [data-card-type] { transition: width 1.5s; margin-left: calc(100% - 130px); } [data-credit-card].is-visa { background: linear-gradient(135deg, #622774 0%, #c53364 100%); } [data-credit-card].is-mastercard { background: linear-gradient(135deg, #65799b 0%, #5e2563 100%); } .is-visa [data-card-type], .is-mastercard [data-card-type] { width: auto; } input.is-invalid, .is-invalid input { text-decoration: line-through; } ::placeholder { color: #fff; } </style>
<div class="mdc-card mdc-card--outlined" data-credit-card> <div class="mdc-card__primary-action"> <img src="https://placehold.it/120x60.png?text=Card" data-card-type/> <div data-cc-digits> <input type="text" size="4" placeholder="----"/> <input type="text" size="4" placeholder="----"/> <input type="text" size="4" placeholder="----"/> <input type="text" size="4" placeholder="----"/> </div> <div data-cc-info> <input type="text" size="20" placeholder="Name Surname"/> <input type="text" size="6" placeholder="MM/YY"/> </div> </div> </div> <button class="mdc-button" data-pay-btn>Pay & Checkout Now</button> <script> const appState ={}; const formatAsMoney =(amount,buyerCountry)=>{ const getCountry=countries.find(country=>{return country.country===buyerCountry;}); countries.forEach(country=>{if(!getCountry){ let formattedTotalBill=amount.toLocaleString(countries[0].code,{style:"currency",currency:countries[0].currency}); }else{ formattedTotalBill=amount.toLocaleString(getCountry.code,{style:"currency",currency:getCountry.currency}) }console.log(formattedTotalBill); return formattedTotalBill; }); }; const flagIfInvalid =(field,isValid)=>{ if(isValid ===true){ field.classList.remove("is-invalid"); }else { field.classList.add("is-invalid"); } }; const expiryDateFormatIsValid=(target)=>{ const pattern = /0?[1-9]|1[0-2]\/(\d{2})/; if(target.match(pattern)){ return true; }else{ return false; } }; const detectCardType = ({target})=>{ const num = target.value.split(''); //for visa card if(num[0]==='4'){ document.querySelector('[data-credit-card]').classList.add('is-visa'); document.querySelector('[data-credit-card]').classList.remove('is-mastercard'); document.querySelector('[data-card-type]').src=supportedCards.visa; return 'is-visa'; } //for mastercard else if(num[0]==='5'){ document.querySelector('[data-credit-card]').classList.add('is-mastercard'); document.querySelector('[data-credit-card]').classList.remove('is-visa'); document.querySelector('[data-card-type]').src=supportedCards.mastercard; return 'is-mastercard'; } else{ console.log('The card is not supported.') } }; const validateCardExpiryDate = ({target})=>{ let boo= expiryDateFormatIsValid(target.value); if(boo){ let dateArr=target.value.split('/'); const month= dateArr[0]; const year = '20' + [dateArr]; const expDate = new Date(year + '-' + month + '-01'); if(expDate>new Date()){ flagIfInvalid(target,true); return true; } } }; const validateCardHolderName=({target})=>{ const {valu}=target; const isValid=/^[a-zA-Z]{3,30} +[a-zA-Z]{3,30}$/.test(valu); flagIfInvalid(target,isValid); return isValid; }; const validateWithLuhn = (digits)=>{ let hasInvalidChars= digits.some(digit=>{ return(typeof digit !== 'number'); }); let hasValidChecksum = (digits=>{ let checksum= digits.reverse().map((digit,index)=>{ let computedDigit = digit; if((index+1) % 2==0){ computedDigit*=2; if(computedDigit>9){ computedDigit-=9; } } return computedDigit; }).reduce(((sum,digit)=>{ return sum + digit; }),0); return ((checksum % 10)==0); })(digits); return (digits.length == 16) && !hasInvalidChars && hasValidChecksum; }; const validateCardNumber=()=>{ let values = ''; document.querySelectorAll('div[data-cc-digits] input').forEach(inputField =>{ values +=inputField.value; },validateCardNumber); let digits = values.split('').map(value=>{ return parseInt(value); }); let isValidCardNumber = validateWithLuhn(digits); if(isValidCardNumber){ document.querySelector('div[data-cc-digits]').classList.remove('is-invalid'); }else{ document.querySelector('div[data-cc-digits]').classList.add('is-invalid'); } return isValidCardNumber; }; const uiCanInteract =()=>{ const digitInputs=document.querySelectorAll("[data-cc-digits]") const first= digitInputs[0]; const infoInputs= document.querySelectorAll("[data-cc-info]") const firstInfo= infoInputs[0]; const secondInfo= infoInputs[1]; if(first){ first.addEventListener('blur',detectCardType); } if(firstInfo){ firstInfo.addEventListener('blur',validateCardHolderName); } if(secondInfo){ secondInfo.addEventListener('blur',validateCardExpiryDate); } const btn = document.querySelector("[data-pay-btn]"); if(btn){ btn.addEventListener('click',validateCardNumber); } first.focus(); }; const displayCartTotal =({results})=>{ const[data] =results; const{itemsInCart,buyerCountry}=data; appState.items = itemsInCart; appState.country=buyerCountry; appState.bill= itemsInCart.reduce((total,{qty,price})=>{ return total + (price*qty) },0); appState.billFormatted = formatAsMoney(appState.bill,appState.country); document.querySelector('span[data-bill]').textContent=appState.billFormatted; uiCanInteract(); }; const fetchBill =()=>{ const api="https://randomapi.com/api/006b08a801d82d0c9824dcfdfdfa3b3c"; fetch(api).then(response=>response.json()).then(data=>{displayCartTotal(data);}).catch(error=>{console.log(error);}); }; const supportedCards = { visa, mastercard }; const countries = [ { code: "US", currency: "USD", country: 'United States' }, { code: "NG", currency: "NGN", country: 'Nigeria' }, { code: 'KE', currency: 'KES', country: 'Kenya' }, { code: 'UG', currency: 'UGX', country: 'Uganda' }, { code: 'RW', currency: 'RWF', country: 'Rwanda' }, { code: 'TZ', currency: 'TZS', country: 'Tanzania' }, { code: 'ZA', currency: 'ZAR', country: 'South Africa' }, { code: 'CM', currency: 'XAF', country: 'Cameroon' }, { code: 'GH', currency: 'GHS', country: 'Ghana' } ]; const startApp = () => { fetchBill(); }; startApp(); </script>
Sorry, something went wrong.
cab42bb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shopping_cart