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));
	}