Cmb2: Character counter / max option

Created on 15 Mar 2019  路  16Comments  路  Source: CMB2/CMB2

A project of ours needs a character counter, applicable to WYSIWYGs and textareas. It would show how many characters have been entered, and optionally enforce a limit.

Just wanted to check (1) if you've anything in the pipeline along these lines, and (2) if not, would it be something you'd be interested in as a contribution to CMB2, or would you prefer a separate plugin?

I'm thinking of 2 new field parameters, applicable to textareas and WYSIWYGs:

  • char_counter (true / false)
  • char_max (integer, only works if char_counter is true)

Most helpful comment

Success! I was looking for $this->types->iterator. PR hopefully heading your way very soon.

All 16 comments

I know we have https://github.com/CMB2/CMB2-Snippet-Library/blob/master/misc/adding-wordcount-to-cmb2-wysiwyg-field.php which talks about this topic and has a working solution, or at least was working last I knew :D

Thanks - so you'd prefer this stuff kept as snippets, rather than as part of the plugin?

I'd be open to a PR. Please consider the contribution guidelines if/when submitting. Thanks!.

To add to Justin's feedback, it hasn't traditionally been a large requested feature, which is why it was left as a snippet thus far.

Thanks, I'll have a crack at a PR.

Making good progress, though I've just hit an odd issue.

I've created a new file, cmb2-char-counter.js, which closely follows the structure of cmb2-wysiwyg.js. It's been working well until now, the initAll() function no longer seems to work.

I can post all the code if necessary, but I can briefly explain. Imagine the line in my file that corresponds to this in the WYSIWYG file:

$( document ).on( 'cmb_init', wysiwyg.initAll );

If I output to the console above or below this, I get the output. However, if I try to output to console inside the initAll() function, nothing.

If I add something like this just next to my cmb_init hook:

$( document ).on( 'cmb_init', function() { console.log( 'test' ); });

Again, nothing. So it looks like either cmb_init isn't being run for some reason, or hooking to it is no longer working.

No errors from jshint, no console errors in the browser, and the loaded JS source is correct so no caching issues.

It's all been working until just recently, I'm trying to remove stuff I've added but most of it is inside functions that aren't being called, so I'm focussing more on this apparent cmb_init issue. Just wondered if you'd ever encountered something like this before.

OK, got back to this and the above issue seems to have 'cleared itself up'.

A couple of general points:

  • For now I'm sticking to textareas. Text inputs can have the maxlength attribute added, and WYSIWYG I may tackle later. (The main WP editor has a built-in word count. It doesn't appear by default with CMB2 fields. Any ideas about this?)
  • I've added a parameter to enforce, which just adds the maxlength attribute to the textarea (defaults to false). When a max is set, the counter counts down with 'characters/words left' as per Twitter. If there's no enforcement, it shows a customisable message in red when you go over (e.g. 'Your text may be truncated.' I've left server-side enforcement for devs to handle with hooks if necessary.

@tw2113 @jtsternberg I've got things working with repeatable groups, I'm currently struggling with repeatable individual fields. From a method in CMB2_Type_Base.php, how would I get the index of the repeatable field? $this->field->index and $this->field->iterator both seem to be 0 for all fields, even though the iterator value and the field ID is set properly for the field itself on output. I need the proper field ID, with the _n suffix for repeatable fields.

@tw2113 @jtsternberg Any ideas on this? I'm having another go at getting the repeatable field index but basically I'm still stuck in the same place with this. I think this is the last hurdle before I can submit a PR.

Success! I was looking for $this->types->iterator. PR hopefully heading your way very soon.

I have nothing, for the record.

@tw2113 @jtsternberg Latest: I've got the character counter working well for WYSIWYGs. I'm stuck on WYSIWYGs in repeatable groups. I realise this configuration needed some special handling, and the complexity here is baffling me. Any chance of some pointers? The current state of the code is here:

https://github.com/gyrus/CMB2/tree/188d341c2af14481a34edacf6d92f76828a780e2

The counter is being included twice for existing fields, not sure why. And I'm not sure how to integrate with the templating code in CMB2_Type_Wysiwyg->add_wysiwyg_template_for_group(). Any help appreciated.

One other thing is that this is a bit of code I've adapted from WP core:

https://github.com/gyrus/CMB2/blob/188d341c2af14481a34edacf6d92f76828a780e2/js/cmb2-char-counter.js#L210

_.debounce() fails JS lint. _ is available from core when running, I guess the lint test can't infer this from core?

@tw2113 @jtsternberg I'm probably not going to find time to get the character counter working for WYSIWYGs in groups. Should I add proper exceptions, so the system doesn't try to add counters to such fields - and we can include what I've done in an upcoming release?

Also, I'm having problems with the JS lint issue. Once I put the code I've got on staging or live, I get _ not defined errors. Clearly it's an issue with cmb2.min.js being used (cmb2.js works locally).

I've tried simply copying the contents of cmb2.js into cmb2.min.js as a temporary hack, but that broken the counters completely (the init code didn't run).

