Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Избавится от ID в поле input (https://javascript.ru/forum/dom-window/70685-izbavitsya-ot-id-v-pole-input.html)

RGBPlus 25.09.2017 13:39

Избавится от ID в поле input
 
Добрый день!

Есть такая форма: https://jsfiddle.net/m6vxq34u/20/

Когда прикрепляешь файл, то JS выводит имя файла + его размер. С первым файлом все ок, отрабатывает как нужно, но у второго ID тот же что и у первого и по этому не отрабатывает.

Как переписать, что бы не привязываться к ID input!?

Спасибо!

laimas 25.09.2017 13:43

Что-то не видно нескольких полей. Можно и по имени, только нужно экранировать:

$('body').on('change', 'input[name="files\\[\\]"]', ....

RGBPlus 25.09.2017 13:47

Нажмите "Добавить еще файл" появится еще одно поле!

Обновил ссылку: https://jsfiddle.net/m6vxq34u/20/

laimas 25.09.2017 13:58

Цитата:

Сообщение от RGBPlus
Нажмите "Добавить еще файл"

:) я даже и не смотрел вправо, только на код.

Ну в общем по имени можно как написано, можно и по классу, если добавить его, обработка делегируется. ID удалить.

RGBPlus 25.09.2017 14:02

Если бы я был на столько силен в знаниях JS как вы!

Поможете в решение задачи? Можно прям там и ссылку сюда, или тут показать, как поправить. Спасибо!

laimas 25.09.2017 14:55

ID my-file-name заменены на классы (в стилях также изменить). Обработка делегируется ближайшему родителю div class="row", которому добавлен ID files-group. В этом случае, коли полей в форме иных нет, достаточно имя тега в качестве селектора.

<div class="application-project">
  <div class="container">
    <div class="row" id="files-group">
      <div class="col-md-6 form-group">
            <div class="file-upload">
    			<label>
    			    <div class="form-file-box">
    			        <span class="status">Выберите файл</span>
    			    </div>
    				<input type="file" name="files[]" value=""  />
    			</label>
    			<div class="my-file-name"></div>
	        	<div class="my-file-size"></div>
			</div>
        </div>
        <div class="col-lg-12 form-group">
    		<div class="button-file"><span><i class="fa fa-plus" aria-hidden="true"></i> Добавить еще файл</span>
    		</div>
    	</div>
    </div>
  </div>
</body>


$(document).ready(function () {
	
    // Добавить еще один файл
	$('.button-file').on('click', function() {
		$(this).closest('.row')
               .children()
               .first()
               .clone()
               .insertBefore($(this).parent())
               .find('input')
               .val('')
               .end()
               .find('[class|=my]')
               .text('');
	});
    
    // Загрузка файла
	$('#files-group').on('change', 'input', function(){
		var f = $(this), file, fileSize;
        if (!f.val()) {
			f.prev().addClass('disabled');
			f.prev().find('.status').text('Файл выбран');
            return;
		}
        
        file = this.files[0];
		fileSize = file.size > 1024 * 1024 ? Math.round(file.size * 100 / (1024 * 1024)) / 100 + 'MB'
                                           : Math.round(file.size * 100 / 1024) / 100 + 'KB';
		f.closest('.file-upload')
         .find('[class|=my]')
         .first()
         .text('Имя: ' + file.name)
         .end()
         .last()
         .text('Размер: ' + fileSize);
    });
});


Если это форма и есть другие поля ее, то добавьте полю file класс, который использовать как селектор, здесь:

$('#files-group').on('change', '.имя_класса_поля_выбора_файла', function(){


Примечание: чего этим хочется добиться if (!f.val()) .... 'Файл выбран' не понятно, но такое проверяется не здесь.

RGBPlus 25.09.2017 15:30

Вот это круто ))) То, что доктор прописал!

laimas 25.09.2017 15:37

Цитата:

Сообщение от RGBPlus
Вот это круто

