2

I'm trying to put a custom css on a plugin loaded only by "div" so i can't change it

The plugin output is:

<input type="file" name="file" accept=".jpg,.jpeg,.gif,.png">

i need to set it to be

<input type="file" id="file" name="file" accept=".jpg,.jpeg,.gif,.png">

using javascript

I've already tried

<script type="text/javascript">
    document.getElementsByName('file')[0].setAttribute('id','file');
</script>

and it returns Uncaught TypeError: Cannot read property 'setAttribute' of undefined

Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
Sheilem
  • 59
  • 5
  • 1
    That should work. You can also just use `.id='file'` – Barmar Apr 05 '18 at 00:20
  • it is working .. – Taki Apr 05 '18 at 00:20
  • The Element has to Exist to access it with JavaScript. If that's in the head, `addEventListener('load', fuction(){ /* put your code in here */ });`. – StackSlave Apr 05 '18 at 00:21
  • Are you getting any error in the Javascript console? – Barmar Apr 05 '18 at 00:21
  • 2
    It might be the problem here: https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element – Barmar Apr 05 '18 at 00:23
  • The problem with statements like `But with no luck` is that they provide no information. For future reference, all browsers have what is known as a *Developers Tools Console* - mostly accessible using F12 key. This console is an invaluable tool for developers such as yourself, as errors are output to this, so that you could say, instead of *with no luck* something more meaningful like *I get an error in the console which says `TypeError: document.getElementsByName(...)[0] is undefined`* for example – Jaromanda X Apr 05 '18 at 00:33
  • @JaromandaX Im not an expert and new to stackoverflow I forgot to mention that it returns Uncaught TypeError: Cannot set property 'id' of null – Sheilem Apr 05 '18 at 00:36
  • I'm surprised that `document.getElementsByName('file')[0]` is `null`! should be `undefined` or an element, not null! what browser are you using? – Jaromanda X Apr 05 '18 at 00:37
  • @JaromandaX My Mistake, It returns null after i changed it to querySelector With getElementsByName it returns Uncaught TypeError: Cannot read property 'setAttribute' of undefined – Sheilem Apr 05 '18 at 00:40
  • right ... so, the issue is that you are running the javascript BEFORE the element exists in the DOM ... I bet your script tag is ABOVE the element you are trying to change – Jaromanda X Apr 05 '18 at 00:41
  • 1
    So, Barmar's link - i.e. https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element should be where you are looking for a clue :p – Jaromanda X Apr 05 '18 at 00:42
  • @JaromandaX No, the script tag comes after.. I'm looking for clues :) – Sheilem Apr 05 '18 at 00:50
  • Really? because [this fiddle with script below input](https://jsfiddle.net/7gdtsbf6/) works - where as [this fiddle with the script above the input](https://jsfiddle.net/cbw7u0jh/) behaves as you describe – Jaromanda X Apr 05 '18 at 00:54

5 Answers5

2

As an alternate CSS option, you could wrap your div and used nested styles, for example.

<div id="container"> 
  <div> // Generated stuff</div>
</div>

Then in your styles

#container {
  // General styling
}

#container > div > input {
  // Other styles 
}
John Pavek
  • 2,595
  • 3
  • 15
  • 33
0

Are you able to wrap the input element in another element, say a div, of your own making? If so, you can give the div an id; use the id to get an object reference to the div; then use the .firstChild property of the div object to reference the input element. Then assign the input element object an id. For example:

    <div id="d1">
    <input type="file" name="file" accept=".jpg,.jpeg,.gif,.png">
    </div>

    <script>
    let d = document.getElementById("d1");
    let ip = d.firstChild;
    ip.id = "file";
    </script>
Syntax Junkie
  • 589
  • 6
  • 13
  • Tried that, I can't add a div id, but it already came with a div class so i used document.getElementsByClassName("d1")[0]; and returned with Uncaught TypeError: Cannot read property 'firstChild' of undefined – Sheilem Apr 05 '18 at 00:49
