__('Text', __FILE__), // Module Title 'summary' => __('Single line of text', __FILE__), // Module Summary 'version' => 106, 'permanent' => true, ); } /** * Construct * */ public function __construct() { parent::__construct(); $this->setAttribute('type', 'text'); $this->setAttribute('size', 0); $this->setAttribute('maxlength', $this->getDefaultMaxlength()); $this->setAttribute('placeholder', ''); $this->setAttribute('pattern', ''); $this->setAttribute('minlength', 0); $this->set('requiredAttr', 0); $this->set('initValue', ''); // optional initial value $this->set('stripTags', false); // strip tags from input? $this->set('noTrim', false); $this->set('showCount', self::showCountNone); } /** * Wired to API * */ public function wired() { // if multi-language, support placeholders for each language $languages = $this->wire()->languages; if($languages) { foreach($languages as $language) { // set to blank value so that Field::getInputfield() will recogize this setting is for InputfieldText if(!$language->isDefault()) $this->set("placeholder$language", ''); } } parent::wired(); } /** * Get the default maxlength attribute value * * @return int * */ public function getDefaultMaxlength() { return self::defaultMaxlength; } /** * Render ready * * @param Inputfield $parent * @param bool $renderValueMode * @return bool * @throws WireException * */ public function renderReady(Inputfield $parent = null, $renderValueMode = false) { $showCount = (int) $this->getSetting('showCount'); if($showCount) { $this->addClass('InputfieldTextLength'); $this->attr('data-showCount', $showCount); $config = $this->wire('config'); if(!$config->js('InputfieldTextLength')) { $labels = array( 'word1' => $this->_('1 word'), 'words' => $this->_('%d words'), 'char1' => $this->_('1 character'), 'chars' => $this->_('%d characters'), 'min' => $this->_('(at least %d required)'), 'max' => $this->_('(%d max)'), ); $config->scripts->add($config->urls('InputfieldText') . 'InputfieldTextLength.js'); $config->js('InputfieldTextLength', $labels); } } return parent::renderReady($parent, $renderValueMode); } /** * Render Inputfield * * @return string * */ public function ___render() { $attrStr = $this->getAttributesString(); $out = ""; return $out; } /** * Get all attributes in an associative array * * @return array * */ public function getAttributes() { $attrs = parent::getAttributes(); if(empty($attrs['size'])) { unset($attrs['size']); if(!$this->hasClass('InputfieldSetWidth')) { $attrs['class'] = (empty($attrs['class']) ? '' : $attrs['class'] . ' ') . 'InputfieldMaxWidth'; } } if($this->initValue) { if(!strlen("$attrs[value]")) { $attrs['value'] = $this->initValue; } } if(isset($attrs['minlength'])) { // convert minlength attr to a data-minlength attr, since minlength doesn't have wide browser support if($attrs['minlength'] > 0) $attrs['data-minlength'] = $attrs['minlength']; unset($attrs['minlength']); } if(isset($attrs['maxlength']) && (int) $attrs['maxlength'] < 1) unset($attrs['maxlength']); // placeholder attribute, languages support if(!empty($attrs['placeholder']) && $this->wire()->languages) { $language = $this->wire()->user->language; if($language && $language->id && !$language->isDefault()) { $placeholder = parent::get("placeholder$language->id"); if(strlen($placeholder)) $attrs['placeholder'] = $placeholder; } } return $attrs; } /** * Set an attribute * * @param array|string $key * @param array|int|string $value * @return Inputfield|InputfieldText|$this * */ public function setAttribute($key, $value) { if($key == 'maxlength' && $value !== 0 && $value !== "0" && ((int) $value) < 1) { $value = $this->getDefaultMaxlength(); } if($key == 'minlength') { $value = (int) $value; if($value < 1) $value = 0; } if($key == 'value') $value = $this->setAttributeValue($value); return parent::setAttribute($key, $value); } /** * Prepare the 'value' attribute * * @param string $value * @return string * @throws WireException * */ protected function setAttributeValue($value) { if($this->maxlength > 0) { $value = $this->wire()->sanitizer->text($value, array( 'maxLength' => $this->maxlength, 'maxBytes' => $this->maxlength*4, 'stripTags' => false, 'trim' => $this->noTrim ? false : true, )); } if($this->stripTags) $value = strip_tags($value); return $value; } /** * Return the length of the given value * * @param string $value * @param bool $countWords Optionally get a word count rather than a character count. * @return int * */ protected function getValueLength($value, $countWords = false) { if($countWords) { return str_word_count($value); } else { return function_exists('mb_strlen') ? mb_strlen($value) : strlen($value); } } /** * Process input * * @param WireInputData $input * @return $this * */ public function ___processInput(WireInputData $input) { parent::___processInput($input); $name = $this->attr('name'); $value = $this->attr('value'); $minlength = (int) $this->attr('minlength'); $maxlength = (int) $this->attr('maxlength'); $length = $this->getValueLength($value); if($length > 0) { if($this->pattern) { $regex = '#' . str_replace('#', '\#', $this->pattern) . '#'; // add delimeters if(!preg_match($regex, $value)) { $this->error($this->_('Does not match required pattern')); } } if($minlength > 0 && $length < $minlength) { $this->error(sprintf( $this->_('A minimum of %1$d characters are required (currently there are %2$d characters).'), $minlength, $length) ); } if($maxlength > 0) { $dirtyValue = $this->noTrim ? (string) $input->$name : trim($input->$name); $dirtyLength = $this->getValueLength($dirtyValue); if($dirtyLength > $maxlength) { $this->error(sprintf( $this->_('Value exceeded maximum allowed length of %d characters and has been truncated.'), $maxlength) ); } } } return $this; } /** * Get field configuration * * @return InputfieldWrapper * @throws WireException * */ public function ___getConfigInputfields() { $modules = $this->wire()->modules; $languages = $this->wire()->languages; $inputfields = parent::___getConfigInputfields(); /** @var InputfieldInteger $field */ $field = $modules->get('InputfieldInteger'); $field->setAttribute('name', 'minlength'); $field->label = $this->_('Minimum length'); $field->setAttribute('value', (int) $this->minlength); $field->setAttribute('size', 6); $field->description = $this->_('The minimum length (in characters) that are required by this field.'); $field->notes = $this->_('If the field is not “required” then minimum length is only enforced when a value is present.'); $field->columnWidth = 50; $inputfields->append($field); /** @var InputfieldInteger $field */ $field = $modules->get('InputfieldInteger'); $field->setAttribute('name', 'maxlength'); $field->label = $this->_('Maximum length'); $field->setAttribute('value', $this->attr('maxlength')); $field->setAttribute('size', 6); $field->description = $this->_('The maximum length (in characters) that are allowed by this field.'); $field->notes = $this->_('A value of “0” indicates no maximum.'); $field->columnWidth = 50; $inputfields->append($field); /** @var InputfieldRadios $field */ $field = $modules->get('InputfieldRadios'); $field->attr('name', 'showCount'); $field->label = $this->_('Counter'); $field->addOption(0, $this->_('No counter')); $field->addOption(1, $this->_('Character counter')); $field->addOption(2, $this->_('Word counter')); $field->attr('value', (int) $this->getSetting('showCount')); $field->description = $this->_('It is recommended that you show a character counter when using minimum/maximum length settings above.'); $field->optionColumns = 1; if(!$field->attr('value')) $field->collapsed = Inputfield::collapsedYes; $inputfields->add($field); /** @var InputfieldInteger $field */ $field = $modules->get('InputfieldInteger'); $field->setAttribute('name', 'size'); $field->label = $this->_('Size'); $field->setAttribute('value', $this->attr('size') > 0 ? $this->attr('size') : 0); $field->setAttribute('size', 4); $field->description = $this->_('The displayed width of this field (in characters). Set to 0 for full width.'); $field->collapsed = Inputfield::collapsedYes; $inputfields->append($field); /** @var InputfieldCheckbox $field */ $field = $modules->get('InputfieldCheckbox'); $field->attr('name', 'stripTags'); $field->label = $this->_('Strip Tags'); $field->description = $this->_('When checked, any HTML tags will be stripped from the input when the form is processed.'); $field->notes = $this->_('This is recommended if the field does not need to support HTML in it.'); $field->attr('value', 1); if($this->stripTags) { $field->attr('checked', 'checked'); } else { $field->collapsed = Inputfield::collapsedYes; } $inputfields->append($field); /** @var InputfieldText $field */ $field = $modules->get('InputfieldText'); $field->setAttribute('name', 'placeholder'); $field->label = $this->_('Placeholder Text'); $field->setAttribute('value', $this->attr('placeholder')); $field->description = $this->_('Optional placeholder phrase of text that appears in the field when blank.'); $field->collapsed = Inputfield::collapsedBlank; if($languages) { $field->useLanguages = true; foreach($languages as $language) { if($language->isDefault()) continue; $value = $this->getSetting("placeholder$language"); if(!is_null($value)) $field->set("value$language", $value); } } $inputfields->append($field); /** @var InputfieldText $field */ $field = $modules->get('InputfieldText'); $field->setAttribute('name', 'pattern'); $field->label = $this->_('Pattern'); $field->setAttribute('value', $this->attr('pattern')); $field->description = $this->_('Optional regular expression pattern to require in the input. This is used both client side (HTML5 pattern attribute) and server side for validation. Be sure to provide an example of the required pattern in your field description.'); // Pattern description $field->notes = $this->_('See [html5pattern.com](http://html5pattern.com) for examples of patterns you can use and create.'); // Pattern notes $field->collapsed = Inputfield::collapsedBlank; $inputfields->append($field); if($this->hasFieldtype === false) { /** @var InputfieldText $field */ $field = $modules->get('InputfieldText'); $field->setAttribute('name', 'initValue'); $field->label = $this->_('Initial Value'); $field->description = $this->_('Optional initial/default value pre-populated for the user.'); $field->setAttribute('value', $this->initValue); $field->collapsed = Inputfield::collapsedBlank; $inputfields->append($field); } return $inputfields; } /** * Get array of field names allowed for field/template context * * @param Field $field * @return array * */ public function ___getConfigAllowContext($field) { $a = array('initValue', 'pattern', 'placeholder', 'maxlength', 'minlength', 'required', 'requiredAttr'); return array_merge(parent::___getConfigAllowContext($field), $a); } }