Несколько динамически создаваемых значений поля ввода не могут превышать указанное число - PullRequest
1 голос
/ 28 февраля 2020

У меня есть несколько дропзон (элемент загрузки), в которых элементы предварительного просмотра отображаются для каждого добавляемого файла. Каждый предварительный просмотр имеет поле ввода номера.

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

Так, например:

Dropzone 1 has total sum of: 10
And two previews with inputs, then for example this is possible:
input1: 10
input2: 0
Or 
input1: 5
input2:5
etc

, пока общая сумма составляет 10. Вы не должны быть в состоянии превысить 10 или когда, например, input1 имеет 3 в качестве значения, второй вход не должен превышать 7 et c.

Я попробовал следующее:

const attributeVal = $input;

attributeVal.on("change paste keyup input", function(e) {
  let newVal = Math.floor($input.val());
  newVal = Math.max(0, newVal);
  newVal = Math.min(10, newVal);
  const maxValue = parseInt(aantal);
  let valueSpent = 0;
  $input.not(this).each(function() {
    valueSpent += +$input.val();
  });
  if (newVal + valueSpent > maxValue) {
    // Invalid, reset these points to the maximum allowable:
    newVal = maxValue - valueSpent;
  }
  // New value has been validated, put it into the DOM:
  $input.val(newVal);
});

attributeVal.on("cut copy paste", function(e) {
  e.preventDefault();
});

Где $input - это поле ввода в текущем предварительном просмотре, а aantal - общая сумма. Проблема в том, что (в данном случае aantal = 10) каждое поле ввода может иметь 10 (оно не превышает), поэтому оно не видит значений других входных данных.

