Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

bind() is deprecated. To bind events us on(). bind internally calls on. By using on() directly, yo'll save one extra function call. See this answerthis answer on StackOverflow.

bind() is deprecated. To bind events us on(). bind internally calls on. By using on() directly, yo'll save one extra function call. See this answer on StackOverflow.

bind() is deprecated. To bind events us on(). bind internally calls on. By using on() directly, yo'll save one extra function call. See this answer on StackOverflow.

Bounty Ended with 100 reputation awarded by Ismael Miguel
Used `data()` instead of `attr('data-*')`
Source Link
Tushar
  • 3k
  • 1
  • 21
  • 28
jQuery(document).ready(function($) {
  'use strict';

  $('input:file').each(function() {
    var $this = $(this);
    var $parent = $this.parent();
    var id = $this.attr('id');

    $this.detach();
    $parent.prepend(
      $('<div id="' + id + '_input-group" class="input-group">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn">' + ($this.attrdata('data-label''label') || 'New image:') + '</span>' +
        '</label>' +
        '<input id="' + id + '_path" type="text" class="form-control" readonly="readonly">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn btn-primary">' +
        ($this.attrdata('data-button-label''buttonLabel') || 'Browse') +
        '<div style="display:none;"></div>' +
        '</span>' +
        '</label>' +
        '</div>')
    );

    $this.appendTo('#' + id + '_input-group label:last-child div:last-child');

    var $path = $('#' + id + '_path', $parent).click(function() {
      $this.click();
    });

    $this.on('change.input_file_styler', function() {
      $path.val(this.files[0] ? this.files[0].name : '');
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

<input type="file" id="file" data-label="Select file to upload:" data-button-label="...">
jQuery(document).ready(function($) {
  'use strict';

  $('input:file').each(function() {
    var $this = $(this);
    var $parent = $this.parent();
    var id = $this.attr('id');

    $this.detach();
    $parent.prepend(
      $('<div id="' + id + '_input-group" class="input-group">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn">' + ($this.attr('data-label') || 'New image:') + '</span>' +
        '</label>' +
        '<input id="' + id + '_path" type="text" class="form-control" readonly="readonly">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn btn-primary">' +
        ($this.attr('data-button-label') || 'Browse') +
        '<div style="display:none;"></div>' +
        '</span>' +
        '</label>' +
        '</div>')
    );

    $this.appendTo('#' + id + '_input-group label:last-child div:last-child');

    var $path = $('#' + id + '_path', $parent).click(function() {
      $this.click();
    });

    $this.on('change.input_file_styler', function() {
      $path.val(this.files[0] ? this.files[0].name : '');
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

<input type="file" id="file" data-label="Select file to upload:" data-button-label="...">
jQuery(document).ready(function($) {
  'use strict';

  $('input:file').each(function() {
    var $this = $(this);
    var $parent = $this.parent();
    var id = $this.attr('id');

    $this.detach();
    $parent.prepend(
      $('<div id="' + id + '_input-group" class="input-group">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn">' + ($this.data('label') || 'New image:') + '</span>' +
        '</label>' +
        '<input id="' + id + '_path" type="text" class="form-control" readonly="readonly">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn btn-primary">' +
        ($this.data('buttonLabel') || 'Browse') +
        '<div style="display:none;"></div>' +
        '</span>' +
        '</label>' +
        '</div>')
    );

    $this.appendTo('#' + id + '_input-group label:last-child div:last-child');

    var $path = $('#' + id + '_path', $parent).click(function() {
      $this.click();
    });

    $this.on('change.input_file_styler', function() {
      $path.val(this.files[0] ? this.files[0].name : '');
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

<input type="file" id="file" data-label="Select file to upload:" data-button-label="...">
Source Link
Tushar
  • 3k
  • 1
  • 21
  • 28

Function('return this')()

It took two minutes to me to understand what it does. Let's see what it does step by step

Function('return this')()

This is another way of creating function. An anonymous function which simply returns this object. () at the end of it will invoke this function immediately. This is equivalent to window. Why not just use window instead of writing this mysterious statement.

Do we need IIFE?

IIFE is used to avoid polluting global scope. In the code, there is no code other than window.jQuery(function($){ inside it. Thus, IIFE is not containing any variable or function that could be global. As variables/functions defined inside a function are not accessible from outside of it(provided variables are declared using var keyword), the callback function of window.jQuery(function($){ serves as the container scope.

In simple words, IIFE can be removed safely.

jQuery(function($) {

I, generally don't use the shorthand of ready. It looks confusing for readers who are not familiar with it.

jQuery(document).ready(function() {

is readable. jQuery, call the function when document is ready.

window.jQuery

window here is not required as jQuery is global object and only jQuery will work. No harm in using window but using only jQuery will save some keystrokes.

If you're not using any other library like prototype.js, MooTools, YUI, etc. that also uses $ namespace, you can use $ instead of typing jQuery.

See Avoiding Conflicts with Other Libraries

:file selector

You may use :file pseudo-selector to select <input type="file" /> elements. This again, saves some keystrokes and is readable too.

$('input:file').each(function() {

Caching $this.attr('id')

$this.attr('id') is used 6 times in the code. This can be cached just like you cached $(this) so that, jQuery don't have to read the attribute value again and again.

var id = $this.attr('id'); // Cached the ID of element

and use id in the code.

attr() vs data()

To read the value of data-* attribute, jQuery has provided data() method. Instead of $this.attr('data-button-label'), $this.data('buttonLabel') can be used.

bind()

bind() is deprecated. To bind events us on(). bind internally calls on. By using on() directly, yo'll save one extra function call. See this answer on StackOverflow.

jQuery(document).ready(function($) {
  'use strict';

  $('input:file').each(function() {
    var $this = $(this);
    var $parent = $this.parent();
    var id = $this.attr('id');

    $this.detach();
    $parent.prepend(
      $('<div id="' + id + '_input-group" class="input-group">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn">' + ($this.attr('data-label') || 'New image:') + '</span>' +
        '</label>' +
        '<input id="' + id + '_path" type="text" class="form-control" readonly="readonly">' +
        '<label class="input-group-btn" for="' + id + '">' +
        '<span class="btn btn-primary">' +
        ($this.attr('data-button-label') || 'Browse') +
        '<div style="display:none;"></div>' +
        '</span>' +
        '</label>' +
        '</div>')
    );

    $this.appendTo('#' + id + '_input-group label:last-child div:last-child');

    var $path = $('#' + id + '_path', $parent).click(function() {
      $this.click();
    });

    $this.on('change.input_file_styler', function() {
      $path.val(this.files[0] ? this.files[0].name : '');
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

<input type="file" id="file" data-label="Select file to upload:" data-button-label="...">