PDA

View Full Version : How to create a FileUploadField with a clear button trigger



Snahrck
27 Feb 2012, 6:16 PM
I tried to adapt the code of this thread with no success:

http://www.sencha.com/forum/showthread.php?83895-ComboBox-with-a-possibility-to-clear-value&p=743472#post743472
(http://www.sencha.com/forum/showthread.php?83895-ComboBox-with-a-possibility-to-clear-value&p=743472#post743472)
Anyone knows how to do this or could point me to the right direction?

Thanks in advance.

Snahrck
27 Feb 2012, 8:06 PM
I think I am almost there, but I'm facing two problems:

1 - I could not get the size of the trigger to adjust the size of the input accordingly so I set it to 25
2 - (most important) My trigger never gets the focus and clicking over it fires up the browse button.


public class FileUploadFieldWithClear extends FileUploadField {

protected El trigger;


private final String triggerStyle = "x-form-clear-trigger";
private El span;


@Override
protected void onResize(int width, int height) {
super.onResize(width, height);

//Could not read the value of the trigger width so I set it to 25
getInputEl().setWidth(getInputEl().getWidth() - 25, true);
}

@Override
protected void afterRender() {
super.afterRender();
addStyleOnOver(trigger.dom, "x-form-trigger-over");
}


@Override
protected void onRender(Element target, int index) {


trigger = new El(DOM.createImg());
trigger.dom.setClassName("x-form-trigger " + triggerStyle);
trigger.dom.setPropertyString("src", GXT.BLANK_IMAGE_URL);


span = new El(DOM.createSpan());
span.dom.setClassName("x-form-triggers");


span.appendChild(trigger.dom);


super.onRender(target, index);

el().appendChild(span.dom);

DOM.sinkEvents(trigger.dom, Event.ONCLICK | Event.MOUSEEVENTS);
}

@Override
public void onComponentEvent(ComponentEvent ce) {


super.onComponentEvent(ce);

int type = ce.getEventTypeInt();
//ce.getTarget() is never equal to trigger.dom
if ((ce.getTarget() == trigger.dom) && (type == Event.ONCLICK)) {
onTriggerClick(ce);
}
}

protected void onTriggerClick(ComponentEvent ce) {
setValue(null);
clearInvalid();
fireEvent(Events.TriggerClick, ce);
}
}

Any comment is welcome.

Snahrck
1 Mar 2012, 5:31 PM
The trigger was some how behind the other components, but still showing up.

setting zindex did the trick: trigger.setZIndex(4);

Here is the hole component including a fix to remove the "fakepath" from the inputfield:



package com.extjs.gxt.ui.client.widget.form;


import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;


public class FileUploadFieldWithClear extends FileUploadField {


protected El trigger;


private final String triggerStyle = "x-form-clear-trigger";
private El span;


@Override
protected void onResize(int width, int height) {
super.onResize(width, height);


// Could not read the value of the trigger width so I set it to 25
getInputEl().setWidth(getInputEl().getWidth() - 25, true);
}


@Override
protected void afterRender() {
super.afterRender();
addStyleOnOver(trigger.dom, "x-form-trigger-over");
}


@Override
protected void onRender(Element target, int index) {

trigger = new El(DOM.createImg());
trigger.dom.setClassName("x-form-trigger " + triggerStyle);
trigger.dom.setPropertyString("src", GXT.BLANK_IMAGE_URL);

span = new El(DOM.createSpan());
span.dom.setClassName("x-form-triggers");

span.appendChild(trigger.dom);

super.onRender(target, index);

el().appendChild(span.dom);

DOM.sinkEvents(trigger.dom, Event.ONCLICK | Event.MOUSEEVENTS);

//Added to fix focus problem
trigger.setZIndex(4);
}


@Override
public void onComponentEvent(ComponentEvent ce) {
super.onComponentEvent(ce);

int type = ce.getEventTypeInt();
if ((ce.getTarget() == trigger.dom) && (type == Event.ONCLICK)) {
onTriggerClick(ce);
}
}

protected void onTriggerClick(ComponentEvent ce) {
setValue(null);
clearInvalid();
fireEvent(Events.TriggerClick, ce);
}

// this is to remove the "fakepath" from the inputfield
@Override
protected void onChange(ComponentEvent ce) {
final String fullPath = getFileInput().getValue();
final int lastIndex = fullPath.lastIndexOf('\\');
final String fileName = fullPath.substring(lastIndex + 1);
setValue(fileName);
}
}


If you need to do something else, other than clearing the input field, just add a listner to the TriggerClick event:



fileUploadField.addListener(Events.TriggerClick, new Listener<ComponentEvent>() {
public void handleEvent(ComponentEvent event) {
fileUploadField.setToolTip("Click 'Browse' to select a file");
fileUploadField.setEmptyText("No file selected");
}
});


Se the attached image of the component.

Snahrck
31 Mar 2012, 2:06 PM
This code works nice in chrome but the trigger appears misplaced in firefox.
Here is a fix so that it works in both browsers (I have not tested this in any other):



@Override
protected void onResize(int width, int height) {
super.onResize(width, height);


// Could not read the value of the trigger width so I use 25
getInputEl().setWidth(getInputEl().getWidth() - 25, true);
trigger.setLeft(getInputEl().getWidth());
}