Я попытался изменить $input.not(this).each(function() { на $input.each(function() { но когда я добавляю два изображения и, таким образом, есть два поля ввода, я могу только от go до 5 в каждом. Итого 10, так что это правильно, но невозможно добавить 9 в одном и 1 в другом, только до 5 в каждом.

Как я могу получить это результат?

Я добавил jsfiddle здесь: https://jsfiddle.net/ar2395bw/ (чтобы получить предварительный просмотр, вы можете перетащить файлы в большие поля или щелкнуть по ним и загрузить некоторые файлы).

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Существует несколько проблем:

  1. Не в каждой зоне сброса есть aantalinput
  2. aantalinput должен быть классом, а не идентификатором let aantal = $el.find('.aantalinput').val();
  3. $input все время от текущей зоны падения должно быть как let $input = $('table').find('.fileinput');
  4. let $input = $('table').find('.fileinput'); должно быть внутри attributeVal.on("change paste keyup input", function(e) { и const attributeVal =$preview.find('.fileinput');

let counter = 0;
$('.dropzone').each(function(index, element){
    let $el = $(element);
    let $maxfiles = $el.attr('maxfiles');
    let $inputquantity = $el.find('input').val();
    let uploaded_preview = $('.hiddendiv').html();
    let aantal = $el.find('.aantalinput').val();
    let $thisdropzone = $el;
    
    let total_container = $el.parent().find('.row-total');
    
    $el.dropzone({
        paramName: 'postedFile',
        addRemoveLinks: true,
        dictDefaultMessage: '<i class="fas fa-file-upload uploadicon"></i> <span class="uploadtxt">Upload je bestand(en)</span>',
        dictRemoveFile: 'Verwijder',
        dictCancelUpload: 'Annuleren',
        dictInvalidFileType: 'Dit type bestand is niet toegestaan',
        dictCancelUploadConfirmation: 'Weet je zeker dat je het uploaden wilt annuleren?',
        dictMaxFilesExceeded: 'Maximale aantal bestanden overschreden',
        maxFiles: $maxfiles,
        acceptedFiles: '.jpg, .jpeg, .png, .pdf, .tif, .tiff',
        thumbnailWidth: '205',
        thumbnailHeight: '140',
        thumbnailMethod: 'crop',
        previewTemplate: uploaded_preview,
        processing: function (file) {

        },
        // File contains dropzone file object, response contains ajax response from php file
        error: function (file, response) {
            
            counter++;
            console.log('Option ' + counter);
            response = '[{"status":"error","filename":"instablok'+counter+'.jpg","filesize":22822,"tmp_name":"\/tmp\/phpI6ov6y","height":172,"width":565,"heightcm":"6'+counter+',07","widthcm":"19'+counter+',93","tifwidth":null,"dpi":"72"}]';

let file_meta = JSON.parse(response);
		let $preview = $(file.previewElement);
		let $plusbtn = $preview.find('#plusupload');
		let $minbtn = $preview.find('#minupload');
	
    
    const attributeVal =$preview.find('.fileinput');

	attributeVal.on("change paste keyup input", function(e) {
  			  let $input = $('table').find('.fileinput');
				  let newVal = Math.floor(this.value);
				  newVal = Math.max(0, newVal);
				  newVal = Math.min(10, newVal);
				  const maxValue = parseInt(aantal);
				  let valueSpent = 0;
				 $input.not(this).each(function() {
				    valueSpent += parseInt(this.value);
				  });
				  if (newVal + valueSpent > maxValue) {
				    // Invalid, reset these points to the maximum allowable:
				    newVal = maxValue - valueSpent;
				  }
				  // New value has been validated, put it into the DOM:
				  this.value = newVal;
				});

				attributeVal.on("cut copy paste", function(e) {
				  e.preventDefault();
				});
            

            if(file_meta[0].status == 'success'){

            }else if(file_meta[0].status == 'error'){
                $preview.find('.vrijgevenbtn').show();
                $preview.find('.foutformaat').show();
            }
            $preview.find('.bestandnaam').text('Bestandsnaam: ' + file_meta[0].filename);
            $preview.find('.resolutie').text('Resolutie: ' + file_meta[0].dpi + ' DPI');
            $preview.find('.formaat').text('Formaat: ' + file_meta[0].heightcm + ' x ' + file_meta[0].widthcm + 'cm');
        },
    })
});
.hiddendiv {
   display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://rawgit.com/enyo/dropzone/master/dist/dropzone.js"></script>
<script type="text/javascript">
  // Disable auto discover for all elements:
  Dropzone.autoDiscover = false;

</script>
<link rel="stylesheet" href="https://rawgit.com/enyo/dropzone/master/dist/dropzone.css">

<table class="table upload-table">
  <tbody>
    <tr>
      <td class="plantmore-product-thumbnail uploadimg" width="100">
        <a href=""><img src="assets/images/noimg.jpg" alt=""></a>
      </td>
      <td class="plantmore-product-name" width="200">
        <div class="prodinfocheckout">
          <a class="prodname" href="">
            Monomeer
          </a>
          <span id="togglespecscheckout" class="prodspecscheckout noselect">
            <i class="fas fa-chevron-down"></i> Specificaties
          </span>
          <div class="togglespecscheckout">
            Hoogte : 20cm
            <br>
            Breedte : 20cm
            <br>
            uploaden : 1
            <br>
            Lijmlaag : Wit
            <br>
            Laminaat : Anti-slip laminaat
            <br>
            Afwerking : Contoursnijden
            <br>
          </div>
        </div>
      </td>
      <td class="plantmore-product-quantity" width="190">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">
            Benodigd formaat:<br>
            <span class="benodigd">20 x 20cm</span>
          </span>
        </span>
      </td>
      <td class="plantmore-product-quantity" width="185">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">Benodigde aantal<br> bestanden: <span class="benodigd">10</span></span>
        </span>
      </td>
      <td class="plantmore-product-quantity">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">Bestanden <br>toegewezen: <span class="benodigd">0 / 10</span></span>
        </span>
      </td>
      <td class="plantmore-product-quantity" valign="top">
        <button class="uploadbutton btn yellowbtn dz-clickable">Bestand(en) uploaden</button>
      </td>
    </tr>
    <tr class="newrow">
      <td colspan="6">
      <h6 class="row-total">total: 0     </h6>
        <form action="upload/uploaden.php" class="dropzone dropzoneform dz-clickable" maxfiles="10" id="dropzone1">
          <input type="hidden" value="Monomeer" name="productnaam">
          <input type="hidden" value="Twan" name="klantnaam">
          <input type="hidden" value="20" name="hoogte">
          <input type="hidden" value="20" name="breedte">
          <input class="aantalinput" type="hidden" value="10" name="aantal">
          <div class="dz-default dz-message"><span><i class="fas fa-file-upload uploadicon"></i> <span class="uploadtxt">Upload je bestand(en)</span></span></div>
        </form>
      </td>
    </tr>
    <tr>
      <td class="plantmore-product-thumbnail uploadimg" width="100">
        <a href=""><img src="assets/images/noimg.jpg" alt=""></a>
      </td>
      <td class="plantmore-product-name" width="200">
        <div class="prodinfocheckout">
          <a class="prodname" href="">
            Monomeer
          </a>
          <span id="togglespecscheckout" class="prodspecscheckout noselect">
            <i class="fas fa-chevron-down"></i> Specificaties
          </span>
          <div class="togglespecscheckout">
            Hoogte : 90cm
            <br>
            Breedte : 90cm
            <br>
            uploaden : 1
            <br>
            Lijmlaag : Wit
            <br>
            Laminaat : Anti-slip laminaat
            <br>
            Afwerking : Contoursnijden
            <br>
          </div>
        </div>
      </td>
      <td class="plantmore-product-quantity" width="190">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">
            Benodigd formaat:<br>
            <span class="benodigd">90 x 90cm</span>
          </span>
        </span>
      </td>
      <td class="plantmore-product-quantity" width="185">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">Benodigde aantal<br> bestanden: <span class="benodigd">1</span></span>
        </span>
      </td>
      <td class="plantmore-product-quantity">
        <span class="centervertical">
          <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
            <i class="fas fa-info-circle"></i>
          </button>
          <span class="amount">Bestanden <br>toegewezen: <span class="benodigd">0 / 1</span></span>
        </span>
      </td>
      <td class="plantmore-product-quantity" valign="top">
        <button class="uploadbutton btn yellowbtn dz-clickable">Bestand(en) uploaden</button>
      </td>
    </tr>
    <tr class="newrow">
      <td colspan="6">
      
      <h6 class="row-total">total: 0     </h6>
        <form action="upload/uploaden.php" class="dropzone dropzoneform dz-clickable" maxfiles="1" id="dropzone4">
          <input type="hidden" value="Monomeer" name="productnaam">
          <input type="hidden" value="Twan" name="klantnaam">
          <input type="hidden" value="90" name="hoogte">
          <input type="hidden" value="90" name="breedte">
          <input class="aantalinput" type="hidden" value="10" name="aantal">
          <div class="dz-default dz-message"><span><i class="fas fa-file-upload uploadicon"></i> <span class="uploadtxt">Upload je bestand(en)</span></span></div>
        </form>
      </td>
    </tr>
  </tbody>
</table>


<div class="hiddendiv">

  <div class="dz-preview dz-file-preview">
    <div class="dz-image"><img data-dz-thumbnail /></div>
    <div class="dz-details">
      <div class="dz-size"><span data-dz-size></span></div>
      <div class="dz-filename"><span data-dz-name></span></div>
    </div>
    <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
    <div class="dz-error-message"><span data-dz-errormessage></span></div>
    <span class="infoline">
      <span class="infospan bestandnaam">Bestandnaam:</span>
      <!-- <i class="fas fa-times-circle afgekeurd"></i> -->
    </span>
    <span class="infoline">
      <span class="infospan resolutie">Resolutie:</span>
      <!-- <i class="fas fa-check-circle goedgekeurd"></i> -->
    </span>
    <span class="infoline">
      <span class="infospan formaat">Formaat:</span>
      <!-- <i class="fas fa-times-circle afgekeurd"></i> -->
    </span>
    <div class="foutformaat">
      <span>Bestand heeft niet het benodigde formaat.</span>
      <span class="uploadinfobox">
        <button class="infotooltip tooltipupload" data-tooltip="Lorem ipsum">
          <i class="fas fa-info-circle"></i>
        </button>
      </span>
    </div>
    <button class="yellowbtn btn vrijgevenbtn" type="button">Bestand vrijgeven</button>
    <hr class="uploadline">
    <span class="toewijzen">Aantal</span>
    <div class="uploadcontent">
      <input type="number" value="0" min="0" class="fileinput">
    </div>
  </div>
</div>
1 голос
/ 03 марта 2020

Есть несколько проблем с кодом в JSFiddle (приведенного выше кода недостаточно для диагностики проблемы).

Не найдены все $input

let $preview = $(file.previewElement);
let $input = $preview.find('.fileinput');

Ваш $preview подключен к каждому файлу, поэтому вы всегда найдете только один $input, тот, который изменяется.

Неправильное использование .each()

$input.not(this).each(function() {

Функция, переданная в .each(), должна принимать в качестве аргументов индекс и значение. Как установлено в настоящий момент, $input всегда будет ссылаться на одно и то же значение на каждой итерации l oop.

Попытка вычислить сумму с sanitized / модифицированное значение

  newVal = Math.max(0, newVal);
  newVal = Math.min(10, newVal);

Здесь убедитесь, что newVal находится в диапазоне 0-10, но затем вы используете измененное значение для вычисления общей суммы newVal + valueSpent > maxValue

Решение

Следующий код устраняет все эти проблемы.

const attributeVal = $input;

attributeVal.on("change paste keyup input", function (e) {
  const maxValue = parseInt(aantal);
  let valueSpent = 0;
  $preview.closest('.dropzone').find('.fileinput').each(function (index, input) {
    valueSpent += +$(input).val();
  });
  if (valueSpent > maxValue) {
    // Invalid, reset these points to the maximum allowable:
    $input.val($input.val() - (valueSpent - maxValue));
  }
});

attributeVal.on("cut copy paste", function (e) {
  e.preventDefault();
});

Это работает для меня на JSFiddle.

...