groupedlist field not rendered #450

Closed
opened 2019-07-24 11:03:59 +00:00 by marcodings · 9 comments
marcodings commented 2019-07-24 11:03:59 +00:00 (Migrated from github.com)

Steps to reproduce the issue

Expected result

field to show up in the form XML ( and eventually the edit view)

Actual result

field is not rendered to the XML, nor is it listed in $tabLayoutFields in the model

### Steps to reproduce the issue - create field-type based on https://docs.joomla.org/Groupedlist_form_field_type, type `groupedlist` - create field on aforementioned type - add field to admin view ### Expected result field to show up in the form XML ( and eventually the edit view) ### Actual result field is not rendered to the XML, nor is it listed in $tabLayoutFields in the model

Jackpot... you found the fieldtype that is not yet in JCB, and will not work.

This simply because I could not yet see how we will map it in the current subform field properties approach.

Give me some screenshots and explanation how you think this can work.

Jackpot... you found the fieldtype that is not yet in JCB, and will not work. This simply because I could not yet see how we will map it in the current subform field properties approach. Give me some screenshots and explanation how you think this can work.

Took you long enough.... lol

Took you long enough.... lol
marcodings commented 2019-07-25 06:04:46 +00:00 (Migrated from github.com)

Yeah please mock me ;)

This simply because I could not yet see how we will map it in the current subform field properties approach.
Give me some screenshots and explanation how you think this can work.

I don't understand what you are asking here. I do not see the implications for subformfield..

My Usecase: I have it in use in on one place atm. I have the field entered as a normal listfield and i manipulate the xml to change the type to groupedlist. The "options" i build dynamically.

I have not looked into how the field would be initialised statically in th fieldtype.

Yeah please mock me ;) > This simply because I could not yet see how we will map it in the current subform field properties approach. > Give me some screenshots and explanation how you think this can work. I don't understand what you are asking here. I do not see the implications for subformfield.. My Usecase: I have it in use in on one place atm. I have the field entered as a normal listfield and i manipulate the xml to change the type to groupedlist. The "options" i build dynamically. I have not looked into how the field would be initialised statically in th fieldtype.

That is my point exactly... each fieldtype is build of the bases of a set of properties we set in a subform called properties:
image

So how to map the groupedlist so it also works is the help I need. Does not help to overwrite everything (that JCB does), but to instead adapt JCB so that it is able to build it out of the box like it does the other fieldtypes.

So I need help with the approach, since the groupedlist has more complex option listing design... so how will we list those fields per/group in the current subform/properties of the fieldtypes in JCB.

