Skip to content

Instantly share code, notes, and snippets.

@mrg
Last active May 4, 2016 10:39
Show Gist options
  • Save mrg/6f2bedfcb006dc9bd716 to your computer and use it in GitHub Desktop.
Save mrg/6f2bedfcb006dc9bd716 to your computer and use it in GitHub Desktop.
Tapestry 5(.4) component to re-style a standard HTML upload to be more 21st century.
Put this in your src/main/resources/META-INF/assets/css folder:
.btn-file
{
position: relative;
overflow: hidden;
}
.btn-file input[type=file]
{
position: absolute;
top: 0;
right: 0;
min-width: 100%;
min-height: 100%;
font-size: 999px;
text-align: right;
filter: alpha(opacity = 0);
opacity: 0;
outline: none;
background: white;
cursor: inherit;
display: block;
}
This Tapestry 5.4 component allows you to use a standard HTML upload
input (<input type="file" ... /> -- as produced Tapestry's upload
component), but with a more modern-looking Bootstrap styling.
Screenshot:
https://raw.githubusercontent.com/mrg/mrg-sandbox/master/screenshots/BootstrapUpload.png
This component only includes the upload facility and the parent must
provide the HTML FORM to handle the upload. Currently does not support
multiple file upload (since Tapestry does not).
Example usage:
<t:bootstrapUpload t:value="file" />
The t:value parameter is required and needs to be an instance of
Tapestry's UploadedFile class. You can also provide a t:instructions
parameter to change the help text below the Browse/FilenameUpload row.
Heavily based upon:
http://www.surrealcms.com/blog/whipping-file-inputs-into-shape-with-bootstrap-3
Put this in your src/main/resources/META-INF/modules folder:
define ["jquery"],
($) ->
# Useful shorthands.
emptySelection = "No file selected..."
filenameLabel = $('.btn-file :file').parents('.input-group').find(':text')
# Set the initial filename label values.
filenameLabel.val(emptySelection)
filenameLabel.css("fontStyle", "italic")
# When the file upload value changes, find the text label
# beside the browse button and show the filename to upload.
$('.btn-file :file').on 'change', ->
browseButton = $(this)
filenameLabel = browseButton.parents('.input-group').find(':text')
filesSelected = browseButton.get(0).files.length
filename = browseButton.val().replace(/\\/g, '/').replace(/.*\//, '')
if filesSelected > 0
filenameLabel.val(filename)
filenameLabel.css("fontStyle", "normal")
else
filenameLabel.val(emptySelection)
filenameLabel.css("fontStyle", "italic")
# Exports.
{ }
Put this in your src/main/java/.../app/components package:
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.upload.services.UploadedFile;
/**
* File Upload component which uses Bootstrap 3 for styling. Heavily based upon:
*
* http://www.surrealcms.com/blog/whipping-file-inputs-into-shape-with-bootstrap-3
*
* This component utilizes the standard Tapestry upload component, which in turn
* uses the standard HTML file upload control, therefore it can only handle one
* file.
*/
@Import(module = "BootstrapUpload", stylesheet = "css/bootstrap-upload.less")
public class BootstrapUpload
{
@Parameter(defaultPrefix=BindingConstants.LITERAL, value="Click 'Browse Files...' to select a file to upload and then click 'Upload' to process it.")
@Property
private String instructions;
@Parameter(required=true)
@Property
private UploadedFile value;
}
Put this in your src/main/resources/.../app/components folder:
<!DOCTYPE html>
<t:container xmlns="http://www.w3.org/1999/xhtml"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p="tapestry:parameter">
<div>
<div class="col-md-8">
<span class="input-group">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
<i class="glyphicon glyphicon-folder-open" style="padding-right: 6px;" />
Browse Files...
<input t:type="upload" t:id="upload" t:value="value" t:validate="required" />
</span>
</span>
<input type="text" class="form-control" readonly="true" />
</span>
</div>
<div class="col-md-4">
<t:submit class="btn btn-primary" value="Upload" />
</div>
</div>
<div>
<div class="col-md-12">
<span class="help-block">
${instructions}
</span>
</div>
</div>
</t:container>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment