Link to home
Start Free TrialLog in
Avatar of earwig75
earwig75

asked on

Add count to hidden text field with jquery/javascript from dynamic inputs

I am using the below form/jquery to add dynamic rows of input to a form. I would like to add a hidden text box to the form with a total count of how many items are in the dynamic form. Can someone assist?

<form method="post" action="actionPage.cfm">
<div class="input_fields_wrap">
    <button class="add_field_button">Add More Fields</button>
    <div><input type="text" name="name1"> <input type="radio" name="auth1" value="auth">Authorized <input type="radio" name="auth1" value="noauth">Not Authorized </div>
</div>
<input type="submit" value="submit">
</form>
<script>
$(document).ready(function() {
    var max_fields      = 10; //maximum input boxes allowed
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID
   
    var x = 1; //initlal text box count
    $(add_button).click(function(e){ //on add input button click
        e.preventDefault();
        if(x < max_fields){ //max input box allowed
            x++; //text box increment
          //  $(wrapper).append('<div><input type="text" name="name"/> <input type="radio" name="auth" value="auth">Authorized <input type="radio" name="auth" value="noauth">Not Authorized <a href="#" class="remove_field">Remove</a></div>'); //add input box
		$(wrapper).append('<div><input type="text" name="name' + x + '"/> <input type="radio" name="auth' + x + '" value="auth">Authorized <input type="radio" name="auth' + x  + '" value="noauth">Not Authorized <a href="#" class="remove_field">Remove</a></div>');
        }
    });
   
    $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
        e.preventDefault(); $(this).parent('div').remove(); x--;
    })
});
</script>

Open in new window

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Add the input to the form like so
<input type="hidden" name="totalfields" />

Open in new window

Add the following to the add_button
$('input[name="totalfields"]').val(x);

Open in new window

Add the following to the remove button
$('input[name="totalfields"]').val(x);

Open in new window

Full listing at the end
However, there is an error with your current setup as per solution given you in previous question. The problem is that you can end up with duplicate names.
Add two rows then delete the middle and add again - you will see the problem.

This is easy to fix but depends on what you want the behaviour to be.

Do you want it that the fields must be sequential and contiguous i.e 1,2,3,4
Or must they just be different so you could have 1,2,5,6

Post back on which you want and I will post a solution.

<!doctype html>
<html>
<head>
<title>Test</title>
<link href="css/bootstrap.css" rel="stylesheet" />
<style type="text/css">
</style>
</head>
<body>
<form method="post" action="actionPage.cfm">
<input type="hidden" name="totalfields" />
<div class="input_fields_wrap">
    <button class="add_field_button">Add More Fields</button>
    <div><input type="text" name="name"> <input type="checkbox" name="auth" value="auth">Authorized <input type="checkbox" name="auth" value="noauth">Not Authorized </div>
</div>
<input type="submit" value="submit">
</form>
<script src="http://code.jquery.com/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    var max_fields      = 10; //maximum input boxes allowed
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID
   
    var x = 1; //initlal text box count
    $(add_button).click(function(e){ //on add input button click
        e.preventDefault();
        if(x < max_fields){ //max input box allowed
            x++; //text box increment
            $(wrapper).append('<div><input type="text" name="name' + x + '"/> <input type="checkbox" name="auth' + x + '" value="auth">Authorized <input type="checkbox" name="auth' + x + '" value="noauth">Not Authorized <a href="#" class="remove_field">Remove</a></div>'); //add input box
			$('input[name="totalfields"]').val(x);
        }
    });
   
    $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
        e.preventDefault(); 
			$(this).parent('div').remove(); 
			x--;
			$('input[name="totalfields"]').val(x);
    })
});
</script>
</body>
</html>

Open in new window

Avatar of earwig75
earwig75

ASKER

The field names do not have to be sequential, as long as they are different. Thank you very much.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you for all the help. This is great.
You are most welcome.
Thank you for the help today. Would you be able to show me the example with keeping the numbers in sequence as well, if it isn't too much trouble?
I am now using radio buttons instead of check boxes, and I also made the first choice begin with "1". Below is my current code:

<form method="post" action="actionpage.cfm">
<input type="hidden" name="totalfields" />
<div class="input_fields_wrap">
    <button class="add_field_button">Add More Fields</button>
    <div><input type="text" name="name1"> <input type="radio" name="auth1" value="auth">Authorized <input type="radio" name="auth1" value="noauth">Not Authorized </div>