That is my point exactly... each fieldtype is build of the bases of a set of properties we set in a subform called properties: ![image](https://user-images.githubusercontent.com/5607939/61878540-7e403800-aef1-11e9-97f9-a1943245e052.png) So how to map the `groupedlist` so it also works is the help I need. Does not help to overwrite everything (that JCB does), but to instead adapt JCB so that it is able to build it out of the box like it does the other fieldtypes. So I need help with the approach, since the `groupedlist` has more complex option listing design... so how will we list those fields per/group in the current subform/properties of the fieldtypes in JCB.

Solve that and we will have the groupedlist 👍

Solve that and we will have the `groupedlist` :+1:
marcodings commented 2019-07-25 16:07:55 +00:00 (Migrated from github.com)

In the joomla documention the groupedlist (documentation) only differs from the list on the

  • required (optional)
  • useglobal (optional)

I have a "list" field with the approriate listfield options which i change to type "groupedlist" in the xml. That works as a charm. I dymacally populate the options.

So afaik we can just start with the "list" options and we are good.

I think the Joomla documentation on "groupedlist" is incomplete. I'll do some code inspection to see what gives.

In the joomla documention the groupedlist (documentation) only differs from the list on the - required (optional) - useglobal (optional) I have a "list" field with the approriate listfield options which i change to type "groupedlist" in the xml. That works as a charm. I dymacally populate the options. So afaik we can just start with the "list" options and we are good. I think the Joomla documentation on "groupedlist" is incomplete. I'll do some code inspection to see what gives.
marcodings commented 2019-07-25 16:25:18 +00:00 (Migrated from github.com)

I see the following atributes in the code:

  • size
  • onchange
  • required
  • autofocus

( there is no useglobal)

I see the following atributes in the code: - size - onchange - required - autofocus ( there is no useglobal)
marcodings commented 2019-07-25 16:36:19 +00:00 (Migrated from github.com)

As for defining the grouped list i have used the following format in a textarea

 1|Events@1G
,2|Familyday@1
,3|MemberConference@1

,4|member@2G
,5|Members@2
,6|Donors@2
,7|Volunteers@2
,8|Companies@2

,9|Question@3G
,10|Question@3

This resembles the "normal" list options definition. In my context i stored the definition in a global component option to be used to build the formfield dynamically in the getform for the model.
So i guess this code can be used in interpreting the formfield in jcb and build the XML
entrypoint is prepFormType

	/**
	 * @param \Joomla\CMS\Form\Form $form
	 * @param Registry              $componentconfig
	 *
	 *
	 * @since version
	 */
	private function prepFormType(\Joomla\CMS\Form\Form $form, Registry $componentconfig): void
	{
		// get all available "form types" from the components configuration
		$formTypeDefinitions = $this->getFormTypeDefinitions($componentconfig);
		// by convention the `group name` should be the `form viewname`, filter the options
		$formTypes = $this->typesByGroup($formTypeDefinitions, $this->name);
		// populate the options for field named "b42_formtype" ( a convention ;)
		$this->populateFormType($form, $formTypes, 'b42_formtype');
	}

	/**
	 * getFormTypeDefinitions
	 *
	 * @param Registry $componentconfig
	 *
	 * convert string to an array
	 * 1|FormGroup 1@1G
	 * ,2|Option 1@1
	 * ,3|Option 2@1
	 * ,4|FormGroup 2@2G
	 * ,5|Option 3@2
	 *
	 * @since version
	 */
	private function getFormTypeDefinitions(Registry $componentconfig): array
	{
		foreach (explode(",", $componentconfig->get('fieldtype')) as $key => $fieldtype)
		{
			list($formtypes[$key]['id'],    $fieldtype) = explode("|", trim($fieldtype));
			list($formtypes[$key]['name'],  $fieldtype) = explode("@", $fieldtype);
			$formtypes[$key]['isgroup'] = strtoupper(substr("$fieldtype", -1))=='G';
			$formtypes[$key]['group'] = $formtypes[$key]['isgroup'] ? substr($fieldtype, 0, -1): $fieldtype;
		}
		return $formtypes;
	}
	
	/**
	 * typesByGroup
	 *
	 * @param array  $formTypeDefinitions
	 * @param string $thisformTypes
	 *
	 * @return array
	 *
	 * @since version
	 */
	private function typesByGroup(array $formTypeDefinitions, string $thisformTypes): array
	{
		foreach ($formTypeDefinitions as $item)
		{
			if ($item['isgroup'] && $item['name'] == $thisformTypes)
			{
				$group = $item['group'];
			}
		}
		$return=[];
		foreach ($formTypeDefinitions as $item)
		{
			if ($item['group'] == $group && !$item['isgroup'])
			{
				$return[] = $item;
			}
		}

		return $return;
	}

	/**
	 * populateFormType
	 *
	 * populate the options for field named "b42_formtype" ( a convention ;) )
	 *
	 * @param \Joomla\CMS\Form\Form $form
	 * @param array                 $formTypes
	 *
	 *
	 * @since version
	 */
	private function populateFormType(\Joomla\CMS\Form\Form $form, array $formTypes, string $b42_formtype = 'b42_formtype' ): void
	{
		$xpath = '//field[@name=\''.$b42_formtype.'\']/option';
		foreach ($form->getXml()->xpath($xpath) as $option)
		{
			unset($option[0]);
		}
		$xpath            = '//field[@name=\''.$b42_formtype.'\']';
		$b42_formtype_sxe = $form->getXml()->xpath($xpath);
		if (sizeof($b42_formtype_sxe))
		{
			$option = $b42_formtype_sxe[0]->addChild('option', ' - select -');
			$option->addAttribute('value', "0");
			foreach ($formTypes as $formType)
			{
				$option = $b42_formtype_sxe[0]->addChild('option', $formType["name"]);
				$option->addAttribute('value', $formType["id"]);
			}
		}
	}
As for defining the grouped list i have used the following format in a textarea ``` 1|Events@1G ,2|Familyday@1 ,3|MemberConference@1 ,4|member@2G ,5|Members@2 ,6|Donors@2 ,7|Volunteers@2 ,8|Companies@2 ,9|Question@3G ,10|Question@3 ``` This resembles the "normal" list options definition. In my context i stored the definition in a global component option to be used to build the formfield dynamically in the getform for the model. So i guess this code can be used in interpreting the formfield in jcb and build the XML entrypoint is `prepFormType` ```php /** * @param \Joomla\CMS\Form\Form $form * @param Registry $componentconfig * * * @since version */ private function prepFormType(\Joomla\CMS\Form\Form $form, Registry $componentconfig): void { // get all available "form types" from the components configuration $formTypeDefinitions = $this->getFormTypeDefinitions($componentconfig); // by convention the `group name` should be the `form viewname`, filter the options $formTypes = $this->typesByGroup($formTypeDefinitions, $this->name); // populate the options for field named "b42_formtype" ( a convention ;) $this->populateFormType($form, $formTypes, 'b42_formtype'); } /** * getFormTypeDefinitions * * @param Registry $componentconfig * * convert string to an array * 1|FormGroup 1@1G * ,2|Option 1@1 * ,3|Option 2@1 * ,4|FormGroup 2@2G * ,5|Option 3@2 * * @since version */ private function getFormTypeDefinitions(Registry $componentconfig): array { foreach (explode(",", $componentconfig->get('fieldtype')) as $key => $fieldtype) { list($formtypes[$key]['id'], $fieldtype) = explode("|", trim($fieldtype)); list($formtypes[$key]['name'], $fieldtype) = explode("@", $fieldtype); $formtypes[$key]['isgroup'] = strtoupper(substr("$fieldtype", -1))=='G'; $formtypes[$key]['group'] = $formtypes[$key]['isgroup'] ? substr($fieldtype, 0, -1): $fieldtype; } return $formtypes; } /** * typesByGroup * * @param array $formTypeDefinitions * @param string $thisformTypes * * @return array * * @since version */ private function typesByGroup(array $formTypeDefinitions, string $thisformTypes): array { foreach ($formTypeDefinitions as $item) { if ($item['isgroup'] && $item['name'] == $thisformTypes) { $group = $item['group']; } } $return=[]; foreach ($formTypeDefinitions as $item) { if ($item['group'] == $group && !$item['isgroup']) { $return[] = $item; } } return $return; } /** * populateFormType * * populate the options for field named "b42_formtype" ( a convention ;) ) * * @param \Joomla\CMS\Form\Form $form * @param array $formTypes * * * @since version */ private function populateFormType(\Joomla\CMS\Form\Form $form, array $formTypes, string $b42_formtype = 'b42_formtype' ): void { $xpath = '//field[@name=\''.$b42_formtype.'\']/option'; foreach ($form->getXml()->xpath($xpath) as $option) { unset($option[0]); } $xpath = '//field[@name=\''.$b42_formtype.'\']'; $b42_formtype_sxe = $form->getXml()->xpath($xpath); if (sizeof($b42_formtype_sxe)) { $option = $b42_formtype_sxe[0]->addChild('option', ' - select -'); $option->addAttribute('value', "0"); foreach ($formTypes as $formType) { $option = $b42_formtype_sxe[0]->addChild('option', $formType["name"]); $option->addAttribute('value', $formType["id"]); } } } ```

Okay I changed the convention a little so to make it easier I hope... so to declare options and groups it is done the following way:

Group Name@@1,1|Option 1|1,2|Option 2|1,Group Name 2@@2,3|Option 3|2

So when we declare a group we use two at @@ and no pipe | in the string and after the @@ the group unique ID like this Group Name@@1. When we add options to a group we use the normal options way, just now with two pipes | and the group ID at the end like this 3|Option 3|2.

You can also mix them up like this:

1|Option 1|1,2|Option 2|1,3|Option 3|2,Group Name@@1,Group Name 2@@2

If you use only one pipe | or no pipe in the option string then the option will not be added to a group but act like an independent option.

I will add this new field type to JCB but to add it to existing installs of JCB you will need to copy/save as copy the list fieldtype and add the following to the options row as the new default:

Group Name@@1,1|Option 1|1,2|Option 2|1,Group Name 2@@2,3|Option 3|2

Then update the fieldtype name to groupedlist and other details to what is found here in the documentation on Joomla.

Well let me know how this works. Be sure to test both implementations string manipulation and simplexml in relation to the field builder.

Okay I changed the convention a little so to make it easier I hope... so to declare options and groups it is done the following way: ``` Group Name@@1,1|Option 1|1,2|Option 2|1,Group Name 2@@2,3|Option 3|2 ``` So when we declare a group we use two at `@@` and no pipe `|` in the string and after the `@@` the group unique ID like this `Group Name@@1`. When we add options to a group we use the normal options way, just now with two pipes `|` and the group ID at the end like this `3|Option 3|2`. You can also mix them up like this: ``` 1|Option 1|1,2|Option 2|1,3|Option 3|2,Group Name@@1,Group Name 2@@2 ``` If you use only one pipe `|` or no pipe in the option string then the option will not be added to a group but act like an independent option. I will add this new field type to JCB **but to add it to existing installs** of JCB you will need to copy/save as copy the list fieldtype and add the following to the options row as the new default: ``` Group Name@@1,1|Option 1|1,2|Option 2|1,Group Name 2@@2,3|Option 3|2 ``` Then update the fieldtype name to `groupedlist` and other details to [what is found here](https://docs.joomla.org/Groupedlist_form_field_type) in the documentation on Joomla. Well let me know how this works. Be sure to test both implementations string manipulation and simplexml in relation to the field builder.
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: joomla/Component-Builder#450
No description provided.