Browse Source

Group radio buttons when outside a form element (#779)

mcukstorm 5 months ago
parent
commit
36b6876d6a

+ 2 - 1
Include/RmlUi/Core/ElementUtilities.h

@@ -69,7 +69,8 @@ public:
 	/// @param[out] elements Resulting elements.
 	/// @param[in] root_element First element to check.
 	/// @param[in] tag Tag to search for.
-	static void GetElementsByTagName(ElementList& elements, Element* root_element, const String& tag);
+	/// @param[in] stop_tag Optional, tag to stop searching at i.e. won't look for other elements within this tag.
+	static void GetElementsByTagName(ElementList& elements, Element* root_element, const String& tag, const String& stop_tag = "");
 	/// Get all elements with the given class set on them.
 	/// @param[out] elements Resulting elements.
 	/// @param[in] root_element First element to check.

+ 7 - 4
Source/Core/ElementUtilities.cpp

@@ -74,7 +74,7 @@ Element* ElementUtilities::GetElementById(Element* root_element, const String& i
 	return nullptr;
 }
 
-void ElementUtilities::GetElementsByTagName(ElementList& elements, Element* root_element, const String& tag)
+void ElementUtilities::GetElementsByTagName(ElementList& elements, Element* root_element, const String& tag, const String& stop_tag)
 {
 	// Breadth first search on elements for the corresponding id
 	typedef Queue<Element*> SearchQueue;
@@ -90,9 +90,12 @@ void ElementUtilities::GetElementsByTagName(ElementList& elements, Element* root
 		if (element->GetTagName() == tag)
 			elements.push_back(element);
 
-		// Add all children to search.
-		for (int i = 0; i < element->GetNumChildren(); i++)
-			search_queue.push(element->GetChild(i));
+		if (stop_tag.empty() || element->GetTagName() != stop_tag)
+		{
+			// Add all children to search.
+			for (int i = 0; i < element->GetNumChildren(); i++)
+				search_queue.push(element->GetChild(i));
+		}
 	}
 }
 

+ 12 - 4
Source/Core/Elements/InputTypeRadio.cpp

@@ -27,6 +27,7 @@
  */
 
 #include "InputTypeRadio.h"
+#include "../../../Include/RmlUi/Core/ElementDocument.h"
 #include "../../../Include/RmlUi/Core/ElementUtilities.h"
 #include "../../../Include/RmlUi/Core/Elements/ElementForm.h"
 #include "../../../Include/RmlUi/Core/Elements/ElementFormControlInput.h"
@@ -94,15 +95,22 @@ bool InputTypeRadio::GetIntrinsicDimensions(Vector2f& dimensions, float& ratio)
 void InputTypeRadio::PopRadioSet()
 {
 	// Uncheck all other radio buttons with our name in the form.
-	ElementForm* form = nullptr;
+	String stop_tag;
 	Element* parent = element->GetParentNode();
-	while (parent != nullptr && (form = rmlui_dynamic_cast<ElementForm*>(parent)) == nullptr)
+	while (parent != nullptr && rmlui_dynamic_cast<ElementForm*>(parent) == nullptr)
 		parent = parent->GetParentNode();
 
-	if (form != nullptr)
+	//If no containing form was found, use the containing document as the parent
+	if (parent == nullptr)
+	{
+		parent = element->GetOwnerDocument();
+		stop_tag = "form"; // Don't include any radios that are inside form elements
+	}
+
+	if (parent != nullptr)
 	{
 		ElementList form_controls;
-		ElementUtilities::GetElementsByTagName(form_controls, form, "input");
+		ElementUtilities::GetElementsByTagName(form_controls, parent, "input", stop_tag);
 
 		for (size_t i = 0; i < form_controls.size(); ++i)
 		{