Не радуйтесь, читайте примечание. Что хотели этим не понять, поэтому оставил, а надо выбросить, так как это работать все равно не будет. Если пользователь не выберет файла, а просто закроет диалог, в этом случае value поля будет пустое если до этого файл не выбирался, это да. Но при этом его значение не изменится, оно же не изменится если файл уже выбирали, затем опять хотели выбрать, но закрыли диалог.

То есть события onchange не возникнет и проверка if (!f.val()) в обработчике этого события мягко говоря бред.

RGBPlus 25.09.2017 15:41

Скажите, я могу вместо этого куска
// Добавить еще один файл
	$('.button-file').on('click', function() {
		$(this).closest('.row').children().first().clone().insertBefore($(this).parent()).find('input').val('').end().find('[class|=my]').text('');
	});


Свой старый использовать? Я понимаю, что это более красивое решение, но он копирует все + новые классы. т.е. у меня есть украшательство:

Когда выбрали файл, он меняет статус лейбла и пишет, что файл выбран
// Форма обратной связи | Статус файла
	$('body').on('change', 'input[name="files[]"]', function(){
		if ($(this).val() != '') {
			$(this).prev().addClass('disabled');
			$(this).prev().find('.status').html('Файл выбран');
		}
	});


Проще, вот временная ссылка на работу: https://svetliygrad.ru/res
Выберите файл, посмотрите как изменится кнопка, потом добавьте еще поле, что бы прикрепить файл

рони 25.09.2017 15:46

RGBPlus,
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">.application-project {
  background: #ececec;
  margin: 3rem auto;
  display: block;
  width: 800px;
  padding: 3rem 2rem;
}
.application-project .h4 {
  font: 600 16px/16px Helvetica,Arial,sans-serif;
  color: #2C3E50;
  margin: 2rem 0 1rem 0;
}
.application-project .h4.form-title {
  color: #16A085;
  padding: 0 0 1.3rem 0;
  border-bottom: 1px solid #16A085;
}
.application-project label {
  display: block;
  font: 300 16px/16px pragmatica,Helvetica,Arial,sans-serif;
  padding: 0;
  margin: 0.8rem 0;
}
.application-project label span.sure,
.form-information span.sure {
  color: #C0392B;
}
.application-project .select,
.application-project .select-tags {
  width: 100%;
}
.application-project .select2-selection {
  border: 1px solid #c3d3e4;
  box-shadow: 0 1px 1px 1px #ececec inset;
  border-radius: 4px;
  font: 300 15px/15px pragmatica,Helvetica, Arial, sans-serif;
  height: 35px;
  padding: 0.4rem 0 0 0.3rem;
}
.application-project .select2-selection .select2-selection__arrow b {
  border-color: #2C3E50 transparent transparent transparent;
  margin-left: -9px;
  margin-top: 1px;
}
.application-project input,
.application-project textarea {
  font: 300 15px/15px pragmatica, Helvetica, Arial, sans-serif;
  border: 1px solid #c3d3e4;
  border-radius: 5px;
  margin: 0;
  box-shadow: 0 1px 1px 1px #ececec inset;
  width: 100% !important;
}
.application-project input {
  height: 33px;
  padding: 0 1rem;
}
.application-project textarea {
  padding: 1rem;
}
.application-project .button-file span {
  color: #16A085;
  font: 600 16px/16px Helvetica,Arial,sans-serif;
  display: inline-block;
  cursor: pointer;
  padding: 0.2rem 0;
  border-bottom: 1px dashed;
  margin: 1rem 0;
}
.application-project .button-file span i {
  font-weight: normal;
  font-size: 15px;
  color: #2C3E50;
}
.application-project .file-upload {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 65px;
}
.application-project .file-upload label {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}
.application-project .file-upload label .form-file-box {
  background: #16A085;
  color: #fff;
  cursor: pointer;
  text-transform: uppercase;
  padding: 0.7rem 0 0.5rem 0;
  font: 300 14px/14px pragmatica,Helvetica,Arial,sans-serif;
  width: 100%;
  text-align: center;
}
.application-project .file-upload label .form-file-box:hover,
.application-project .file-upload label .form-file-box.disabled {
  background: #1ABC9C;
}
.application-project .file-upload label .form-file-box.disabled {
  cursor: not-allowed;
}
.application-project .file-upload input[type="file"] {
  display: none;
}
.application-project .my-file-name {
  margin: 2.2rem 0 0 0;
}
.application-project .my-file-name,
.application-project .my-file-size {
  font: 300 11px/13px pragmatica, Helvetica, Arial, sans-serif;
  padding: 0.2rem 0 0 0;
}

