Recent Topics

Feature request: Dynamic Input Groups

Started by on Jan 02, 2018 – Contents updated: Jul 13, 2018

Jan 02, 2018 17:46    

I would like to put this feature on my wishlist and do believe it will be a great addition to b2evolution. Now I know we don't always get what we want, but hey, if you don't ask, you won't get...

As always, my request is to enhance settings (plugins, widgets, skins, col-settings, user-settings, ect...) and this is very similar to Dynamic Sets, except I would like for this NOT to be wrapped in a Fieldset, but rather in a group...

The idea here is to have dynamic settings which will add a few items only and in a group and that works very similar as that found in user profile preference settings:

Feature request: Dynamic Input Groups

It must have a selection select [#2], and an Add button [#1] and a DELETE button [#3] that will be added next to the input_group || input_input. The exception is how it is defined:

function GetDefaultSettings( & $params )
	{
		return array(
			
	
			
			'plugin_input_group' => array(
				'label' => T_('Set'),
				'note' => T_('Your note'),
				'multiple' => true, // or false .... Supported ...  ?
				'type' => 'NEW_TYPE',
				'options' => array( // Select List like $Form->select_input()
									/*
									 *	'type' => T_('LABEL'),
									 *	
									 *	TYPE can be: integer | color | checkbox | checklist | html_input | password | text | radio | fileselect (The most common types)
									*/	
			
									'integer' => T_('Your Numeric'),
									'color' => T_('Your Color'),
									'text' => T_('Your Text'),
									// ect, ect...
									'input_group' => T_('Your Inline Group'),
			
									),
				'entries' => array(
			
			
			/*
			*	We only specified 4 types for this example, 
			*	3 types are inputs
			*	1 type is a group with inline groups
			*	depending on what was selected is what will be added
			*	when the user clicks the ADD button
			*	if the user selected multiple values, it will add multiple values on click action
			*	each new dynamically field will have a REMOVE button/link/action next to it
			*	thus fields can be removed independently
			*	each time the add button is clicked, it will add more fields
			*
			*	THESE ARE INDPENDENT INPUTS
			*/
											'_color' => array(
																'label' => T_('Set Set Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Set Set Item Color'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
															),
			
											'_text' => array(
																'label' => T_('Set Set Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'text',
																'allow_empty' => false,
															),
			
			
			
			/*
			*	
			*	each time the add button is clicked, it will add the inline group fields
			*	each new dynamically group will have a REMOVE button/link/action next to it
			*	thus if clicked will remove the group
			*
			*	THESE ARE GROUPED INLINE INPUTS
			*/	
			
			'_input_group' => array(
					'label' 		=> T_('Group'),
					'type' 			=> 'input_group',
					'inputs' 		=> array(
			
											'_color' => array(
																'label' => T_('Set Set Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Set Set Item Color'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
															),
			
											'_text' => array(
																'label' => T_('Set Set Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'text',
																'allow_empty' => false,
															),
						),
			
															
			
			))));
	}

Jan 05, 2018 14:28

Please can i be updated on your thoughts re this pull request?

This pull request is incomplete and not yet ready for merging, but you are able to see what needs to happen and how this behaves.

https://github.com/b2evolution/b2evolution/pull/63/files

Here is the plugin code:


<?php
/**
 * -----------------------------------------------------------------------------------------
 * This file provides a skeleton to create a new {@link http://b2evolution.net/ b2evolution}
 * plugin quickly.
 * See also:
 *  - {@link http://b2evolution.net/man/creating-plugin}
 *  - {@link http://doc.b2evolution.net/stable/plugins/Plugin.html}
 * (Delete this first paragraph, of course)
 * -----------------------------------------------------------------------------------------
 *
 * This file implements the Foo Plugin for {@link http://b2evolution.net/}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2010 by Your NAME - {@link http://example.com/}.
 *
 * @package plugins
 *
 * @author Your NAME
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );


/**
 * Foo Plugin
 *
 * Your description
 *
 * @package plugins
 */
class development_plugin extends Plugin
{
	/**
	 * Variables below MUST be overriden by plugin implementations,
	 * either in the subclass declaration or in the subclass constructor.
	 */
	/**
	 * Human readable plugin name.
	 */
	var $name = 'Plugin Name';
	/**
	 * Code, if this is a renderer or pingback plugin.
	 */
	var $code = 'devplugin';
	var $priority = 50;
	var $version = '0.1-dev';
	var $author = 'http://example.com/';
	var $help_url = '';

	/**
	 * Group of the plugin, e.g. "widget", "rendering", "antispam"
	 */
	var $group = 'Test';


	/**
	 * Init: This gets called after a plugin has been registered/instantiated.
	 */
	function PluginInit( & $params )
	{
		$this->short_desc = $this->T_('Short description');
		$this->long_desc = $this->T_('Longer description. You may also remove this.');
	}


	/**
	 * Define the GLOBAL settings of the plugin here. These can then be edited in the backoffice in System > Plugins.
	 *
	 * @param array Associative array of parameters (since v1.9).
	 *    'for_editing': true, if the settings get queried for editing;
	 *                   false, if they get queried for instantiating {@link Plugin::$Settings}.
	 * @return array see {@link Plugin::GetDefaultSettings()}.
	 * The array to be returned should define the names of the settings as keys (max length is 30 chars)
	 * and assign an array with the following keys to them (only 'label' is required):
	 */
	
	function GetDefaultSettings( & $params )
	{
		return array(
			'plugin_input_group' => array(
				'label' => T_('Set'),
				'note' => T_('Your note'),
				'multiple' => true, // or false .... Supported ...  ?
				'defaultvalue' => 'input_group',
				'type' => 'select_input',
				'options' => array( // Select List like $Form->select_input()
									/*
									 *	'type' => T_('LABEL'),
									 *	
									 *	TYPE can be: integer | color | checkbox | checklist | html_input | password | text | radio | fileselect (The most common types)
									*/	
			
									'integer' => T_('Your Numeric'),
									'color' => T_('Your Color'),
									'text' => T_('Your Text'),
									// ect, ect...
									'input_group' => T_('Your Inline Group'),
			
									),
				'entries' => array(
			
			
			/*
			*	We only specified 4 types for this example, 
			*	3 types are inputs
			*	1 type is a group with inline groups
			*	depending on what was selected is what will be added
			*	when the user clicks the ADD button
			*	if the user selected multiple values, it will add multiple values on click action
			*	each new dynamically field will have a REMOVE button/link/action next to it
			*	thus fields can be removed independently
			*	each time the add button is clicked, it will add more fields
			*
			*	THESE ARE INDPENDENT INPUTS
			*/
											'_color' => array(
																'label' => T_('Single Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Single Item Integer'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
																'defaultvalue' => '0',
															),
			
											'_text' => array(
																'label' => T_('Single Item Text'),
																'defaultvalue' => 'blank text',
																'type' => 'text',
																'allow_empty' => false,
															),
			
			
			
			/*
			*	
			*	each time the add button is clicked, it will add the inline group fields
			*	each new dynamically group will have a REMOVE button/link/action next to it
			*	thus if clicked will remove the group
			*
			*	THESE ARE GROUPED INLINE INPUTS
			*/	
			
			'_input_group' => array(
					'label' 		=> T_('Group'),
					'type' 			=> 'input_group',
					'inputs' 		=> array(
			
											'_color' => array(
																'label' => T_('Group Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Group Item Integer'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
																'defaultvalue' => '0',
															),
			
											'_text' => array(
																'label' => T_('Group Item Text'),
																'defaultvalue' => 'blank text',
																'type' => 'text',
																'allow_empty' => false,
															),
						),
			
															
			
			))));
	}

	
}
?>

Jan 08, 2018 22:38

The type is: input_select
The options for the list is build from the 'entries' specified.
The item that is selected will be added when the user clicks the Add button.
Each added item has its own remove button
Each item can be added multiple times
The amount/number of items that can be added can be limited with: $parmeta['max_number']

Feb 25, 2018 22:21

for a working example https://github.com/b2evolution/b2evolution/pull/63

Tested: text | integer | color | input_group
NOT tested: checkbox | checklist | html_input | password | radio | fileselect
plugin settings example:

	function get_widget_param_definitions( $params )
	{
		$r = array_merge( array(
		
						 
			
			'select_input' => array(
				'label' => T_('Set'),
				'note' => T_('Your note'),
				'multiple' => true, 
				'defaultvalue' => '',
				'type' => 'select_input',
				'entries' => array(

									'_color' => array(
														'label' => T_('Single Item Color'),
														'defaultvalue' => '#fed136',
														'type' => 'color',
													),

									'_integer' => array(
														'label' => T_('Single Item Integer'),
														'note' => '1-9',
														'valid_range' => array( 'min'=>1, 'max'=>9 ),
														'type' => 'integer',
														'defaultvalue' => 1,
													),

									'_text' => array(
														'label' => T_('Single Item Text'),
														'defaultvalue' => 'blank text',
														'type' => 'text',
														'allow_empty' => false,
													),
			
			'input_group' => array(
					'label' 		=> T_('Group'),
					'type' 			=> 'input_group',
					'inputs' 		=> array(
			
											'_color' => array(
																'label' => T_('Group Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Group Item Integer'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
																'defaultvalue' => 1,
															),
			
											'_text' => array(
																'label' => T_('Group Item Text'),
																'defaultvalue' => 'blank text',
																'type' => 'text',
																'allow_empty' => false,
															),
						),
			
															
			
			))),
		
		), parent::get_widget_param_definitions( $params ) );

}

Mar 08, 2018 03:07

@achillis please help me get an entry point to this request. It would help me if you could phrase it like this:

The code we already have in XXX does YYY but does not allow to do ZZZ.

And my first problem is XXX because you write "user profile preference settings" and this doesn't match your screenshot... and I have literally zero time, even with the best intentions in the world, to enter a guessing game :]

Mar 08, 2018 07:49

@fplanque

The code we already have in b2evolution 6.10.0-beta does provide (Skin | Plugin | Widget ) settings with the ability to dynamically add Predefined Form Inputs in a grouped fieldset layout [See: Image 1] but does not allow to dynamically add a single inline Predefined Form Input [See: image 2] .

@fplanque please note: the reason why this request allows the user to "select" the desired "input" to be inserted, is to allow the user, to only add settings that are needed. For example: Imagine this input will allow the user to add an item to a custom form, the list offers three predefined items: checkbox, radio and text. but the user only wishes to add a checkbox, then it can be done by selecting the desired item from the list and adding it only.

Images:

Mar 08, 2018 23:51

Ok, thanks for the details. It's clearer now. We'll look at this.

Mar 16, 2018 21:14

Hi @fplanque and @yurabakh as per https://github.com/b2evolution/b2evolution/tree/feature/dynamic-input-groups please note that I added some additions and fixes to https://github.com/b2evolution/b2evolution/pull/63 and made it closer inline with your style.

  1. All form types are supported
  2. checkbox, checklist, radio types works
  3. can add and remove inputs independently
  4. each item can have defined max_number with warning alert to user if exceded

see screenshot

I tested it with test plugin using these params:

	/**
	 * Param definitions when added as a widget.
	 *
	 * Plugins used as widget need to implement the SkinTag hook.
	 *
	 * @return array
	 */
	function get_widget_param_definitions( $params )
	{
		
		global $app_version;
		
		$type = version_compare( $app_version, '6.6.5', '>' ) ? 'array:array:string' : 'array';
		$r = array_merge( array(

			'select_input' => array(
				'label' => T_('Set'),
				'note' => T_('Your note'),
				'multiple' => true, 
				'defaultvalue' => '',
				'type' => 'select_input',
				'entries' => array(
			
			
			
				'_html_textarea' => array(
						'label' => T_('HTML textarea'),
						'type' => 'html_textarea',
						'rows' => 15,
						'note' => '',
						'defaultvalue' => '',
					),
			
				'_html_input' => array(
						'label' => T_('HTML input'),
						'type' => 'html_input',
						'rows' => 15,
						'note' => '',
						'defaultvalue' => '',
					),
			
				'_acheckbox' => array(
					'label' => T_('Checkbox'),
					'type' => 'checkbox',
					'defaultvalue' => 1,
					'note' => '',
				),
			
					'_achecklist' => array(
							'label' => T_('Check List'),
							'note' => '',
							'type' => 'checklist',
							'options' => array(
									array( 'one', 	T_('First'), 0 ),
									array( 'two',	T_('Second'), 0 ),
									array( 'three', T_('Third'), 0 ),
								),
							),
			
			
							'_aradio' => array(
								'label' => T_('Radio buttons'),
								'note' => '',
								'type' => 'radio',
								'inline' => false,
								'options' => array(
										array( 'one', T_('First') ),
										array( 'two', T_('Second') ),
										array( 'three', T_('Third') )
									),
								),


							'_fileselect' => array(
								'label' => T_('File Select'),
								'note' => '',
								'defaultvalue' => '',
								'type' => 'fileselect',
								'thumbnail_size' => 'fit-320x320',
							),
			


									'_password' => array(
														'label' => T_('Password Item Text'),
														'defaultvalue' => 'blank text',
														'type' => 'password',
														'allow_empty' => false,
													),
									'_color' => array(
														'label' => T_('Single Item Color'),
														'defaultvalue' => '#fed136',
														'type' => 'color',
														'max_number' => 2,
			
													),

									'_integer' => array(
														'label' => T_('Single Item Integer'),
														'note' => '1-9',
														'valid_range' => array( 'min'=>1, 'max'=>9 ),
														'type' => 'integer',
														'defaultvalue' => 1,
													),

									'_text' => array(
														'label' => T_('Single Item Text'),
														'defaultvalue' => 'blank text',
														'type' => 'text',
														'allow_empty' => false,
													),
			
			'_input_group' => array(
					'label' 		=> T_('Group'),
					'type' 			=> 'input_group',
					'inputs' 		=> array(
			/*
							'_fileselect' => array(
								'label' => T_('File Select'),
								'note' => '',
								'defaultvalue' => '',
								'type' => 'fileselect',
								'thumbnail_size' => 'fit-320x320',
							),
							*/
			
											'_color' => array(
																'label' => T_('Group Item Color'),
																'defaultvalue' => '#fed136',
																'type' => 'color',
															),
			
											'_integer' => array(
																'label' => T_('Group Item Integer'),
																'note' => '1-9',
																'valid_range' => array( 'min'=>1, 'max'=>9 ),
																'type' => 'integer',
																'defaultvalue' => 1,
															),
			
											'_text' => array(
																'label' => T_('Group Item Text'),
																'defaultvalue' => 'blank text',
																'type' => 'text',
																'allow_empty' => false,
															),
						),
			
															
			
			))),
		
		), parent::get_widget_param_definitions( $params ) );

		return $r;
	
		
	}	

Jul 11, 2018 15:31

Hi @achillis, we tried to use your code after merging commit https://github.com/b2evolution/b2evolution/commit/c771b58b27ee7a1678db7f0ee4d3a47631d95e2e, but it breaks default value, see the attached screenshot, so it was reverted with next commit.
Also is it possible to use default value for 'type' => 'select_input'? I mean to preselect some options by default without click on the button "+ Add" right after plugin has been installed. Currently I see only 'defaultvalue' => '', in your samples.
Thanks.

Jul 11, 2018 16:20

@achillis We are wasting too much of our limited time to get this to work. This is approximately priority #400 on our TODO list. I have to cut losses on our development time.

Jul 12, 2018 10:35

@yurabakhtin wrote earlier:

Hi @achillis, we tried to use your code after merging commit https://github.com/b2evolution/b2evolution/commit/c771b58b27ee7a1678db7f0ee4d3a47631d95e2e, but it breaks default value, see the attached screenshot, so it was....Thanks.

@yurabakhtin I did a new install from fresh from the develop branch I then merged the PR into develop and tested it and I was unable to reproduce your results. The default values works. I then changed the image and tried a different image and this too works. I then clicked Reset Params button in skin settings and it restored all default values as expected and this too, also works.

I cleared all caches and retested and it still works. I was unable to reproduce your result. Could you possibly explain the process you followed?

This is the branch I used: https://github.com/midnight-studios/b2evolution/tree/Feature-Dynamic-Select-Input

@yurabakhtin wrote earlier:

Also is it possible to use default value for 'type' => 'select_input'? I mean to preselect some options by default without click on the button "+ Add" right after plugin has been installed. Currently I see only 'defaultvalue' => '', in your samples.

@yurabakhtin I understand what you are referring to, but the answer is that 'defaultvalue' will have no effect because this item is somewhat complex. If a 'defaultvalue' were somehow specified, it would need to point which Form item and the form item's value. Would that really make sense?

@fplanque wrote earlier:

@achillis We are wasting too much of our limited time to get this to work. This is approximately priority #400 on our TODO list. I have to cut losses on our development time.

@fplanque you have poor people skills. It is unclear what you were trying to achieve with your comment. Please explain your public development contribution policy so that I can understand what exactly about my efforts and contribution is causing you to express so much contempt in your comment.

Jul 12, 2018 11:47

@achillis You are probably right about my poor people skills.

I am under a lot of stress.

There is no comtempt.

I was just trying to explain that it costs us too much time and money to continue to try to merge this feature into the core. We are only trying to include it because you need it; not because we need it. We will probably need it one day but as said, albeit this feature is powerful in itself, there are already approximately 400 more urgent/critical things for us to work on. We have limited resources and limited budget. We tried to integrate this feature, but the cost is too high.

The policy would be: we will merge in anything that has a clear use case without compromising security, performance or costs too much in debugging/integration time.

In this case we have already spend about 2 developer days on this feature which is not a priority for us. I cannot give it any more dev budget until it gets higher on our priority list.

Example of contributions that we prioritize very high for merging: bug fixes, security fixes ( even spelling/wording fixes ).

Side note: have you made available any plugins that leverage the previous core changes we already merged in to facilitate your plugin developments?

Jul 12, 2018 15:35

UPDATE

It seems when I merged Develop it removed the feature, so this might explain why I didn't see the issue. Let me roll back and check again.

Thank you for your effort @fplanque. I actually understood the points you mentioned above at the time of making the feature request, which is why I did the development myself, thinking that it would save you on those aspects. I guess not.

It doesn't take much to realize that you are under extreme pressure and if I could I would sponsor you a week holiday or invite you to a South African Braai, but I am certain you have too many balls in the air.

In terms of the issues and dev time you allocated, if you had issues, you should have reverted it back to me to fix, but like I explained to @yurabakhtin in my previous post, I tried to reproduce the issue he explained using your latest git branch develop with the feature merged into it. On my tests everything works 100%. In fact I have been using it on my sites already with no known issues, so even if you don't merge it yet, I can still use it.

@fplanque wrote earlier:

Side note: have you made available any plugins that leverage the previous core changes we already merged in to facilitate your plugin developments?

The short answer is no. Because there are two items using many of those requests, the first is a Skin, the second is a Custom Contact Form and both items make use of the Feature that causes you to pull out your hair. I am developing another plugin that uses the same feature: a shopping cart plugin that basically changes the collection into an online shop with shopping carts ect. This same plugin has a parallel plugin that integrates as a paygate with the shopping cart plugin and another that serves as a courier service plugin... (I know, its allot)...

The Custom Contact Form (I suspect you might be scratching your head) allow the user to add custom forms in containers and posts and can be customized to the heart's content and it can basically be used for Surveys or just a contact message. All submissions are sent to the recipient's email. I would love to share those with the b2e community, but will be suspended until your budget allows merging previously mentioned feature.

I would like to thank you for what you have done and the requests you implemented. It is really appreciated! For now I won't be submitting more requests, hopefully that will give you an atom or two more breathing space.

This post has 1 feedback awaiting moderation...


Form is loading...

b2 – This forum is powered by b2evolution CMS, a complete engine for your website.