How can I Display Count of Characters in Field where Field Name is a Variable

I'm trying to create a form that will have a variable number of data entry record fields depending on the user requirements.  I'm using php to generate unique IDs for the fields based on an array that in the real setting is a list of IDs from a table in SQL Server.  The data entry fields needs to display feedback to the user about how many characters have been used/remain so that the user does not create text that is longer than can be stored.  In the code that I'm showing below, I have everything working except the javascript function that I've called 'feedback', no longer displays a running count of characters as the user types into the field.  

The code pasted below shows a form with a select box where the user will select the appropriate # of field records to display.  For example, if the user selects 3, then three text boxes and corresponding feedback text will display.

Your feedback and help on this problem is greatly appreciated.  I'm a bit of a newbie to javascript/php.

<script>
$(document).ready(

	function feedback() {
		var text_max_record = []
		var text_length_record = []
		var text_remaining_record = []
		var m = maxcount.value;
		for (var k=0; k<=m; k++) {
			$('#record' + k).bind('input change paste keyup mouseup', function () {
				text_max_record[k] = 150;
				text_length_record[k] = $('#record' + k).val().length;
				text_remaining_record[k]  = text_max_record[k] - text_length_record[k];
				$(this).after($('#feedback_record' + k).html(text_remaining_record[k]  + ' characters remain'));
			});
			$('#record' + k).keyup();
		}		
	}

	);
</script>

<script>
function show(recordcount){
	//Get value of record count when user changes value in select 
	var n = recordcount.options[recordcount.selectedIndex].value;
	var x = n;
	var z = maxcount.value;

	//Hide Data Entry Fieldset and all Data Entry rows
	document.getElementById('records').style.display = "none";
	for (j = 1; j <= z; j++) { 
		document.getElementById('recorddiv' + j).style.display = "none";
	}
	//For # in Select Box
	for (i = 0; i <= n; i++) { 
		//show or hide Data Entry fieldset
		if (n == 0) {
			document.getElementById('records').style.display = "none";
		} else { 
			document.getElementById('records').style.display = "block";
		}
		//show the correct # of Data Entry Rows
		document.getElementById('recorddiv' + x).style.display = "block";
		x--
	}
}
</script>
<html>
<body>
<div class="row">
<hr>
<div class="large-12 columns">
<a name="example_addvariable"></a>
<h3>Add Record(s)</h3>
<hr>
<form action="" method="post" name="form_example_addvariable" onSubmit="javascript: return validate();" enctype="multipart/form-data">
<div class="row">
<div class="large-12 columns">
<fieldset>
<legend>Record Details:</legend>
<div class="row">
<div class="large-12 columns">
<div id="fieldint">
<div class="large-3 columns">
<label for="fieldint">
<span data-tooltip aria-haspopup="true" class="has-tip" title="Required.  Select zero if you have no data to add.  This field represents the number of fields you want to display for data entry."># of Records to Add:
<i class="fi-info"></i>
</span>
</label>
<select required name='recordcount' id='recordcount' placeholder="Choose # of Records" onchange="show(this)">
<option value="">Select # of Records To Add...</option>
<option value="0" selected>0</option>
<option value='1'>1</option>
<option value='2'>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
</select>
</div>
</div>
<div class="large-4 columns" style="display:none;">
<label for="maxcount">Hidden Max # Records:
<input type="text" id="maxcount" name="maxcount" value="5">
</label>
</div>
</div>
</div>
</fieldset>
</div>
</div>
<div id="records" style="display:none;">
<fieldset>
<legend>Record Fields For Data Entry:</legend>
<?php
$sql1 = array ("1","2","3","4","5");
$sql1result = count($sql1);
for($x = 0; $x < $sql1result; $x++) {
?>
<div id = "recorddiv<?php echo $sql1[$x];?>" class="row" style="display:none;">
<div class="large-12 columns">
<div class="large-6 columns">
<label for="record<?php echo $sql1[$x];?>">Record #<?php echo $sql1[$x];?> Data Entry:</label>
<input type="text" name="record<?php echo $sql1[$x];?>" id="record<?php echo $sql1[$x];?>" maxlength="150" placeholder="Record #<?php echo $sql1[$x];?> Data Entry">
<p style="text-align: right" id="feedback_record<?php echo $sql1[$x];?>"></p>
</div>
</div>
</div>
<?php }?>
</fieldset>
</div>
</form>
</div>
</div>
</body>
</html>

Open in new window

SueJStevensAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
This feels kind of clunky to me, but it makes some sense.  On the server side, after the form is submitted, you would want to check the input control named "kount" to know how many of the textareas you wanted to process.  I set the character count to 16 to make it easier to test by hand.
http://iconoun.com/demo/temp_suejstevens.php
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style type="text/css">
/* STYLE SHEET HERE */
</style>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function(){

    $('#unit1').hide();
    $('#unit2').hide();
    $('#unit3').hide();

    $('#howmany').change(function(){
        var kount = $('#howmany').val();

        $('#unit1').hide();
	$('#unit2').hide();
        $('#unit3').hide();

        if (kount > 0) $('#unit1').show();
        if (kount > 1) $('#unit2').show();
        if (kount > 2) $('#unit3').show();
    });

    $('#textarea1').keypress(function(){
        if(this.value.length > 15){
            return false;
        }
        $("#remainingChr1").html("Remaining characters: " +(15 - this.value.length)+ " of 16");
    });

    $('#textarea2').keypress(function(){
        if(this.value.length > 15){
            return false;
        }
        $("#remainingChr2").html("Remaining characters: " +(15 - this.value.length)+ " of 16");
    });

    $('#textarea3').keypress(function(){
        if(this.value.length > 15){
            return false;
        }
        $("#remainingChr3").html("Remaining characters: " +(15 - this.value.length)+ " of 16");
    });

});
</script>

<title>HTML5 Page With jQuery in UTF-8 Encoding</title>
</head>
<body>

<noscript>Your browsing experience will be much better with JavaScript enabled!</noscript>

<form>

<select name="kount" id="howmany">
<option value="0">How many?</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>

<p id="unit1">
<span id='remainingChr1'></span>
<br>
<textarea id="textarea1"></textarea>
</p>

<p id="unit2">
<span id='remainingChr2'></span>
<br>
<textarea id="textarea2"></textarea>
</p>

<p id="unit3">
<span id='remainingChr3'></span>
<br>
<textarea id="textarea3"></textarea>
</p>

</form>

</body>
</html>

Open in new window

0
SueJStevensAuthor Commented:
Ray,
I was very much hoping you'd be the person to pick up this question.  Thank you!  You have been so helpful to me in the past and now.   I'm going to test it on my side in a bit and then I will get back to you with more questions or award points.
0
SueJStevensAuthor Commented:
Ray,
Here's my problem:  It looks like your solution requires a series of code for each '#unit'.  So what if I have 50 to start -- I write that code 50 times?  Then what if my user calls me and asks for 51 slots?  --in fact that is what I've done and that is what happened--my user just asked me for more slots.  I was hoping to create a solution that utilized a variable.
Thanks.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Julian HansenCommented:
Your show script was not working because the x value was being decremented to 0 and there was no recorddiv0 - which was throwing an error.
You can achieve the show functionality with jQuery much easier with this code
<script>
function show(recordcount){
  var n = $(recordcount).val();
  if (n == 0) {
    $('#records').hide();
  }
  else {
    $('#records').show();
    $('.recorddiv').hide();
    $('.recorddiv:lt(' + n + ')').show();
  }
}
</script>

Open in new window

This sorts the showing problem - your feedback function still does not work - I will post an update to that shortly.
0
Julian HansenCommented:
PS. for the above to work you need to add a class to your recorddiv's like this
<div id = "recorddiv<?php echo $sql1[$x];?>" class="row recorddiv" style="display:none;">

Open in new window

0
SueJStevensAuthor Commented:
Julian,
Thank you -- your code is certainly cleaner than mine!  I'm looking forward to your update on my feedback function.
Thanks again for your help.
0
Julian HansenCommented:
Here is the remaining code
$(function() {
  $('body').on('keyup','.limit-input', function() {
    var len = $(this).val().length;
    var max = $(this).attr('maxlength');
    var available = max - len;
    var index = $(this).data('index'); 
    $('#feedback_record' + index).html(available + ' characters remain');
  });
});

Open in new window

I have made some modifications to your html code as well leveraging some of the features of HTML5.
I changed the <input> definition as follows
 <input class="limit-input" data-index="<?php echo $sql1[$x];?>" type="text" name="record<?php echo $sql1[$x];?>" id="record<?php echo $sql1[$x];?>" maxlength="150" placeholder="Record #<?php echo $sql1[$x];?> Data Entry">

Open in new window

I gave the input a class (limit-input) that is used to attach the event handler to
(Note: bind() has been deprecated - you should use .on())