.form-group {
  margin: 15px;
}

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    function d(a) {
        return a.on("change", 'input[name="files[]"]', function() {
            a.addClass("disabled");
            $(".status", a).text("Файл выбран");
            var c = this.files[0],
                b = 1048576 < c.size ? Math.round(100 * c.size / 1048576) / 100 + "MB" : Math.round(100 * c.size / 1024) / 100 + "KB";
            $(".my-file-name", a).text("Имя: " + c.name);
            $(".my-file-size", a).text("Размер: " + b)
        })
    }
    var b = $(".col-md-6.form-group");
    b = d(b).clone();
    $(".button-file").on("click", function() {
            $(".col-md-6.form-group:last").after(d(b.clone()))
        })
});

  </script>
</head>

<body>
<div class="application-project">
  <div class="container">
    <div class="row">
      <div class="col-md-6 form-group">
            <div class="file-upload">
    			<label>
    			    <div class="form-file-box">
    			        <span class="status">Выберите файл</span>
    			    </div>
    				<input type="file" name="files[]" value=""  />
    			</label>
    		<div class="my-file-name"></div>
          	<div class="my-file-size"></div>
      </div>
        </div>
        <div class="col-lg-12 form-group">
    		<div class="button-file"><span><i class="fa fa-plus" aria-hidden="true"></i> Добавить еще файл</span>
    		</div>
    	</div>
    </div>
  </div>
</div>
</body>
</html>

laimas 25.09.2017 15:47

Цитата:

Сообщение от RGBPlus
Свой старый использовать?

Зачем? Вы же добавляете тоже самое, а следовательно нужно взять уже существующее, клонировать, вставить, очистить поле, и удалить текст об имени и размере. Надобности хранить описание добавляемого в атрибуте кнопки нет. Если какие-то классы при добавлении нового не нужны, их нужно тоже удалить, а какие я не в курсе, ибо мне не понятно какие там "новые", а какие "старые".

Цитата:

Сообщение от RGBPlus
Когда выбрали файл, он меняет статус лейбла и пишет, что файл выбран

Я же написал, что это работать не будет, if ($(this).val() != '') ... в событии onchange это бред, не будет такого события вообще! Вместо этого бесполезного лучше проверять тип файла выбранного для загрузки.

laimas 25.09.2017 15:49

Цитата:

Сообщение от RGBPlus
Выберите файл, посмотрите как изменится кнопка,

Не вижу изменений.

RGBPlus 25.09.2017 15:53

Обновите еще раз, поставил старый код:

$(document).ready(function () {
	// Форма обратной связи | Статус файла
	$('body').on('change', 'input[name="files[]"]', function(){
		if ($(this).val() != '') {
			$(this).prev().addClass('disabled');
			$(this).prev().find('.status').html('Файл выбран');
		}
	});
    // Форма обратной связи | Добавить еще один файл
	$('.button-file').on('click', function() {
		$(this).closest('.row').children().first().clone().insertBefore($(this).parent()).find('input').val('').end().find('[class|=my]').text('');
	});
    // Форма обратной связи | Загрузка файла
	$('#files-group').on('change', 'input', function(){
		var f = $(this), file, fileSize;
        if (!f.val()) {
			f.prev().addClass('disabled');
			f.prev().find('.status').html('Файл выбран');
            return;
		}
        file = this.files[0];
		fileSize = file.size > 1024 * 1024 ? Math.round(file.size * 100 / (1024 * 1024)) / 100 + ' Mb': Math.round(file.size * 100 / 1024) / 100 + ' Kb';
		f.closest('.file-upload').find('[class|=my]').first().text('Имя: ' + file.name).end().last().text('Размер: ' + fileSize);
    });
});

