__('Integer', __FILE__), // Module Title 'summary' => __('Integer (positive or negative)', __FILE__), // Module Summary 'version' => 105, 'permanent' => true, ); } /** * Module init * */ public function init() { parent::init(); $this->attr('type', 'text'); $this->attr('min', ''); $this->attr('max', ''); $this->attr('step', ''); $this->attr('size', '10'); $this->attr('placeholder', ''); $this->set('inputType', 'text'); $this->set('initValue', ''); $this->set('defaultValue', ''); } /** * Render Inputfield * * @return string * */ public function ___render() { if(!$this->attr('type')) $this->attr('type', 'text'); $attrs = $this->getAttributes(); if(empty($attrs['size'])) { $attrs['class'] = (isset($attrs['class']) ? "$attrs[class] " : "") . 'InputfieldMaxWidth'; unset($attrs['size']); } if($attrs['type'] === 'text') { // input[type=text] unset attributes not applicable unset($attrs['step'], $attrs['min'], $attrs['max']); } else { // input[type=number] unset any that aren't applicable foreach(array('min', 'max', 'step') as $name) { if(isset($attrs[$name]) && !strlen((string) $attrs[$name])) unset($attrs[$name]); } } if(!strlen("$attrs[value]")) { if(strlen("$this->initValue")) { $attrs['value'] = (int) $this->initValue; // Inputfield-only version } else if(strlen("$this->defaultValue")) { $attrs['value'] = (int) $this->defaultValue; // Fieldtype version } } $out = "getAttributesString($attrs) . " />"; return $out; } /** * Sanitize value * * @param string|int|float $value * @return int * */ protected function sanitizeValue($value) { if(is_int($value)) return $value; $value = (string) $value; $value = trim($value); if(!strlen("$value")) return ''; $negative = substr($value, 0, 1) === '-'; if($negative) $value = substr($value, 1); // remove non digits, except commas and periods if(!ctype_digit("$value")) $value = preg_replace('/[^\d,.]/', '', $value); if(!strlen("$value")) return ''; if(strpos($value, '.') !== false || strpos($value, ',') !== false) $value = round((float) $value); $value = (int) $value; if($negative) $value = -1 * $value; return $value; } /** * Typecast value to integer * * @param string|int|float $value * @return int * */ protected function typeValue($value) { return (int) $value; } /** * Is current value considered empty? * * @return bool * */ public function isEmpty() { $value = $this->val(); return strlen("$value") === 0; } /** * Is current value in specified min/max range? * * @param int $value * @return bool * */ protected function isInRange($value) { if(!strlen("$value")) return true; // no value present yet list($min, $max) = array($this->attr('min'), $this->attr('max')); if(strlen("$min") && ($this->typeValue($value)) < ($this->typeValue($min))) return false; if(strlen("$max") && ($this->typeValue($value)) > ($this->typeValue($max))) return false; return true; } /** * Set attribute * * @param array|string $key * @param array|bool|int|string $value * @return Inputfield * */ public function setAttribute($key, $value) { if($key === 'value') { $value = $this->sanitizeValue($value); if(strlen("$value") && !$this->isInRange($value)) { $min = $this->attr('min'); $max = $this->attr('max'); $any = $this->_('any'); // referring to “any” minimum or maximum number if(!strlen("$min")) $min = $any; if(!strlen("$max")) $max = $any; $this->error(sprintf($this->_('Specified value %3$s removed because it is out of bounds (min=%1$s, max=%2$s)'), $min, $max, $value)); $value = $this->val(); // restore previous value } } else if($key === 'min' || $key === 'max') { if(strlen("$value")) { $value = strpos("$value", '.') !== false ? (float) $value : (int) $value; } } return parent::setAttribute($key, $value); } /** * Set setting or attribute * * @param string $key * @param mixed $value * @return Inputfield|WireData * */ public function set($key, $value) { if($key === 'inputType') $this->attr('type', $value); return parent::set($key, $value); } /** * Inputfield configuration * * @return InputfieldWrapper * */ public function getConfigInputfields() { $inputfields = parent::getConfigInputfields(); $modules = $this->wire()->modules; /** @var InputfieldRadios $f */ $f = $modules->get('InputfieldRadios'); $f->attr('name', 'inputType'); $f->label = $this->_('Numeric Input Type'); $f->addOption('text', $this->_('Text')); $f->addOption('number', $this->_('Number (HTML5)')); $f->attr('value', $this->inputType); $f->description = $this->_('Choosing the "Number" type enables some additional client-side validation in browsers that support it.'); $f->columnWidth = 50; $inputfields->add($f); /** @var InputfieldInteger $f */ $f = $modules->get('InputfieldInteger'); $f->attr('name', 'size'); $f->label = $this->_('Input Size'); $f->description = $this->_('Specify the size attribute for the input, or specify 0 for full width.'); $f->notes = sprintf($this->_('The default value is %d.'), $f->attr('size')); $f->columnWidth = 50; $f->attr('value', $this->attr('size')); $f->attr('min', 0); $f->attr('type', 'number'); $inputfields->add($f); /** @var InputfieldText $f */ $f = $modules->get('InputfieldText'); $f->attr('name', 'min'); $f->attr('value', $this->attr('min')); $f->label = $this->_('Minimum Value'); $f->description = $this->_('The minimum allowed value for this field. Leave blank to ignore.'); $f->columnWidth = 50; $inputfields->add($f); $f = $modules->get('InputfieldText'); $f->attr('name', 'max'); $f->attr('value', $this->attr('max')); $f->label = $this->_('Maximum Value'); $f->description = $this->_('The maximum allowed value for this field. Leave blank to ignore.'); $f->columnWidth = 50; $inputfields->add($f); if($this->hasFieldtype === false) { $f = $modules->get('InputfieldText'); $f->attr('name', 'initValue'); $f->attr('value', $this->initValue); $f->label = $this->_('Initial value'); $f->description = $this->_('Initial assigned value.'); $f->collapsed = Inputfield::collapsedBlank; $inputfields->add($f); } return $inputfields; } }