/* Donation form · tovtorah.org/en/donate/ · English v1 (02/11/2026), built from the Hebrew v8. Same keys as the Hebrew page (purpose=general, beitmidrash, learning, bochurim, meals, hour; maaser is a separate tick), so the donors sheet and the readers see one list. Period tiles (Yissachar-Zevulun day, week, month, year) are priced in shekels only and are not offered here; ?purpose=yz... falls back to general. Currency: USD or ILS, chosen on the page. ILS is preselected when the browser clock is set to Israel. PayPal item_name = "Donation - Tov Torah - ": the Latin token "Tov Torah" is what keeps an English gift out of the ten-maaser sheet and away from R' Shimon (Kaddish file 0.9). Option names Dedication / Notes are read by tt-donors.php. Return = /en/donate/?thanks=1&amt=&p=&cur= (GTM reads cur). Block comments only, and never two ampersands or two pipes: WordPress breaks them. */ (function(){ var F = document.getElementById('ttDonForm'); if(!F){ return; } if(F.getAttribute('data-ready') === 'en1'){ return; } F.setAttribute('data-ready', 'en1'); var PUR = { general:'Where it is needed most', beitmidrash:'Strengthening the beit midrash', learning:'Supporting Torah learning', bochurim:'Help for yeshiva students', meals:'Meals with dignity', hour:'Partnership in an hour of learning' }; var DESC = { general:'The fund directs your gift to wherever the need is greatest at the time.', beitmidrash:'Strengthening the beit midrash and the people who learn in it.', learning:'Support for those who learn Torah, so they can keep sitting and learning.', bochurim:'Help for yeshiva students with what they are missing.', meals:'Meals for students whose families cannot provide them, given in a way that never embarrasses them.', hour:'A share in the merit of the hours of learning in the beit midrash, in any amount.' }; var MAASER_TAG = 'from maaser funds'; var DED = { none:'', iluy:'In memory of', refua:'For the recovery of', zchut:'In the merit of' }; var NAME_LBL = { iluy:'Name of the departed', refua:'Name of the person who is ill', zchut:'Name' }; var PARENT_LBL = { iluy:'Father’s name', refua:'Mother’s name', zchut:'Father’s or mother’s name' }; var PREFIX = 'Donation - Tov Torah - '; var MAXAMT = 100000; var RET = 'https://tovtorah.org/en/donate/?thanks=1'; var CUR = { USD:{ sym:'$', presets:[18, 36, 54, 100, 180, 360], def:54 }, ILS:{ sym:'₪', presets:[36, 100, 180, 360, 500, 1000], def:180 } }; var q = new URLSearchParams(location.search); function el(id){ return document.getElementById(id); } var amtIn = el('ttDonAmt'), out = el('ttDonOut'), fOut = el('ttDonFieldOut'), err = el('ttDonErr'); var desc = el('ttDonDesc'), dedBox = el('ttDonDedBox'), dedRow = el('ttDonDedRow'), dedOut = el('ttDonDedOut'); var nameIn = el('ttDonName'), parentIn = el('ttDonParent'), dateIn = el('ttDonDate'), dateWrap = el('ttDonDateWrap'); var nameLbl = el('ttDonNameLbl'), parentLbl = el('ttDonParentLbl'), notes = el('ttDonNotes'); var pre = el('ttDonPre'), thanks = el('ttDonThanks'), mBox = el('ttDonMaaser'); var dock = el('ttDonDock'), dAmt = el('ttDonDockAmt'), dWhat = el('ttDonDockWhat'); var goAmt = el('ttDonGoAmt'), curSym = el('ttDonCurSym'), lastN = null; function hid(n){ return F.querySelector('input[name="' + n + '"]'); } var hName = hid('item_name'), hNum = hid('item_number'), hCustom = hid('custom'), hRet = hid('return'); var hCur = hid('currency_code'); var on0 = hid('on0'), os0 = hid('os0'), on1 = hid('on1'), os1 = hid('os1'); if(!amtIn){ return; } var state = { field:'general', maaser:false, ded:'none', gen:'ben', cur:'USD' }; function money(n, c){ var k = c ? c : state.cur; return CUR[k].sym + n.toLocaleString('en-US'); } function clean(v){ var s = String(v === null ? '' : v).replace(/[^0-9.]/g, ''); var n = Math.round(parseFloat(s)); if(isNaN(n)){ return 0; } if(n < 0){ return 0; } if(n > MAXAMT){ return MAXAMT; } return n; } function txt(node, max){ if(!node){ return ''; } var s = String(node.value).replace(/\s+/g, ' ').replace(/^\s+/, '').replace(/\s+$/, ''); if(s.length > max){ s = s.slice(0, max); } return s; } function cut(s, max){ if(s.length > max){ return s.slice(0, max); } return s; } function setOn(sel, node){ var a = F.querySelectorAll(sel), i; for(i = 0; i < a.length; i++){ a[i].classList.remove('is-on'); a[i].setAttribute('aria-pressed', 'false'); } if(node){ node.classList.add('is-on'); node.setAttribute('aria-pressed', 'true'); } } function chipFor(sel, attr, val){ var a = F.querySelectorAll(sel), i; for(i = 0; i < a.length; i++){ if(a[i].getAttribute(attr) === String(val)){ return a[i]; } } return null; } function setOpt(nm, vl, val){ if(!nm){ return; } if(val){ nm.disabled = false; vl.disabled = false; vl.value = val; } else { nm.disabled = true; vl.disabled = true; vl.value = ''; } } /* the key recorded with the donation and sent to measurement (same keys as the Hebrew page) */ function key(){ if(!state.maaser){ return state.field; } if(state.field === 'general'){ return 'maaser'; } return state.field + '-maaser'; } function label(){ var s = PUR[state.field]; if(state.maaser){ s = s + ', ' + MAASER_TAG; } return s; } function dedText(){ if(state.ded === 'none'){ return ''; } var n = txt(nameIn, 60); if(!n){ return ''; } var s = DED[state.ded] + ' ' + n; var p = txt(parentIn, 60); if(p){ s = s + ' ' + state.gen + ' ' + p; } if(state.ded === 'iluy'){ var d = txt(dateIn, 40); if(d){ s = s + ', ' + d; } } return cut(s, 190); } /* the preset amount chips follow the currency */ function paintPresets(){ var a = F.querySelectorAll('.ttm-chip[data-amt]'), i, p = CUR[state.cur].presets; for(i = 0; i < a.length; i++){ if(i < p.length){ a[i].setAttribute('data-amt', String(p[i])); a[i].textContent = money(p[i]); a[i].hidden = false; } else { a[i].hidden = true; } } if(curSym){ curSym.textContent = CUR[state.cur].sym; } if(hCur){ hCur.value = state.cur; } } function paintDock(n){ if(!dock){ return; } if(dAmt){ dAmt.textContent = money(n); } var w = label(); if(state.ded !== 'none'){ w = w + ' · ' + DED[state.ded]; } if(dWhat){ dWhat.textContent = w; } } function paint(){ var n = clean(amtIn.value); if(out){ out.textContent = money(n); } if(goAmt){ goAmt.textContent = n > 0 ? money(n) : ''; } if(out){ if(lastN !== null){ if(n !== lastN){ out.classList.remove('is-pulse'); void out.offsetWidth; out.classList.add('is-pulse'); } } } lastN = n; setOn('.ttm-chip[data-amt]', chipFor('.ttm-chip[data-amt]', 'data-amt', n)); if(fOut){ fOut.textContent = label(); } if(desc){ desc.textContent = DESC[state.field]; } if(mBox){ mBox.checked = state.maaser; } if(hNum){ hNum.value = key(); } if(hName){ hName.value = cut(PREFIX + label(), 127); } var dt = dedText(); if(dedRow){ dedRow.hidden = dt === ''; } if(dedOut){ dedOut.textContent = dt; } paintDock(n); if(n > 0){ if(err){ err.hidden = true; } } } function pickCur(c, keepAmt){ if(!CUR[c]){ return; } var wasDefault = clean(amtIn.value) === CUR[state.cur].def; state.cur = c; setOn('.ttm-chip[data-cur]', chipFor('.ttm-chip[data-cur]', 'data-cur', c)); paintPresets(); if(!keepAmt){ if(wasDefault){ amtIn.value = String(CUR[c].def); } } paint(); } function pickField(k){ if(k === 'maaser'){ state.maaser = true; k = 'general'; } if(!PUR[k]){ return; } state.field = k; setOn('.ttm-chip[data-field]', chipFor('.ttm-chip[data-field]', 'data-field', k)); paint(); } function pickDed(k){ if(!(k in DED)){ return; } state.ded = k; setOn('.ttm-chip[data-ded]', chipFor('.ttm-chip[data-ded]', 'data-ded', k)); if(dedBox){ dedBox.hidden = k === 'none'; } if(k !== 'none'){ if(nameLbl){ nameLbl.textContent = NAME_LBL[k]; } if(parentLbl){ parentLbl.textContent = PARENT_LBL[k] + ' (optional)'; } if(dateWrap){ dateWrap.hidden = k !== 'iluy'; } } paint(); } function pickGen(g){ state.gen = g; setOn('.ttm-chip[data-gen]', chipFor('.ttm-chip[data-gen]', 'data-gen', g)); paint(); } var a = F.querySelectorAll('.ttm-chip[data-amt]'), i; for(i = 0; i < a.length; i++){ a[i].addEventListener('click', function(){ amtIn.value = this.getAttribute('data-amt'); paint(); }); } a = F.querySelectorAll('.ttm-chip[data-cur]'); for(i = 0; i < a.length; i++){ a[i].addEventListener('click', function(){ pickCur(this.getAttribute('data-cur'), false); }); } a = F.querySelectorAll('.ttm-chip[data-field]'); for(i = 0; i < a.length; i++){ a[i].addEventListener('click', function(){ pickField(this.getAttribute('data-field')); }); } a = F.querySelectorAll('.ttm-chip[data-ded]'); for(i = 0; i < a.length; i++){ a[i].addEventListener('click', function(){ pickDed(this.getAttribute('data-ded')); }); } a = F.querySelectorAll('.ttm-chip[data-gen]'); for(i = 0; i < a.length; i++){ a[i].addEventListener('click', function(){ pickGen(this.getAttribute('data-gen')); }); } if(mBox){ mBox.addEventListener('change', function(){ state.maaser = mBox.checked; paint(); }); } amtIn.addEventListener('input', paint); amtIn.addEventListener('change', paint); var live = [nameIn, parentIn, dateIn]; for(i = 0; i < live.length; i++){ if(live[i]){ live[i].addEventListener('input', paint); } } /* ---------- prefill from the URL ---------- */ var src = String(q.get('src') === null ? '' : q.get('src')).toLowerCase().replace(/[^a-z0-9-]/g, '').slice(0, 40); if(!src){ src = 'en-donate'; } if(hCustom){ hCustom.value = src; } var startCur = 'USD'; try { var tz = Intl.DateTimeFormat().resolvedOptions().timeZone; if(tz === 'Asia/Jerusalem'){ startCur = 'ILS'; } if(tz === 'Asia/Tel_Aviv'){ startCur = 'ILS'; } } catch(e){} var qc = String(q.get('cur') === null ? '' : q.get('cur')).toUpperCase(); if(CUR[qc]){ startCur = qc; } state.cur = startCur; setOn('.ttm-chip[data-cur]', chipFor('.ttm-chip[data-cur]', 'data-cur', startCur)); paintPresets(); var filled = false; var pp = q.get('purpose'); if(pp){ filled = true; if(pp === 'maaser'){ state.maaser = true; state.field = 'general'; } else { if(PUR[pp]){ state.field = pp; } else { state.field = 'general'; } } } setOn('.ttm-chip[data-field]', chipFor('.ttm-chip[data-field]', 'data-field', state.field)); var pa = clean(q.get('amount')); if(pa > 0){ amtIn.value = String(pa); filled = true; } else { amtIn.value = String(CUR[state.cur].def); } setOn('.ttm-chip[data-ded]', chipFor('.ttm-chip[data-ded]', 'data-ded', 'none')); setOn('.ttm-chip[data-gen]', chipFor('.ttm-chip[data-gen]', 'data-gen', 'ben')); setOpt(on0, os0, ''); setOpt(on1, os1, ''); paint(); /* ---------- thank-you state, after PayPal returns ---------- PayPal appends the payer's name, email and phone to the URL. tt-tracking.php removes them at the top of the page, before any measurement; only the confirmation number, status and gross reach window.ttPayPal. */ function showThanks(){ if(!thanks){ return; } var pp = window.ttPayPal; if(!pp){ pp = { tx:q.get('tx'), st:q.get('st'), gross:q.get('mc_gross') }; } var c = String(q.get('cur') === null ? '' : q.get('cur')).toUpperCase(); if(!CUR[c]){ c = 'USD'; } var n = clean(q.get('amt')); if(!(n > 0)){ n = clean(pp.gross); } var k = String(q.get('p') === null ? '' : q.get('p')).replace(/[^a-z-]/g, ''); var m = false; if(k === 'maaser'){ k = 'general'; m = true; } if(/-maaser$/.test(k)){ k = k.replace(/-maaser$/, ''); m = true; } if(!PUR[k]){ k = 'general'; } var what = PUR[k]; if(m){ what = what + ', ' + MAASER_TAG; } var aOut = el('ttThxAmt'), wOut = el('ttThxWhat'), sOut = el('ttThxState'); var rRow = el('ttThxRefRow'), rOut = el('ttThxRef'), dot = el('ttThxDot'); if(n > 0){ if(aOut){ aOut.textContent = money(n, c); } } else { if(aOut){ aOut.hidden = true; } if(dot){ dot.hidden = true; } } if(wOut){ wOut.textContent = what; } var st = pp.st ? String(pp.st).toLowerCase() : ''; if(st === 'pending'){ if(sOut){ sOut.textContent = 'Your donation reached PayPal and is awaiting confirmation'; } } var tx = pp.tx ? String(pp.tx).replace(/[^A-Za-z0-9]/g, '').slice(0, 24) : ''; if(tx.length > 7){ if(rOut){ rOut.textContent = tx; } if(rRow){ rRow.hidden = false; } } var hero = document.querySelector('.tt-hero--page'); if(hero){ hero.style.setProperty('display', 'none', 'important'); } F.style.setProperty('display', 'none', 'important'); if(pre){ pre.hidden = true; } var hs = document.querySelectorAll('[data-dn-thanks-hide]'), j; for(j = 0; j < hs.length; j++){ hs[j].style.setProperty('display', 'none', 'important'); } if(dock){ dock.style.setProperty('display', 'none', 'important'); } thanks.hidden = false; document.title = 'Thank you for your donation | Tov Torah'; window.scrollTo(0, 0); try { thanks.focus({ preventScroll:true }); } catch(e){} } if(q.get('thanks') === '1'){ showThanks(); filled = false; } if(filled){ if(pre){ pre.hidden = false; } } /* ---------- the bottom dock on phones and tablets (same behaviour as the Hebrew page) ---------- */ var resBox = F.querySelector('.ttm-result'); var mq = window.matchMedia ? window.matchMedia('(max-width: 1023px)') : null; var vis = { form:false, res:false, typing:false }; function typingIn(t){ if(!t){ return false; } if(!F.contains(t)){ return false; } if(t.tagName === 'TEXTAREA'){ return true; } if(t.tagName === 'INPUT'){ if(t.type !== 'checkbox'){ return true; } } return false; } function dockOn(){ if(!mq){ return false; } if(!mq.matches){ return false; } if(!vis.form){ return false; } if(vis.res){ return false; } if(vis.typing){ return false; } return true; } function showDock(){ if(!dock){ return; } var on = dockOn(); dock.classList.toggle('is-on', on); document.documentElement.classList.toggle('tt-dock-on', on); } if(dock){ if('IntersectionObserver' in window){ new IntersectionObserver(function(es){ vis.form = es[es.length - 1].isIntersecting; showDock(); }, { rootMargin: '0px 0px -30% 0px' }).observe(F); if(resBox){ new IntersectionObserver(function(es){ vis.res = es[es.length - 1].isIntersecting; showDock(); }, { rootMargin: '0px 0px -110px 0px' }).observe(resBox); } } F.addEventListener('focusin', function(e){ vis.typing = typingIn(e.target); showDock(); }); F.addEventListener('focusout', function(){ setTimeout(function(){ vis.typing = typingIn(document.activeElement); showDock(); }, 80); }); if(mq){ if(mq.addEventListener){ mq.addEventListener('change', showDock); } else { if(mq.addListener){ mq.addListener(showDock); } } } } F.addEventListener('submit', function(e){ var n = clean(amtIn.value); if(!(n > 0)){ e.preventDefault(); if(err){ err.hidden = false; } amtIn.focus(); return; } amtIn.value = String(n); paint(); if(hCur){ hCur.value = state.cur; } setOpt(on0, os0, dedText()); setOpt(on1, os1, txt(notes, 190)); if(hRet){ hRet.value = RET + '&amt=' + n + '&p=' + key() + '&cur=' + state.cur; } }); })();