RGBPlus 25.09.2017 15:55

С этим кодом кнопка не работает:

$(document).ready(function () {
	
    // Добавить еще один файл
	$('.button-file').on('click', function() {
		$(this).closest('.row')
               .children()
               .first()
               .clone()
               .insertBefore($(this).parent())
               .find('input')
               .val('')
               .end()
               .find('[class|=my]')
               .text('');
	});
    
    // Загрузка файла
	$('#files-group').on('change', 'input', function(){
		var f = $(this), file, fileSize;
        if (!f.val()) {
			f.prev().addClass('disabled');
			f.prev().find('.status').text('Файл выбран');
            return;
		}
        
        file = this.files[0];
		fileSize = file.size > 1024 * 1024 ? Math.round(file.size * 100 / (1024 * 1024)) / 100 + 'MB'
                                           : Math.round(file.size * 100 / 1024) / 100 + 'KB';
		f.closest('.file-upload')
         .find('[class|=my]')
         .first()
         .text('Имя: ' + file.name)
         .end()
         .last()
         .text('Размер: ' + fileSize);
    });
});


Я понял ваш посыл, схожу еще раз перечитаю, а то немного запутался

рони 25.09.2017 16:01

RGBPlus,
пост №10 посмотрите ... там id переделано на классы

laimas 25.09.2017 16:03

Если вы хотите запретить выбор файла полем уже с выбором, то к чему такие глупости, просто так:

$('#files-group').on('change', 'input', function(){
        var f = $(this), file, fileSize;
        
        f.prev().addClass('disabled');
         
        file = this.files[0];
        fileSize = file.size > 1024 * 1024 ? Math.round(file.size * 100 / (1024 * 1024)) / 100 + 'MB'
                                           : Math.round(file.size * 100 / 1024) / 100 + 'KB';
        f.closest('.file-upload')
         .find('[class|=my]')
         .first()
         .text('Имя: ' + file.name)
         .end()
         .last()
         .text('Размер: ' + fileSize);
    });



Я ошибся, не равное пусто проверка, но она также глупа! Если файл выбран, то есть изменилось значение поля, то только в этом случае наступит событие onchange! К чему эта проверка которая ничего не дает? Пощелкайте вы диалог выбора файла с выбором и без выбора, что получите?

Запрещать же вновь сделать выбор полем думаю плохо и вряд ли вы этого хотите, а значит выбрано или не выбрано проверяют при отправке формы, но у вас не видно, чтобы это поле было обязательным для выбора.

Чего надо то?

RGBPlus 25.09.2017 16:11

Ребята спасибо большое!

Рони предложил простой и отвечающий всем требованиям вариант!

$(function() {
		function d(a) {
			return a.on("change", 'input[name="files[]"]', function() {
				a.addClass("disabled");
				$(".status", a).text("Файл выбран");
				var c = this.files[0],
					b = 1048576 < c.size ? Math.round(100 * c.size / 1048576) / 100 + "MB" : Math.round(100 * c.size / 1024) / 100 + "KB";
				$(".my-file-name", a).text("Имя: " + c.name);
				$(".my-file-size", a).text("Размер: " + b)
			})
		}
		var b = $(".col-md-6.form-group");
		b = d(b).clone();
		$(".button-file").on("click", function() {
				$(".col-md-6.form-group:last").after(d(b.clone()))
			})
	});


Требовалось:
При после выбора файла указать его имя + размер + изменить статус на кнопке, что файл выбран, далее я уже на CSS подправил что требуется!

Запрещать пользователю ни кто не чего не будет, просто показать, что файл выбран

Все проверки: размер загружаемого файла и разрешенного расширения файла, уже будет проверятся на стороне движка сайта!

Ребят: laimas и рони искренняя благодарность за помощь, еще раз спасибо )))

