Parsley to validate a file was uploaded? - grails

I am using Parsley throughout an application on text fields and selects. Is there a way to use Parsley to validate a file was uploaded within a file input?
<input type="file" name="letterFile1" class="custom-file-input" data-parsley-required="true"/>

You can always write a custom validator, with Parsley.
window.ParsleyConfig = {
validators: {
filerequired: {
fn: function (value, requirements) {
if (value=="") return false;
else return true;
},
priority: 32
}
}
};

Related

How to read file zip using JSZip in Firefox SDK

I want to make addons to work to extract the zip file locally like this (here). But I have a problem when making use firefox SDK. Which can not be read zip because somethings wrong when get path of fileinput and errors unsupported format because dataType not ArrayBuffer.
HTML
<input type="file" name="file" id="import" class="hide" />
myscript.js
var fileInput = document.getElementById('import');
fileInput.addEventListener('change', function(e) {
var zipFileToLoad = fileInput.files[0];
var tampJson = [];
JSZip.loadAsync(zipFileToLoad)
.then(function(zip) {
console.dir(zip);
zip.forEach(function (relativePath, zipEntry) {
if(zipEntry.dosPermissions == null){
alert('Permissions trouble !')
}
if(typeof(zipEntry['_data']['compressedContent']) != 'undefined'){
//var text = String.fromCharCode.apply(null, new Uint8Array(zipEntry['_data']['compressedContent']));
var text = new TextDecoder("utf-8").decode(zipEntry['_data']['compressedContent']);
var dec = text.toString();
var json = JSON.parse(dec);
if(json != null){
var keys = ['name', 'description', 'data', 'created_at', 'updated_at'];
keys.forEach(function(key){
if (key in json){
if(key == keys[keys.length - 1]){
tampJson.push(json);
}
}else{
dialog({
title: "Warning",
description: "<b>Wrong format, </b> are you sure to continue?",
yesButton: "yes",
cancelButton: "No",
yesCallback: function() {
$(this).closest('.overlay').removeClass("active");
},
cancelCallback: function() {
$(this).closest('.overlay').removeClass("active");
return false;
}
});
}
});
}else{
alert('format parse gagal');
}
}
});
if(tampJson.length > 0){
saveByImport(tampJson, 0);
}else{
alert('Oops file empty');
}
}, function (e) {
alert('Oops import fail '+ e);
});
Can't error in console. I just can not ArrayBuffer from fileinput.
This script can work in chrome extension but not work in firefox sdk.
So please help me for solving this problem.
I used an older version of jszip in my addon here. You can use the jszip from my repository and use it the way I did. See here - https://github.com/Noitidart/Chrome-Store-Foxified/blob/master/resources/scripts/MainWorker.js#L195

Setting error message in html with knockout validation

I would like to use knockout-validation by only adding validation rules in HTML5, which works great:
http://jsfiddle.net/gt228dgm/1/
I would then like to change the default error messages generated by the browser (like "This field is required." or "Invalid"). This is pretty easily done in javascript code, But I believe this kind of texts should go into the HTML. Is that possible and how? I guess I'm looking for something like:
<input data-bind='value: firstName, validate: { message: "Please enter first name" }' required pattern="^[A-Za-z]{1,255}$"/></label>
I have implemented a custom knockout binding that solves my issue:
ko.bindingHandlers.validate = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var valueBinding = allBindings().value;
var value = valueAccessor();
if (value) {
valueBinding.extend(value);
}
}
};
The binding then looks like this
<input data-bind='value: firstName, validate: { required: { message: 'Full name is missing' }, pattern: { message: 'Full name should be max. 255 alphanumeric characters' } }' required pattern="^[A-Za-z]{1,255}$"/>
Any other suggestions?
I've been playing these days with knockout validation. For your need, you could use validationMessage binding. Here is an example of your code modified, to use this binding: http://jsfiddle.net/elbecita/gt228dgm/4/
Basically, you'd end up having something like:
<span data-bind="validationMessage: firstName, text: 'Your error.'"></span>
<input data-bind='value: firstName, valueUpdate: "input"' required pattern="^[A-Za-z]{1,255}$" />
I've added the valueUpdate binding just to have the validation message shown immediately. And then, in your javascript code, when you define the validation configuration, be sure to turn to false the insertMessages option. If not, you'll see the default message too.
But... I think is easier and cleaner to do this with the knockout extenders in javascript code, having all custom messages centralized in some sort of constants file, instead of having them scattered through the html.
Anyway, dig into the knockout validation bindings, they may help you with your needs. :)
Proper way to handle custom validation message in KO is to create a custom validation not binding.
Here is an example of simple number validation
ko.validation.rules['integerFormat'] = {
validator: function (value, options) {
if (!value) return true;
var regex = /^\d+$/;
var matches = regex.test(value);
if(matches){
value = parseInt(value,10);
return typeof value== "number" && isFinite(value) && value%1===0;
}else{
return false
}
},
message: app.MyCustomIntegerNotValidMSG
}
app.MyCustomIntegerNotValidMSG is just a variable holding your MSG
You would use this in your ViewModel like this
self.myIntegerToValidate = ko.observable().extend({
integerFormat:{}
});;

