Tengo varias zonas de caída (elemento de carga) en las que se muestran elementos de vista previa para cada archivo que se agrega. Cada vista previa tiene un campo de número de entrada.

Cada zona de caída es un formulario que tiene un campo de entrada oculto con un valor, este valor es la suma total permitida de todos los campos de entrada dentro del elemento de la zona de caída.

Así, por ejemplo:

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

Siempre que el total sea 10. No debe poder superar el 10 o cuando, por ejemplo, input1 tiene 3 como valor, la segunda entrada no debe poder exceder 7, etc.

Intenté lo siguiente:

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();
});

Donde $input es el campo de entrada en esa vista previa actual y aantal es la suma total. El problema es (en este caso aantal = 10) cada campo de entrada puede tener 10 (no excede) por lo que no está viendo los valores de otras entradas.

Intenté cambiar $input.not(this).each(function() { a $input.each(function() { pero cuando agrego dos imágenes y hay dos campos de entrada, solo puedo ir a 5 en cada una. El total es 10, por lo que es correcto, pero no es posible agregar 9 en uno y 1 en el otro, solo hasta 5 en cada uno.

¿Cómo puedo obtener ese resultado?

Agregué un jsfiddle aquí: https://jsfiddle.net/ar2395bw/ (para obtener las vistas previas que pueda arrastre archivos en los cuadros grandes o haga clic en ellos y cargue algunos archivos).

1
twan 28 feb. 2020 a las 13:37

2 respuestas

La mejor respuesta

Hay algunos problemas con el código en JSFiddle (el código publicado anteriormente no es suficiente para diagnosticar el problema).

No encontrar todas $input

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

Su $preview está conectado a cada archivo, por lo que solo encontrará uno $input, el que se está cambiando.

Uso incorrecto de .each()

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

La función pasada a .each() debe aceptar como argumentos un índice y el valor. Como está configurado actualmente, $input siempre se referirá al mismo valor en cada iteración del bucle.

Intente calcular un total con un valor desinfectado / modificado

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

Aquí asegúrese de que newVal esté en el rango de 0-10, pero luego use el valor cambiado para calcular el total newVal + valueSpent > maxValue

Solución

El siguiente código corrige todos estos problemas.

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();
});

Esto funciona para mí en el JSFiddle.

1
Codebling 4 mar. 2020 a las 16:59

Hay múltiples problemas:

  1. No todas las zonas de colocación tienen aantalinput
  2. aantalinput debe ser una clase, no una identificación let aantal = $el.find('.aantalinput').val();
  3. $input todo el tiempo desde la zona de colocación actual debería ser como let $input = $('table').find('.fileinput');
  4. let $input = $('table').find('.fileinput'); debe estar dentro de attributeVal.on("change paste keyup input", function(e) { y 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
Observer 4 mar. 2020 a las 13:40