add dynamic form contents with JS enabled

by default all content is enabled and displayed, this allows users
without javascript enabled to still use the form and understand what is
happening.

users with javascript enabled will see actions and options
disabled until the files selected allow, and show information and
warnings about zip files in needed.
This commit is contained in:
Rob Loranger 2019-08-26 11:24:38 -07:00
parent 232d6b56c9
commit 44d2a9585b
No known key found for this signature in database
GPG key ID: D6F1633A4F0903B8
4 changed files with 95 additions and 15 deletions

View file

@ -6,5 +6,6 @@
@import "effects";
@import "admin";
@import "pages/error";
@import "pages/import";
@import "lib/elements";
@import "lib/material";

18
less/pages/import.less vendored Normal file
View file

@ -0,0 +1,18 @@
form.import-form {
display: flex;
flex-direction: column;
align-items: center;
&span.row {
justify-content: space-around;
}
input[type=file] {
width: 100%;
align-self: center;
}
input[type=submit] {
width: 100%;
margin-top: .5rem;
}
}

49
static/js/import.js Normal file
View file

@ -0,0 +1,49 @@
const selectElem = document.querySelector('select[name="collection"]');
const submitElem = document.querySelector('input[type="submit"]');
const zipInfo = document.querySelector('span.zip > ul.info');
const zipWarning = document.querySelector('span.zip > p.error');
const fileInput = document.querySelector('input[type="file"]')
document.onreadystatechange = () => {
if ( document.readyState === "complete") {
selectElem.disabled = true;
submitElem.disabled = true;
zipInfo.hidden = true;
zipWarning.hidden = true;
}
}
fileInput.onchange = function() {
if ( this.files.length === 1 ) {
if ( this.files[0].type === 'application/zip' ) {
selectElem.disabled = true;
submitElem.disabled = false;
zipInfo.hidden = false;
zipWarning.hidden = true;
} else if ( this.files[0].type.match('text.*')) {
selectElem.disabled = false;
submitElem.disabled = false;
zipInfo.hidden = true;
zipWarning.hidden = true;
}
}
if ( this.files.length > 1 ) {
selectElem.disabled = false;
submitElem.disabled = false;
var zips = 0;
Array.from(this.files).forEach(file => {
if ( file.name.endsWith(".zip") ) {
zips++;
}
})
if ( zips > 0 ) {
zipInfo.hidden = true;
zipWarning.hidden = false;
} else {
zipInfo.hidden = true;
zipWarning.hidden = true;
}
}
}

View file

@ -8,22 +8,33 @@
</div>
{{end}}
<h2 id="posts-header">Import</h2>
<p>Upload text or markdown files to import as posts.</p>
<div class="formContainer">
<form id="importPosts" class="import" enctype="multipart/form-data" action="/api/me/import" method="POST">
<p>This form allows you to import posts from files on your computer.</p>
<p>Any number text or markdown files are supported, as well as zip archives of posts.</p>
<div>
<form class="import-form" enctype="multipart/form-data" action="/api/me/import" method="POST">
<label for="file" hidden>Browse files to upload</label>
<input class="fileInput" name="files" type="file" multiple accept="text/markdown, text/plain, application/zip"/>
<br />
<label for="collection">Select a blog to import the posts under.</label>
<select name="collection">
{{range $i, $el := .Collections}}
<option value={{.Alias}}>
{{if .Title}}{{.Title}}{{else}}{{.Alias}}{{end}}
</option>
{{end}}
<option value="" selected>drafts</option>
</select>
<br />
<input name="files" type="file" multiple accept="text/*, application/zip"/>
<span class="row">
<label for="collection">Select a blog to import the posts under.</label>
<select name="collection">
{{range $i, $el := .Collections}}
<option value={{.Alias}}>
{{if .Title}}{{.Title}}{{else}}{{.Alias}}{{end}}
</option>
{{end}}
<option value="" selected>drafts</option>
</select>
</span>
<span class="row zip">
<p class="error">
WARNING: zip files must be uploaded separately, one at a time.
</p>
<ul class="info">
<li>Root level zip files are imported as drafts</li>
<li>ZIP sub-directories are imported as blog collections.<br/>
If no blog exists matching the sub-directory name, one will be created if possible.</li>
</ul>
</span>
<input type="submit" value="Import" />
</form>
</div>
@ -35,4 +46,5 @@
</div>
{{template "footer" .}}
<script src="/js/import.js"></script>
{{end}}