0

I've been working on a code snippet for a template module that I have been creating and I've hit a wall so to speak. I'm trying to loop through all textareas on my page, and apply formatting with some very basic validation.

Javascript is not my strongest suit but I can understand it to a point, my question is how do I collect the ID's and then use them to apply the formatting.

For example,

for each (textarea) 
{
    collect character restriction from html
    display character restriction in a formatted manner
}

I have included my JSFiddle which I have been using to build this snippet.

6
  • 2
    You can use getAttribute('id') to get the id of the object: jsfiddle.net/grhLupp7/2. However, you're already collecting all the textareas in count. Just access them via count[i] Commented Aug 12, 2016 at 10:20
  • 2
    @eithedog el.id <- This is shortest Commented Aug 12, 2016 at 10:21
  • I could access them via the index, but it would be numeric, how would i capture the ID's ? Commented Aug 12, 2016 at 10:22
  • 2
    @TheProHands aye, I keep making my life harded :D, @Beaniie - no, i is the index, count[i] is the textarea. Have a look at linked fiddle, I've put in a line that console.logs retrieval of id. And as @TheProHands pointed out you can use count[i].id to retrieve id as well Commented Aug 12, 2016 at 10:25
  • 1
    @JeremyThille I tried to keep it away from jquery as the majority of all the code elements in the is project are Pure JS. Just keeping it consistant. Thanks for pointing out my hiccup. :) Commented Aug 12, 2016 at 10:25

2 Answers 2

2

I would suggest creating a prototype class for this, that can be extended to do other things aswell:

var CharWatcher = function(input){
  this.max = input.getAttribute('max-length');
  this.input = input;

  input.onKeyDown = this.update.bind(this);

  this.wrapper = document.createElement('div');
  this.wrapper.innerHTML = 'Chars left: '+ (max - input.value.length);
  /* style wrapper element */
  /* append around input */
};

CharWatcher.prototype = {
  update: function(){
     this.wrapper.innerHTML = 'Chars left: ' + (this.max - this.input.value.length);
  }
};

/* Somewhere else */

var textareas = document.getElementsByTagName('textarea');
for(var i = 0, l = textareas.length; i < l; i++)
    new CharWatcher(textareas[i]);
Sign up to request clarification or add additional context in comments.

Comments

1

I've based on @FodorZoltán's class. My class does now:

  • append the counter below the textarea;
  • position the counter in the below part of the textarea;

Yeah, I'm lazy and the code has grown up. I added some events and renamed the class name to "TextAreaRanger". It's working here:

var TextAreaRanger = function(input) {

    this.MAX = parseInt(input.getAttribute('maxlength'));
    this.INPUT = input;

    // add input events
    input["oncut"] =
    input["onpaste"] =
    input["onkeydown"] =
    input["onkeyup"] = this.update.bind(this);

    // create wrapper element
    this.wrapper = document.createElement('div');
    this.wrapper.innerHTML = 'Chars left: '+ (this.MAX - input.value.length);

    /* input parent element */
    var ipar = input.parentNode;

    // find input's i
    for (var i = 0, el; el = ipar.children[i]; i ++) {
        if(el === input) break;
    }

    // append wrapper below the input
    if (ipar.children[++i]) {
        ipar.insertBefore(this.wrapper, ipar.children[i]);
    } else ipar.appendChild(this.wrapper);

    /* stylize wrapper */
    this.wrapper.style.position = "relative";
    this.wrapper.style.color = '#f00';
    this.wrapper.style.fontSize = '11px';
    this.wrapper.style.left = (input.offsetLeft + (input.offsetWidth - 100)) + "px";
    this.wrapper.style.top = (-parseInt(this.wrapper.style.fontSize) * 2) + "px";
};

// Update the counter
TextAreaRanger.prototype["update"] = function() {
    this.wrapper.innerHTML = 'Chars left: ' + (this.MAX - this.INPUT.value.length);
};

2 Comments

It's quite jarring to see how others work, this is quite elegant in my opinion. I think i need to research Javascript classes a bit more among other aspects before I fully understand your answer. Thank you for your assistance with this. :)
@Beaniie Oh... classes aren't a solution for this, but they're recommended to store less data in the JavaScript memory, that's because every class (function) contain the prototype object where it's possible to store values or methods which can be used in a instance of the same class. function A() {this.call = function() { alert(1); };}; var a = new A, b = new A; is slower than function A() {}; A.prototype.call = function() { alert(1); }; var a = new A, b = new A;.

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.