0

You want to use document.querySelector(), which, unlike document.getElementsByName() returns a DOM element (the first one to match the selector), not a DOM element collection. And instead of using the name, let's use a selector that is really unlikely to be found on any other element in your page:

let el = document.querySelector('[accept=".jpg,.jpeg,.gif,.png"]');
el.id = 'mahFile'

let el = document.querySelector('[accept=".jpg,.jpeg,.gif,.png"]');
el.id = 'mahFile';
console.log(el.getAttribute('id'))
<input type="file" name="file" accept=".jpg,.jpeg,.gif,.png">

That's how I would select that element.
But, as Jaromanda realized, your problem is that, in fact, the element is not yet present in DOM at the time you run your script. Depending on how much time it takes to load that script, the following might or might not work:

Since you don't have the ability to call a function when your script loads, you might as well check if the element was added to the page. If it hasn't, try again after another second:

<script type="text/javascript">
  function maybeAddId() {
    let el = document.querySelector('[accept=".jpg,.jpeg,.gif,.png"]');
    if (el) {
      el.id = 'mahFile';
      console.log('Success!', el.getAttribute('id'))
    } else {
      console.log('element is not yet in DOM...')
      setTimeout(maybeAddId, 1000);
    }
  }
  maybeAddId();
</script>

<input type="file" name="file" accept=".jpg,.jpeg,.gif,.png">

Feel free to run it more often than 1 second.

tao
  • 82,996
  • 16
  • 114
  • 150
  • Thanks for the downvote. Now read my answer and please tell me why you consider it bad. – tao Apr 05 '18 at 00:35
  • Alternative methods of doing the same thing wont help if the original code is trying to change an element that does not yet exist :p – Jaromanda X Apr 05 '18 at 00:35
  • @Jaro, and you figured it out from *"but with no luck"*? I always wondered what that phrase really meant. – tao Apr 05 '18 at 00:37
  • No, I figured it out from `returns Uncaught TypeError: Cannot set property 'id' of null` in a comment to an answer :p (and now a similar one in the question) – Jaromanda X Apr 05 '18 at 00:38
  • Thanks (again) for downvoting the answer for answering the question without regard to knowledge that was about to be added in. – tao Apr 05 '18 at 00:40
  • the comment I referred to is on an answer (that is basically the same as yours), and the comment itself actually predates your answer by 7 minutes – Jaromanda X Apr 05 '18 at 00:47
  • as for your edit ... while taht may be a solution, you could just move the script block below the input element you want to change – Jaromanda X Apr 05 '18 at 00:51
  • I placed it up on purpose, so the first time would be unsuccessful, to demonstrate the principle :) – tao Apr 05 '18 at 00:52
  • fair enough - I'd add that there's a much simpler solution though:p – Jaromanda X Apr 05 '18 at 00:53
  • @Jaro, knock yourself out. I'll be back to my movie and delete this in about an hour, hoping it was helpful to OP. Cheers! – tao Apr 05 '18 at 00:53
  • meh, never mind - no downvote now, so all is right in the world – Jaromanda X Apr 05 '18 at 00:55
  • @AndreiGheorghiu It works. Genius. – Sheilem Apr 05 '18 at 01:44
  • @Gal, yes, you can do [anything](https://stackoverflow.com/questions/2739667/add-another-class-to-a-div-with-javascript) with JavaScript. Has its pitfalls, tho. Do note trying something every 1 second until you succeed is not exactly the pinnacle of best practice. Effective, but far from how development should be done. – tao Apr 05 '18 at 02:22
0

try this:

  var el = document.querySelectorAll("[name='file']");
  el.setAttribute("id", "file");

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute

Krysdow
  • 53
  • 5
-2

This is a much simpler approach:

document.querySelector("input[type='file']").id = "file";
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71