ValidForm Builder file type validation - validform

Does anybody know how to validate the file type input.
I have modified (hard coded) the class.vf_file.php input.
$strOutput .= "<input accept=\".pdf,.doc,.docx\" etc----/>\n";
This helps with Google Chrome, but Safari, Firefox ignore the modifications
Preventing users to submit the form if any other type of file is detected would be the ideal solution.
Thank you

I would recommend using a third party file uploading library like Plupload. We always use ValidForm Builder together with Plupload; works like a charm.
However you can use the meta array to implement custom attributes in the <input> tag without having to hardcode anything:
$objForm->addField(
"upload-document",
"Upload Document",
ValidForm::VFORM_FILE,
array(), // Validation array
array(), // Error handling array
array( // Meta array
"fielddata-extensions" => "pdf,doc,docx"
)
);
By prefixing meta keys with the 'field' prefix, you add that specific meta to the <input> field itself instead of it's wrapping <div class='vf__optional'></div>
The above example will output:
<div class="vf__optional">
<label for="upload-image">Upload Image</label>
<input type="hidden" name="MAX_FILE_SIZE" value="2097152">
<input type="file" value="" name="upload-image[]" id="upload-image" class="vf__file" data-extensions="pdf,doc,docx">
</div>
So using a combination of meta and a third party file upload handler, you can actually to pretty cool stuff.
That being said -- I must admit that the file upload field didn't get as much attention as the other field types lately.

Related

How to get the filename of a filepicker.io picture to appear in the input field next to it

I am trying to get the filename of an uploaded picture to appear in the input field next to the picker button (for filepicker.io) . Basically I am trying to find what to put in the value field for the input tag to get the filename to appear once the picture is uploaded. Here is the code I have:
<div class="row margin" id='img-row'>
<input id="filename" disabled="disabled" value="<WHAT DO I PUT HERE?>" class="input" type="text" style="width: 360px;"/>
<input name="img" data-fp-class="form-simple-action-btn filepicker_launcher" data-fp-button-text="Choose Image" data-fp-services="COMPUTER,FACEBOOK,FLICKR,INSTAGRAM,PICASA" data-fp-container="modal" data-fp-mimetypes="image/*" type="filepicker" data-fp-apikey="#################" id='campaign-img-input' value="<php echo h($_POST['img'])"/>
</div>
Thank you for your help! I haven't found any other examples like this in the documentation.
The recommended way to do this would be to bind a function to the onchange event of the filepicker input type. Once the upload occurs, the function will be called, and you can pull the filename out of the e.fpfile attribute.
Alternatively, it may be easier to use the filepicker.pick call directly given that you are interested in customizing the behavior. The widget is great for a drop-in solution in many cases, but if you're looking to customize further I'd recommend using the javascript api directly.

Generate <input type="search" /> using Play! framework

I'm using the Play Framework. I want to use the HTML5 input type 'search'. So, I want to output:
<input type="search" />
I've tried:
#inputText(field = myForm("myField"), 'type -> "search")
but it still kept the type="input"
the method inputText represents an HTML input text (see the source code here).
You have to define your own template to define the input of type search. Take a look at the Play documentation.
#helper.input(myForm("myField")) { (id, name, value, args) =>
<input type="search" name="#name" id="#id" #toHtmlArgs(args)>
}
Most probably your search field will not use many typical things from common form element (like constraints or error messages) so you can just use plain HTML to insert it, and add field's value in the proper attribute (if required at all):
<input type="search" name="myField" value="#myForm("myField").value" />
If it's just a search form (with this only field) you even don't need to wrap it with the Form class
(of course Nico's suggest is advisable in more sophisticated scenarios)
Some helpers you're looking for are avalaible in a play 2 module. The html5 input helpers are not in the core part of the framework because play authors want to keep it light.
Here is the module page on github : https://github.com/loicdescotte/Play2-HTML5Tags

Play 2.0 Nested forms: generate <input id="email"> instead of <input id="user_email">

Posted this to Play user group; I account for the sole view, so hoping to get a view, or perhaps even an answer ;-)
Nested forms are great, but there's one glitch that adds boilerplate to either javascript or scala templates.
For example, given:
#inputText(field = _form("user.email"),
'_label-> "Email Address*",
'class-> "required email",
'placeholder-> "jdoe#gmail.com"
)
the generated input field is something like:
<input id="user_email" name="user.email" ...>
Now, when you want to validate the email address client-side you then have to reference DOM id: $('#user_email')
Where $('#email') would be more natural.
I know I can set the id attrib manually in the template but would prefer to, by default, have the nested name (user in this case) stripped out from the id attrib.
Looking in github views helper directory, I am not finding where I can get access to the generated id (i.e. which file I need to overload and how).
Anyone know how to pull this off and/or have a better approach?
Here is where the field's ID is auto-generated:
https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/data/Form.scala#L274
There's not really any way you can override that behaviour, but you could write your own #inputText helper that strips the "user_" part from the ID when generating the HTML.
Basically copy-paste the default helper and replace
<input type="text" id="#id" ...
with your own code, e.g.
<input type="text" id="#processFieldId(id)" ...
or (untested!):
<input type="text" id="#(id.split('_').last)" ...
Then just import your custom helper in your template, and use it just like you would use #inputText.

