Open Hours of City Government Mon - Fri: 8.00 am - 5.00 pm

Jackson is Rising - Come Visit

Open Hours of City Government

Mon - Fri: 8.00 am - 5.00 pm

#jxn-events,.jx-scrim{--blue:#0B5FA5;--blue-d:#084B84;--ink:#0B1726;--text:#2B3A4D;--muted:#5A6B80;--line:#E2E6EC;--soft:#EFF1F5;--bg:#F7F8FA;--disp:'Archivo',sans-serif;--body:'IBM Plex Sans',sans-serif;--mono:'IBM Plex Mono',monospace} #jxn-events{container-type:inline-size;container-name:jxn;background:var(--bg);color:var(--text);font:400 16px/1.6 var(--body);padding-bottom:48px} #jxn-events *,.jx-scrim *{box-sizing:border-box} #jxn-events a,.jx-scrim a{color:var(--blue-d);text-decoration:none} #jxn-events a:hover,.jx-scrim a:hover{text-decoration:underline} #jxn-events button,.jx-scrim button{font-family:var(--body);margin:0} #jxn-events h1,#jxn-events h2,#jxn-events h3,.jx-scrim h2{text-transform:none} .jx-wrap{max-width:1200px;margin:0 auto;padding:0 24px} .jx-hero{background:var(--blue-d);color:#fff} .jx-hero-in{max-width:1200px;margin:0 auto;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);gap:40px;align-items:center;padding:44px 24px 40px} .jx-eyebrow{font:500 11px/1.2 var(--mono);letter-spacing:.12em;color:#fff} #jxn-events .jx-hero h1{margin:12px 0 0;font:700 clamp(30px,4.4vw,46px)/1.05 var(--disp);letter-spacing:-.02em;color:#fff} .jx-hero p{margin:12px 0 0;max-width:56ch;font:400 16px/1.55 var(--body);color:#fff} .jx-btns{display:flex;flex-wrap:wrap;gap:10px;margin-top:22px} #jxn-events .jx-btn{display:inline-flex;align-items:center;gap:8px;height:48px;padding:0 22px;border-radius:6px;font:700 16px/1 var(--body);border:0;cursor:pointer;text-decoration:none;color:#fff;white-space:nowrap} #jxn-events .jx-btn:hover{text-decoration:none;filter:brightness(1.08)} #jxn-events .jx-btn-blue{background:var(--blue)} #jxn-events .jx-btn-line{border:1px solid rgba(255,255,255,.45);background:transparent} #jxn-events .jx-btn-gold{background:#E2A30C;color:var(--ink)} #jxn-events .jx-btn-gold-d{background:#B37F09} #jxn-events .jx-btn-green{background:#2F9E44} #jxn-events .jx-btn-white{background:#fff;color:var(--blue-d)} #jxn-events .jx-btn-sm{height:40px;padding:0 18px;font-size:15px} .jx-stats{display:flex;flex-wrap:wrap;gap:28px;margin-top:26px;padding-top:18px;border-top:1px solid rgba(255,255,255,.2)} .jx-stat b{display:block;font:700 26px/1 var(--disp);color:#fff;margin-bottom:6px} .jx-stat span{font:500 11px/1.2 var(--mono);letter-spacing:.1em;color:#fff} .jx-hero-img{border-radius:8px;overflow:hidden;background:#fff;padding:16px;display:flex;align-items:center;justify-content:center} .jx-hero-img img{display:block;margin:0;width:auto;max-width:100%;height:auto;max-height:420px;object-fit:contain} .jx-subnav{background:#fff;border-bottom:1px solid var(--line)} .jx-subnav .jx-wrap{display:flex;flex-wrap:wrap;column-gap:22px;row-gap:0;align-items:center;font:500 14px/1 var(--body)} #jxn-events .jx-subnav a.jx-l{padding:14px 0;color:var(--text);white-space:nowrap} .jx-subnav .jx-r{margin-left:auto;display:flex;flex-wrap:wrap;gap:10px;padding:8px 0} .jx-sec{padding-top:44px} .c-municipal{--c:#0B5FA5;--c2:#084B84}.c-special{--c:#B37F09;--c2:#8A6200}.c-community{--c:#0E7D83;--c2:#0E7D83}.c-cleanup{--c:#2F7A3E;--c2:#1F7A33}.c-ink{--c:#0B1726;--c2:#0B1726} .jx-head{border-top:5px solid var(--c);padding-top:18px;display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap} .jx-title{display:block;font:800 clamp(28px,3.1vw,36px)/1.08 var(--disp);text-transform:uppercase;letter-spacing:-.01em;color:var(--c2)} #jxn-events .jx-sub{margin:6px 0;font:600 18px/1.35 var(--disp);color:var(--text);letter-spacing:-.01em} .jx-desc{margin:0;font:400 13px/1.55 var(--body);color:var(--muted);max-width:62ch} .jx-count{font:400 12px/1.4 var(--mono);color:var(--muted)} .jx-grid{margin-top:18px;display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:16px} .jx-tile{background:#fff;border:1px solid var(--line);border-radius:8px;overflow:hidden;display:flex;flex-direction:column;transition:box-shadow .16s,transform .16s} .jx-tile:hover{box-shadow:0 8px 24px rgba(11,23,38,.1);transform:translateY(-3px)} .jx-hit{cursor:pointer} .jx-thumb{height:104px;padding:12px;display:flex;flex-direction:column;justify-content:space-between;background:var(--c)} .jx-badge{align-self:flex-start;padding:3px 8px;border-radius:999px;font:500 10px/1.3 var(--mono);letter-spacing:.08em;background:#fff;color:var(--c2)} .jx-thumb strong{font:700 14px/1.25 var(--disp);color:#fff} .jx-meta{padding:12px;display:flex;flex-direction:column;gap:6px} .jx-date{font:500 12px/1.3 var(--mono);letter-spacing:.05em;color:var(--c2)} .jx-loc{font:400 13px/1.5 var(--body);color:var(--muted)} #jxn-events .jx-permit-btn{border:0;border-top:1px solid var(--soft);background:var(--bg);cursor:pointer;padding:11px 14px;display:flex;justify-content:space-between;align-items:center;font:500 12px/1.3 var(--mono);letter-spacing:.06em;color:var(--text);width:100%;border-radius:0} .jx-permit-btn:hover{background:rgba(11,95,165,.07)} .jx-chev{display:grid;place-items:center;width:20px;height:20px;border-radius:4px;background:rgba(11,95,165,.1);color:var(--blue-d);font-size:11px} .jx-conds{padding:14px;border-top:1px solid var(--soft);display:flex;flex-direction:column;gap:10px} .jx-kv{display:grid;grid-template-columns:132px 1fr;gap:12px;align-items:baseline} .jx-kv span:first-child{font:500 10px/1.4 var(--mono);letter-spacing:.08em;color:#8494A8} .jx-kv span:last-child{font:400 13px/1.45 var(--body);color:var(--ink)} .jx-card{margin-top:18px;background:#fff;border:1px solid var(--line);border-radius:8px;overflow:hidden} .jx-cardhead{padding:12px 14px;background:var(--bg);border-bottom:1px solid var(--line);font:500 11px/1.2 var(--mono);letter-spacing:.09em;color:var(--text)} .jx-closure{display:grid;grid-template-columns:120px minmax(0,1fr);gap:14px;padding:11px 14px;border-bottom:1px solid var(--soft);cursor:pointer;align-items:baseline} .jx-closure:hover{background:rgba(11,95,165,.07)} .jx-closure span:first-child{font:500 11px/1.4 var(--mono);letter-spacing:.05em;color:#8A6200} .jx-closure span:last-child{font:400 13px/1.5 var(--body);color:var(--text)} .jx-closure b{color:var(--ink);font-weight:600} .jx-week{margin-top:18px;display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px} .jx-day{background:#fff;border:1px solid var(--line);border-radius:8px;padding:12px;display:flex;flex-direction:column;gap:10px;min-height:152px} .jx-dayhead{display:flex;align-items:baseline;justify-content:space-between;padding-bottom:10px;border-bottom:1px solid var(--soft)} .jx-dayhead span{font:500 11px/1.2 var(--mono);letter-spacing:.1em;color:var(--muted)} .jx-dayhead b{font:800 26px/1 var(--disp);color:var(--ink)} .jx-today{align-self:flex-start;padding:3px 8px;border-radius:999px;background:rgba(11,95,165,.12);border:1px solid var(--blue);font:500 10px/1.2 var(--mono);letter-spacing:.08em;color:var(--blue-d)} .jx-item{display:flex;gap:8px;cursor:pointer} .jx-item:hover{opacity:.7} .jx-item i{width:3px;min-height:28px;border-radius:2px;background:var(--c);flex-shrink:0} .jx-item small{display:block;font:400 11px/1.2 var(--mono);color:var(--muted)} .jx-item span{font:500 13px/1.35 var(--body);color:var(--ink)} .jx-none{font:400 12px/1.5 var(--body);color:#8494A8} .jx-cal{margin-top:18px;display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;align-items:start} .jx-calbox{background:#fff;border:1px solid var(--line);border-radius:8px;overflow:hidden} .jx-caltop{padding:16px;display:flex;flex-wrap:wrap;gap:12px;align-items:center;border-bottom:1px solid var(--soft)} #jxn-events .jx-nav{width:34px;height:34px;border:1px solid var(--line);background:#fff;border-radius:4px;cursor:pointer;font-size:16px;color:var(--text);padding:0} .jx-month{font:700 20px/1.1 var(--disp);color:var(--ink);min-width:190px} .jx-filters{flex-basis:100%;display:flex;gap:8px;flex-wrap:wrap} #jxn-events .jx-chip{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:#fff;cursor:pointer;font:500 11px/1.2 var(--mono);letter-spacing:.07em;color:var(--text)} .jx-chip i{width:8px;height:8px;border-radius:2px;background:var(--c);border:1px solid var(--c)} #jxn-events .jx-chip.off{opacity:.5} .jx-chip.off i{background:transparent} .jx-dows,.jx-row{display:grid;grid-template-columns:repeat(7,minmax(0,1fr))} .jx-dows span{padding:10px 4px;text-align:center;font:500 10px/1.2 var(--mono);letter-spacing:.1em;color:#8494A8;border-bottom:1px solid var(--soft)} .jx-cell{min-width:0;overflow:hidden;min-height:80px;border-right:1px solid var(--soft);border-bottom:1px solid var(--soft);padding:7px;cursor:pointer;display:flex;flex-direction:column;gap:4px;background:#fff} .jx-cell:hover{background:rgba(11,95,165,.07)} .jx-cell.sel{box-shadow:inset 0 0 0 2px var(--blue)} .jx-cell.blank{cursor:default;background:#FBFCFD} .jx-num{font:500 13px/1.2 var(--mono);color:var(--text)} .jx-num.now{display:grid;place-items:center;width:24px;height:24px;margin:-3px 0 0 -4px;border-radius:999px;background:var(--blue);color:#fff;font-weight:700} .jx-tag{display:block;width:100%;font:500 10px/1.3 var(--mono);color:var(--c2);border-left:3px solid var(--c);padding-left:5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .jx-dots{display:none;gap:3px;flex-wrap:wrap} .jx-dots i{width:7px;height:7px;border-radius:999px;background:var(--c)} .jx-panel{background:#fff;border:1px solid var(--line);border-radius:8px;padding:18px} #jxn-events .jx-panel h3{margin:8px 0 14px;font:700 20px/1.15 var(--disp);color:var(--ink)} .jx-plist{display:flex;flex-direction:column;gap:10px} .jx-pev{display:flex;flex-direction:column;gap:6px;border:1px solid var(--line);border-left:4px solid var(--c);border-radius:6px;padding:12px;cursor:pointer;background:#fff} .jx-pev:hover{background:rgba(11,95,165,.07)} .jx-pev small{font:500 10px/1.2 var(--mono);letter-spacing:.08em;color:var(--c2)} .jx-pev b{font:600 14px/1.35 var(--body);color:var(--ink)} .jx-pev span{font:400 12px/1.4 var(--mono);color:var(--muted)} .jx-band{margin-top:44px;background:var(--blue-d);border-radius:8px;padding:32px;display:flex;gap:28px;flex-wrap:wrap;align-items:center;justify-content:space-between;color:#fff} #jxn-events .jx-band h2{margin:0;font:700 24px/1.15 var(--disp);color:#fff} .jx-band p{margin:10px 0 0;max-width:58ch;font:400 15px/1.6 var(--body);color:#fff} .jx-scrim{position:fixed;inset:0;z-index:999999;background:rgba(11,23,38,.6);display:none;align-items:flex-start;justify-content:center;padding:32px 20px;overflow-y:auto;font:400 16px/1.6 var(--body);color:var(--text)} .jx-scrim.open{display:flex} .jx-toggle{position:absolute;opacity:0;pointer-events:none;width:1px;height:1px;margin:0} #jx-t-cleanup:checked~#jx-apply-cleanup,#jx-t-volunteer:checked~#jx-apply-volunteer,#jx-t-event:checked~#jx-apply-event{display:flex} .jx-backdrop{position:fixed;inset:0;z-index:0;cursor:pointer} .jx-apply .jx-modal{position:relative;z-index:1} #jxn-events label.jx-btn{user-select:none} .jx-modal{width:100%;max-width:760px;background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 20px 60px rgba(11,23,38,.3)} .jx-mhead{position:relative;padding:24px 60px 24px 24px;background:var(--blue-d);color:#fff} .jx-scrim .jx-close{position:absolute;top:16px;right:16px;width:34px;height:34px;border-radius:4px;border:1px solid rgba(255,255,255,.35);background:transparent;color:#fff;cursor:pointer;font-size:20px;line-height:1;padding:0} .jx-mbadge{display:inline-flex;padding:4px 10px;border-radius:999px;font:500 10px/1.3 var(--mono);letter-spacing:.08em;background:rgba(255,255,255,.15);color:#fff} .jx-scrim .jx-mhead h2{margin:12px 0 0;font:700 26px/1.1 var(--disp);letter-spacing:-.02em;color:#fff} .jx-mdate{margin:12px 0 0;font:500 14px/1.5 var(--mono);letter-spacing:.04em;color:#fff} .jx-mloc{margin:4px 0 0;font:400 14px/1.5 var(--body);color:#fff} .jx-mbody{padding:24px;display:grid;grid-template-columns:minmax(0,1fr) 220px;gap:24px} .jx-mdesc{margin:0;font:400 15px/1.6 var(--body);color:var(--text)} .jx-mconds{margin-top:18px;border:1px solid var(--line);border-radius:8px;overflow:hidden} .jx-mconds .jx-conds{border-top:0} .jx-flyer{height:190px;border-radius:8px;background:var(--c);display:flex;flex-direction:column;justify-content:space-between;padding:14px;color:#fff} .jx-flyer strong{font:700 16px/1.2 var(--disp);color:#fff} .jx-flyer span{font:500 11px/1.4 var(--mono);letter-spacing:.06em;color:#fff} .jx-info{display:flex;flex-direction:column;gap:12px;margin-top:16px} .jx-info div{display:flex;flex-direction:column;gap:3px} .jx-info small{font:500 10px/1.4 var(--mono);letter-spacing:.08em;color:#8494A8} .jx-info span{font:400 13px/1.45 var(--body);color:var(--ink);overflow-wrap:anywhere} .jx-scrim .jx-ics{display:inline-flex;align-items:center;height:42px;padding:0 18px;margin-top:18px;border:0;border-radius:6px;background:var(--blue);color:#fff;font:600 14px/1 var(--body);cursor:pointer} @container jxn (max-width:900px){.jx-hero-in,.jx-cal{grid-template-columns:1fr}.jx-hero-img img{max-height:320px}} @container jxn (max-width:600px){.jx-wrap,.jx-hero-in{padding-left:16px;padding-right:16px}.jx-cell{min-height:54px;padding:5px}.jx-tag{display:none}.jx-dots{display:flex}.jx-subnav .jx-r{margin-left:0}.jx-kv{grid-template-columns:1fr;gap:2px}.jx-band{padding:22px}.jx-month{min-width:0;flex:1}} .jx-form{padding:24px;display:flex;flex-direction:column;gap:18px} .jx-fsec{border:1px solid var(--line);border-radius:8px;overflow:hidden} .jx-fsec>div:first-child{padding:12px 16px;background:var(--bg);border-bottom:1px solid var(--line);font:600 12px/1.2 var(--mono);letter-spacing:.1em;color:var(--c2)} .jx-fgrid{padding:16px;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px} .jx-fl{display:flex;flex-direction:column;gap:6px;font:500 13px/1.4 var(--body);color:var(--text)} .jx-full{grid-column:1/-1} .jx-scrim .jx-fl input:not([type=checkbox]):not([type=radio]),.jx-scrim .jx-fl select,.jx-scrim .jx-fl textarea{width:100%;min-height:42px;padding:8px 12px;border:1px solid #C9CFD9;border-radius:6px;font:400 15px/1.4 var(--body);color:var(--ink);background:#fff;margin:0} .jx-scrim .jx-fl textarea{min-height:84px;resize:vertical} .jx-opts{display:flex;flex-wrap:wrap;gap:8px 18px} .jx-opts label{display:flex;align-items:center;gap:8px;font:400 14px/1.4 var(--body);color:var(--ink)} .jx-opts input{width:17px;height:17px;margin:0} .jx-note{font:400 12px/1.5 var(--body);color:var(--muted)} .jx-alert{padding:12px 14px;border:1px solid #E2A30C;border-radius:6px;background:rgba(226,163,12,.08);font:500 13px/1.55 var(--body);color:var(--ink)} .jx-scrim .jx-submit{align-self:flex-start;display:inline-flex;align-items:center;height:48px;padding:0 24px;border:0;border-radius:6px;background:var(--c);color:#fff;font:700 16px/1 var(--body);cursor:pointer} .jx-done{padding:28px 24px;display:flex;flex-direction:column;gap:10px} .jx-done b{font:700 22px/1.2 var(--disp);color:var(--ink)} .jx-done p{margin:0;font:400 14px/1.6 var(--body);color:var(--text)} @media (max-width:760px){.jx-mbody{grid-template-columns:1fr}} @media (max-width:600px){.jx-fgrid{grid-template-columns:1fr}.jx-form{padding:16px}} @media (max-width:600px){.jx-scrim .jx-kv{grid-template-columns:1fr;gap:2px}}
MUNICIPAL EVENTS · CITY OF JACKSON

What's happening in Jackson

One page for every gathering in the city — council meetings and public hearings, permitted festivals, and the neighborhood events your block is planning. Pick a date, see everything on it.

Holly Jolly Jackson
THIS WEEK AT A GLANCE

MUNICIPAL EVENTS

City-sponsored and sanctioned

All city-sponsored events, division and departmental events approved and sanctioned by the Mayor, City Council meetings, workshops, classes, and public hearings.

SPECIAL EVENTS

Approved by the Special Events Committee

Each listing carries the permit as approved. Open the conditions to see closures, hours, sound and insurance requirements on record.

STREET CLOSURES · PERMITTED SPECIAL EVENTS
COMMUNITY CLEANUP

Neighborhood, waterway, and vacant-lot cleanups

Cleanup projects approved by the Municipal Events Office. Approved cleanups appear on the monthly calendar in green. City support may include bags, gloves, vests, and Solid Waste debris pickup.

COMMUNITY EVENTS

Neighborhood happenings

Submitted by residents, churches, schools, and local businesses, and approved for posting on this page.

MONTHLY CALENDAR

Every event, one grid

Days show a marker per category — Community Cleanup events in green. Click a date to read everything scheduled that day.

SUNMONTUEWEDTHUFRISAT
SELECTED DATE

Post your event on this page

