php - Create optimal form to POST bulk add information to Challonge API
I am using this documentation: https://api.challonge.com/v1/documents/participants/bulk_add
I have figured out to how leverage bulk add by using a multiline textarea, however I cannot figure out have to also add additional information besides just the names. For example, I want to also add miscellaneous information as well.
This works, but I cannot determine how to also gather the additional information:
<form action="bulkadd.php" method="post">
<textarea id='name' name='name' rows='64' cols='25'></textarea>
</form>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
I'd like my resulting array to be:
{"participants": [
{"name": "John Doe", "misc": null},
{"name": "Jane Doe", "misc": "*"},
{"name": "Jenn Doe", "misc": "*"}]
}
I attempted to add a checkbox to set the "misc" as follows: <input type="checkbox" name="sidepot" id="misc" value="*">
, but I couldn't figure out how to synch that up to the correct "name". Any ideas on how to accomplish this?
Answer
Solution:
To relate fields within a form you can use the []
syntax on the elements names - multiple elements of the same name with the square braces in the names act like arrays and have an index. If the other fields also have the square braces the same index can be used to link, say, name[1]
and misc[1]
etc
Some very simple Javascript can be used to clone the relevant HTML so that when the form is actually submitted the fields within each section are relatable to one another. The snippet at the bottom shows the cloning process in action. Note: I used username
here rather than name
for the input element but that was an oversight on my part.
For instance:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>Challonge</title>
<style>
body,body *{box-sizing:border-box;font-family:verdana;}
form{display:block;width:40%;padding:1rem;border:1px solid black;margin:auto;float:left;background:whitesmoke;clear:both;}
section{margin:1rem auto;padding:0.25rem;border:1px dotted gray;background:white;}
label{display:block;margin:0.25rem auto;padding:0.25rem;}
label > input{float:right;padding:0.25rem;}
label:before{content:attr(for);text-transform:capitalize}
[type='submit'],
[type='reset'],
[name='add']{padding:0.5rem;height:3rem}
input[name='add']{font-weight:bold;float:right}
pre{display:block;margin:2rem auto;float:left;clear:both; width:40%;font-size:smaller;}
</style>
</head>
<body>
<form name='challonge' method='post'>
<section>
<label for='username'><input type='text' name='username[]' value='john doe' /></label>
<label for='misc'><input type='text' name='misc[]' value='abc-1' /></label>
</section>
<div>
<input type='submit' />
<input type='reset' />
<input type='button' name='add' value='+' />
</div>
</form>
<script>
document.querySelector('input[name="add"]').addEventListener('click',e=>{
let form=document.forms.challonge;
form.insertBefore( form.querySelector('section').cloneNode( true ), form.querySelector('div') );
});
</script>
<?php
/*
The following PHP emulates what you would put within bulkadd.php
before sending the json data to the challonge api. In effect this
is acting as the form target here for demo.
*/
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['username'] ) ){
// to show raw post data is related by index
printf('<pre>%s</pre>',print_r( $_POST, true ) );
// process the POST data to form desired output
$data=array();
foreach( $_POST['username'] as $index => $name ){
$data[]=array(
'name' => $name,
'misc' => $_POST['misc'][$index]
);
}
$json=json_encode( array( 'participants'=>$data ) );
// to show processed json data
printf('<pre>%s</pre>',print_r( $json, true ) );
}
?>
</body>
</html>
The above yields the following output:
Array
(
[username] => Array
(
[0] => john doe
[1] => jane doe
[2] => jenn doe
)
[misc] => Array
(
[0] => abc-1
[1] => abc-2
[2] => abc-3
)
)
{
"participants":[
{"name":"john doe","misc":"abc-1"},
{"name":"jane doe","misc":"abc-2"},
{"name":"jenn doe","misc":"abc-3"}
]
}
/*
Clone the portion of the form that contains the fields we wish to
include in the final json data. No element should have an ID assigned
unless other steps are taken to account for and prevent duplicate IDs.
*/
document.querySelector('input[name="add"]').addEventListener('click',e=>{
let form=document.forms.challonge;
form.insertBefore( form.querySelector('section').cloneNode( true ), form.querySelector('div') );
});
body,body *{box-sizing:border-box;font-family:verdana;}
form{display:block;width:80%;padding:1rem;border:1px solid black;margin:auto;float:left;background:whitesmoke;clear:both;}
section{margin:1rem auto;padding:0.25rem;border:1px dotted gray;background:white;}
label{display:block;margin:0.25rem auto;padding:0.25rem;}
label > input{float:right;padding:0.25rem;}
label:before{content:attr(for);text-transform:capitalize}
[type='submit'],
[type='reset'],
[name='add']{padding:0.5rem;height:3rem}
input[name='add']{font-weight:bold;float:right}
pre{display:block;margin:2rem auto;float:left;clear:both; width:80%;font-size:smaller;}
<form name='challonge' method='post'>
<section>
<label for='username'><input type='text' name='username[]' value='john doe' /></label>
<label for='misc'><input type='text' name='misc[]' value='abc-1' /></label>
</section>
<div>
<input type='submit' />
<input type='reset' />
<input type='button' name='add' value='+' />
</div>
</form>
Source