Input validation #86

Merged
bones7242 merged 3 commits from input-validation into master 2017-07-14 18:14:52 +02:00
8 changed files with 66 additions and 36 deletions

View file

@ -119,6 +119,11 @@ table {
word-wrap: break-word;
}
.input-error {
font-weight: bold;
color: red;
}
@media (max-width: 1250px) {
.wrapper {

View file

@ -17,7 +17,6 @@ function toggleSection(event){
}
}
// create a progress animation
function createProgressBar(element, size){
var x = 1;
var adder = 1;
@ -55,3 +54,26 @@ function dataURItoBlob(dataURI) {
return new Blob([ia], {type:mimeString});
}
function showError(elementId, errorMsg) {
var errorDisplay = document.getElementById(elementId);
errorDisplay.hidden = false;
errorDisplay.innerText = errorMsg;
}
// Create new error objects, that prototypically inherit from the Error constructor
function FileError(message) {
this.name = 'FileError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
FileError.prototype = Object.create(Error.prototype);
FileError.prototype.constructor = FileError;
function NameError(message) {
this.name = 'NameError';
this.message = message || 'Default Message';
this.stack = (new Error()).stack;
}
NameError.prototype = Object.create(Error.prototype);
NameError.prototype.constructor = NameError;

View file

@ -11,7 +11,13 @@ function publishSelectedImage(event) {
try {
validateSubmission(stagedFiles, name);
} catch (error) {
alert(error.message);
if (error.name === 'FileError'){
showError('input-error-file-selection', error.message);
} else if (error.name === 'NameError') {
showError('input-error-claim-name', error.message);
} else {
showError('input-error-publish-submit', error.message);
}
return;
}
// make sure the name is available then start the upload
@ -20,7 +26,7 @@ function publishSelectedImage(event) {
uploader.submitFiles(stagedFiles); //note: must pass the file as part of an array.
})
.catch(function(error) {
alert(error);
showError('input-error-claim-name', error);
})
};

View file

@ -47,19 +47,4 @@ socket.on('publish-complete', function(msg){
publishResults += '<a href="/meme-fodder/play"><button>Reload</button></a></p>';
// update publish area
document.getElementById('publish-active-area').innerHTML = publishResults;
// update the link holder
document.getElementById('direct-link-holder').innerText = 'https://spee.ch' + directUrl;
// enable copy-to-clipboard
var copyBtn = document.querySelector('.copy-button');
copyBtn.addEventListener('click', function(event) {
// select the text
var text = document.getElementById('direct-link-holder');
text.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
} catch (err) {
alert('Oops, unable to copy');
}
});
});

View file

@ -29,16 +29,16 @@ function validateFile(file) {
function validateSubmission(stagedFiles, name){
// make sure only 1 file was selected
if (!stagedFiles) {
throw new Error("Please select a file");
throw new FileError("Please select a file");
} else if (stagedFiles.length > 1) {
throw new Error("Only one file is allowed at a time");
throw new FileError("Only one file is allowed at a time");
}
// validate 'name' field
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
if (invalidCharacters) {
throw new Error(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, and "-" only.');
throw new NameError(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, and "-" only.');
} else if (name.length < 1) {
throw new Error("You must enter a name for your claim");
throw new NameError("You must enter a name for your claim");
}
}
@ -77,7 +77,7 @@ function previewAndStageFile(selectedFile){
try {
validateFile(selectedFile);
} catch (error) {
alert(error.message);
showError('input-error-file-selection', error.message);
return;
}
// set the preview
@ -145,10 +145,10 @@ function stageAndPublish(file) {
var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name);
// validate 'name'
if (invalidCharacters) {
alert(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.');
showError('input-error-claim-name', invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.');
return;
} else if (name.length < 1) {
alert("You must enter a name for your claim");
showError('input-error-claim-name', 'You must enter a name for your claim');
return;
}
// stage files
@ -157,7 +157,7 @@ function stageAndPublish(file) {
if (stagedFiles) {
// make sure only 1 file was selected
if (stagedFiles.length < 1) {
alert("A file is needed");
showError('input-error-file-selection', 'A file is needed');
return;
}
// make sure the content type is acceptable
@ -169,10 +169,10 @@ function stageAndPublish(file) {
uploader.submitFiles(stagedFiles);
break;
default:
alert("Only .png, .jpeg, .gif, and .mp4 files are currently supported");
showError('input-error-publish-submit', 'Only .png, .jpeg, .gif, and .mp4 files are currently supported');
break;
}
} else {
alert("Please select a file");
showError('input-error-file-selection', 'Please select a file');
}
}

View file

@ -6,8 +6,9 @@
<h2 class="subheader">Links</h2>
{{!--direct link to asset--}}
<a href="/{{fileInfo.name}}/{{fileInfo.claimId}}">Direct Link</a>
<div class="input-error" id="input-error-copy-direct-link" hidden="true"></div>
<br/>
<input type="text" id="direct-link" class="link" readonly="true" spellcheck="false" value="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}"/>
<input type="text" id="direct-link" class="link" readonly spellcheck="false" value="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" onclick="select()"/>
<button class="copy-button" data-elementtocopy="direct-link" onclick="copyToClipboard(event)">copy</button>
<br/>
<br/>
@ -15,27 +16,30 @@
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
{{else}}
Markdown
<div class="input-error" id="input-error-copy-markdown-text" hidden="true"></div>
<br/>
<input type="text" id="markdown-text" class="link" readonly="true" spellcheck="false" value='![{{fileInfo.name}}](https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}})'/>
<input type="text" id="markdown-text" class="link" readonly onclick="select()" spellcheck="false" value='![{{fileInfo.name}}](https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}})'/>
<button class="copy-button" data-elementtocopy="markdown-text" onclick="copyToClipboard(event)">copy</button>
<br/>
<br/>
{{/ifConditional}}
{{!-- html text for embedding asset--}}
Embed HTML
<div class="input-error" id="input-error-copy-embed-text" hidden="true"></div>
<br/>
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
<input type="text" id="embed-text" class="link" readonly="true" spellcheck="false" value='&lt;video autoplay controls>&lt;source src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" />&lt;/video>'/>
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='&lt;video autoplay controls>&lt;source src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" />&lt;/video>'/>
{{else}}
<input type="text" id="embed-text" class="link" readonly="true" spellcheck="false" value='&lt;img src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" />'/>
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='&lt;img src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" />'/>
{{/ifConditional}}
<button class="copy-button" data-elementtocopy="embed-text" onclick="copyToClipboard(event)">copy</button>
<br/>
<br/>
{{!-- link to show route for asset--}}
<a href="/show/{{fileInfo.name}}/{{fileInfo.claimId}}">Details Link</a>
<div class="input-error" id="input-error-copy-show-link" hidden="true"></div>
</br>
<input type="text" id="show-link" class="link" readonly="true" spellcheck="false" value="https://spee.ch/show/{{fileInfo.name}}/{{fileInfo.claimId}}"/>
<input type="text" id="show-link" class="link" readonly onclick="select()" spellcheck="false" value="https://spee.ch/show/{{fileInfo.name}}/{{fileInfo.claimId}}"/>
<button class="copy-button" data-elementtocopy="show-link" onclick="copyToClipboard(event)">copy</button>
<br/>
<br/>

View file

@ -3,6 +3,7 @@
<div class="col-left">
<div id="drop-zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
<p>Drag and drop your file here, or choose your file below.</p>
<div class="input-error" id="input-error-file-selection" hidden="true"></div>
<input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
</div>
<div id="asset-preview-holder">
@ -12,7 +13,7 @@
<div class="col-right">
<textarea id="direct-link-holder" hidden="true">No URL yet</textarea>
<div id="publish-active-area">
<div class="input-error" id="input-error-claim-name" hidden="true"></div>
<input type="text" id="publish-name" placeholder="Your claim name" class="form-control">
<p>
<label for="publish-license">License:</label>
@ -25,6 +26,7 @@
<label for="publish-nsfw">NSFW</label>
</p>
<p>
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
<button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button>
<a href="/"><button id="publish-reset">Reset</button></a>
</p>

View file

@ -10,14 +10,20 @@
</div>
<script type ="text/javascript">
function focusThisInput(event){
}
function copyToClipboard(event){
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
var errorElement = 'input-error-copy-text' + elementToCopy;
element.select();
try {
document.execCommand('copy');
} catch (err) {
alert('Oops, unable to copy');
showError(errorElement, 'Oops, unable to copy');
}
}
</script>