laimas 25.09.2017 16:16

Цитата:

Сообщение от RGBPlus
Требовалось:
При после выбора файла указать его имя + размер + изменить статус на кнопке

Ну так это же совсем иное, а то что написано было изначально так это сущий бред :)

Рони ничего нового не добавил, тоже самое. Вот только класс "disabled" в бутстрап, это "недоступен", отсюда и не понять чего вы хотите. Уберите его и выберите иной.

RGBPlus 25.09.2017 16:22

Рони, всю портянку объединил в один скрипт + заставил работать как требовалось. В Бустрапе использую только сетку, остальное предпочитаю сам )))

Результат: https://svetliygrad.ru/res обновил, можно посмотреть!

Еще немного доделаю недочеты и буду запускать форму!

Еще раз, спасибо!

laimas 25.09.2017 16:32

Цитата:

Сообщение от RGBPlus
Рони, всю портянку объединил в один скрипт + заставил работать как требовалось.

У рони тоже самое, написано не так, где-то кажется короче потому как используются псевоселекторы (работать будет чуть медленнее), где-то наоборот лишнее, но суть также самое потому как по другому и не ... И также два обработчика.

Цитата:

Сообщение от RGBPlus
В Бустрапе использую только сетку, остальное предпочитаю сам

Классы в бутсрапе определены, что вы там при этом используете не важно, класс то вы его берете и не переопределяете (и не надо), а класс disabled в бустрапе, это икона типа дорожного знака "Запрещено", это я и буду видеть. И где логика?

RGBPlus 25.09.2017 16:39

Форма будет запускаться, ну пусть из 200-500 посетителей один раз, я думаю будет не критично, если будет работать чуть медленнее - вряд ли это кто заметит (знаю, что могут посыпаться помидоры в виде: есть возможность сделать быстрее - нужно делать)!

Что касается Бутсрапа я вас услышал, исправлюсь!

laimas 25.09.2017 16:48

Цитата:

Сообщение от RGBPlus
Форма будет запускаться, ну пусть из 200-500 посетителей один раз

Это конечно не важно. У рони главное отличие не в этом, но об этом вам лучше не говорить, все равно не поймете. :)

А вот что касается логики поведения, то ее у вас нет. Смотрите, у вас перечислены разрешенные для загрузки типы файлов и их размер, но при этом нет проверки ни типа, ни размера выбранного. Я и предположил, что данная никчемная проверка и предполагалась для этого, тогда и можно было бы как-то сказать, что класс "disabled" к месту. А иначе...

RGBPlus 25.09.2017 16:55

Прикрепить можно попробовать хоть слона, но вот отправить его - это уже другой вопрос!

Попробуйте прикрепить файл и нажать отправить заявку! Вам покажут на ваши ошибки, с селектами еще работаю!

laimas 25.09.2017 17:02

Цитата:

Сообщение от RGBPlus
Прикрепить можно попробовать хоть слона, но вот отправить его - это уже другой вопрос!

Ну если есть проверка при отправке формы, или же отправка Ajax и сервер отдает ошибку. Но и при выборе файла это сразу и сделать можно, если не разрешен тип или больший размер, то выбор сбрасывается и сразу сообщение, а не потом.

RGBPlus 25.09.2017 17:49

Не совсем уверен, что мне это нужно. В форме указал, что можно загрузить и каким объемом. Поля на заполнение я же не проверяю на лету, и в это смысла не вижу. Пусть будет так как есть. Спасибо за помощь!

laimas 25.09.2017 18:12

RGBPlus,
да как хотите, я ведь не предлагаю, я к тому, что увидев код, возник вопрос к чему тут "disabled" да еще по такому условию. И просто было предположение, что ...

Кстати, проверка на тип и размер сразу при выборе файла, а не во время отправки формы, наоборот более логична, ибо это же обязан проверять и сервер и тут уже он возвращает ошибки выбора. Возьмите любой файл, смените у него расширение на .jpg и выберите - браузер даже не вякнет.


Часовой пояс GMT +3, время: 06:10.