Input validation #86
8 changed files with 66 additions and 36 deletions
|
@ -119,6 +119,11 @@ table {
|
|||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.input-error {
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
|
||||
@media (max-width: 1250px) {
|
||||
|
||||
.wrapper {
|
||||
|
|
|
@ -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;
|
|
@ -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);
|
||||
})
|
||||
};
|
||||
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
});
|
|
@ -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');
|
||||
}
|
||||
}
|
|
@ -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='<video autoplay controls><source src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" /></video>'/>
|
||||
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='<video autoplay controls><source src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" /></video>'/>
|
||||
{{else}}
|
||||
<input type="text" id="embed-text" class="link" readonly="true" spellcheck="false" value='<img src="https://spee.ch/{{fileInfo.name}}/{{fileInfo.claimId}}" />'/>
|
||||
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='<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/>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
Loading…
Reference in a new issue