Skip to content

Instantly share code, notes, and snippets.

@Korko
Last active November 18, 2015 15:18
Show Gist options
  • Save Korko/9a35cc83d316be947bce to your computer and use it in GitHub Desktop.
Save Korko/9a35cc83d316be947bce to your computer and use it in GitHub Desktop.
SecretSanta form to select random friend to gift
<?php
if(isset($_POST['submit'])) {
handleForm();
}
else {
displayForm();
}
function displayForm() {
$html = '<html>
<head>
<title>Secret Santa Sorter</title>
<style>
.participant:nth-child(-n+2) a{display: none}
</style>
<script type="text/javascript">
function addParticipant() {
var el = document.getElementsByClassName("participant")[0].cloneNode(true);
var inputs = el.getElementsByTagName("input");
for(i in inputs) {
inputs[i].value = "";
}
document.getElementById("participants").appendChild(el);
}
function removeParticipant(participant) {
var index = Array.prototype.slice.call(document.getElementsByClassName("participant")).indexOf(participant);
participant.parentNode.removeChild(participant);
var parts = document.getElementsByClassName("participant"), select;
for(var i = 0; i < parts.length; i++) {
select = parts[i].getElementsByTagName("select")[0];
if(parseInt(select.options[select.selectedIndex].value, 10) === index) {
select.selectedIndex = 0;
}
for(var j = 0; j < select.options.length; j++) {
if(parseInt(select.options[j].value, 10) === index) {
select.removeChild(select.options[j]);
break;
}
}
}
}
function updateParticipant(participant) {
var index = Array.prototype.slice.call(document.getElementsByClassName("participant")).indexOf(participant);
var parts = document.getElementsByClassName("participant"), select, option, founded;
for(var i = 0; i < parts.length; i++) {
if(i === index) continue;
select = parts[i].getElementsByTagName("select")[0];
founded = false;
for(var j = 0; j < select.options.length; j++) {
if(parseInt(select.options[j].value, 10) === index) {
select.options[j].text = participant.getElementsByTagName("input")[0].value;
founded = true;
}
}
if(!founded) {
option = document.createElement("option");
option.value = index;
option.text = participant.getElementsByTagName("input")[0].value;
select.appendChild(option);
}
}
}
</script>
</head>
<body>';
$html .= '<form action="" method="post">
<fieldset>
<legend>Participants Details</legend>
<ol id="participants">';
$html .= ' <li class="participant">
<input type="text" name="name[]" required="required" placeholder="Name Surname" onblur="updateParticipant(event.target.parentNode)" />
<input type="email" name="email[]" required="required" placeholder="Email" />
<a href="" onclick="removeParticipant(event.target.parentNode.parentNode);return false;"><img src="https://cdn1.iconfinder.com/data/icons/realistiK-new/16x16/actions/edit_remove.png" /></a>
<select name="partner[]"><option value="" disabled="disabled" selected="selected">Partner</option></select>
</li>
<li class="participant">
<input type="text" name="name[]" required="required" placeholder="Name Surname" onblur="updateParticipant(event.target.parentNode)" />
<input type="email" name="email[]" required="required" placeholder="Email" />
<a href="" onclick="removeParticipant(event.target.parentNode.parentNode);return false;"><img src="https://cdn1.iconfinder.com/data/icons/realistiK-new/16x16/actions/edit_remove.png" /></a>
<select name="partner[]"><option value="" disabled="disabled" selected="selected">Partner</option></select>
</li>';
$html .= ' </ol>
<a href="" onclick="addParticipant();return false;"><img src="https://cdn2.iconfinder.com/data/icons/splashyIcons/add_small.png" alt="+" title="Add new participant" /></a><br />
<input type="submit" name="submit" value="Randomize" />';
$html .= ' </fieldset>
</form>
</body>
</html>';
echo $html;
}
function handleForm() {
$participants = array();
for($i=0;$i<count($_POST['name']);$i++) {
$participants[$i] = array('name' => $_POST['name'][$i], 'email' => $_POST['email'][$i], 'partner' => isset($_POST['partner'][$i]) ? $_POST['partner'][$i] : null);
}
$hat = array_keys($participants);
foreach($participants as $i => $participant) {
if(count($hat) !== 2 or !in_array($i+1, $hat)) {
$userHat = array_diff($hat, array($i, $participant['partner']));
$secretSanta = $userHat[array_rand($userHat)];
$participants[$i]['secretsanta'] = $secretSanta;
$hat = array_diff($hat, array($secretSanta));
} else {
// Special case, participants A,B,C, A picked B then B can pick either A or C but if B picks A, then C can only pick C
// So check if next participant left is in the hat. If so, force. If no, random.
$participants[$i]['secretsanta'] = $i+1;
$hat = array_diff($hat, array($i+1));
}
echo $participants[$i]['name']." => ".$participants[$participants[$i]['secretsanta']]['name']."<br />";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment