Jump to content
bfncs

Char counter for text/textarea fields

Recommended Posts

Aha yes now I see. Ryan explains why and he's correct that a InputfieldTextareaCount would be a good/better way to go.

I think a way around it could be a check at line #41

if ($this->process != 'ProcessField') {
    return;
}

Edit: There's a bug filed on github long time ago.

But as with many modules up here, the problem is, dev's have time to make the module but not maintain it. :D

  • Like 4

Share this post


Link to post
Share on other sites

I've helped so many modules and filed issues or proposed a fix, it's getting annoying :/

Share this post


Link to post
Share on other sites

I've helped so many modules and filed issues or proposed a fix, it's getting annoying :/

That's because you are one of the good guys!

Share this post


Link to post
Share on other sites

Hi everyone,

thanks, Joss for again pointing to the issue and Some for suggesting a fix.

I want to maintain the module and would be more than happy to add a fix to the repository. The bug described (as well as the one on Github) does only occured when used in conjunction with Formbuilder, which is a paid module. I don't own it because I have no particular use for it, so it's also not possible for me to test suggested fixes.

If someone could please check whether Soma's suggestion works out (which I suppose, because actually he is one of the good guys) and I'll add it in an instant.

P.S.: Ryan's post mentioned above is actually an answer to me seeking advice on the best implementation. At the time asked and answered I didn't see too much benefit in implementing the functionality as an Inputfield of it's own in comparison with the current implementation - both had their advantages and drawbacks.

Seeing that that this now caused confusion to some and the Inputfield implementation could possibly be used with Formbuilder, I see the really benefit in doing the other implementation. I'm seriously considering to add the other implementation as a separate module now.

Share this post


Link to post
Share on other sites

@boundaryfunctions

I think this would also happen if used in a front-end form with using form API, which used Inputfield->render(). This would be the same as Formbuilder.

Share this post


Link to post
Share on other sites

That might explain why it is happening in my front end form.

I have tried that edit and it seems to work. I haven't checked thoroughly whether it causes any other issues in the process, though I cant think what problems it would cause.

boundaryfunctions - you should be able to check those yourself okay because it is not a question of having form builder installed.

Thanks guys!

  • Like 1

Share this post


Link to post
Share on other sites

Ok, I just pushed an update to the modules repository, also bumping the version number to 1.0.3. Could you please confirm that this fixes the problem for you?

@Soma:

I just tried to force the error in a frontend form but that worked fine instead. The problem in this case was in the function hooked after InputfieldTextarea::getConfigInputfields() which was only called in the backend. Thanks anyway for your - as always - very helpful suggestion!

@Martijn:

Thanks for the suggestion. I'm not sure whether this would be too restrictive because there might be handy uses of this module in the frontend - which would then be forbidden. I currently much favour to convert it into an Inputfield on it's own.

Thanks a lot to all of you for your help.

  • Like 1

Share this post


Link to post
Share on other sites

There is an up and downside as an input field.

The up is that conflicts should be non-existent.

The down is that you cannot add it to an existing field.

Maybe there is a way to do it where it targets very specific fields rather than just hitting all textareas.

That way it might also play with text fields as well? (is that possible?) for instance when you want to limit a title length.

Share this post


Link to post
Share on other sites

Hmm nananana... you can always switch the fieldtype and inputfield. As they would be compatible.

Now this module gets loaded on every request.

Share this post


Link to post
Share on other sites

Any chance this module can be updated to support textarea language fields?

Share this post


Link to post
Share on other sites

Great tip, Martijn Geerts!

Do anyone here now how to setup fields in ProcessPageEditTruncate.js? 

Readme says 4. Configure your fields in ProcessPageEditTruncate.js and save the file.

But I cannot see how to do it in the JS-file.

Share this post


Link to post
Share on other sites

@laban, sorry didn't spot your question earlier.

But here's the answer.

// DOM is ready
$(function () {
    // field with the name attribute title
    $("[name='title']").truncate({
        characters: 55,
        prefix: '',
        suffix: ' character(s)'
    });

    // field with the name attribute an-other-field
    $("[name='an-other-field']").truncate({
        characters: 160,
        prefix: '',
        suffix: ' character(s)'
    });

});

  • Like 3

Share this post


Link to post
Share on other sites

I have now installed the plugin, moved ProcessPageEditTruncate.js to AdminCustomFiles's root folder in "modules" and tested the custom settings you have provided (thank you!) multiple places, but I cannot seem to get it right. I'll paste my code below.

ProcessPageEdit is also activated in the module settings in ProcessWire (but no other options have been setup there).

Some guidance on what I am doing wrong would be much appreciated. (I am running ProcessWire 2.7.2). 

(function ($) {
	$.fn.truncate = function(options) {

		var $fields = this,
			name = $fields.attr('name'),
			settings = $.extend({
				characters: 128,
				prefix: '',
				suffix: '',
				class: 'notes'
			}, options );

		if ($fields.parent('.LanguageSupport').length) {
			var $fields = $("#langTabs_Inputfield_" + name ).find("input, textarea");
		}

		$fields.after("<span class='" + settings.class + "'></span>");

		$fields.each(function (index, el) {
			var truncate = function () {
				var value = $(el).val(),
					typed = typeof value != 'undefined' ? value.length : 0,
					left = settings.characters - typed;
				if (left < 0) {
					$(el).val(value.substr(0, settings.characters));
					truncate();
				} else {
					$(el).next("span").text(settings.prefix + left + settings.suffix);
				}
			}

			$(el).keyup(function() { truncate(); });
			truncate();
		});

		return this;
	};

}(jQuery));

// DOM is ready
$(function () {
    // field with the name attribute title
    $("[name='meta_title']").truncate({
        characters: 55,
        prefix: 'You have',
        suffix: ' character(s) left'
    });

});

Share this post


Link to post
Share on other sites

01. Is the name of your field in the actually 'meta_title'?

02. ProcessPageEditTruncate.js should be in '/site/templates/AdminCustomFiles/'!

  • Like 2

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By VeiJari
      Hi, this is the first we are trying to make a page that has only one type of user that has access to every page. 
      The other users should only have a given access to specific pages, not to the whole template.
      My structure
      -Field -Organisation -Project -Report I want that the "measurer" role only has access to "project x" and it's children, but no view access to every project, organisation or field. I've tried to do this with https://modules.processwire.com/modules/page-edit-per-user/ but it still needs a view access to the whole tree to see the "project x" page. Or is there something I haven't figured out?
      Maybe I have to make it via the API: a select field in the "organisation" template where the admins could add the users and then I use hook to update the privileges?
      Have you done something like this and how did you accomplish it?
      Any help would be appreciated.
       
    • By MoritzLost
      This module allows you to integrate hCaptcha bot / spam protection into ProcessWire forms. hCaptcha is a great alternative to Google ReCaptcha, especially if you are in the EU and need to comply with privacy regulations.

      The development of this module is sponsored by schwarzdesign.
      The module is built as an Inputfield, allowing you to integrate it into any ProcessWire form you want. It's primarily intended for frontend forms and can be added to Form Builder forms for automatic spam protection. There's a step-by-step guide for adding the hCaptcha widget to Form Builder forms in the README, as well as instructions for API usage.
      Features
      Inputfield that displays an hCaptcha widget in ProcessWire forms. The inputfield verifies the hCaptcha response upon submission, and adds a field error if it is invalid. All hCaptcha configuration options for the widget (theme, display size etc) can be changed through the inputfield configuration, as well as programmatically. hCaptcha script options can be changed through a hook. Error messages can be translated through ProcessWire's site translations. hCaptcha secret keys and site-keys can be set for each individual inputfield or globally in your config.php. Error codes and failures are logged to help you find configuration errors. Please check the README for setup instructions.
      Links
      Github Repository and documentation InputfieldHCaptcha in the module directory Screenshots (configuration)

      Screenshots (hCaptcha widget)

       
       

       
    • By Juergen
      Hello @ all,
      I have created an inputfield with a configuration field in the backend where you can set a time format for every language (see screenshot below).

      As you can see both language values (default and German) have the default value(%R), but I have set different values, which were correctly stored in the DB (see screenshot below):

      As you can see the values are '%R' and '%r'.
      I have created the configuration inputfield like this:
      /** @var InputfieldText $f */ $languages = $this->wire('languages'); $f = $this->wire('modules')->get('InputfieldText'); $f->attr('name+id', 'timeformat'); $f->label = $this->_('Timeformat on frontend'); $f->initValue = '%R';//default value $f->attr('value', $this->timeformat ? $this->timeformat : '%R'); $this->message($this->get('timesformat')); if($languages) { $f->useLanguages = true; foreach($languages as $language) { if($language->isDefault()) continue; $f->set("value$language", (string) $this->get("timeformat$language->id")); } } $f->inputType = 'text'; $f->description = $this->_('Please enter the time format that the times should appear on the frontend in strftime format.'); $f->notes = sprintf($this->_('For example shows the time as 08:00, as 08:00 AM. You can find more examples at %s.'), '<a href="https://www.php.net/manual/de/function.strftime.php">https://www.php.net/manual/de/function.strftime.php</a>'); $f->columnWidth = 100; The important part here is:
      if($languages) { $f->useLanguages = true; foreach($languages as $language) { if($language->isDefault()) continue; $f->set("value$language", (string) $this->get("timeformat$language->id")); } } I have borrowed the code from the DateTimeInputfield (https://github.com/processwire/processwire/blob/master/wire/modules/Inputfield/InputfieldDatetime/InputfieldDatetime.module), but the field values will be always populated with the default value ('%R').
      Are I am missing something? Does anyone has experience with multilanguage fields and could help me out?
      Thanks in advance.
    • By Juergen
      Hello @ all,
      I am creating a new inputfield/fieldtype to store opening hours, but I am struggeling to save values from multiple dynamic created inputfields in 1 column of the database.
      Scenario:
      The user can enter one or more opening times per day in a UI.
      Fe:
      Monday open from 08:00 to 12:00 and from 14:00 to 17:00 Tuesday open from 08:00 to 12:00 and from 14:00 to 19:00 and so on
      Via a little JavaScript you can add as much opening times as you need per day - the additional inputfield will be created dynamically.
      After form submission all the values are in the POST array -> this works (see example below):
      ProcessWire\WireInputData Object ( [openinghours_mo-0-start] => 09:00 [openinghours_mo-0-finish] => 13:00 [openinghours_mo-1-start] => 14:00 [openinghours_mo-1-finish] => 18:00 [openinghours_mo-2-start] => 21:00 [openinghours_mo-2-finish] => 23:00 [openinghours_tu-0-start] => 09:00 [openinghours_tu-0-finish] => 13:00 [openinghours_tu-1-start] => 14:00 [openinghours_tu-1-finish] => 18:00 [openinghours_we-0-start] => 09:00 [openinghours_we-0-finish] => 13:00 [openinghours_we-1-start] => 14:00 [openinghours_we-1-finish] => 18:00 [openinghours_th-0-start] => 09:00 [openinghours_th-0-finish] => 13:00 [openinghours_th-1-start] => 14:00 [openinghours_th-1-finish] => 18:00 [openinghours_fr-0-start] => 09:00 [openinghours_fr-0-finish] => 13:00 [openinghours_fr-1-start] => 14:00 [openinghours_fr-1-finish] => 18:00 [openinghours_sa-0-start] => [openinghours_sa-0-finish] => [openinghours_so-0-start] => [openinghours_so-0-finish] => ) The property name is always the name attribute of the field 😉 . If the property is empty means closed on that day.
      Now I need to combine all those values into 1 array (or json array) and store it in the database in 1 column called 'hours' in my case (see screenshot below):

      In my ___processInput(WireInputData $input) method I have tried to make it work like this:
      public function ___processInput(WireInputData $input): self { $name = $this->attr('name'); $value = $this->attr('value'); //input object includes always every input on the page, so lets filter out only inputs from this field //we need to do this, because the number of values is variable - so extract only values that starts with $name.'_' $nameAttributes = []; foreach($input as $key=>$value){ if(substr($key, 0, strlen($name.'_')) === $name.'_'){ $nameAttributes[$key] = $value; } } // loop through all inputfields of this fieldtype $time_values = []; foreach($nameAttributes as $nameAttr => $value) { $time_values[$nameAttr] = $value; } } //save it in the database $input->set('hours', serialize($time_values)); return $this; } The only important part of this code is the last part with the serialize function.
      After saving it will create a record in the database, but the value is always NULL (default value) (see below).

      Checking $time_values returns all the values, but printing out "$this" shows me that the property "hours" inside the Openinghours object is empty (see below) - so the mistake must be there, but I dont know where?!?!?!?
      [title] => Home [openinghours] => ProcessWire\OpeningHours Object ( [data] => Array ( [hours] => ) ) If I check the sleepValue() method or the sanitizeValue() - they are also empty. So it seems that the values will not reach these methods. I havent found a clear documentation of whats going on behind the saving process of an inputfield.
      As far as I know the saving process starts with the form submission. The values are in the POST array and will be processed by the processInput() method. Before they will be saved in the database they will be sanitized by the sanitizeValue() mehtod and afterwards they will be prepared for storage in the sleepValue() method.  The last step is the storage itself.
      Has someone an idea what is missing by storing values from multiple fields into 1 database column or has someone a working example of such a scenario on github to help me out.
      A clear explanation of the storage process will be also helpful.
      Thanks and best regards
    • By Juergen
      Hello @ all!
      I want to share a simple fieldtype and inputfield to store address data with you.
      I have created this inputfield for learning purposes and it has no fancy functionality. It is simply for storing address data such as street, number, postalcode and so on in one table. As an addition you can store latitude and longitude too, so you can use them in maps.
      Here is a screenshot of what it looks like:

      You can select which fields are mandatory and you can choose if the inputs for longitude and latitude should be displayed. These settings can be configured in the field configuration.
      If you find this inputfield useful you can download it at https://github.com/juergenweb/FieldtypeSimpleAddress
      There you will find a detailed explanation. If you have an idea of an usefull feature that can be added or you have detected a bug, please report it in my github account.
       
×
×
  • Create New...