Take the data attribute value of an input file field

Asked

Viewed 1,282 times

0

I am in need of help with the following situation

I have several input files fields with the same name and which are used to do various file uploads.

<form>
<label> Foto 3*4</label>
<input type="file" name="file[]" data-name="foto34">
<input type="submit">

<br/>

<label> Foto 16*9</label>
<input type="file" name="file[]" data-name="foto169">
<input type="submit">
</form>

And I would like to take the date attribute so that I can identify which file name is being uploaded via ajax I’ve tried to take it with

this.getAtributte("name")
ou
this.dataset.name

in this last case returns me Undefined. The ajax call is being made like this:

  $(document).ready(function(e){
        $("#form").on('submit', function(e){
           e.preventDefault();
            $.ajax({
                type: 'POST',
                url: 'upload.php',
                data: new FormData(this), //PRECISO PASSAR o DATA_ATRIBUTTE AQUI
                contentType: false,
                cache: false,
                processData:false,
                success: function(msg){
                    $(".btn").removeAttr("disabled");
                }
            });
    });

});

Someone would know to help me?

$(document).ready(function(e){
   $("#form").on('submit', function(e){
      e.preventDefault();
      var formulario = new FormData(this);

      var files = $(":file");
  		console.log(files[0].value);	
	  	console.log(files[1].value);			
      // percorre os campos
      files.each(function(i, e){
         if($(e).val()){
	formulario.append('data-name'+i, $(e).data("name"));
}else{
	formulario.append(i, null);
}
      });

      $.ajax({
         type: 'POST',
         url: 'upload.php',
         data: formulario, 
         contentType: false,
         cache: false,
         processData:false,
         success: function(msg){
            $(".btn").removeAttr("disabled");
         }
      });
   });
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <style>
    
input[type='file'] {
 display: none
}

    </style>
<form enctype="multipart/form-data" id="form">
 
        <div class="col-md-4">
            <div class="panel panel-info">
                <div class="panel-heading">
                    <h3 class="panel-title">Foto 3x4</h3>
                </div>
                <div class="panel-body">
                    Panel content
                    <br />
                    
                    <label for="file" class="bootstrap btn btn-info btn-xs" ><i class="fa fa-upload"></i> Selecionar Arquivo</label>
                            <input type="file" name="file[]" id="file" class="inputfile" data-name="foto34" >    
                            <button type="submit" class="bootstrap btn btn-primary btn-xs"> Enviar</button>
                            
                </div>
            </div>
        </div>
           
		<div class="col-md-4">
			<div class="panel panel-info">
				<div class="panel-heading">
					<h3 class="panel-title">Foto 16x9</h3>
				</div>
				<div class="panel-body">
					Panel content
					<br />
					<label for="file" class="bootstrap btn btn-info btn-xs"><i class="fa fa-upload"></i> Selecionar Arquivo</label>
						<input type="file" name="file[]" id="file" class="inputfile" data-name="foto169">    
						<button type="submit" class="bootstrap btn btn-primary btn-xs"> Enviar</button>
				</div>
			</div>
		</div>
    </form>

  • if you can post the entire function from where you are trying to capture this information

  • added to doubt

  • Take the attribute date-name you say?

  • Exactly that

  • Why you use multiple Submit buttons in the same form?

  • The correct is this.dataset.name but it depends on where you’re calling it, because the value of this can change, so it gives Undefined.

  • If you’re using the this within this Submit function will give Undefined even, because the this refers to the <form>

  • @Sam for each input file, the client can upload. As the uploads are separated into bootstrap card, it was easier for the client to understand that at each upload he should submit the file, could upload via javascript, once loading the file, but could not do so

  • Know.. so you want to send all the dates of all the file fields?

  • @Sam yes, that’s even this being my difficulty, in sending everyone in an identified way

  • Can’t you do that in PHP? For example, the first field file is the index [0], so in PHP you know that the image in index [0] is referring to "foto34", as well as the index [1] is "foto169".

  • It could, but these upload inputs are mounted dynamically according to the user’s profile, so I don’t have a reference to the position of each, or even if it will exist. I could insert a logic for this, but I thought to do via Js

  • Perhaps another way would be to make several formats for each document upload, but for me this would be very bad in practical terms

  • @Sam any idea how you could help me?

  • Already put a solution

Show 10 more comments

1 answer

1


You can go through the type fields file and add to FormData() an array of values of data-name using .append(). Just assign the FormData() to a variable and use .each to add the values. An array will be created in this form, in the order of the fields' indexes file, beginning in 0:

Array
(
    [data-name0] => foto34
    [data-name1] => foto169
)

In PHP you will get the files normally with $_FILES['file'], already the array above you will catch with $_POST.

The Ajax code will look like this:

$(document).ready(function(e){
   $("#form").on('submit', function(e){
      e.preventDefault();

      // atribui o FormData a uma variável
      var formulario = new FormData(this);

      // seleciona os campos tipo file
      var files = $(":file");

      // percorre os campos
      files.each(function(i, e){
         // adiciona os valores no FormData
         formulario.append('data-name'+i, $(e).data("name"));
      });

      $.ajax({
         type: 'POST',
         url: 'upload.php',
         data: formulario, //PRECISO PASSAR o DATA_ATRIBUTTE AQUI
         contentType: false,
         cache: false,
         processData:false,
         success: function(msg){
            $(".btn").removeAttr("disabled");
         }
      });
   });
});

Or you don’t even need to send a name for the array items, just send only the index, like this:

formulario.append(i, $(e).data("name"));

Thus resulting in PHP:

Array
(
    [0] => foto34
    [1] => foto169
)

By the array index you will know in PHP to which file you are associated, because the $_FILES['file'] also results in an array:

array(5) {
  ["name"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["type"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["tmp_name"]=>
  array(2) {
    [0]=>
    string(0) ""
    [1]=>
    string(0) ""
  }
  ["error"]=>
  array(2) {
    [0]=>
    int(4)
    [1]=>
    int(4)
  }
  ["size"]=>
  array(2) {
    [0]=>
    int(0)
    [1]=>
    int(0)
  }
}
  • Very good @Sam I will do some tests with your code, thanks

  • I get it, but how do I make the relationship between them? If it’s not the right position, you could just upload a file and how would you know which photo it belonged to? For example, uploading only photo169 the file would fall into the zero position array, while the zero position in data-name0 equals photo34

  • You can check if the file field is with file to do . append

  • And how could I do that? Through value? but by clicking another input even without file in the first it will not insert the 2 file in the first position? I didn’t understand the logic Sam, could you give me a help? See how was the execution.

  • See that when the input is empty, the index of the array name is empty, ie, will always return an array with the same number of fields. In the case of append you can do the same. See if it works like this: https://jsfiddle.net/erpqkyaf/

  • Unfortunately not, thus [data-name0] always receives the first date-name value in the photo34 case. But I think the way is this, I will try to find a solution and finding I put here. Thank you

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.