I also gave the <input> a custom data attribute (data-index) and set this equal to the SQL index (same index used to append values to your id's) This makes it easier to target the #feedback_record attached to the input.
The rest is pretty straight forward - full source below - working sample here
<html>
<body>
<div class="row">
  <hr>
  <div class="large-12 columns">
  <a name="example_addvariable"></a>
  <h3>Add Record(s)</h3>
  <hr>
  <form action="" method="post" name="form_example_addvariable" onSubmit="javascript: return validate();" enctype="multipart/form-data">
    <div class="row">
      <div class="large-12 columns">
        <fieldset>
          <legend>Record Details:</legend>
          <div class="row">
            <div class="large-12 columns">
              <div id="fieldint">
                <div class="large-3 columns">
                  <label for="fieldint">
                    <span data-tooltip aria-haspopup="true" class="has-tip" title="Required.  Select zero if you have no data to add.  This field represents the number of fields you want to display for data entry."># of Records to Add:
                    <i class="fi-info"></i>
                    </span>
                  </label>
                  <select required name='recordcount' id='recordcount' placeholder="Choose # of Records" onchange="show(this)">
                    <option value="">Select # of Records To Add...</option>
                    <option value="0" selected>0</option>
                    <option value='1'>1</option>
                    <option value='2'>2</option>
                    <option value='3'>3</option>
                    <option value='4'>4</option>
                    <option value='5'>5</option>
                  </select>
                </div>
              </div>
              <div class="large-4 columns" style="display:none;">
                <label for="maxcount">Hidden Max # Records:
                <input type="text" id="maxcount" name="maxcount" value="5">
                </label>
              </div>
            </div>
          </div>
        </fieldset>
      </div>
    </div>
    <div id="records" style="display:none;">
      <fieldset>
        <legend>Record Fields For Data Entry:</legend>
        <?php
        $sql1 = array ("1","2","3","4","5");
        $sql1result = count($sql1);
        for($x = 0; $x < $sql1result; $x++) {
        ?>
          <div id = "recorddiv<?php echo $sql1[$x];?>" class="row recorddiv" style="display:none;">
            <div class="large-12 columns">
              <div class="large-6 columns">
                <label for="record<?php echo $sql1[$x];?>">Record #<?php echo $sql1[$x];?> Data Entry:</label>
                <input class="limit-input" data-index="<?php echo $sql1[$x];?>" type="text" name="record<?php echo $sql1[$x];?>" id="record<?php echo $sql1[$x];?>" maxlength="150" placeholder="Record #<?php echo $sql1[$x];?> Data Entry">
                <p style="text-align: right" id="feedback_record<?php echo $sql1[$x];?>"></p>
              </div>
            </div>
          </div>
        <?php }?>
      </fieldset>
    </div>
  </form>
  </div>
</div>
<script src="http://code.jquery.com/jquery.js"></script>
<script>
$(function() {
  $('body').on('keyup','.limit-input', function() {
    var len = $(this).val().length;
    var max = $(this).attr('maxlength');
    var available = max - len;
    var index = $(this).data('index'); 
    $('#feedback_record' + index).html(available + ' characters remain');
  });
});
</script>

<script>
function show(recordcount){
  var n = $(recordcount).val();
  if (n == 0) {
    $('#records').hide();
  }
  else {
    $('#records').show();
    $('.recorddiv').hide();
    $('.recorddiv:lt(' + n + ')').show();
  }
}
</script>
</body>
</html>

Open in new window

[Edit: to fix spelling error]
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Julian HansenCommented:
For completeness (because at EE we are particular about our sample scripts working) I made a small change to the onload
<script>
$(function() {
  $('body').on('keyup','.limit-input', function() {
    var len = $(this).val().length;
    var max = $(this).attr('maxlength');
    var available = max - len;
    var index = $(this).data('index'); 
    $('#feedback_record' + index).html(available + ' characters remain');
  });
  // ADDED THIS
  $('.limit-input').trigger('keyup');
});
</script>

Open in new window

0
Julian HansenCommented:
One other point I forgot to make - the keyup routine uses the maxlength attribute defined on the <input> to work out how many characters to type - so that needs to be defined.
0
Ray PaseurCommented:
Hi, Sue.  Yes, I thought about that but didn't want to make it more complicated than it needed to be in the first cut.  It's my practice to write the simplest possible take on things first, then refactor to make it better.  The central objective would be to have an equal number of matching DOM elements that were named textareas and named character counters.  A jQuery solution that had a button with "add a textarea" functionality would seem to make sense.  The PHP side of things would need a little thought - what if a client asked for 50 textareas but only used number 3 and number 37, for example.  I'll let you an d Julian work it out - it's late in the day here and I'm ready to go home.

Best of luck with it, ~Ray
0
SueJStevensAuthor Commented:
Julian,
Wow!  Thanks.  I need to study and absorb what you've put together for me so I can modify to make it work in my real model with my real data.  I will be back soon to award points or ask questions.
0
SueJStevensAuthor Commented:
Julian,
Thank you so much for doing this.  So very helpful to me.  Wish I could double the point value!
0
Julian HansenCommented:
You re most welcome.

I need to study and absorb what you've put together for me so I can modify to make it work in my real model with my real data.
Feel free to post back if you need an explanation of what was done.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.