Wicket用于添加图像的拖放function

我正在制作一个wicket应用程序,可以管理cashdesk应用程序的一些选项。 其中一个选项是更改selected 产品的图像。

当选择此选项时,用户(管理员)可以从数据库中已存在的图像(SQL)中进行选择,或者如果不存在所需图像,则添加新图像。 不要提到测试名称和令人敬畏的图像(它仍然在测试 -  fase) 不要提到测试名称和令人敬畏的图像(它仍然在测试 – fase)

我更喜欢通过拖放html5演示添加图像[dnd-upload]
(从桌面进入浏览器)

我目前正在使用Wicket-6.2.0wicket-dnd 0.5.0 ,我似乎无法让这个工作! 我能找到的所有例子都来自wicket 2.x或更低。

可以在Wicket-6.2中使用拖放function,但我该如何实现呢?

在wicket中似乎有一些DraggableBehavior ? 欢迎任何帮助!

[UPDATE]

升级到wicket-dnd 0.6

根据您的代码,我编写了自定义Ajax行为。 然而,我简化了它,它在没有拖动黑客的情况下为我工作。

AbstractFileDropAjaxBehavior.java

 public abstract class AbstractFileDropAjaxBehavior extends AbstractDefaultAjaxBehavior { @Override protected void respond(final AjaxRequestTarget target) { RequestCycle requestCycle = RequestCycle.get(); StringValue data = requestCycle.getRequest().getRequestParameters().getParameterValue("data"); String[] base64Data = data.toString().split(";"); String fileName = base64Data[0].substring(base64Data[0].indexOf(':') + 1, base64Data[0].length()); String dataType = base64Data[1].substring(base64Data[1].indexOf(':') + 1, base64Data[1].length()); String binaryData = base64Data[2].substring(base64Data[2].indexOf(',') + 1, base64Data[2].length()); byte[] rawData = DatatypeConverter.parseBase64Binary(binaryData); processFile(fileName, dataType, rawData); } @Override protected void onComponentTag(ComponentTag tag) { tag.put("my:dropcontainer.callback", getCallbackUrl().toString()); tag.put("ondragover", "return false;"); tag.put("ondrop", "return AbstractFileDropAjaxBehavior_upload(event, '#" + tag.getId() + "');"); tag.put("ondragenter", "$('#" + tag.getId() + "').addClass('dropover')"); tag.put("ondragleave", "$('#" + tag.getId() + "').removeClass('dropover')"); } @Override public void renderHead(Component component, IHeaderResponse response) { super.renderHead(component, response); response.render(OnDomReadyHeaderItem.forScript("jQuery.event.props.push('dataTransfer');")); response.render(JavaScriptContentHeaderItem.forScript("function AbstractFileDropAjaxBehavior_upload(e, selector) {\n" + " var files = e.dataTransfer.files;\n" + " \n" + " $.each(files, function(i, file) {\n" + " var reader = new FileReader();\n" + " \n" + " reader.onload = function(input) {\n" + " var fileName = \"fileName:\" + file.name + \";\";\n" + " var base64data = input.target.result;\n" + " \n" + " Wicket.Ajax.post({\n" + " \"u\": $(selector).attr('my:dropcontainer.callback'),\n" + " \"ep\": {\n" + " \"data\" : fileName + base64data,\n" + " },\n" + " });\n" + " \n" + " };\n" + "\n" + " reader.readAsDataURL(file);\n" + " });\n" + " \n" + " $(selector).removeClass('dropover');\n" + " \n" + " return false; \n" + "}\n", "AbstractFileDropAjaxBehavior-script")); } protected abstract void processFile(String fileName, String dataType, byte[] rawData); } 

所以这是答应的答案! (只有代码,但如果您熟悉检票口,则易于理解)

代码可以将文件拖到某个区域,并将其发送到wicket服务器(无论它获得什么文件),这并不总是你想要的(但只是我需要的)。

