Моя проблема немного сложна, так как я работаю с окном, в котором содержимое динамически загружается с помощью AJAX.
Я пытаюсь реализовать это решение (Styling & Customizing FileВходы)
У меня есть два файловых ввода с метками (один простой, другой - множественный)
<form id="my_form" action="/" method="post" enctype="multipart/form-data">
<!-- Elements inside <form> are loaded with ajax -->
<input type="file" id="photos" data-name="photos" name="photos[]" multiple="multiple" style="margin-top:15px;" class="inputfile inputfile-photos" data-multiple-caption="{count} files selected">
<label class="btn btn-sm btn-outline-primary d-block" for="photos" style="max-width: 250px;overflow: hidden;text-overflow: ellipsis;text-transform: initial;"><i class="icon-upload"></i> <span>Choose files…</span></label>
<input type="file" name="file-agrement" id="file-agrement" class="inputfile inputfile-agrement" accept=".pdf, .jpeg, .jpg, .png"/>
<label class="btn btn-sm btn-outline-primary d-block" for="file-agrement" style="max-width: 250px;overflow: hidden;text-overflow: ellipsis;text-transform: initial;"><i class="icon-upload"></i> <span>Choose file…</span></label>
</form>
И у меня есть этот код JS, который заменяет текст метки именем файлаесли он уникален или выбрано n файлов, если несколько
Весь код js находится внутри обратного вызова функции ajax .get;вот почему я не могу сделать $input.on( 'change', function( e ) {
, и я вынужден сделать $(document).on( 'change', $input, function( e ) {
$( '#my_form .inputfile' ).each( function() {
var $input = $( this );
var $label = $input.next( 'label' );
var labelVal = $label.html();
$(document).on( 'change', $input, function( e ) {
/* first issue: these two things give different values */
console.debug({'$input.val()': $input.val()});
console.debug({'e.target.value': e.target.value});
var fileName = '';
if( $input.prop('files') && $input.prop('files').length > 1 ) {
fileName = ( $input.attr( 'data-multiple-caption' ) || '' ).replace( '{count}', $input.prop('files').length );
}
else if( $input.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});
/* Firefox bug fix */
$input
.on( 'focus', function(){ $input.addClass( 'has-focus' ); })
.on( 'blur', function(){ $input.removeClass( 'has-focus' ); });
});
Проблема здесь в том, что текст метки заменяется на обе метки, и событие измененияКажется, срабатывает на каждом входе, когда изменяется только одно.
Я пробовал много вещей, но каждый раз либо «меняются», либо меняется только первый, как в этом примере:
var inputs = document.querySelectorAll( '#my_form .inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label = input.nextElementSibling,
labelVal = label.innerHTML;
input.addEventListener( 'change', function( e )
{
var fileName = '';
if( this.files && this.files.length > 1 )
fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
else
fileName = e.target.value.split( '\\' ).pop();
if( fileName )
label.querySelector( 'span' ).innerHTML = fileName;
else
label.innerHTML = labelVal;
});
});
Здесь срабатывает только событие изменения ввода #photos, и никогда не # file-agrement.
Я даже пытался переместить весь код из цикла foreach и попыталсясделать это «вручную» на каждом входе, но то же самое произошло;либо «меняется» только первое, либо оба ...
Это то, что я пробовал:
$photos = $('#my_form .inputfile#photos');
$agrement = $('#my_form .inputfile#file-agrement');
$(document).on( 'change', $photos, function( e ) {
console.log('change');
var $label = $photos.next( 'label' );
var labelVal = $label.html();
var fileName = '';
if ( $photos.prop('files') && $photos.prop('files').length > 1 ) {
fileName = ( $photos.attr( 'data-multiple-caption' ) || '' ).replace( '{count}',$photos.prop('files').length );
}
else if ( $photos.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});
$(document).on( 'change', $agrement, function( e ) {
console.log('change');
var $label = $agrement.next( 'label' );
var labelVal = $label.html();
var fileName = '';
if ( $agrement.prop('files') && $agrement.prop('files').length > 1 ) {
fileName = ( $agrement.attr( 'data-multiple-caption' ) || '' ).replace( '{count}',$agrement.prop('files').length );
}
else if ( $agrement.prop('files') ) {
fileName = e.target.value.split( '\\' ).pop();
}
if( fileName ) {
$label.find( 'span' ).html( fileName );
}
else {
$label.html( labelVal );
}
});