0

I have a form with multiple fields each has a name attribute, how can I extract these name attributes and store in an array or something for future use?

var inputs = $("input[type='text']"),
  outputs = [];
$("#submit").click(function() {
  inputs.each(function() {
    outputs.push(inputs.attr("name"));
  });
  console.log(outputs)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <label for="Forename">
    Forename
  </label>
  <input type="text" id="Forename" name="forename">
</div>
<div>
  <label for="Middlename">
  Middle Names
</label>
  <input type="text" id="Middlename" name="middlename">
</div>
<div>
  <label for="Lastname">
  Lastname
</label>
  <input type="text" id="Lastname" name="lastname">
</div>
<p id="message"></p>
<input type="button" id="submit" value="submit">

outputs is still empty after clicking the button, why are the strings not being pushed into the empty array?

3
  • "outputs is still empty after clicking the button" No, it isn't. Your snippet doesn't ever use outputs after clicking the button. I copied it, added console.log(outputs) to just after the each call in the click handler, and outputs has the names in it. Edit: mplungjan changed your snippet to output outputs. Now it has the first name repeated in it, because you're doing inputs.attr("name"), not this.name. Use this.name to access the name for the input the each loop is visiting. Commented Nov 19, 2019 at 11:56
  • Yes I had to add the console.log where I added it. You cannot show it outside the submit Commented Nov 19, 2019 at 12:02
  • @mplungjan - I edited the comment after you edited the snippet. Using this.name does work. Commented Nov 19, 2019 at 12:11

1 Answer 1

1

inputs is a jQuery collection. You will get the first element of that collection every time you only access inputs But if you loop over inputs with each, then $(this).attr("name) or this.name will return the attribute of each element

PS: .each IS a for loop - here is some of the code from the jQuery.js file

if ( isArrayLike( obj ) ) {
  length = obj.length;
  for ( ; i < length; i++ ) {
    if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
      break;
    }
  }
}

You have several possibilities

$(this).attr("name") or this.name

var $inputs = $("input[type='text']"),
  outputs = [];
$("#submit").click(function() {
  $inputs.each(function() {
    outputs.push($(this).attr("name")); // $(this) is the input;  this.name works too
  });
  console.log(outputs)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <label for="Forename">
    Forename
  </label>
  <input type="text" id="Forename" name="forename">
</div>
<div>
  <label for="Middlename">
  Middle Names
</label>
  <input type="text" id="Middlename" name="middlename">
</div>
<div>
  <label for="Lastname">
  Lastname
</label>
  <input type="text" id="Lastname" name="lastname">
</div>
<p id="message"></p>
<input type="button" id="submit" value="submit">

accessing the input's DOM node using the parameters passed to the function

var inputs = $("input[type='text']"),
  outputs = [];
$("#submit").click(function() {
  inputs.each(function(_,inp) { // inp is the DOM node
    outputs.push(inp.name);
  });
  console.log(outputs)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <label for="Forename">
    Forename
  </label>
  <input type="text" id="Forename" name="forename">
</div>
<div>
  <label for="Middlename">
  Middle Names
</label>
  <input type="text" id="Middlename" name="middlename">
</div>
<div>
  <label for="Lastname">
  Lastname
</label>
  <input type="text" id="Lastname" name="lastname">
</div>
<p id="message"></p>
<input type="button" id="submit" value="submit">

Use a map:

let outputs;
$("#submit").click(function() {
  outputs = $("input[type='text']").map((_,inp) => inp.name).get()
  console.log(outputs)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <label for="Forename">
    Forename
  </label>
  <input type="text" id="Forename" name="forename">
</div>
<div>
  <label for="Middlename">
  Middle Names
</label>
  <input type="text" id="Middlename" name="middlename">
</div>
<div>
  <label for="Lastname">
  Lastname
</label>
  <input type="text" id="Lastname" name="lastname">
</div>
<p id="message"></p>
<input type="button" id="submit" value="submit">

Sign up to request clarification or add additional context in comments.

4 Comments

Surely this is more of a comment and close-as-typo situation.
@T.J.Crowder - or a dupe, but I added some more information
What's the difference here between $(this) and directly using the variable inputs? I thought both would work?
Inputs is a jQuery collection. You will get the first element of that collection every time you only access inputs But if you loop over inputs with each then $(this).attr("name) or this.name will return the attribute of each element

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.