如果您只想上传一种类型的文件,请在drop.js中添加以下javascript检查:

 // For each file: check if files are images for (i = 0; i < files.length; i++) { if (!files[i].type.match('image.*')) { // Replace with what you need $('#dropAppearance p').html('Hey! Images only'); return false; } } 

文件:
- MyPage.java
- MyPage.html
- DropZone.java
- DropZone.html
- DropZone.properties
- DropAjaxBehavior
- drop.js
- drop.css

二手Libs:
- jQuery.js
- jQuery-ui.js
- 检票口6.2
- slf4j-1.2.16
- log4j-1.2.16
- 番石榴-13.0.1

我没有包括import因为,我很懒

MyPage.java

 public final class MyPage extends Page { /** * Constructor */ public HomePage() { } @Override public void onInitialize() { super.onInitialize(); add(new DropZone("dropZone", 300, 200)); } } 

myPage.html下

     // The following line adds a DropZone 

DropZone.java

 public class DropZone extends Panel { private static final ResourceReference JS_DROP = new JavaScriptResourceReference(DropZone.class, "drop.js"); private static final ResourceReference CSS_DROP = new CssResourceReference(DropZone.class, "drop.css"); private static final ResourceReference JQUERY = new JavaScriptResourceReference(DropZone.class, "jQuery.js"); private static final ResourceReference JQUERY_UI = new JavaScriptResourceReference(DropZone.class, "jQuery-ui.js"); private static final String ID_DROPZONE = "drop-container"; /** * Constructor * * @param id String The component id * @param height int The height of the DropZone component [in pixels] * @param width int The width of the DropZone component [in pixels] */ public DropZone(String id, int width, int height) { super(id); final WebMarkupContainer dropZone = new WebMarkupContainer(ID_DROPZONE); final DropAjaxBehavior dropAjaxBehavior = new DropAjaxBehavior(); dropZone.add(dropAjaxBehavior); dropZone.add(new AttributeModifier("style", new Model("width:" + width + "px;height:" + height + "px;"))); add(dropZone); } @Override public final void renderHead(IHeaderResponse response) { super.renderHead(response); // Important to add jQuery before own javascript response.render(JavaScriptHeaderItem.forReference(JQUERY)); response.render(JavaScriptHeaderItem.forReference(JQUERY_UI)); response.render(JavaScriptHeaderItem.forReference(JS_DROP)); response.render(CssContentHeaderItem.forReference(CSS_DROP)); } } 

DropZone.html

    

[DROPZONE MESSAGE]

DropZone.properties

 drop-message = Drop Files Here 

DropAjaxBehavior.java

 public class DropAjaxBehavior extends AbstractAjaxBehavior { private static final Logger LOG = LoggerFactory.getLogger(DropAjaxBehavior.class); @Override public final void onRequest() { LOG.debug("Received request"); final RequestCycle requestCycle = RequestCycle.get(); processRequest(requestCycle); sendResponse(requestCycle); } private void processRequest(RequestCycle requestCycle) { final WebRequest wr = (WebRequest)requestCycle.getRequest(); final HttpServletRequest hsr = (HttpServletRequest)wr.getContainerRequest(); try { final byte[] data = new byte[hsr.getContentLength()]; ByteStreams.readFully(hsr.getInputStream(), data); // filename:;data:;base64, final String[] base64Data = new String(data).split(";"); final String fileName = base64Data[0].substring(base64Data[0].indexOf(':') + 1, base64Data[0].length()); final String dataType = base64Data[1].substring(base64Data[1].indexOf(':') + 1, base64Data[1].length()); final String binaryData = base64Data[2].substring(base64Data[2].indexOf(',') + 1, base64Data[2].length()); // [in my case] do something if the fileType is an image if (dataType.contains("image")) { final byte[] image = DatatypeConverter.parseBase64Binary(binaryData); DatabaseQuery.addImage(image, fileName); } // But you can make a local file // final File file = new File(fileName); // final ByteArrayInputStream binaryInputstream = new ByteArrayInputStream(image); // final FileOutputStream outputStream = new FileOutputStream(file); // ByteStreams.copy(binaryInputstream, outputStream); // outputStream.close(); } catch (IOException ioe) { LOG.error("IO error while reading HttpServletRequest: ", ioe); } } private void sendResponse(RequestCycle requestCycle) { // Just some response requestCycle.scheduleRequestHandlerAfterCurrent(new TextRequestHandler("text/html", "UTF-8", "done")); } @Override protected final void onComponentTag(ComponentTag tag) { tag.put("my:dropcontainer.callback", getCallbackUrl().toString()); } } 

drop.css

 #dropContainer { background-color: #FFFFFF; border: 4px dashed #C9C9C9; -moz-box-sizing: border-box; box-sizing: border-box; position: absolute; } #dropAppearance { height: 100%; width: 100%; display: table; box-sizing: border-box; } #dropAppearance p { display: table-cell; vertical-align: middle; text-align: center; font-size: 2em; color: #797979; } 

drop.js

 $(document).ready( function() { // Makes sure the dataTransfer information is sent when we // Drop the item in the drop box. jQuery.event.props.push('dataTransfer'); // As far as i know Firefox needs to cancel this event (otherwise it // opens // dropped files in the browser) $('#dropContainer').attr('ondragover', "return false"); $('#dropContainer').bind( 'drop', function(e) { // Files that have been dragged into the drop area var files = e.dataTransfer.files; // Upload each file $.each(files, function(i, file) { var reader = new FileReader(); reader.onload = function(input) { var fileName = "fileName:" + file.name + ";"; var base64data = input.target.result; $.ajax({ url : $('#dropContainer').attr( 'my:dropcontainer.callback'), type : 'post', cache : false, // Add date before raw base64 file data data : fileName + base64data, processData : false, contentType : false, }); }; // decode into base64 reader.readAsDataURL(file); }); return false; }); // Using little dragging hack because of the HTML5 spec problem // URL: // http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html // works like: //  // dragging = 0 //  // dragging = 1 //  // dragging = 2 //  // dragging = 1 //  // dragging = 0 //  var dragging = 0; $('#dropContainer').bind('dragenter', function() { dragging++; setHoverDropContainer(); return false; }); $('#dropContainer').bind('dragleave', function() { dragging--; if (dragging === 0) { resetHoverDropContainer(); } return false; }); $('#dropContainer').bind('drop', function() { dragging = 0; // reset dragging hack resetHoverDropContainer(); return false; }); }); function setHoverDropContainer() { // change colors with smooth transition setCSS('#dropContainer', { 'border-color' : '#0000FF', 'background-color' : '#EDF4FE', '-webkit-transition' : 'background-color 0.6s ease', '-moz-transition' : 'background-color 0.6s ease', '-o-transition' : 'background-color 0.6s ease', 'transition' : 'background-color 0.6s ease', '-webkit-transition' : 'border-color 0.6s ease', '-moz-transition' : 'border-color 0.6s ease', '-o-transition' : 'border-color 0.6s ease', 'transition' : 'border-color 0.6s ease' }); } function resetHoverDropContainer() { // change colors with smooth transition setCSS('#dropContainer', { 'border-color' : '#C9C9C9', 'background-color' : '#FFFFFF', '-webkit-transition' : 'background-color 0.6s ease', '-moz-transition' : 'background-color 0.6s ease', '-o-transition' : 'background-color 0.6s ease', 'transition' : 'background-color 0.6s ease', '-webkit-transition' : 'border-color 0.6s ease', '-moz-transition' : 'border-color 0.6s ease', '-o-transition' : 'border-color 0.6s ease', 'transition' : 'border-color 0.6s ease' }); } function setCSS(element, values) { $(element).css(values); } }