Classroom responsibility rotation

Classroom Jobs Wheel

Classroom Jobs Wheel rotates suitable helper roles such as line leader, materials monitor, timekeeper, and board helper in a visible and engaging way.

classroom jobsstudent helpersresponsibility chartfair rotation

It works as a student-helper rotation tool, classroom-role picker, and fair duty selector for daily routines.

Wheel of Names

Elimination: OFF Accumulation: OFF Auto-Spin: OFF Fair Rotation: OFF
Add entries and spin the wheel.
(()=>{ const r=document.currentScript.closest(‘.wnx-spinner’); if(!r||r.dataset.ready)return; r.dataset.ready=’1′; const $=s=>r.querySelector(s),$$=s=>[…r.querySelectorAll(s)]; const params=new URLSearchParams(location.search),cfg=document.querySelector(‘.wnx-config’); const mode=cfg?.dataset.mode||r.dataset.mode||’standard’; const title=cfg?.dataset.title||r.dataset.title||document.querySelector(‘.wn-page h1′)?.textContent||’Wheel of Names’; const raw=params.get(‘wnitems’)||cfg?.dataset.items||r.dataset.items||’Alice~Bob~Charlie~David~Eve~Frank’; const palettes=[ ((cfg?.dataset.palette)||r.dataset.palette||”).split(‘,’).filter(Boolean), [‘#6366f1′,’#8b5cf6′,’#ec4899′,’#f97316′,’#14b8a6′,’#3b82f6’], [‘#ef476f’,’#f78c6b’,’#ffd166′,’#06d6a0′,’#118ab2′,’#7353ba’], [‘#22c55e’,’#06b6d4′,’#3b82f6′,’#8b5cf6′,’#ec4899′,’#f59e0b’] ].filter(x=>x.length>2); let colors=palettes[0]; let entries=raw.split(‘~’).map(v=>{try{return decodeURIComponent(v)}catch(e){return v}}).filter(Boolean).map(v=>{ const p=v.split(‘|’); const weight=mode===’weighted’?Math.max(1,Number(p.pop())||1):1; return{name:p.join(‘|’),weight,count:0,last:-999,image:”}; }); let angle=0,busy=false,history=[],undo=[],redo=[],spinNumber=0,lastReceipt=null,preSpin=[]; let backgroundImage=”,centerImage=”,backgroundOpacity=.45,centerRadius=76,pendingEntryImage=”,pendingEntryFilename=”; const imageCache=new Map(); const canvas=$(‘.wnx-canvas’),ctx=canvas.getContext(‘2d’),spin=$(‘.wnx-spin’),result=$(‘.wnx-result’),list=$(‘.wnx-list’); const elimination=$(‘.wnx-elimination’),accumulation=$(‘.wnx-accumulation’),auto=$(‘.wnx-auto’),winnerCount=$(‘.wnx-winner-count’),duration=$(‘.wnx-duration’); const balance=$(‘.wnx-smart-balance’),cooldown=$(‘.wnx-smart-cooldown’); $(‘.wnx-title’).textContent=title; elimination.checked=mode===’norepeat’||params.get(‘wnremove’)===’1′; winnerCount.value=mode===’multi’?Math.max(1,Number(cfg?.dataset.count||r.dataset.count)||3):1; $(‘.wnx-multi-field’).classList.toggle(‘wnx-hidden’,mode!==’multi’); const escapeHtml=s=>String(s).replace(/[&”‘]/g,m=>({‘&’:’&’,”:’>’,'”‘:’"’,”‘”:’'’}[m])); const snapshot=()=>JSON.stringify(entries); const save=()=>{undo.push(snapshot());if(undo.length>25)undo.shift();redo=[];}; const randomInt=n=>{if(n=limit);return a[0]%n;}; function getImage(src){ if(!src)return null; if(imageCache.has(src))return imageCache.get(src); const img=new Image(); img.onload=draw; img.src=src; imageCache.set(src,img); return img; } function drawCover(img,x,y,w,h){ if(!img||!img.complete||!img.naturalWidth)return; const scale=Math.max(w/img.naturalWidth,h/img.naturalHeight); const dw=img.naturalWidth*scale,dh=img.naturalHeight*scale; ctx.drawImage(img,x+(w-dw)/2,y+(h-dh)/2,dw,dh); } function readOptimizedImage(file,maxSize=1000){ return new Promise((resolve,reject)=>{ if(!file||!file.type.startsWith(‘image/’)){reject(new Error(‘Please choose an image file.’));return;} const reader=new FileReader(); reader.onerror=()=>reject(new Error(‘The image could not be read.’)); reader.onload=()=>{ const img=new Image(); img.onerror=()=>reject(new Error(‘The image format is not supported.’)); img.onload=()=>{ const scale=Math.min(1,maxSize/Math.max(img.naturalWidth,img.naturalHeight)); const w=Math.max(1,Math.round(img.naturalWidth*scale)),h=Math.max(1,Math.round(img.naturalHeight*scale)); const temp=document.createElement(‘canvas’);temp.width=w;temp.height=h; const t=temp.getContext(‘2d’);t.drawImage(img,0,0,w,h); const type=file.type===’image/png’?’image/png’:’image/jpeg’; resolve(temp.toDataURL(type,type===’image/jpeg’?.86:undefined)); }; img.src=String(reader.result||”); }; reader.readAsDataURL(file); }); } const smartOn=()=>!elimination.checked&&(balance.checked||Number(cooldown.value)>0); function eligibleEntries(){ let pool=[…entries]; if(!smartOn())return pool; const cd=Number(cooldown.value); if(cd>0){const cooled=pool.filter(e=>spinNumber-e.last>=cd);if(cooled.length)pool=cooled;} if(balance.checked&&pool.length){const min=Math.min(…pool.map(e=>e.count));pool=pool.filter(e=>e.count===min);} return pool.length?pool:[…entries]; } function segments(){ const total=entries.reduce((s,e)=>s+e.weight,0)||1; let used=0; return entries.map(entry=>{const start=used/total*Math.PI*2;used+=entry.weight;return{entry,start,end:used/total*Math.PI*2};}); } function draw(){ const size=900,center=450,radius=418,segs=segments(),allowed=new Set(eligibleEntries()); ctx.clearRect(0,0,size,size); if(backgroundImage){ const img=getImage(backgroundImage); ctx.save();ctx.beginPath();ctx.arc(center,center,radius,0,Math.PI*2);ctx.clip();ctx.globalAlpha=backgroundOpacity;drawCover(img,center-radius,center-radius,radius*2,radius*2);ctx.restore(); } if(!segs.length){ ctx.beginPath();ctx.arc(center,center,radius,0,Math.PI*2);ctx.fillStyle=’#0b1628′;ctx.fill();ctx.strokeStyle=’rgba(129,140,248,.24)’;ctx.lineWidth=6;ctx.stroke();ctx.fillStyle=’#94a3b8′;ctx.font=’800 34px system-ui’;ctx.textAlign=’center’;ctx.fillText(‘Add entries’,center,center);return; } segs.forEach((seg,index)=>{ const dim=smartOn()&&!allowed.has(seg.entry); const start=seg.start+angle,end=seg.end+angle; ctx.save(); ctx.globalAlpha=dim?.2:1; ctx.beginPath();ctx.moveTo(center,center);ctx.arc(center,center,radius,start,end);ctx.closePath(); if(seg.entry.image){ ctx.save();ctx.clip();drawCover(getImage(seg.entry.image),center-radius,center-radius,radius*2,radius*2);ctx.restore(); ctx.globalAlpha=dim?.12:.22;ctx.fillStyle=colors[index%colors.length];ctx.fill();ctx.globalAlpha=dim?.2:1; }else{ ctx.fillStyle=colors[index%colors.length]; if(backgroundImage)ctx.globalAlpha=dim?.14:.72; ctx.fill();ctx.globalAlpha=dim?.2:1; } ctx.strokeStyle=’rgba(255,255,255,.82)’;ctx.lineWidth=5;ctx.stroke(); const mid=(seg.start+seg.end)/2+angle; ctx.translate(center,center);ctx.rotate(mid);ctx.textAlign=’right’;ctx.fillStyle=’#fff’;ctx.shadowColor=’rgba(0,0,0,.55)’;ctx.shadowBlur=8; ctx.font=`850 ${Math.max(18,Math.min(33,350/entries.length+16))}px system-ui`; const label=seg.entry.name.length>22?seg.entry.name.slice(0,20)+’…’:seg.entry.name; ctx.fillText(label,radius-34,10);ctx.restore(); }); ctx.save();ctx.beginPath();ctx.arc(center,center,centerRadius,0,Math.PI*2);ctx.clip(); if(centerImage){drawCover(getImage(centerImage),center-centerRadius,center-centerRadius,centerRadius*2,centerRadius*2);}else{ctx.fillStyle=’#0b1628′;ctx.fillRect(center-centerRadius,center-centerRadius,centerRadius*2,centerRadius*2);} ctx.restore();ctx.beginPath();ctx.arc(center,center,centerRadius,0,Math.PI*2);ctx.strokeStyle=’rgba(255,255,255,.24)’;ctx.lineWidth=10;ctx.stroke(); } function updateBadges(){ [[ $(‘.wnx-badge-elimination’),elimination,’Elimination’],[$(‘.wnx-badge-accumulation’),accumulation,’Accumulation’],[$(‘.wnx-badge-auto’),auto,’Auto-Spin’],[$(‘.wnx-badge-smart’),{checked:smartOn()},’Fair Rotation’]].forEach(([el,input,label])=>{el.textContent=`${label}: ${input.checked?’ON’:’OFF’}`;el.classList.toggle(‘is-on’,input.checked);}); } function balanceScore(){ if(!entries.length)return 100; const total=entries.reduce((s,e)=>s+e.count,0),mean=total/entries.length; if(!mean)return 100; const deviation=entries.reduce((s,e)=>s+Math.abs(e.count-mean),0)/entries.length; return Math.max(0,Math.round(100-deviation/mean*100)); } function updateDashboard(){ $(‘.wnx-balance-score’).textContent=balanceScore()+’%’;$(‘.wnx-smart-spins’).textContent=String(spinNumber); $(‘.wnx-smart-counts’).innerHTML=[…entries].sort((a,b)=>a.count-b.count||a.name.localeCompare(b.name)).map(e=>`
${escapeHtml(e.name)}${e.count}
`).join(”)||’

No entries yet.

‘; const status=$(‘.wnx-smart-status’); if(elimination.checked&&(balance.checked||Number(cooldown.value)>0))status.textContent=’Smart Fair Rotation is paused while Elimination mode is active.’; else if(!smartOn())status.textContent=’Pure random mode is active.’; else{const parts=[];if(balance.checked)parts.push(‘least-selected priority’);if(Number(cooldown.value)>0)parts.push(`${cooldown.value}-spin cooldown`);status.textContent=`Smart mode active: ${parts.join(‘ + ‘)}. Dimmed slices are temporarily ineligible.`;} } function render(){ list.innerHTML=entries.map((entry,index)=>`
  • ⋮⋮
    ${entry.image?``:”}
    ${entry.weight}
  • `).join(”); $(‘.wnx-undo’).disabled=!undo.length;$(‘.wnx-redo’).disabled=!redo.length;draw();updateBadges();updateDashboard(); } function choose(pool){ const total=pool.reduce((s,e)=>s+e.weight,0);let n=randomInt(total),used=0; for(let i=0;i<pool.length;i++){used+=pool[i].weight;if(nv.toString(16).padStart(2,’0′)).join(”); const bytes=new TextEncoder().encode(text),hash=await crypto.subtle.digest(‘SHA-256′,bytes); return[…new Uint8Array(hash)].map(v=>v.toString(16).padStart(2,’0’)).join(”); } async function createReceipt(selected){ const payload={version:2,site:location.origin,page:location.pathname,timestamp:new Date().toISOString(),spinNumber,result:selected.map(e=>e.name),entries:preSpin,entryImages:selected.map(e=>({name:e.name,hasImage:Boolean(e.image)})),backgroundImage:Boolean(backgroundImage),centerImage:Boolean(centerImage),smartFairRotation:balance.checked,cooldownSpins:Number(cooldown.value),elimination:elimination.checked,accumulation:accumulation.checked,autoSpin:auto.checked}; const hash=await sha256(JSON.stringify(payload));lastReceipt={…payload,sha256:hash,receiptId:’WNR-‘+hash.slice(0,16).toUpperCase()}; $(‘.wnx-receipt-id’).textContent=lastReceipt.receiptId;$(‘.wnx-copy-receipt’).disabled=false;$(‘.wnx-download-receipt’).disabled=false; } function finish(selected){ spinNumber++;selected.forEach(e=>{e.count++;e.last=spinNumber;}); const time=new Date().toLocaleTimeString();history.unshift(`${time} — ${selected.map(e=>e.name).join(‘, ‘)}`); $(‘.wnx-history’).innerHTML=history.map(v=>`
  • ${escapeHtml(v)}
  • `).join(”);$(‘.wnx-empty’).classList.toggle(‘wnx-hidden’,history.length>0); result.textContent=(selected.length>1?’Winners: ‘:’Winner: ‘)+selected.map(e=>e.name+(accumulation.checked?` (${e.count})`:”)).join(‘, ‘); createReceipt(selected); if(elimination.checked){save();const set=new Set(selected);entries=entries.filter(e=>!set.has(e));render();}else{draw();updateDashboard();updateBadges();} busy=false;spin.disabled=false;if(auto.checked&&entries.length)setTimeout(startSpin,1200); } function startSpin(){ if(busy||!entries.length){if(!entries.length)result.textContent=’Add at least one entry.’;return;} busy=true;spin.disabled=true;preSpin=entries.map(e=>({name:e.name,weight:e.weight,hasImage:Boolean(e.image)})); let base=eligibleEntries();if(mode===’multi’&&base.length<Math.max(1,Number(winnerCount.value)||1))base=[…entries]; const pool=[…base],selected=[],wanted=Math.min(pool.length,Math.max(1,Number(winnerCount.value)||1)); for(let i=0;i<wanted;i++){const index=choose(pool);selected.push(pool[index]);pool.splice(index,1);} const segs=segments(),targetIndex=entries.indexOf(selected[0]),middle=(segs[targetIndex].start+segs[targetIndex].end)/2,target=-Math.PI/2-middle,start=angle,delta=((target-start)%(Math.PI*2)+Math.PI*2)%(Math.PI*2)+(5+randomInt(4))*Math.PI*2,ms=Number(duration.value)*1000,startTime=performance.now(); function frame(now){const progress=Math.min(1,(now-startTime)/ms),ease=1-Math.pow(1-progress,3);angle=start+delta*ease;draw();if(progress{if(e.key===’Enter’||e.key===’ ‘){e.preventDefault();startSpin();}}; $(‘.wnx-add-button’).onclick=()=>{const input=$(‘.wnx-new-entry’),value=input.value.trim();if(!value)return;save();entries.push({name:value,weight:1,count:0,last:-999,image:”});input.value=”;render();}; $(‘.wnx-new-entry’).onkeydown=e=>{if(e.key===’Enter’)$(‘.wnx-add-button’).click();}; $(‘.wnx-apply’).onclick=()=>{const values=$(‘.wnx-bulk’).value.split(/n|,/).map(v=>v.trim()).filter(Boolean);if(!values.length)return;save();entries=values.map(name=>({name,weight:1,count:0,last:-999,image:”}));spinNumber=0;render();}; $(‘.wnx-file’).onchange=e=>{const file=e.target.files?.[0];if(!file)return;const reader=new FileReader();reader.onload=()=>{$(‘.wnx-bulk’).value=String(reader.result||”).replace(/,/g,’n’);};reader.readAsText(file);}; $(‘.wnx-shuffle’).onclick=()=>{save();for(let i=entries.length-1;i>0;i–){const j=randomInt(i+1);[entries[i],entries[j]]=[entries[j],entries[i]];}render();}; $(‘.wnx-clear’).onclick=()=>{save();entries=[];spinNumber=0;render();}; $(‘.wnx-undo’).onclick=()=>{if(!undo.length)return;redo.push(snapshot());entries=JSON.parse(undo.pop());render();}; $(‘.wnx-redo’).onclick=()=>{if(!redo.length)return;undo.push(snapshot());entries=JSON.parse(redo.pop());render();}; list.onclick=e=>{const button=e.target.closest(‘[data-act]’);if(!button)return;save();const index=Number(button.dataset.i),action=button.dataset.act;if(action===’remove’)entries.splice(index,1);if(action===’plus’)entries[index].weight++;if(action===’minus’)entries[index].weight=Math.max(1,entries[index].weight-1);render();}; list.onchange=e=>{if(!e.target.matches(‘[data-edit]’))return;save();entries[Number(e.target.dataset.edit)].name=e.target.value.trim()||’Untitled’;render();}; $(‘.wnx-bg-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{backgroundImage=await readOptimizedImage(file,1200);$(‘.wnx-bg-status’).textContent=file.name;$(‘.wnx-remove-bg’).disabled=false;draw();}catch(err){$(‘.wnx-bg-status’).textContent=err.message;}}; $(‘.wnx-bg-opacity’).oninput=e=>{backgroundOpacity=Number(e.target.value)/100;draw();}; $(‘.wnx-remove-bg’).onclick=()=>{backgroundImage=”;$(‘.wnx-bg-file’).value=”;$(‘.wnx-bg-status’).textContent=’No image selected’;$(‘.wnx-remove-bg’).disabled=true;draw();}; $(‘.wnx-center-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{centerImage=await readOptimizedImage(file,600);$(‘.wnx-center-status’).textContent=file.name;$(‘.wnx-remove-center’).disabled=false;draw();}catch(err){$(‘.wnx-center-status’).textContent=err.message;}}; $(‘.wnx-center-size’).oninput=e=>{centerRadius=Number(e.target.value);draw();}; $(‘.wnx-remove-center’).onclick=()=>{centerImage=”;$(‘.wnx-center-file’).value=”;$(‘.wnx-center-status’).textContent=’No image selected’;$(‘.wnx-remove-center’).disabled=true;draw();}; $(‘.wnx-entry-image-file’).onchange=async e=>{const file=e.target.files?.[0];if(!file)return;try{pendingEntryImage=await readOptimizedImage(file,650);pendingEntryFilename=file.name.replace(/.[^.]+$/,”);const preview=$(‘.wnx-entry-image-preview’);preview.querySelector(‘img’).src=pendingEntryImage;preview.querySelector(‘span’).textContent=file.name;preview.hidden=false;$(‘.wnx-add-image-entry’).disabled=false;}catch(err){result.textContent=err.message;}}; $(‘.wnx-add-image-entry’).onclick=()=>{if(!pendingEntryImage)return;const label=$(‘.wnx-image-entry-name’).value.trim()||pendingEntryFilename||’Image entry’;save();entries.push({name:label,weight:1,count:0,last:-999,image:pendingEntryImage});pendingEntryImage=”;pendingEntryFilename=”;$(‘.wnx-image-entry-name’).value=”;$(‘.wnx-entry-image-file’).value=”;$(‘.wnx-entry-image-preview’).hidden=true;$(‘.wnx-add-image-entry’).disabled=true;render();}; $(‘.wnx-reset-images’).onclick=()=>{backgroundImage=”;centerImage=”;pendingEntryImage=”;entries.forEach(e=>e.image=”);$(‘.wnx-bg-file’).value=”;$(‘.wnx-center-file’).value=”;$(‘.wnx-entry-image-file’).value=”;$(‘.wnx-bg-status’).textContent=’No image selected’;$(‘.wnx-center-status’).textContent=’No image selected’;$(‘.wnx-remove-bg’).disabled=true;$(‘.wnx-remove-center’).disabled=true;$(‘.wnx-add-image-entry’).disabled=true;$(‘.wnx-entry-image-preview’).hidden=true;render();}; duration.oninput=()=>{$(‘.wnx-duration-text’).textContent=duration.value;}; [elimination,accumulation,auto,balance,cooldown].forEach(control=>control.onchange=()=>{updateBadges();updateDashboard();draw();}); $(‘.wnx-smart-reset’).onclick=()=>{entries.forEach(e=>{e.count=0;e.last=-999;});spinNumber=0;lastReceipt=null;$(‘.wnx-receipt-id’).textContent=’No receipt yet’;$(‘.wnx-copy-receipt’).disabled=true;$(‘.wnx-download-receipt’).disabled=true;render();}; $(‘.wnx-hide-panel’).onclick=()=>{const panel=$(‘.wnx-panel’);panel.classList.toggle(‘wnx-hidden’);$(‘.wnx-hide-panel’).textContent=panel.classList.contains(‘wnx-hidden’)?’Show Panel’:’Hide Panel’;}; $(‘.wnx-fullscreen’).onclick=()=>r.requestFullscreen?.(); $(‘.wnx-export’).onclick=()=>{const csv=’entry,weight,count,has_imagen’+entries.map(e=>`”${e.name.replace(/”/g,'””‘)}”,${e.weight},${e.count},${e.image?’yes’:’no’}`).join(‘n’),a=document.createElement(‘a’);a.href=URL.createObjectURL(new Blob([csv],{type:’text/csv’}));a.download=’wheel-entries.csv’;a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);}; $(‘.wnx-share’).onclick=async()=>{const url=new URL(location.href);url.searchParams.set(‘wnitems’,entries.map(e=>encodeURIComponent(e.name)+(e.weight>1?’|’+e.weight:”)).join(‘~’));elimination.checked?url.searchParams.set(‘wnremove’,’1′):url.searchParams.delete(‘wnremove’);try{await navigator.clipboard.writeText(url);result.textContent=entries.some(e=>e.image)||backgroundImage||centerImage?’Share link copied. Images stay in this browser session.’:’Share link copied.’;}catch(e){result.textContent=url;}}; $(‘.wnx-copy-receipt’).onclick=async()=>{if(!lastReceipt)return;const text=`${lastReceipt.receiptId}nWinner: ${lastReceipt.result.join(‘, ‘)}nTime: ${lastReceipt.timestamp}nSHA-256: ${lastReceipt.sha256}`;try{await navigator.clipboard.writeText(text);$(‘.wnx-copy-receipt’).textContent=’Copied’;setTimeout(()=>$(‘.wnx-copy-receipt’).textContent=’Copy Receipt’,1200);}catch(e){$(‘.wnx-receipt-id’).textContent=text;}}; $(‘.wnx-download-receipt’).onclick=()=>{if(!lastReceipt)return;const report={receipt:lastReceipt,balanceScore:balanceScore()+’%’,selectionCounts:Object.fromEntries(entries.map(e=>[e.name,e.count]))},a=document.createElement(‘a’);a.href=URL.createObjectURL(new Blob([JSON.stringify(report,null,2)],{type:’application/json’}));a.download=lastReceipt.receiptId+’.json’;a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);}; $$(‘.wnx-tab’).forEach(button=>button.onclick=()=>{$$(‘.wnx-tab’).forEach(x=>x.classList.remove(‘is-active’));$$(‘.wnx-pane’).forEach(x=>x.classList.remove(‘is-active’));button.classList.add(‘is-active’);$(`.wnx-pane[data-pane=”${button.dataset.tab}”]`).classList.add(‘is-active’);if(button.dataset.tab===’smart’)updateDashboard();}); palettes.forEach((palette,index)=>{const button=document.createElement(‘button’);button.type=’button’;button.className=’wnx-palette’+(index?”:’ is-active’);button.style.background=`linear-gradient(135deg,${palette.join(‘,’)})`;button.onclick=()=>{colors=palette;$$(‘.wnx-palette’).forEach(x=>x.classList.remove(‘is-active’));button.classList.add(‘is-active’);draw();};$(‘.wnx-palettes’).append(button);}); render(); })();

    What is classroom-role picker?

    student-helper rotation tool is a free browser-based classroom responsibility rotator for helper roles such as materials, board, library, or line leader. Edit the sample entries, confirm the eligible list, choose the mode that matches the activity, and spin for a visible random result. Only include roles suitable for every listed student, adjust duties for access needs, and use elimination when each role should appear once.

    Plan jobs before assigning them

    Add only roles that are age-appropriate, clearly explained, and possible that day. You can spin a job first and then select an eligible student, or place student names on the wheel and assign roles from a separate chart.

    📦

    Materials

    Hand out and collect approved classroom materials.

    ⏱️

    Timekeeping

    Give friendly reminders during planned activities.

    🧹

    Shared care

    Support simple tidy-up tasks without replacing staff duties.

    Do not assign safety-critical, confidential, heavy, or unsuitable tasks through a random wheel.

    Education resource: UNESCO education resources.

    classroom-role picker FAQs

    How often should jobs rotate?

    Daily or weekly rotation can work. Choose a schedule that students understand and teachers can manage consistently.

    Can I remove completed jobs?

    Yes. The no-repeat mode removes each selected role until the list is reset.

    What if a student cannot perform a job?

    Offer an appropriate alternative rather than forcing the assignment.