</div>
<input type="submit" value="submit">
</form>
<script type="text/javascript">
$(document).ready(function() {
    var max_fields      = 10; //maximum input boxes allowed
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID
   
    var x = 1; //initlal text box count
    $(add_button).click(function(e){ //on add input button click
        e.preventDefault();
        var total = $('.input_fields_wrap div').length;
        if(total < max_fields){ //max input box allowed
            x++; //text box increment
            $(wrapper).append('<div><input type="text" name="name' + x + '"/> <input type="radio" name="auth' + x + '" value="auth">Authorized <input type="radio" name="auth' + x + '" value="noauth">Not Authorized <a href="#" class="remove_field">Remove</a></div>'); //add input box
      $('input[name="totalfields"]').val(total+1);
        }
    });
   
    $(wrapper).on("click",".remove_field", function(e){ //user click on remove text
        e.preventDefault(); 
        $(this).parent('div').remove(); 
		
		// GET THE TOTAL INPUTS USING JQUERY
        var total = $('.input_fields_wrap div').length;
		
		// SET THE TOTAL NUMBER OF INPUTS
        $('input[name="totalfields"]').val(total);
    })
});
</script>

Open in new window

Here you go
var max_fields      = 10; //maximum input boxes allowed

$(function() {
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID

    $(add_button).click(function(e){ //on add input button click
    e.preventDefault();

    // Get the number of divs in the pile
    var length = $('.input_fields_wrap > div').length;

    // Check that we have not reached the max
    if (length < max_fields) {
  
      // Create the new div
      var div = $('<div><input type="text" name="name"> <input type="checkbox" name="auth" value="auth">Authorized <input type="checkbox" name="auth" value="noauth">Not Authorized <a href="#" class="remove_field">Remove Field<a/></div>');
      // Increment length because we are dealing with the next 1
      length++;
    
    // Set the name value for the new div using the length 
    // last man in so the length is the one to use
      $('input', div).each(function() {
        $(this).attr('name', 'name' + length);
      });
    
    // Add it
      wrapper.append(div);
    
    // Update hidden val
      $('input[name="totalfields"]').val(length);
    }
  });


    //user click on remove text
  wrapper.on("click",".remove_field", function(e){ 
    e.preventDefault(); 
  
    //  Remove the closest div
    $(this).closest('div').remove();

    // Get list of active divs
    var divs = $('.input_fields_wrap > div');
    // Loop through them
    divs.each(function(i) {

      // Loop through the inputs in each one
      $('input', $(this)).each(function() {
        // Get the name value
        var name = $(this).attr('name');
    
        // Do a regex replace of the digit
        // WARNING: names cannot contain other numbers
        name = name.replace(/\d+/, i+1);
    
        // Put it back
        $(this).attr('name', name);
      });
    });
    // Update hidden value
    $('input[name="totalfields"]').val(divs.length);
  })
});

Open in new window

Thanks but I think there are some errors with the last example. It only sent across the below. 1 auth, and then put the ohters into a list as names like this:

AUTH1=auth
FIELDNAMES=TOTALFIELDS,NAME1,AUTH1,NAME2,NAME3
NAME1=charlie
NAME2=bob,noauth
NAME3=henry,auth
TOTALFIELDS=3
I posted a new question for this so if you can get it working and want to help you can at least get credit for it. Thanks again.
Simple change - a line was left out of the code - it should have been setting the name of the input to its previous name + length not the string 'name' + length.

Corrected code
var max_fields      = 10; //maximum input boxes allowed

$(function() {
    var wrapper         = $(".input_fields_wrap"); //Fields wrapper
    var add_button      = $(".add_field_button"); //Add button ID

    $(add_button).click(function(e){ //on add input button click
    e.preventDefault();

    // Get the number of divs in the pile
    var length = $('.input_fields_wrap > div').length;

    // Check that we have not reached the max
    if (length < max_fields) {
  
      // Create the new div
      var div = $('<div><input type="text" name="name"> <input type="checkbox" name="auth" value="auth">Authorized <input type="checkbox" name="auth" value="noauth">Not Authorized <a href="#" class="remove_field">Remove Field<a/></div>');
      // Increment length because we are dealing with the next 1
      length++;
    
    // Set the name value for the new div using the length 
    // last man in so the length is the one to use
      $('input', div).each(function() {
	    var name = $(this).attr('name');
        $(this).attr('name', name + length);
      });
    
    // Add it
      wrapper.append(div);
    
    // Update hidden val
      $('input[name="totalfields"]').val(length);
    }
  });


    //user click on remove text
  wrapper.on("click",".remove_field", function(e){ 
    e.preventDefault(); 
  
    //  Remove the closest div
    $(this).closest('div').remove();

    // Get list of active divs
    var divs = $('.input_fields_wrap > div');
    // Loop through them
    divs.each(function(i) {

      // Loop through the inputs in each one
      $('input', $(this)).each(function() {
        // Get the name value
        var name = $(this).attr('name');
    
        // Do a regex replace of the digit
        // WARNING: names cannot contain other numbers
        name = name.replace(/\d+/, i+1);
    
        // Put it back
        $(this).attr('name', name);
      });
    });
    // Update hidden value
    $('input[name="totalfields"]').val(divs.length);
  })
});

Open in new window

It is not working; I posted an update in the new question.