Link to home
Start Free TrialLog in
Avatar of SueJStevens
SueJStevensFlag for United States of America

asked on

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

Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

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

Avatar of SueJStevens

ASKER

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.
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.
Avatar of Julian Hansen
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.
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

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.
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
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

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.
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
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.
Julian,
Thank you so much for doing this.  So very helpful to me.  Wish I could double the point value!
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.