0

I'm trying to build an html form with custom styled file inputs. I want the icon of the label to change once the user has selected a file to upload. I came up with some jquery-code but it changes the icon on all of the inputs at once rather then changing it only on the current one.

Does anyone have an idea how to change the icon input by input?

Thanks.

My code:

$("#file-to-upload").change(function(){
 $(".file-upload").css("background", "url(https://css-tricks.com/apple-touch-icon.png) 2% / 45px no-repeat #ececec");
});
input[type="file"] {
    display: none;
}

.file-upload {
 display: block;
 width: 260px;
 padding: 10px 16px 10px 56px;
 border: none;
 outline: none;
 margin-bottom: 10px;
 font: 16px/28px 'Open Sans','Helvetica Neue',Helvetica,sans-serif;
 color: #3f3f3f;
 font-weight: 300;
 background: #ececec;
 -webkit-border-radius: 0;
 cursor: pointer;
 background: url(http://cdn.sstatic.net/stackoverflow/img/favicon.ico?v=4f32ecc8f43d) 2% / 45px no-repeat #ececec;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div><label for="file-to-upload" class="file-upload">File input 1</label>
<input type="file" name="file-to-upload" id="file-to-upload"></div>
<div><label for="file-to-upload" class="file-upload">File input 2</label>
<input type="file" name="file-to-upload" id="file-to-upload"></div>

3 Answers3

2

That's because you querying for ".file-upload" inside handler function, instead of that you can use 'this' which refers the relevant input element, and then use .prev() jQuery's method which refers needed label)

Like this:

$("your-selector").change(function(){
    //$(this).prev();//refers needed label
    $(this).prev().css("background","red");//set element.style to relevant label
});

Important I notice you use multiple times for the same id attribute, which is extremely un-recommended. Because 'id' attribute is used as Element's identifier, so it should be unique on the document. I suggest you to find the time and to read this post: valid id naming

Community
  • 1
  • 1
Nikita Kurtin
  • 4,811
  • 3
  • 41
  • 44
0

Since you have a same css applied for both the divs, you should use $(this) to get the element which is been clicked.

$("#file-to-upload").on('change', function(){
    $(this).parent().find(".file-upload").css("background", "url(https://css-tricks.com/apple-touch-icon.png) 2% / 45px no-repeat #ececec");
});
Karthik
  • 522
  • 3
  • 13
0

the reason is you used same id for both inputs and same class for both labels again. so you can change your code to:

$("#first-file-to-upload").change(function(){
 $("#firstLabel").css("background", "url(https://css-tricks.com/apple-touch-icon.png) 2% / 45px no-repeat #ececec");
});

$("#second-file-to-upload").change(function(){
 $("#secondLabel").css("background", "url(https://css-tricks.com/apple-touch-icon.png) 2% / 45px no-repeat #ececec");
});
input[type="file"] {
    display: none;
}

.file-upload {
 display: block;
 width: 260px;
 padding: 10px 16px 10px 56px;
 border: none;
 outline: none;
 margin-bottom: 10px;
 font: 16px/28px 'Open Sans','Helvetica Neue',Helvetica,sans-serif;
 color: #3f3f3f;
 font-weight: 300;
 background: #ececec;
 -webkit-border-radius: 0;
 cursor: pointer;
 background: url(http://cdn.sstatic.net/stackoverflow/img/favicon.ico?v=4f32ecc8f43d) 2% / 45px no-repeat #ececec;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div><label for="first-file-to-upload" class="file-upload" id="firstLabel">File input 1</label>
<input type="file" name="first-file-to-upload" id="first-file-to-upload"></div>
<div><label for="second-file-to-upload" class="file-upload" id="secondLabel">File input 2</label>
<input type="file" name="second-file-to-upload" id="second-file-to-upload"></div>

also Karthik answered right. but it's not actually a good practice to use same id for multiple elements in a document.

Mohammad Rafigh
  • 660
  • 9
  • 14