I've also tried running grunt jshint:all --force as advised in the console, to no avail.

Any ideas how I can get this running?

At this point, it might make sense to get the WIP up as a PR so we can review and provide feedback. I'm a little leery that this could add a bunch of code to maintain for a pretty small benefit to most users. Don't get me wrong, it's a very cool feature, but I'm not confident it's necessary to be in the core of CMB2 (vs an extension) if it's very involved or a lot of code. I hope that makes sense.

@jtsternberg It would make sense if you'd said that when I initially asked if you'd like this as a contribution! You explicitly approved receiving a PR in this thread, after I'd asked if you'd prefer to keep this separate from the plugin core. On top of the extra effort I've had to go through to implement this as part of CMB2, if you now refuse it, I'll have all the extra effort of unpicking what I've done to implement it as something separate.

I've managed to hack the JS to work on our project for now.

Past that, I'm happy to implement exceptions for WYSIWYGs in groups so that non-working functionality doesn't cause problems. But I'm not happy to spend more time undoing work that you might have made unnecessary through flip-flopping your decisions.

@gyrus I understand your concern/anger, though I appreciate civil conversation.

I am not flip-flopping anything. I'm simply stating that based on the commentary on this issue, it makes me concerned that this may have become a huge code addition to the core code-base vs something fairly simple (e.g. the snippet from the beginning of the discussion: https://github.com/CMB2/CMB2-Snippet-Library/blob/master/misc/adding-wordcount-to-cmb2-wysiwyg-field.php).

Of course I won't know that w/o seeing the code, therefore I'm requesting you start the PR prematurely so we can discuss.

Re: making you do more work, of course you know no one is making you do more work, and again, while I appreciate your efforts, and your concerns, I have also put plenty of work into this project, and am primarily responsible for supporting the new code long-term, so I take new additions seriously. So that you don't have to do more work prematurely, please submit the PR and we can go from there.

@jtsternberg Sure, I'll get to the WYSIWYG group exceptions asap and PR.

Note that many of the issues I've been having here have been problems related to your build processes. I think it's probably best if I leave that for you to sort out from my PR. The actual unprocessed code works absolutely fine - it's just hitches related to strict JS linting.

And yes, it's probably best if you look at the code before passing comment on it. I think it's done pretty well, following CMB2 and WP best practices. It probably could have been less code, but then would have been less robust, and create more maintenance issues for you in the future. But again, if you've not actually looked at the code yet, I'll disregard your previous comments about its complexity!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gorirrajoe picture gorirrajoe  路  4Comments

jflagarde picture jflagarde  路  6Comments

noquierouser picture noquierouser  路  8Comments

mathetos picture mathetos  路  8Comments

apokyro picture apokyro  路  5Comments