Community submissions are reviewed by the Municipal Events Office. Special events require Special Events Committee approval — submit at least 30 days before the event date. Cleanup projects and volunteers apply here too.

Special Events Application

MUNICIPAL EVENTS WIDGET · VERSION 8

(function () { var root = document.getElementById('jxn-events'); if (!root || root.getAttribute('data-ready')) return; root.setAttribute('data-ready', '1'); var EVENTS = [ { id: "m1", cat: "municipal", title: "City Council regular meeting", date: "2026-11-10", time: "10:00 AM", loc: "Council Chambers, City Hall", host: "Jackson City Council", cost: "Free · open to the public", contact: "robbies@jacksonms.gov", ada: "Chambers are wheelchair accessible. Request interpretation 48 hours ahead.", desc: "Regular meeting of the Jackson City Council. The agenda and supporting documents are posted 72 hours in advance by the Municipal Events Office. Public comment is taken at the start of the meeting; sign in at the Municipal Events table before 10:00 AM." }, { id: "m2", cat: "municipal", title: "Public hearing: FY2027 budget", date: "2026-11-12", time: "5:30 PM", loc: "Council Chambers, City Hall", host: "Office of the Mayor · Department of Administration", cost: "Free · open to the public", contact: "budget@jacksonms.gov", ada: "Wheelchair accessible. Written comment accepted through November 19.", desc: "Second of three public hearings on the proposed FY2027 municipal budget. Department directors present proposed appropriations, followed by resident comment. Copies of the proposed budget are available at the Municipal Events Office and online." }, { id: "m3", cat: "municipal", title: "Passport walk-in extended hours", date: "2026-11-11", time: "8:00 AM – 6:00 PM", loc: "Municipal Events Office, 219 S. President St.", host: "Municipal Events Office", cost: "Federal and city fees apply", contact: "passports@jacksonms.gov · (601) 960-0794", ada: "First-floor service counter. Assistance available on request.", desc: "Extended counter hours for first-time passport applications and renewals. Bring a certified birth certificate, valid photo ID, and a completed DS-11. Photo service is available on site." }, { id: "m4", cat: "municipal", title: "Mayor's youth summer send-off", date: "2026-11-14", time: "11:00 AM – 3:00 PM", loc: "Smith Park", host: "Office of the Mayor · Parks and Recreation", cost: "Free", contact: "youth@jacksonms.gov", ada: "Accessible paths and restrooms. Cooling tent on site.", desc: "City-sponsored send-off for students returning to class: school supply distribution, immunization station, live music from JPS bands, and food from local vendors. Sanctioned by the Mayor's Office." }, { id: "m5", cat: "municipal", title: "Zoning and planning workshop", date: "2026-11-17", time: "1:00 PM", loc: "Warren Hood Building, 2nd floor", host: "Department of Planning and Development", cost: "Free", contact: "planning@jacksonms.gov", ada: "Elevator access from President Street entrance.", desc: "Working session on pending rezoning applications and the proposed update to the sign ordinance. No votes are taken at workshops; recommendations advance to the Planning Board." }, { id: "m6", cat: "municipal", title: "Saturday passport clinic", date: "2026-11-21", time: "9:00 AM – 1:00 PM", loc: "Municipal Events Office", host: "Municipal Events Office", cost: "Federal and city fees apply", contact: "passports@jacksonms.gov", ada: "First-floor service counter.", desc: "Monthly Saturday clinic for residents who cannot apply during the work week. Appointments are recommended but walk-ins are accepted until 12:30 PM." }, { id: "m7", cat: "municipal", title: "Records management training", date: "2026-11-26", time: "2:00 PM", loc: "City Hall, Training Room A", host: "Municipal Events Office", cost: "City employees only", contact: "records@jacksonms.gov", ada: "Wheelchair accessible.", desc: "Departmental training on retention schedules, public records request handling, and the new electronic filing workflow. Required for all department records liaisons." }, { id: "m8", cat: "municipal", title: "Ward 2 special election — sample ballot review", date: "2026-12-01", time: "4:00 PM", loc: "Municipal Events Office", host: "Municipal Events Office · Election Commission", cost: "Free", contact: "elections@jacksonms.gov", ada: "Wheelchair accessible.", desc: "Public review of the sample ballot and voting equipment test for the Ward 2 special election. Candidates and their representatives are invited to observe." }, { id: "s1", cat: "special", title: "Fondren First Thursday", date: "2026-11-12", time: "5:00 – 9:00 PM", loc: "Fondren District, N. State Street", host: "Fondren Renaissance Foundation", cost: "Free admission", contact: "events@fondren.org", ada: "Sidewalk route is accessible; accessible parking on Duling Ave.", desc: "Monthly evening street market with open galleries, sidewalk vendors, and live performances along North State Street.", conditions: [ { k: "PERMIT NO.", v: "SEP-2026-0121" }, { k: "APPROVED", v: "September 24, 2026 — Special Events Committee" }, { k: "PERMITTED HOURS", v: "4:00 PM setup · 5:00–9:00 PM event · 10:30 PM clear" }, { k: "STREET CLOSURE", v: "N. State St. between Duling Ave. and Mitchell Ave." }, { k: "AMPLIFIED SOUND", v: "Approved until 9:00 PM" }, { k: "ALCOHOL", v: "Permitted within marked vendor area only" }, { k: "INSURANCE", v: "Certificate on file · $1M general liability" }, { k: "POLICE DETAIL", v: "2 officers · JPD Precinct 4" } ] }, { id: "s2", cat: "special", title: "Belhaven block party", date: "2026-11-21", time: "4:00 – 8:00 PM", loc: "Pinehurst Street, Belhaven", host: "Greater Belhaven Neighborhood Foundation", cost: "Free", contact: "gbnf@belhaven.org", ada: "Level street surface; accessible restroom on site.", desc: "Neighborhood block party with a shared meal, children's activities, and a fire department open truck.", conditions: [ { k: "PERMIT NO.", v: "SEP-2026-0150" }, { k: "APPROVED", v: "October 8, 2026 — Special Events Committee" }, { k: "PERMITTED HOURS", v: "3:00 PM setup · 4:00–8:00 PM event · 9:00 PM clear" }, { k: "STREET CLOSURE", v: "Pinehurst St. between Poplar Blvd. and Peachtree St." }, { k: "AMPLIFIED SOUND", v: "Approved until 8:00 PM" }, { k: "ALCOHOL", v: "Not permitted" }, { k: "INSURANCE", v: "Certificate on file" }, { k: "SANITATION", v: "2 portable units required · host responsible for removal" } ] }, { id: "s3", cat: "special", title: "Farish Street Heritage Festival", date: "2026-11-28", time: "12:00 – 9:00 PM", loc: "Farish Street Historic District", host: "Farish Street Heritage Foundation", cost: "Free · vendor fees apply", contact: "info@farishheritage.org", ada: "Accessible seating at the main stage; shuttle from Mill Street lot.", desc: "Full-day festival of blues, gospel, and Delta food in the Farish Street Historic District, with a juried arts market and a children's stage.", conditions: [ { k: "PERMIT NO.", v: "SEP-2026-0148" }, { k: "APPROVED", v: "October 1, 2026 — Special Events Committee" }, { k: "PERMITTED HOURS", v: "8:00 AM setup · 12:00–9:00 PM event · 11:00 PM clear" }, { k: "STREET CLOSURE", v: "Farish St. from Amite St. to Griffith St. · 6:00 AM–11:00 PM" }, { k: "AMPLIFIED SOUND", v: "Approved until 9:00 PM · 85 dB limit at property line" }, { k: "ALCOHOL", v: "Permitted · licensed vendors, fenced area, ID check required" }, { k: "INSURANCE", v: "Certificate on file · $2M general liability" }, { k: "POLICE DETAIL", v: "8 officers · JPD Precinct 1" }, { k: "FIRE MARSHAL", v: "Tent and cooking inspection November 27, 3:00 PM" } ] }, { id: "s4", cat: "special", title: "JXN half marathon and 5K", date: "2026-12-05", time: "6:30 AM start", loc: "Start and finish at Smith Park", host: "Mississippi Track Club", cost: "Registration required", contact: "race@mstrackclub.org", ada: "Accessible viewing at the finish line.", desc: "Half marathon and 5K on a certified course through downtown, Belhaven, and Fondren, finishing at Smith Park.", conditions: [ { k: "PERMIT NO.", v: "SEP-2026-0155" }, { k: "APPROVED", v: "October 22, 2026 — Special Events Committee" }, { k: "PERMITTED HOURS", v: "5:00 AM staging · 6:30 AM start · 11:30 AM course reopen" }, { k: "STREET CLOSURE", v: "Rolling closure on posted course · see route map" }, { k: "AMPLIFIED SOUND", v: "Approved 6:00–11:00 AM at start/finish only" }, { k: "ALCOHOL", v: "Not permitted" }, { k: "INSURANCE", v: "Certificate on file · USATF sanction" }, { k: "POLICE DETAIL", v: "14 officers plus motor unit · JPD" }, { k: "NOTICE TO RESIDENTS", v: "Door hangers distributed on course by November 28" } ] }, { id: "c1", cat: "community", title: "Small business Saturday pop-up market", date: "2026-11-14", time: "10:00 AM – 2:00 PM", loc: "Georgia Blue lot, Fondren", host: "JXN Makers Collective", cost: "Free admission", contact: "hello@jxnmakers.com", ada: "Paved lot, accessible parking available.", desc: "Twenty local makers and food vendors under one tent. Card and cash accepted at most booths." }, { id: "c2", cat: "community", title: "Back-to-school backpack giveaway", date: "2026-11-15", time: "1:00 PM – 4:00 PM", loc: "New Hope Baptist Church", host: "New Hope Baptist Church", cost: "Free", contact: "outreach@newhopejackson.org", ada: "Accessible entrance on Watkins Drive.", desc: "Free backpacks and supplies for JPS students in grades K–8 while supplies last. Parents should bring proof of enrollment. Haircuts and a hot meal available on site." }, { id: "c3", cat: "community", title: "Ward 3 neighborhood association meeting", date: "2026-11-18", time: "6:00 PM", loc: "Jackson-Hinds Library, Meeting Room B", host: "Ward 3 Neighborhood Association", cost: "Free", contact: "ward3assoc@gmail.com", ada: "Wheelchair accessible; hearing loop available.", desc: "Monthly association meeting. Agenda includes the paving schedule update, a JPD Precinct 3 report, and planning for the fall cleanup day." }, { id: "c4", cat: "community", title: "Free community health screening", date: "2026-11-24", time: "10:00 AM – 2:00 PM", loc: "Grove Park Community Center", host: "Jackson Medical Mall Foundation", cost: "Free", contact: "screenings@jacksonmedicalmall.org", ada: "Accessible entrance and restrooms.", desc: "Blood pressure, A1C, vision, and hearing screenings with no appointment or insurance required. Spanish-language interpreters on site." }, { id: "k1", cat: "cleanup", title: "Ward 3 cleanup day — Livingston Road corridor", date: "2026-11-13", time: "8:00 AM – 12:00 PM", loc: "Meet at Grove Park Community Center", host: "Ward 3 Neighborhood Association · Solid Waste Division", cost: "Free · supplies provided", contact: "cleanup@jacksonms.gov", ada: "Routes include sidewalk-level segments; all ages welcome with a signed waiver.", desc: "Litter sweep and illegal-dump reporting along the Livingston Road corridor. The City provides bags, gloves, grabbers, and safety vests; Solid Waste collects staged debris Monday morning. Approved under the Community Cleanup program." }, { id: "k2", cat: "cleanup", title: "Belhaven Creek waterway cleanup", date: "2026-11-22", time: "9:00 AM – 1:00 PM", loc: "Laurel Street Park entrance", host: "Friends of Belhaven Creek", cost: "Free · closed-toe shoes required", contact: "info@belhavencreek.org", ada: "Creek-bank terrain is uneven; bank-top sorting stations are accessible.", desc: "Debris removal along a half-mile stretch of Belhaven Creek with sorting for recyclables. Waders and litter grabbers provided for registered volunteers. Approved under the Community Cleanup program." }, { id: "k3", cat: "cleanup", title: "Adopt-A-Spot litter sweep — Medgar Evers Blvd", date: "2026-12-04", time: "7:30 – 10:30 AM", loc: "Meet at Medgar Evers Library lot", host: "JXN Adopt-A-Spot volunteers", cost: "Free", contact: "cleanup@jacksonms.gov", ada: "Sidewalk route; reflective vests provided and required.", desc: "Monthly Adopt-A-Spot sweep of the boulevard medians and sidewalks. High-visibility vests provided; volunteers under 16 must be accompanied by an adult. Approved under the Community Cleanup program." }, { id: "c5", cat: "community", title: "Murrah High School fall open house", date: "2026-12-03", time: "5:30 PM", loc: "Murrah High School auditorium", host: "Murrah High School PTA", cost: "Free", contact: "pta@murrahhs.org", ada: "Auditorium is wheelchair accessible.", desc: "Meet teachers, review the fall schedule, and sign up for volunteer and booster roles. Student ensembles perform in the lobby beforehand." } ]; var CATS = { municipal: { label: 'MUNICIPAL EVENT', tag: 'MUNICIPAL', name: 'Municipal' }, special: { label: 'SPECIAL EVENT · PERMITTED', tag: 'PERMITTED', name: 'Special' }, community: { label: 'COMMUNITY EVENT', tag: 'COMMUNITY', name: 'Community' }, cleanup: { label: 'COMMUNITY CLEANUP', tag: 'CLEANUP', name: 'Cleanup' } }; var MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December']; var MAB = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; var DOWS = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; var DOWF = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']; function pad(n) { return (n < 10 ? '0' : '') + n; } function iso(d) { return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()); } function parse(s) { var p = s.split('-'); return new Date(+p[0], +p[1] - 1, +p[2]); } function esc(s) { return String(s == null ? '' : s).replace(/[&"']/g, function (c) { return { '&': '&', '': '>', '"': '"', "'": ''' }[c]; }); } function shortD(s) { var d = parse(s); return DOWS[d.getDay()].toUpperCase() + ' · ' + MAB[d.getMonth()].toUpperCase() + ' ' + d.getDate(); } function longD(s) { var d = parse(s); return DOWF[d.getDay()] + ', ' + MONTHS[d.getMonth()] + ' ' + d.getDate() + ', ' + d.getFullYear(); } function byCat(c) { return EVENTS.filter(function (e) { return e.cat === c; }).sort(function (a, b) { return a.date b.date ? 1 : 0; }); } function find(id) { for (var i = 0; i < EVENTS.length; i++) if (EVENTS[i].id === id) return EVENTS[i]; return null; } function q(s) { return root.querySelector(s); } var now = new Date(); var TODAY = iso(now); var st = { y: now.getFullYear(), m: now.getMonth(), sel: TODAY, f: { municipal: true, special: true, community: true, cleanup: true }, open: {} }; function kv(c) { return '
' + esc(c.k) + '' + esc(c.v) + '
'; } function tile(e) { var h = '
' + '
' + CATS[e.cat].tag + '' + esc(e.title) + '
' + '
' + shortD(e.date) + ' · ' + esc(e.time) + '' + esc(e.loc) + '
'; if (e.cat === 'special' && e.conditions) { var o = !!st.open[e.id]; h += ''; if (o) h += '
' + e.conditions.map(kv).join('') + '
'; } return h + '
'; } function renderLists() { ['municipal', 'special', 'community', 'cleanup'].forEach(function (c) { var list = byCat(c); q('[data-list="' + c + '"]').innerHTML = list.map(tile).join(''); q('[data-count="' + c + '"]').textContent = list.length + (c === 'special' ? ' permitted' : c === 'municipal' ? ' posted' : ' approved'); }); q('#jx-closures').innerHTML = byCat('special').map(function (e) { var c = (e.conditions || []).filter(function (x) { return x.k === 'STREET CLOSURE'; })[0]; return c ? '
' + shortD(e.date) + '' + esc(e.title) + ' — ' + esc(c.v) + '
' : ''; }).join(''); q('#jx-stats').innerHTML = [['municipal', 'MUNICIPAL EVENTS'], ['special', 'PERMITTED SPECIAL EVENTS'], ['cleanup', 'COMMUNITY CLEANUPS'], ['community', 'COMMUNITY POSTINGS']].map(function (p) { return '
' + byCat(p[0]).length + '' + p[1] + '
'; }).join(''); } function renderWeek() { var start = new Date(now.getFullYear(), now.getMonth(), now.getDate() - ((now.getDay() + 6) % 7)); var end = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 6); var html = '', total = 0; for (var i = 0; i < 7; i++) { var d = new Date(start.getFullYear(), start.getMonth(), start.getDate() + i), key = iso(d); var items = EVENTS.filter(function (e) { return e.date === key; }); total += items.length; html += '
' + DOWS[d.getDay()].toUpperCase() + '' + d.getDate() + '
' + (key === TODAY ? 'TODAY' : '') + (items.length ? items.map(function (e) { return '
' + esc(e.time) + '' + esc(e.title) + '
'; }).join('') : 'No events posted.') + '
'; } q('#jx-week').innerHTML = html; var lbl = MONTHS[start.getMonth()] + ' ' + start.getDate() + ' – ' + (end.getMonth() !== start.getMonth() ? MONTHS[end.getMonth()] + ' ' : '') + end.getDate() + ', ' + end.getFullYear(); q('#jx-weeklabel').textContent = lbl; q('#jx-weekcount').textContent = total + ' EVENTS THIS WEEK'; } function visible() { return EVENTS.filter(function (e) { return st.f[e.cat]; }); } function renderCal() { q('#jx-month').textContent = MONTHS[st.m] + ' ' + st.y; root.querySelectorAll('[data-filter]').forEach(function (b) { b.classList.toggle('off', !st.f[b.getAttribute('data-filter')]); }); var vis = visible(); var lead = new Date(st.y, st.m, 1).getDay(), days = new Date(st.y, st.m + 1, 0).getDate(); var cells = []; for (var i = 0; i < lead; i++) cells.push('
'); for (var n = 1; n <= days; n++) { var key = st.y + '-' + pad(st.m + 1) + '-' + pad(n); var de = vis.filter(function (e) { return e.date === key; }); var tags = '', dots = ''; ['municipal', 'special', 'community', 'cleanup'].forEach(function (c) { var a = de.filter(function (e) { return e.cat === c; }); if (!a.length) return; tags += '' + esc(a.length > 1 ? a.length + ' events' : a[0].title) + ''; dots += ''; }); cells.push('
' + '' + n + '' + tags + (dots ? '' + dots + '' : '') + '
'); } while (cells.length % 7) cells.push('
'); var rows = ''; for (var r = 0; r < cells.length; r += 7) rows += '
' + cells.slice(r, r + 7).join('') + '
'; q('#jx-grid').innerHTML = rows; q('#jx-sellabel').textContent = longD(st.sel); var sel = vis.filter(function (e) { return e.date === st.sel; }); q('#jx-sellist').innerHTML = sel.length ? sel.map(function (e) { return '
' + CATS[e.cat].label + '' + esc(e.title) + '' + esc(e.time) + ' · ' + esc(e.loc) + '
'; }).join('') : '

No events posted on this date. Approved submissions appear here within one business day.

'; } var FORM_EMAIL = 'robbies@jacksonms.gov'; var FORM_EMAIL_LABEL = 'robbies@jacksonms.gov'; var YN = ['Yes', 'No']; var WARDS = ['Ward 1', 'Ward 2', 'Ward 3', 'Ward 4', 'Ward 5', 'Ward 6', 'Ward 7', 'Not sure']; var FORMS = { cleanup: { title: 'Community Cleanup Application', cat: 'cleanup', intro: 'Apply to organize a neighborhood cleanup. Approved cleanups are posted to the Municipal Events calendar in green.', sections: [ { h: '1 · ORGANIZER', f: [ { l: "Organizer's name", req: 1 }, { l: "Organizer's phone #", t: 'tel', req: 1 }, { l: "Organizer's email", t: 'email', req: 1 }, { l: "Organization's name" }, { l: "Is this neighborhood association registered with the City's Neighborhood Services Division via the OpenGov online platform?", t: 'radio', o: YN, full: 1 }, { l: 'If yes, registration number' }, { l: "Neighborhood association's email address", t: 'email' }, { l: "Neighborhood association's website (if applicable)", t: 'url', full: 1 } ] }, { h: '2 · EVENT DETAILS', f: [ { l: 'Event name', req: 1 }, { l: 'Ward', t: 'select', o: WARDS, req: 1 }, { l: 'Desired cleanup date', t: 'date', req: 1 }, { l: 'Alternate cleanup date (in case of inclement weather)', t: 'date' }, { l: 'Start time', t: 'time', req: 1 }, { l: 'End time', t: 'time', req: 1 }, { l: 'Meeting location — street name(s)', req: 1 }, { l: 'Cleanup location(s)', req: 1 } ] }, { h: '3 · SECURITY, SAFETY & SITE', f: [ { l: 'Security & safety: Has AMR, JPD & JFD been notified of the event?', t: 'radio', o: YN, full: 1, note: 'AMR & JFD should be notified of the event and its location in case of an emergency. JPD should be aware to provide additional direct patrol of the proposed cleanup area throughout the event for safety purposes.' }, { l: 'Water & bathrooms available?', t: 'radio', o: YN }, { l: 'Illegal dumping site identified?', t: 'radio', o: YN }, { l: 'Expected # of volunteers', t: 'number', req: 1 }, { l: 'Drop-off location for trash bag collection', req: 1 }, { l: "Volunteers' tasks — list details", t: 'textarea', full: 1 } ] }, { h: '4 · EQUIPMENT & CLEANUP GEAR', f: [ { l: 'Will you have your own equipment?', t: 'radio', o: YN }, { l: 'Cleanup gear needed?', t: 'radio', o: YN }, { l: 'If you have your own equipment, list it', t: 'textarea', full: 1 }, { l: 'Bags needed', t: 'number' }, { l: 'Grabbers needed', t: 'number' }, { l: 'Gloves needed', t: 'number' }, { l: 'Vests needed (mandatory for safety)', t: 'number' }, { alert: 'MANDATORY: After the cleanup is complete, within 3 business days, all gear (except used bags) must be returned to Solid Waste in the Hood Building or Municipal Events in City Hall.' } ] } ] }, volunteer: { title: 'Volunteer Application', cat: 'municipal', intro: "Volunteer with city events, community cleanups, and neighborhood programs. The Municipal Events Office will match you with upcoming opportunities.", sections: [ { h: '1 · CONTACT INFORMATION', f: [ { l: 'Full name', req: 1 }, { l: 'Phone', t: 'tel', req: 1 }, { l: 'Email', t: 'email', req: 1 }, { l: 'Ward (if known)', t: 'select', o: WARDS }, { l: 'Are you 18 or older?', t: 'select', o: ['Yes', 'No — a parent or guardian will accompany me'], req: 1 }, { l: 'Organization or group (if applying as a group)' } ] }, { h: '2 · INTERESTS & AVAILABILITY', f: [ { l: "I'm interested in volunteering with", t: 'checks', full: 1, o: ['Community cleanups', 'City-sponsored events', 'Festivals & special events', 'Youth & school programs', 'Registration & check-in tables', 'Setup & teardown crews'] }, { l: 'General availability', t: 'checks', full: 1, o: ['Weekday daytime', 'Weekday evenings', 'Saturdays', 'Sundays'] }, { l: 'Skills or anything else we should know (CPR certified, CDL, bilingual, etc.)', t: 'textarea', full: 1 } ] }, { h: '3 · ACKNOWLEDGMENT', f: [ { l: 'I understand volunteer activities are unpaid, that I participate at my own risk, and that safety instructions from event staff must be followed at all times.', t: 'agree', full: 1, req: 1 } ] } ] }, event: { title: 'Submit a Community Event', cat: 'community', intro: 'Neighborhood, church, school, and business events are reviewed by the Municipal Events Office before posting. If you have a flyer, attach it to the email that opens after you submit.', sections: [ { h: '1 · EVENT', f: [ { l: 'Event name', req: 1 }, { l: 'Hosted by (organization)', req: 1 }, { l: 'Type of host', t: 'select', o: ['Neighborhood / resident', 'Church', 'School', 'Business', 'Nonprofit', 'Other'] }, { l: 'Location / address', req: 1 }, { l: 'Date', t: 'date', req: 1 }, { l: 'Start time', t: 'time', req: 1 }, { l: 'End time', t: 'time' }, { l: 'Admission / cost' }, { l: 'Description', t: 'textarea', full: 1, req: 1 }, { l: 'Accessibility notes', full: 1 } ] }, { h: '2 · CONTACT', f: [ { l: 'Contact name', req: 1 }, { l: 'Contact email', t: 'email', req: 1 }, { l: 'Contact phone', t: 'tel' }, { l: 'Do you have a flyer to include?', t: 'radio', o: YN } ] } ] } }; var fid = 0; function field(f) { if (f.alert) return '
' + f.alert + '
'; var n = esc(f.l), r = f.req ? ' required' : '', star = f.req ? ' *' : '', cls = 'jx-fl' + (f.full ? ' jx-full' : ''), t = f.t || 'text', id = 'jxf' + (++fid); if (t === 'radio' || t === 'checks') { return '
' + n + star + '' + (f.note ? '' + esc(f.note) + '' : '') + '
' + f.o.map(function (o, i) { return ''; }).join('') + '
'; } if (t === 'agree') return '
'; var input = t === 'textarea' ? '' : t === 'select' ? 'Select…' + f.o.map(function (o) { return '' + esc(o) + ''; }).join('') + '' : ''; return ''; } function openForm(key) { var F = FORMS[key]; if (!F) return; scrim.innerHTML = '
' + 'CITY OF JACKSON · MUNICIPAL EVENTS OFFICE

' + esc(F.title) + '

' + esc(F.intro) + '

' + '

SUBMITTAL DATE: ' + pad(now.getMonth() + 1) + '/' + pad(now.getDate()) + '/' + now.getFullYear() + '

' + '' + F.sections.map(function (sec) { return '
' + esc(sec.h) + '
' + sec.f.map(field).join('') + '
'; }).join('') + '* Required. Submitting opens your email app with this application filled in — press Send to deliver it to the Municipal Events Office.
'; scrim.classList.add('open'); document.documentElement.style.overflow = 'hidden'; scrim.scrollTop = 0; } function submitForm(form) { if (!form.reportValidity()) return; var F = FORMS[form.getAttribute('data-formkey')]; var date = (now.getMonth() + 1) + '/' + now.getDate() + '/' + now.getFullYear(); var data = { _subject: F.title + ' — submitted ' + date, _template: 'table', _captcha: 'false', 'Application': F.title, 'Submittal date': date }; var lines = [F.title.toUpperCase(), 'Submittal date: ' + date, '']; var seen = {}; Array.prototype.forEach.call(form.elements, function (el) { if (!el.name || seen[el.name]) return; seen[el.name] = 1; var vals = Array.prototype.filter.call(form.elements, function (x) { return x.name === el.name && ((x.type !== 'checkbox' && x.type !== 'radio') || x.checked); }) .map(function (x) { return x.value; }).filter(function (v) { return v !== ''; }); var v = vals.length ? vals.join(', ') : '—'; data[el.name] = v; lines.push(el.name + ': ' + v); if (/email/i.test(el.name) && /@/.test(v) && !data._replyto) data._replyto = v; }); var btn = form.querySelector('.jx-submit'); btn.disabled = true; btn.textContent = 'Sending…'; btn.style.opacity = '.7'; var head = '
'; var done = function (ok) { var mail = 'mailto:' + FORM_EMAIL + '?subject=' + encodeURIComponent(F.title) + '&body=' + encodeURIComponent(lines.join('\n')); scrim.querySelector('.jx-modal').innerHTML = ok ? head + 'APPLICATION SENT

' + esc(F.title) + '

Thank you — your application was sent.

The Municipal Events Office received your application on ' + date + ' and will contact you using the information you provided. Questions: ' + FORM_EMAIL_LABEL + ' or (601) 960-0794.

' : head + 'NOT SENT

' + esc(F.title) + '

We couldn\'t send your application.

Your connection may have dropped. You can send it by email instead — the button below opens a message with your answers filled in — or call (601) 960-0794.

Send by email instead
'; }; fetch('https://formsubmit.co/ajax/' + FORM_EMAIL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(data) }).then(function (r) { return r.json().catch(function () { return {}; }).then(function (j) { done(r.ok && String(j.success) !== 'false'); }); }) .catch(function () { done(false); }); } var scrim = document.createElement('div'); scrim.className = 'jx-scrim'; scrim.setAttribute('role', 'dialog'); scrim.setAttribute('aria-modal', 'true'); document.body.appendChild(scrim); function openModal(id) { var e = find(id); if (!e) return; scrim.innerHTML = '
' + '' + CATS[e.cat].label + '

' + esc(e.title) + '

' + '

' + longD(e.date) + ' · ' + esc(e.time) + '

' + esc(e.loc) + '

' + '

' + esc(e.desc) + '

' + (e.conditions ? '
PERMIT AS APPROVED
' + e.conditions.map(kv).join('') + '
' : '') + '
' + '
'; scrim.classList.add('open'); document.documentElement.style.overflow = 'hidden'; var c = scrim.querySelector('.jx-close'); if (c) c.focus(); } function closeModal() { scrim.classList.remove('open'); scrim.innerHTML = ''; document.documentElement.style.overflow = ''; } function ics(e) { var d = e.date.replace(/-/g, ''), nx = parse(e.date); nx.setDate(nx.getDate() + 1); var body = ['BEGIN:VCALENDAR', 'VERSION:2.0', 'PRODID:-//City of Jackson//Municipal Events//EN', 'BEGIN:VEVENT', 'UID:' + e.id + '@jacksonms.gov', 'DTSTAMP:' + d + 'T000000Z', 'DTSTART;VALUE=DATE:' + d, 'DTEND;VALUE=DATE:' + iso(nx).replace(/-/g, ''), 'SUMMARY:' + e.title, 'LOCATION:' + e.loc, 'DESCRIPTION:' + e.time + ' — ' + e.desc.replace(/\n/g, ' '), 'END:VEVENT', 'END:VCALENDAR'].join('\r\n'); var a = document.createElement('a'); a.href = 'data:text/calendar;charset=utf-8,' + encodeURIComponent(body); a.download = e.title.replace(/[^a-z0-9]+/gi, '-').toLowerCase() + '.ics'; document.body.appendChild(a); a.click(); a.remove(); } function handle(t, ev) { var x; if ((x = t.closest('[data-form]'))) { if (ev) ev.preventDefault(); openForm(x.getAttribute('data-form')); return true; } if ((x = t.closest('[data-permit]'))) { var id = x.getAttribute('data-permit'); st.open[id] = !st.open[id]; renderLists(); return true; } if ((x = t.closest('[data-ev]'))) { openModal(x.getAttribute('data-ev')); return true; } if ((x = t.closest('[data-day]'))) { st.sel = x.getAttribute('data-day'); renderCal(); return true; } if ((x = t.closest('[data-filter]'))) { var k = x.getAttribute('data-filter'); st.f[k] = !st.f[k]; renderCal(); return true; } if ((x = t.closest('[data-nav]'))) { st.m += +x.getAttribute('data-nav'); if (st.m 11) { st.m = 0; st.y++; } renderCal(); return true; } return false; } root.addEventListener('click', function (ev) { handle(ev.target, ev); }); root.addEventListener('keydown', function (ev) { if ((ev.key === 'Enter' || ev.key === ' ') && ev.target.getAttribute('role') === 'button') { ev.preventDefault(); if (ev.target.tagName === 'LABEL') ev.target.click(); else handle(ev.target, ev); } }); scrim.addEventListener('click', function (ev) { if (ev.target === scrim || ev.target.closest('.jx-close')) { closeModal(); return; } var b = ev.target.closest('[data-ics]'); if (b) ics(find(b.getAttribute('data-ics'))); }); scrim.addEventListener('submit', function (ev) { ev.preventDefault(); submitForm(ev.target); }); document.addEventListener('keydown', function (ev) { if (ev.key === 'Escape' && scrim.classList.contains('open')) closeModal(); }); var sd = (now.getMonth() + 1) + '/' + now.getDate() + '/' + now.getFullYear(); root.querySelectorAll('.jx-apply form').forEach(function (f) { f.querySelector('.jx-sdate').value = sd; var nx = document.createElement('input'); nx.type = 'hidden'; nx.name = '_next'; nx.value = location.href.split('#')[0] + '#jx-sent'; f.appendChild(nx); }); document.addEventListener('keydown', function (ev) { if (ev.key === 'Escape') root.querySelectorAll('.jx-toggle').forEach(function (t) { t.checked = false; }); }); root.querySelectorAll('.jx-toggle').forEach(function (t) { t.addEventListener('change', function () { if (t.checked) { var o = document.getElementById(t.id.replace('jx-t-', 'jx-apply-')); if (o) o.scrollTop = 0; } }); }); if (location.hash === '#jx-sent') setTimeout(function () { alert('Thank you — your application was sent to the Municipal Events Office.'); }, 300); renderLists(); renderWeek(); renderCal(); })();