Select2 dropdown but allow new values by user?

I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.
I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?
The excellent answer provided by #fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.
Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.
$("select").select2({
tags: true
});
By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
}
});
In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.
$("select").select2({
tags: true,
createTag: function (params) {
return {
id: params.term,
text: params.term,
newOption: true
}
},
templateResult: function (data) {
var $result = $("<span></span>");
$result.text(data.text);
if (data.newOption) {
$result.append(" <em>(new)</em>");
}
return $result;
}
});
For version 4+ check this answer below by Kevin Brown
In Select2 3.5.2 and below, you can use something like:
$(selector).select2({
minimumInputLength:1,
"ajax": {
data:function (term, page) {
return { term:term, page:page };
},
dataType:"json",
quietMillis:100,
results: function (data, page) {
return {results: data.results};
},
"url": url
},
id: function(object) {
return object.text;
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
});
(taken from an answer on the select2 mailing list, but cannot find the link now)
Just for the sake of keep the code alive, I'm posting #rrauenza Fiddle's code from his comment.
HTML
<input type='hidden' id='tags' style='width:300px'/>
jQuery
$("#tags").select2({
createSearchChoice:function(term, data) {
if ($(data).filter(function() {
return this.text.localeCompare(term)===0;
}).length===0)
{return {id:term, text:term};}
},
multiple: false,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:
User searches for value (which makes ajax request to server)
If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
When the form is submitted just check to see if that option is in the db and if not create it before saving.
There is a better solution I think now
simply set tagging to true on the select options ?
tags: true
from https://select2.org/tagging
Improvent on #fmpwizard answer:
//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
if ( $(data).filter( function() {
return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
}).length===0) {
return {id:term, text:term};
}
},
//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined
Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.
var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
ajax: {
url: location_url,
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
results = [];
$.each(data, function(index, item){
results.push({
id: item.location_id,
text: item.location_name
});
});
return {
results: results
};
}
},
//Allow manually entered text in drop down.
createSearchChoice:function(term, results) {
if ($(results).filter( function() {
return term.localeCompare(this.text)===0;
}).length===0) {
return {id:term, text:term + ' [New]'};
}
},
});
I just stumbled upon this from Kevin Brown.
https://stackoverflow.com/a/30019966/112680
All you have to do for v4.0.6 is use tags: true parameter.
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;
In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;
return this.text.localeCompare(term)===0;
will better replace to
return this.text.toLowerCase() === term.toLowerCase();

how to use the groovy controller element in JavaScript

I have
def exception = request.exception.stackTraceLines
in Groovy controller. How can I get the value of the exception in the JavaScript.
If you are adding exception to your return like this.
flash.message = message(exception: 'Error: xxx');
you can get it like this
<div class="message" role="status"> ${flash.message} </div>
just use ${ your flash.your_var_name}
You have multiple options to fix this. When using javascript I usually use a wrapper which can hold the error message/stacktrace. It depends on where and how you want to do the error handling. Example:
def book = new Book(params)
book.validate()
render (contentType: "text/json") {[
"data": book,
"errors": book.hasErrors() ? book.errors : null
]}
Then you can check if "errors" has a value when getting back your JSON to determine if there are errors in the input for instance. (Elvis operator probably works too, book.errors ?: null) Other (uncatched) exceptions I handle in the error callback I usually define in my JavaScript. (jQuery mostly, (with malsup jquery.form.js in this case))
$(function() {
$("form").live("submit", function() {
$(this).ajaxSubmit({
error: function (msg) {
/* Catch hard errors here (500's) */
alert("Error occurred: " + msg);
},
success: function(wrapper) {
if (wrapper.errors != null) {
/* Handle model errors here */
} else {
/* Parse data here */
var book = wrapper.data;
}
}
});
return false;
});
You can also do this
render(template:"book",model:[book:theBook, exception:exception])
Or like this (didnt try, don't know if works)
render(template:"book",model:[book:theBook, exception:exception!=null?exception:""])
and then access from the GSP like this
${exception.getMessage()}

remote-true and js validation

I'm using rails remote=>true for a Form , also I want to add some jquery validation.
I tried the following things, but they didn't work:
$('form').live('submit',function(){
alert('submit')
})
$('form').submit(function () {
alert('subm')
});
In order to validate a form using jquery, you should consider using the jquery.validation plugin.
Example:
$('#someFormId').validate({
rules: {
someFieldId: {
required: true,
},
someFieldContainingEmail: {
required: true,
email: true
}
}
});
However, in your example code you've shown usage of the onSubmit event - you can validate this way as well. Example follows:
$('#someFormId').submit(function(){
var someField = $('#someFieldId');
if (someField.val().length < 2) {
return false;
}
});

Resources