Jump to content


Photo

Custom Inputfield with multiple inputs

inputfield multiple

  • Please log in to reply
2 replies to this topic

#1 Soma

Soma

    Hero Member

  • Moderators
  • 3,185 posts
  • 1737

  • LocationSH, Switzerland

Posted 12 January 2012 - 07:45 AM

I'm in need of a special inputfield with multiple input form fields. I created a little Inputfield extending InputfieldTextarea and using it for storing the values as json encoded string. Seeing an example of Ryan recently using this technique I went and tried to do a little custom Inputfield. I got it working so far with a little try and error, but wanted to have feedback, if there's anything done wrong or could be done better.

I need this to store numeric values for the 12 months. These will be used to render a chart on page. So I first did a simple textarea and having each values on a new line, but wanted something more intuitive and convienient for the client to enter the values.

(I know it would also be possible (and maybe better solution) to write a complete new Fieldtype/Inputfield, but I'm not really into it yet and would need some help. But this was kinda simple and does the job, only drawback is that it wouldn't work with selectors as it's stored as json in a text field in db.)

Here's my code:


<?php

/**
* ProcessWire Custom InputfieldMonths
*
* Inputfield that stores numeric values for the 12 months of a year.
*
*/


class InputfieldMonths extends InputfieldTextarea {


	protected $months = array(
			"January" => "jan",
			"February" => "feb",
			"March" => "mar",
			"April" => "apr",
			"May" => "may",
			"June" => "jun",
			"July" => "jul",
			"August" => "aug",
			"September" => "sep",
			"October" => "oct",
			"November" => "nov",
			"December" => "dec"
		);

	public static function getModuleInfo() {
		return array(
			'title' => 'InputfieldMonths',
			'version' => 100,
			'summary' => 'Stores 12 integer values for months of a year',
			'permanent' => false,
			);
	}

	public function init() {
		parent::init();
	}

	public function ___render() {

		$values = json_decode($this->value,true);
		$out = '';
		foreach($this->months as $label => $name) {
			$out .= <<< _OUT
			<p>
				<label for='$name'>$label</label>
				<input id='$name' name='$name' value='$values[$name]'/>
			</p>
_OUT;
		}
		return $out;
	}

	public function ___processInput(WireInputData $input) {

		foreach($input as $key => $val) {
			if(!in_array($key, $this->months) or $val === '') continue;
			if(!is_numeric($val)) return $this->error("Wrong format. Value '$val' is not numeric!");
		}

		$months_values = array();

		foreach($this->months as $month) {
			$months_values[$month] = $input[$month];
		}

		$data = json_encode($months_values);

		if($this->value != $data) {
			parent::trackChange('value');
			$this->value = $data;
		}

		return $this;
	}


}

@somartist | modules created | support me, flattr my work flattr.com


#2 ryan

ryan

    Hero Member

  • Administrators
  • 5,771 posts
  • 3107

  • LocationAtlanta, GA

Posted 12 January 2012 - 12:02 PM

I think for what you are trying to do: provide a simple solution to this particular need, it seems like a good solution. I like it. From a storage perspective, you could make it a little more efficient by using the month numbers (integers) in your encoded JSON rather than the month names, and then unset any blank values from the array before encoding it. This would ensure it's reduced to the smallest encoded format possible. Also, December is spelled wrong in your $months array at the top. :)

#3 Soma

Soma

    Hero Member

  • Moderators
  • 3,185 posts
  • 1737

  • LocationSH, Switzerland

Posted 13 January 2012 - 06:20 AM

From a storage perspective, you could make it a little more efficient by using the month numbers (integers) in your encoded JSON rather than the month names, and then unset any blank values from the array before encoding it. This would ensure it's reduced to the smallest encoded format possible.


You're right, thanks for the suggestions. But I need the blank values to be 0 for the chart, so I implemented a check that sets not filled in fields to 0. I know it would be possible to check for them in the output, but wanted to make it simple as possible.

Thanks for pointing out the typo! Must have been sleeping...

@somartist | modules created | support me, flattr my work flattr.com






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users