Jump to content

Mixed Use of jQuery Selectors


iwato

Recommended Posts

Please consider the following code and answer the question.  Please do not omit your reasons for answering as you did.

CODE SYNOPSIS:  This handy piece of code places a constraint on the number of words that can be placed in a selected <textarea> element.  In addition, it displays the current status of the selected element as one enters text.  This code, less the iterative aspect, has been tested for one <textarea> element, but I wish now to expand it to include many <textarea> elements.  In order to do this I created a mixed associative array (see below) whose data I use to select each <textarea> element and apply a different constraint.

Although I have identified each <textarea> element by its unique id='' attribute I have used the class='' attribute to display the current status of the selected <textarea> element.  My motivation for doing this latter is, of course, one of efficiency. My belief is that specific overrides general, and that the values generated by the id='' attribute will override those designated by the class='' attribute -- a designation that is common to all <textarea> elements.

QUESTION:  Is this sound Javascript programming logic?  Or, must I change the class='' attributes to the same id='' attribute for each <textarea> element?
 

<?php 
	foreach($wordmax as $textarea => $arr) {
	$area_id = $arr['id'];
	$max = $arr['length'];
	$($area_id).on('keydown', function(e) {
		var words = $.trim(this.value).length ? this.value.match(/\S+/g).length : 0;
		if (words <= $max) {
			$('.display_count').text(words);
			$('.words_remaining').text($max-words);
		}else{
			if (e.which !== 8) e.preventDefault();
		}
	});
}
?>
<textarea id='letter_body' name='letter_body'>...</textarea><br />
Word Count: <span class='display_count'>0</span>  Words Remaining: <span class='words_remaining'>0</span>

<textarea id='letter_abstract' name='letter_abstract'>...</textarea><br />
Word Count: <span class='display_count'>0</span>  Words Remaining: <span class='words_remaining'>0</span>

 

$wordmax = array(
	'letter_abstract' => array (
		'id' => '#letter_abstract',
		'length' => '150'
	),
	'letter_body' => array (
		'id' => '#letter_body',
		'length' => '800'
	),
			.
			.
			.
	'student_bio' => array (
		'id' => '#student_bio',
		'length' => '400'
	),
);

 

Link to comment
Share on other sites

After the above careful consideration I believe that I am in error, for there is nothing that binds the individual span tags to their respective <textarea> element.  OK, so what if I were to include both <textarea> element and its respective <span> elements in the same <div> element, select the uniquely defined <div> element by its id='' attribute, and designate everything else by its more general HTML tag identity -- namely, <textarea> and <span>?

Roddy

Edited by iwato
Link to comment
Share on other sites

<script>
foreach($wordmax as $textarea => $arr) {
	$area_div = $arr['id'];
	$max = $arr['length'];
	$($area_div textarea).on('keydown', function(e) {
		var words = $.trim(this.value).length ? this.value.match(/\S+/g).length : 0;
		if (words <= $max) {
			$('.display_count').text(words);
			$('.words_remaining').text($max-words);
		}else{
			if (e.which !== 8) e.preventDefault();
		}
	});
}
</script>

<div id='letter_abstract'>
	<textarea name='letter_abstract' placeholder="Enter this week's abstract here!"></textarea><br />
	Word Count: <span class='display_count'>0</span>  Words Remaining: <span class='words_remaining'>0</span>
</div><!-- end div#letter_abstract -->

<div id='letter_body'>
	<textarea name='letter_body' placeholder="Enter this week's content here!"><br />
	Word Count: <span class='display_count'>0</span>  Words Remaining: <span class='words_remaining'>0</span>
</div><!-- end div#letter_body -->

One question, though:  Are the selectors of the jQuery objects properly specified?

Edited by iwato
Link to comment
Share on other sites

There many way of targeting elements and related elements by transversing through siblings or using indexing. You can use classname for these specific textarea elements, then use next() which will be next sibling span element, find() which will next element or specific class element, or by indexing, textarea index 0, span with specific class same index.

Then max can be taken from custom data- attribute added to textarea element or the span itself.

Link to comment
Share on other sites

You seem to be confusing PHP with Javascript. They're two differently languages running in completely different environments.

PHP goes inside <?php ?> tags, Javascript must be outside of them and between <script> tags. PHP and Javascript never mix.

Link to comment
Share on other sites

The best approach is to avoid arrays, because you would be constantly updating JavaScript array code for id reference and max word count, and work on a way of using and setting the required information within html, so the script will automatically gather this info and run without the need for adjustment.

class name added to div container 'textarea_maxword', custom data attribute to span 'data-maxcount'

        <div id='letter_abstract' class="textarea_maxword">
            <textarea name='letter_abstract' placeholder="Enter this week's abstract here!"></textarea><br />
            Word Count: <span class='display_count'>0</span>  Words Remaining: <span data-maxcount="800" class='words_remaining'>0</span>
        </div><!-- end div#letter_abstract -->

        <div id='letter_body' class="textarea_maxword">
            <textarea name='letter_body' placeholder="Enter this week's content here!"></textarea><br />
            Word Count: <span class='display_count'>0</span>  Words Remaining: <span data-maxcount="400" class='words_remaining'>0</span>
        </div>
            $(function() {
                $(".textarea_maxword textarea").on('keydown', function(e) {
                    var words = $.trim(this.value).length ? this.value.match(/\S+/g).length : 0;
                    var max = $(this).parent().find('.words_remaining').attr('data-maxcount');
                    if (words <= max) {
                        $(this).parent().find('.display_count').text(words);
                        $(this).parent().find('.words_remaining').text(max - words)
                    } else {
                        if (e.which !== 8)
                            e.preventDefault();
                    }
                });


            });

 

Link to comment
Share on other sites

Ingolme:  You were correct in your observation that I was confusing PHP with Javascript.  Only after I made my posting did I realize this and attempt to correct for it.  Please see my newly created post in the Javascript forum.

Dsonesuk:  I understand what you are saying and will likely do as you suggest, but only if I am unable to easily convert a nested JS object into a nested JS array, or alternatively, simply use the nested object, as if it were a nested array.  I am unfamiliar with the use of Javascript objects, and only today did I truly discover JSON encoding and decoding.  I am trying to avoid still another entirely new block of code learning and work only with what I already know.  There will be time later for further refinement and code upgrade.

As always, thank you for kind and generous guidance.  You are both so very helpful.

Roddy

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...