JSFiddle - React, Tailwind, and code Playground
by David Joseph Guzsik
HTML
<input type="button" value="Add file..." id="dupe">
<hr class="divider">
<ol class="template" id="htmlTemplate">
<li>
<form class="upload_form" method="post" enctype="multipart/form-data" action='ajaximage.php' style="height:0;opacity:0;">
<div class="grid-100 grid-parent">
<div class="grid-20">
<div class="coverArtHolder">
<img class="coverArt" alt="Cover Art" src="coverArt.gif">
</div>
<div data-input>
<span>Cover Art</span>
<input type="file" name="cover">
</div>
<div data-input>
<span>Song</span>
<input type="file" name="song">
</div>
</div>
<div class="grid-80 grid-parent">
<div class="grid-50" data-input>
<span>Title</span>
<input type="text" name="title">
</div>
<div class="grid-50" data-input>
<span>Tags</span>
<input type="text" name="tags">
</div>
<br>
<div class="grid-50" data-input>
<span>Artist(s)</span>
<input type="text" name="artist">
</div>
<div class="grid-50" data-input>
<span>Genre</span>
<select name="genre">
<option value="">-- Select One --</option>
<!-- Later JS or PHP should insert the possible genres or use a typeahead script to fetch the possible values etc. -->
</select>
</div>
<div class="grid-100" data-input>
<span>Description (<span class="remain" style="color:hsl(120, 100%, 55%)">1500</span> character<span class="s">s</span> remaining)</span>
<textarea name="desc" maxlength="1500" rows="16"></textarea>
</div>
</div>
</div>
</form>
</li>
</ol>
<ol id="uploadForms"></ol>
CSS
body {
color:#000;
background-color: #fff;
height:100%;
background-image: linear-gradient(rgba(150,150,150,.3) 2px, transparent 2px),
linear-gradient(90deg, rgba(150,150,150,.3) 2px, transparent 2px),
linear-gradient(rgba(100,100,100,.3) 1px, transparent 1px),
linear-gradient(90deg, rgba(100,100,100,.3) 1px, transparent 1px);
background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px;
background-position:-2px -2px, -2px -2px, -1px -1px, -1px -1px;
}
.upload_form {
background-color:rgba(0,0,0,.6);
padding:16px 30px 10px 30px;
border-bottom-left-radius:15px;
border-bottom-right-radius:15px;
margin-bottom:10px;
}
.coverArtHolder img{
width:100%;
}
.coverArtHolder img.loading {
width:60%;
height:60%;
padding:20%;
}
.coverArtHolder span.error {
width:100%;
height:100%;
box-sizing:border-box;
border:4px inset #f00;
background-color:#fff;
color:#000;
display:block;
padding:10px;
}
#uploadForms div[data-input] > * { display:block; width: 100% }
.info {
display:inline;
vertical-align:top;
}
.close {
float:right;
color:white;
margin:10px;
display:block;
cursor:hand;
border-radius:100%;
cursor:pointer;
width:18px;
height:18px;
text-align:center;
-moz-user-select:none;
-webkit-user-select:none;
}
.close:hover {
background-color:rgba(0,0,0,0.5);
}
ol {
counter-reset:li 2;
margin-left:0;
padding-left:0;
}
ol > li {
position:relative;
margin:0 0 6px 2em;
padding: 0px 0px 8px;
list-style:none;
border-top:2px solid #666;
}
ol > li:before {
content:counter(li);
counter-increment:li -1;
position:absolute;
top:-2px;
left:-2em;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
width:2em;
margin-right:8px;
padding:4px;
border-top:2px solid #666;
color:#fff;
background:#666;
font-weight:bold;
font-family:"Helvetica Neue", Arial, sans-serif;
text-align:center;
}
li ol,
li ul {margin-top:6px;}
ol ol...
JavaScript
$('#uploadForms').html($('#htmlTemplate').html());
$('#uploadForms .upload_form').removeAttr('style');
var mainFormheight = $('#uploadForms .upload_form').css('height');
$('#dupe').click(function(){
$('#uploadForms').prepend($('#htmlTemplate').html());
$($('#uploadForms .upload_form')[0]).animate({height:mainFormheight,opacity:1},500,function(){
$(this).css('height','');
});
totalForms();
$(".upload_form").each(function(){
if (typeof $(this).find('a.close')[0] === 'undefined'){
if ($('#uploadForms .upload_form').size() > 1) $(this).children('div.grid-100').prepend('<a class="close">x</a>');
}
});
$(".upload_form").on("click",".close",function(){
$(this).parent().parent().animate({height:0,opacity:0,paddingTop:0,paddingBottom:0},500,function(){
$(this).parent().remove();
totalForms();
});
if ($('#uploadForms .upload_form').size()-1 <= 1) $('#uploadForms .upload_form').find('a.close').remove();
});
});
function totalForms(){
total = $('#uploadForms .upload_form').size();
$("ol").css('counter-reset', 'li ' + (+total + 1));
}