Why is the choice wrong when file input is hidden?

I was 100% sure that this code works, but in one special case it fails - took an hour to find the error (could not reproduce it on JSFiddle). I finally found the reason, but I do not know why this is happening. This only happens when I hide the input files and the result: which file I am changing, the first shortcut is selected and changed, look:

var activateFileSelection = function( container ) {
    var container = container || $('body');
    container.find(':file').each(function(i) {
        var thisInput = $(this);
        var thisLabel = thisInput.siblings('label');
        if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
            var thisLabelDefaultText = thisLabel.html();
            thisLabel.addClass('file-input-label');
            thisInput.on('change', function(e) {
                if (thisInput.val()) {
                    thisLabel.html(thisInput.val());
                } else {
                    thisLabel.html(thisLabelDefaultText);
                };
            });
        };
    });
};
activateFileSelection();
input {
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <label for="myfile">select 1</label>
    <input id="myfile" type="file" />
</div>
<div>
    <label for="myfile">select 2</label>
    <input id="myfile" type="file" />
</div>
<div>
    <label for="myfile">select 3</label>
    <input id="myfile" type="file" />
</div>
Run code

Also on JSFiddle .

If the input is not hidden, everything works fine: fiddle .

nevermind, , - , script . , , .

+4
4

HTML- , , . for "myfile", , document.getElementById("myfile").

, , . , thisInput.siblings('label') , . , 3 .

, , .

, , .

var activateFileSelection = function (container) {
    var container = container || $('body');
    container.find(':file').each(function (i) {
        var thisInput = $(this);
        var thisLabel = thisInput.siblings('label');
        if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
            var thisLabelDefaultText = thisLabel.html();
            thisLabel.addClass('file-input-label');
            thisInput.on('change', function (e) {
                console.log("Input used: " + thisInput.data("field"));
                if (thisInput.val()) {
                    thisLabel.html(thisInput.val());
                } else {
                    thisLabel.html(thisLabelDefaultText);
                };
            });
        };
    });
};
activateFileSelection();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Test by clicking on label 3 vs clicking on input field 3:</p>
<div>
    <label for="myfile">select 1</label>
    <input id="myfile" type="file" data-field="input1" />
</div>
<div>
    <label for="myfile">select 2</label>
    <input id="myfile" type="file" data-field="input2" />
</div>
<div>
    <label for="myfile">select 3</label>
    <input id="myfile" type="file" data-field="input3" />
</div>
+6

.

var activateFileSelection = function( container ) {
    var container = container || $('body');
    container.find(':file').each(function(i) {
        var thisInput = $(this);
        var thisLabel = thisInput.siblings('label');
        if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
            var thisLabelDefaultText = thisLabel.html();
            thisLabel.addClass('file-input-label');
            thisInput.on('change', function(e) {
                if (thisInput.val()) {
                    thisLabel.html(thisInput.val());
                } else {
                    thisLabel.html(thisLabelDefaultText);
                };
            });
        };
    });
};
activateFileSelection();
input {
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <label for="myfile1">select 1</label>
    <input id="myfile1" type="file" />
</div>
<div>
    <label for="myfile2">select 2</label>
    <input id="myfile2" type="file" />
</div>
<div>
    <label for="myfile3">select 3</label>
    <input id="myfile3" type="file" />
</div>

EDIT: . , . , , . - .

+1

The problem is with duplicate identifiers. Since they are all the same, the change is made in the first instance of this identifier. Changing the identifier fixes the problem:

var activateFileSelection = function( container ) {
    var container = container || $('body');
    container.find(':file').each(function(i) {
        var thisInput = $(this);
        var thisLabel = thisInput.siblings('label');
        if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
            var thisLabelDefaultText = thisLabel.html();
            thisLabel.addClass('file-input-label');
            thisInput.on('change', function(e) {
                if (thisInput.val()) {
                    thisLabel.html(thisInput.val());
                } else {
                    thisLabel.html(thisLabelDefaultText);
                };
            });
        };
    });
};
activateFileSelection();
input {
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <label for="myfile1">select 1</label>
    <input id="myfile1" type="file" />
</div>
<div>
    <label for="myfile2">select 2</label>
    <input id="myfile2" type="file" />
</div>
<div>
    <label for="myfile3">select 3</label>
    <input id="myfile3" type="file" />
</div>
Run code
0
source

I replace events for the label

A trigger based on what we need.

var activateFileSelection = function (container) {
    var container = container || $('body');
    container.find(':file').each(function (i) {
        var thisInput = $(this);
        var thisLabel = thisInput.siblings('label');
        if (thisLabel.length > 0 && !thisLabel.hasClass('file-input-label')) {
            var thisLabelDefaultText = thisLabel.html();
            thisLabel.addClass('file-input-label');
            thisLabel.on("click", function (e) {
                thisInput.trigger("click");
                e.preventDefault() 
            });
            thisInput.on('change',thisLabel, function () {
                console.log("Input used: " + thisInput.data("field"));
                if (thisInput.val()) {
                    thisLabel.html(thisInput.val());
                } else {
                    thisLabel.html(thisLabelDefaultText);
                };
            });
        };
    });
};
activateFileSelection();

And a live example: https://jsfiddle.net/synz/csc5bphy/

0
source

Source: https://habr.com/ru/post/1662474/


All Articles