How to change a form's action in Lift

I am building a Lift application, where one of the pages is based on the "File Upload" example from the Lift demo at: http://demo.liftweb.net/file_upload.
If you look at the source code for that page... you see that there is a Lift "snippet" tag, surrounding two "choose" tags:
<lift:snippet type="misc:upload" form="post" multipart="true">
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
</choose:post>
<choose:get>
Select a file to upload: <ul:file_upload></ul:file_upload><br >
<input type="submit" value="Upload File">
</choose:get>
</lift:snippet>
The idea is that when a user hits the page for the first time (i.e. a GET request), then Lift will show the form for uploading a file. When the user submits the form (i.e. a POST request to the same page), then Lift instead displays the outcome of the file being processed.
With my application, the new wrinkle is that my "results" POST view needs to also contain a form. I want to provide a text input for the user to enter an email address, and a submit button that when pressed will email information about the processed file:
...
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!-- BEGIN NEW STUFF -->
Output: <br/>
<textarea rows="30" cols="100"><ul:output></ul:output></textarea>
<br/><br/>
Email the above output to this email address:<br/>
<ul:email/><br/>
<input type="submit" value="Email"/>
<!-- END NEW STUFF -->
</choose:post>
...
However, both the GET and POST versions of this page are wrapped by the same Lift-generated form, which has its "action" set to the same snippet in both cases. How can I change this such that in the POST version, the form's action changes to a different snippet?
In a typical web framework, I would approach something like this with an "onclick" event and two basic lines of JavaScript. However, I haven't even begun to wrap my mind around Lift's... err, interesting notions about writing JavaScript in Scala. Maybe I need to go down that route, or maybe there's a better approach altogether.
First, I will suggest you use Lift's new designer friendly CSS binding instead of the custom XHTML tag.
And one thing you should remember when you're using Lift's snippet, is that it is recursive, you could put an lift snippet inside another snippet's HTML block.
For example, if you wish there is another form after POST, then just put it into the block.
<choose:post>
<p>
File name: <ul:file_name></ul:file_name><br >
MIME Type: <ul:mime_type></ul:mime_type><br >
File length: <ul:length></ul:length><br >
MD5 Hash: <ul:md5></ul:md5><br >
</p>
<!--
The following is same as <lift:snippet type="EMailForm" form="post" multipart="true">
-->
<form action="" method="post" data-lift="EMailForm">
<input type="text" name="email"/>
<input type="submit" />
</form>
</choose:post>
Then deal with the email form action at snippet class EMailForm.
Finally, you may pass the filename / minetype and other information by using hidden form element or SessionVar.
I agree with Brian, use Lift's new designer friendly CSS binding.
Use two separate forms, one for the file upload and one for the submitting the email. Use S.seeOther to redirect the user to the second form when the first has finished processing.
I also prefer the new 'data-lift' HTML attribute.
File upload HTML:
<div data-lift="uploadSnippet?form=post">
<input type="file" id="filename" />
<input type="submit" id="submit" />
</div
File upload snippet:
class uploadSnippet {
def processUpload = {
// do your processing
....
if (success)
S.seeOther("/getemail")
// if processing fails, just allow this method to exit to re-render your
// file upload form
}
def render = {
"#filename" #> SHtml.fileUpload(...) &
"#submit" #> SHtml.submit("Upload", processUpload _ )
}
}
GetEmail HTML:
<div data-lift="getEmailSnippet?form=post">
<input type="text" id="email" />
<input type="submit" id="submit" />
</div
Get Email Snippet:
class getEmailSnippet {
def processSubmit = {
....
}
def render = {
"#email" #> SHtml.text(...) &
"#submit" #> SHtml.submit("Upload", processSubmit _ )
}
There's a bit more on form processing in my blog post on using RequestVar's here:
http://tech.damianhelme.com/understanding-lifts-requestvars
Let me know if you want more detail.
Hope that's useful
Cheers
Damian
If somebody comes up with a more elegant (or "Lift-y") approach within the next few days, then I'll accept their answer. However, I came up with a workaround approach on my own.
I kept the current layout, where the view has a GET block and a POST block both submitting to the same snippet function. The snippet function still has an if-else block, handling each request differently depending on whether it's a GET or POST.
However, now I also have a secondary if-else block inside of the POST's block. This inner if-else looks at the name of the submit button that was clicked. If the submit button was the one for uploading a file, then the snippet handles the uploading and processing of the file. Otherwise, if it was the send email submit button shown after the first POST, then the snippet processes the sending of the email.
Not particularly glamorous, but it works just fine.

jQuery ajaxSubmit(): ho to send the form referencing on the fields id, instead of the fields name?

im pretty new to jQuery, and i dont know how to do that, and if it can be done without editing manually the plugin.
Assume to have a simply form like that:
<form action="page.php" method="post">
Name: <input type="text" name="Your name" id="contact-name" value="" />
Email: <input type="text" name="Your email" id="contact-email" value="" />
</form>
When you submit it, both in 'standard' way or with ajaxSubmit(), the values of the request take the label of the field name, so in the page.php i'll have:
$_POST['Your name'];
$_POST['Your email'];
Instead i'll like to label the submitted values with the id of the field:
$_POST['contact-name'];
$_POST['contact-email'];
Is there a way to do that with jquery and the ajaxsubmit() plugin?
And, maybe, there is a way to do it even with the normal usage of a form?
p.s: yes, i know, i could set the name and id attributes of the field both as 'contact-name', but how does two attributes that contain the same value be usefull?
According to the HTML spec, the browser should submit the name attribute, which does not need to be unique across elements.
Some server-side languages, such as Rails and PHP, take multiple elements with certain identical names and serialize them into data structures. For instance:
<input type="text" name="address[]" />
<input type="text" name="address[]" />
If the user types in 1 Infinite Loop in the first box and Suite 45 in the second box, PHP and Rails will show ["1 Infinite Loop", "Suite 45"] as the contents of the address parameter.
This is all related to the name attribute. On the other hand, the id attribute is designed to uniquely represent an element on the page. It can be referenced using CSS using #myId and in raw JavaScript using document.getElementById. Because it is unique, looking it up in JavaScript is very fast. In practice, you would use jQuery or another library, which would hide these details from you.
It is reasonably common for people to use the same attribute value for id and name, but the only one you need to care about for form submission is name. The jQuery Form Plugin emulates browser behavior extremely closely, so the same would apply to ajaxSubmit.
It's the way forms work in HTML.
Besides, Id's won't work for checkboxes and radio buttons, because you'll probably have several controls with the same name (but a different value), while an HTML element's id attribute has to be unique in your document.
If you really wanted, you could create a preprocessor javascript function that sets every form element's name to the id value, but that wouldn't be very smart IMHO.
var name = $("#contact-name").val();
var email = $("#contact-email").val();
$.post("page.php", { contact-name: name, contact-email: email } );
This will let you post the form with custom attributes.