How to change the button label text of widget created by selectFileInput()

Hi all,

Very simple question, apologies.

When I use createFileInput() in p5.js, the label on the button is always “Choose Files”, and I just can’t find a way to change the dang thing. I suppose createFileInput() creates a button and a label to show the currently selected file, but I can’t fathom how to get to the button. Flailing around here …

  fileSelect = createFileInput(handleFile, "label");

  fileSelect.position(123, 456 );

// Try to change the button label.

  fileSelect.attribute("label", "Load");
  fileSelect.attribute("id", "Load");
  fileSelect.attribute("name", "Load");
  fileSelect.attribute("value", "Load");
  fileSelect.attribute("text", "Load");
  fileSelect.attribute("display", "Load");
  fileSelect.value("");
  fileSelect.elt.label = "Load";
  fileSelect.elt.name = "Load";
  fileSelect.elt.id = "Load";
  // fileSelect.elt.attribute("label", "Load");
  fileSelect.elt.style.fontSize = "24";  // This changes the size of the label text, but not button
  fileSelect.elt.label = "Load";
  fileSelect.elt.name = "Load";
  fileSelect.elt.id = "Load";
  fileSelect.elt.text = "Load";

You can see I’m not great with the gory innards of widgets. Any help appreciated.
Ciao.

Hello @grege2,

No need to apologize. Customizing the HTML file input is actually notoriously tricky. One has to resort to all kinds of trickery to get it done. The basic idea is to hide the element using CSS and then build your own custom “button” to style as you want. This should get you started:

const label = createElement('label', 'Fake button');
const fileSelect = createFileInput(handleFile);

label.child(fileSelect);
fileSelect.hide();

There’s a more elaborate example on MDN Web Docs.

2 Likes

Great, thanks @Sven . I’m trying it now. Plus I’m up early here in Aus (5am) watching the SpaceX launch in the background. No particular reason, just woke early, but a notable event.

1 Like

Programming and Falcon 9 launch – sounds like a pretty good morning to me. :slight_smile:

Yes it was, although you know how the launch ended :=( but that’s ok, don’t want to risk lightning.

Thanks @Sven for the pointers on the fileInput. I’m making good progress on that. But I’ve hit another thing - if you try to select the same file twice, the onchange() event doesn’t fire, because technically it’s the same file as last time. A bit crazy, but maybe there’s some use case where that is reasonable. I’ve found loads of stuff on StackOverflow etc. about it but not a simple solution yet.

Yeah, like it or not, that’s just how change is intended to work according to the specification: “The change event occurs when a control loses the input focus and its value has been modified since gaining focus.”

Lucky for us, there’s a simple workaround. We just have to modify the value ourselves, like this:

let fileSelect; 

function setup() {
  fileSelect = createFileInput(handleFile);
}

function handleFile(file) {
  // Do something interesting with file.
  
  // Reset value, to allow selecting the same file again.
  fileSelect.value('');
}

Thanks again @Sven that worked fine. I came across that idea on Stack Overflow but couldn’t get it going, strangely. The trouble with Stack Overflow is every answer is vastly complicated, with every writer trying to outdo or contradict the previous. If you ask for a simple one-line solution to something, they just can’t do it. Ciao.

2 Likes

Ok folks and @Sven, to repay the help I received, here’s a sketch with a simple solution to this problem. Hope it helps someone else. Ciao tutti.

https://editor.p5js.org/grege2/sketches/4jMmZ-UYk

1 Like

I forgot to say, I abandoned the idea of changing the button label away from “Choose File”, I decided I could live with that.