1

I was trying to style an apex:inputFile to show the name of the file into the box. here what I came to and it works:

<apex:column headerValue="Insert file" rendered="{!if(fileUpload == true, true, false)}" style="text-align:right" headerClass="headerTextAlign">
    <apex:stylesheet value="{!$Resource.FileInput_slds_copy}"/>
    <apex:inputFile value="{!wrapper.file.Body}" fileName="{!wrapper.file.Name}" id="file" styleClass="assistive-text" onchange="document.getElementById('fileName').textContent = this.files[0].name"/>
    <apex:outputLabel styleClass="file-selector__body" for="file">
        <span class="file-selector__button button button_neutral" id="fileName + {!wrapper.product.id}">
            Upload File
        </span>
    </apex:outputLabel>
</apex:column>

the problem is that there can only be a single element on a page with the same id, and since this is a apex:colomn in an apex:pageBlockTable with the objects being iterated over a List with apex:repeat, there are many span with the same id, resulting in the first button being the only one with an id, and when I upload a file on an other line, the text of the document is always shown on the first line.

image of the table

So I tried to make the id of each of the Span to be a little different, so they can exist.

<span class="file-selector__button button button_neutral" id="fileName + {!wrapper.product.id}">

it works, my elements on my page each have a specific Id now, but I don't know how to reference that Id in my javaScript code so it knows which is the id. How can I manage to do that. Or is there an other olution than changing the Id for my problem?

In other words, I want to get the Id of the product that is a row on the pageBlockTable when I click on a button on that row

2 Answers 2

1

If you REALLY can't get access to the id, you can try this:

<span class="{!'spanfileName' + wrapper.product.id}"></span>

Define your input with a styleClass that will tell the script where to look:

<apex:inputFile 
value="{!temp}"
id="file" 
styleClass="{!'fileName' + wrapper.product.id}" assistive-text"
onchange="getFile(this);"/>

In the script, find the element and append:

<script>
  function getFile(source) {
    console.log('hey');
    let element = document.getElementsByClassName('span' + source.classList[0])[0];
    element.textContent = source.files[0].name;
  }
</script>
4
  • I dont think I can reference {!wrapper.product.id} in a javascript tho, I just get an error in my DevTools console: Uncaught SyntaxError: Invalid or unexpected token
    – Alexis
    Jun 30 at 18:32
  • I tried a small function for the onClick event, function test(){console.log('{!$Component.wrapper.product.id}');}. there is not error message, but nothing is printed in the console
    – Alexis
    Jun 30 at 19:14
  • I've got a plan... give me a few mins Jun 30 at 19:46
  • I think I found my problem, function test(){console.log('{!wrapper.product.id}');} is working. I just read somewhere that $Component was nesessary, but it's not true. Sorry for the trouble
    – Alexis
    Jun 30 at 21:04
1

For the Span:

<span class="file-selector__button button button_neutral" id="fileName{!wrapper.product.id}">

For the onchange Event: onchange="document.getElementById('fileName'+'{!wrapper.product.id}').textContent = this.files[0].name"/>

this way, the Ids are unique and can be referenced in javaScript, because each Id have a part where it is the Id of the record on a row of a a pageBlockTable

!Important: all the code must be in the onchange field, it must NOT be onchange that calls a JS function. I don't know why, but '{!wrapper.product.id}' always give the same Id if the function in in a script block, while it wors fine when the code is directly written in the onchange.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.