mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-27 11:06:50 +01:00 
			
		
		
		
	form fixes
This commit is contained in:
		| @@ -118,6 +118,10 @@ void ComboBoxCellRenderer::renderHead(const Renderable* pRenderable, const Rende | ||||
| 	ostr << "})"; | ||||
| 	pCell->beforeLoad += Poco::delegate(&ComboBoxCellRenderer::onLoad); | ||||
| 	WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pOwner->id()), pCell); | ||||
| 	if (!pOwner->getName().empty()) | ||||
| 	{ | ||||
| 		WebApplication::instance().registerFormProcessor(pOwner->getName(), const_cast<ComboBoxCell*>(pCell)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
| #include "Poco/WebWidgets/ExtJS/FormRenderer.h" | ||||
| #include "Poco/WebWidgets/ExtJS/Utility.h" | ||||
| #include "Poco/WebWidgets/DateFieldCell.h" | ||||
| #include "Poco/WebWidgets/WebApplication.h" | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
| @@ -67,6 +68,10 @@ void DateFieldCellRenderer::renderHead(const Renderable* pRenderable, const Rend | ||||
| 	DateFieldCellRenderer::writeCellProperties(pCell, ostr); | ||||
|  | ||||
| 	ostr << "})"; | ||||
| 	if (pCell->getOwner() && !pCell->getOwner()->getName().empty()) | ||||
| 	{ | ||||
| 		WebApplication::instance().registerFormProcessor(pCell->getOwner()->getName(), const_cast<DateFieldCell*>(pCell)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -67,13 +67,14 @@ void FormRenderer::renderHead(const Renderable* pRenderable, const RenderContext | ||||
| 	if (pForm->getMethod() == Form::METHOD_POST) | ||||
| 		ostr << "method:'POST',"; | ||||
| 	ostr << "title:'" << pForm->getName() << "',autoHeight:true,autoWidth:true,url:'" << pForm->getURI().toString() << "',frame:true,items:["; | ||||
| 	//we need to add a hidden entry that contains the Form::FORM_ID plus its id | ||||
| 	ostr << "new Ext.form.Hidden({name:'" << Form::FORM_ID << "', value:" << pForm->id() << "})"; | ||||
| 	 | ||||
| 	ContainerView::ConstIterator it = pForm->begin(); | ||||
| 	ContainerView::ConstIterator itEnd = pForm->end(); | ||||
| 	for (; it != itEnd; ++it) | ||||
| 	{ | ||||
| 		if (it != pForm->begin()) | ||||
| 			ostr << ","; | ||||
| 		ostr << ","; | ||||
| 		// it points to a view pointer | ||||
| 		(*it)->renderHead(context, ostr); | ||||
| 		 | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
| #include "Poco/WebWidgets/ExtJS/FormRenderer.h" | ||||
| #include "Poco/WebWidgets/ExtJS/Utility.h" | ||||
| #include "Poco/WebWidgets/NumberFieldCell.h" | ||||
| #include "Poco/WebWidgets/WebApplication.h" | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
| @@ -67,6 +68,10 @@ void NumberFieldCellRenderer::renderHead(const Renderable* pRenderable, const Re | ||||
|  | ||||
| 	TextFieldCellRenderer::writeCellProperties(pCell, ostr); | ||||
| 	ostr << "})"; | ||||
| 	if (pCell->getOwner() && !pCell->getOwner()->getName().empty()) | ||||
| 	{ | ||||
| 		WebApplication::instance().registerFormProcessor(pCell->getOwner()->getName(), const_cast<NumberFieldCell*>(pCell)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ | ||||
| #include "Poco/WebWidgets/ExtJS/FormRenderer.h" | ||||
| #include "Poco/WebWidgets/ExtJS/Utility.h" | ||||
| #include "Poco/WebWidgets/PasswordFieldCell.h" | ||||
| #include "Poco/WebWidgets/WebApplication.h" | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
| @@ -67,6 +68,10 @@ void PasswordFieldCellRenderer::renderHead(const Renderable* pRenderable, const | ||||
|  | ||||
| 	TextFieldCellRenderer::writeCellProperties(pCell, ostr); | ||||
| 	ostr << "})"; | ||||
| 	if (pCell->getOwner() && !pCell->getOwner()->getName().empty()) | ||||
| 	{ | ||||
| 		WebApplication::instance().registerFormProcessor(pCell->getOwner()->getName(), const_cast<PasswordFieldCell*>(pCell)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -54,6 +54,8 @@ class WebWidgets_API Form: public ContainerView | ||||
| public: | ||||
| 	typedef Poco::AutoPtr<Form> Ptr; | ||||
| 	 | ||||
| 	static const std::string FORM_ID; | ||||
| 	 | ||||
| 	Form(const Poco::URI& uri); | ||||
| 		/// Creates an anonymous Form. | ||||
|  | ||||
|   | ||||
| @@ -41,6 +41,7 @@ | ||||
|  | ||||
|  | ||||
| #include "Poco/WebWidgets/WebWidgets.h" | ||||
| #include "Poco/WebWidgets/Form.h" | ||||
| #include "Poco/WebWidgets/Page.h" | ||||
| #include "Poco/WebWidgets/LookAndFeel.h" | ||||
| #include "Poco/WebWidgets/ResourceManager.h" | ||||
| @@ -58,6 +59,7 @@ namespace WebWidgets { | ||||
|  | ||||
|  | ||||
| class RequestProcessor; | ||||
| class SubmitButtonCell; | ||||
|  | ||||
|  | ||||
| class WebWidgets_API WebApplication | ||||
| @@ -116,11 +118,20 @@ public: | ||||
| 		 | ||||
| 	static std::string clientHostName(); | ||||
| 		/// Returns the host name of the caller | ||||
| 		 | ||||
| 	void notifySubmitButton(Renderable::ID formId); | ||||
| 		/// triggers the click event of the submitbutton | ||||
| 		/// required because click event and POST happens in parallel | ||||
| 		/// and we want click to be triggered after POST | ||||
| private: | ||||
| 	static Form::Ptr insideForm(const View* pChild); | ||||
| 	 | ||||
| private: | ||||
| 	WebApplication(const WebApplication&); | ||||
| 	WebApplication& operator = (const WebApplication&); | ||||
| 	 | ||||
| 	typedef std::map<std::string, RequestProcessor* > RequestProcessorMap; | ||||
| 	typedef std::map<Renderable::ID, SubmitButtonCell*> SubmitButtons; | ||||
| 	 | ||||
| 	ResourceManager::Ptr _pResource; | ||||
| 	LookAndFeel::Ptr _pLookAndFeel; | ||||
| @@ -128,6 +139,7 @@ private: | ||||
| 	Poco::URI _uri; | ||||
| 	RequestProcessorMap _requestProcessorMap; | ||||
| 	RequestProcessorMap _ajaxProcessorMap; | ||||
| 	SubmitButtons       _submitButtons; | ||||
| 	static Poco::ThreadLocal<WebApplication*> _pInstance; | ||||
| 	static Poco::ThreadLocal<std::string> _clientMachine; | ||||
| }; | ||||
|   | ||||
| @@ -41,6 +41,7 @@ namespace Poco { | ||||
| namespace WebWidgets { | ||||
|  | ||||
|  | ||||
| const std::string Form::FORM_ID("__form__"); | ||||
| const std::string Form::METHOD_GET("GET"); | ||||
| const std::string Form::METHOD_POST("POST"); | ||||
| const std::string Form::ENCODING_URL("application/x-www-form-urlencoded"); | ||||
|   | ||||
| @@ -41,9 +41,11 @@ | ||||
| #include "Poco/WebWidgets/Page.h" | ||||
| #include "Poco/WebWidgets/RenderContext.h" | ||||
| #include "Poco/WebWidgets/RequestProcessor.h" | ||||
| #include "Poco/WebWidgets/SubmitButtonCell.h" | ||||
| #include "Poco/WebWidgets/WebWidgetsException.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/NumberParser.h" | ||||
| #include "Poco/URI.h" | ||||
| #include "Poco/ThreadLocal.h" | ||||
| #include <sstream> | ||||
| @@ -90,6 +92,11 @@ void RequestHandler::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: | ||||
| 		{ | ||||
| 			handleForm(form); | ||||
| 		} | ||||
| 		Poco::Net::NameValueCollection::ConstIterator it = form.find(Form::FORM_ID); | ||||
| 		if (it != form.end()) | ||||
| 		{ | ||||
| 			_pApp->notifySubmitButton(Poco::NumberParser::parse(it->second)); | ||||
| 		} | ||||
| 		handlePageRequest(request, response); | ||||
| 	} | ||||
| 	else | ||||
| @@ -144,7 +151,12 @@ void RequestHandler::handleAjaxRequest(Poco::Net::HTTPServerRequest& request, Po | ||||
| 		response.send(); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	SubmitButtonCell* pCell = dynamic_cast<SubmitButtonCell*>(pProc); | ||||
| 	if (pCell) // hide click event from submitbuttons | ||||
| 	{ | ||||
| 		response.send(); | ||||
| 		return; | ||||
| 	} | ||||
| 	try | ||||
| 	{ | ||||
| 		pProc->handleAjaxRequest(args, response); | ||||
|   | ||||
| @@ -36,8 +36,11 @@ | ||||
|  | ||||
| #include "Poco/WebWidgets/WebApplication.h" | ||||
| #include "Poco/WebWidgets/RequestProcessor.h" | ||||
| #include "Poco/WebWidgets/SubmitButtonCell.h" | ||||
| #include "Poco/WebWidgets/WebWidgetsException.h" | ||||
| #include "Poco/Net/HTMLForm.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/NumberFormatter.h" | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
| @@ -119,6 +122,16 @@ RequestProcessor* WebApplication::getFormProcessor(const std::string& fieldName) | ||||
|  | ||||
| void WebApplication::registerAjaxProcessor(const std::string& id, RequestProcessor* pProc) | ||||
| { | ||||
| 	SubmitButtonCell* pCell = dynamic_cast<SubmitButtonCell*>(pProc); | ||||
| 	if (pCell) | ||||
| 	{ | ||||
| 		Form::Ptr pForm = insideForm(pCell->getOwner()); | ||||
| 		if (!pForm) | ||||
| 			throw Poco::WebWidgets::WebWidgetsException("submitButton without outer Form detected"); | ||||
| 		std::pair<SubmitButtons::iterator, bool> res = _submitButtons.insert(std::make_pair(pForm->id(), pCell)); | ||||
| 		if (!res.second) | ||||
| 			res.first->second = pCell; | ||||
| 	}	 | ||||
| 	std::pair<RequestProcessorMap::iterator, bool> res = _ajaxProcessorMap.insert(std::make_pair(id, pProc)); | ||||
| 	if (!res.second) | ||||
| 		res.first->second = pProc; | ||||
| @@ -158,4 +171,31 @@ void WebApplication::handleForm(const Poco::Net::HTMLForm& form) | ||||
| } | ||||
|  | ||||
|  | ||||
| void WebApplication::notifySubmitButton(Renderable::ID id) | ||||
| { | ||||
| 	SubmitButtons::iterator it = _submitButtons.find(id); | ||||
| 	if (it == _submitButtons.end()) | ||||
| 		throw WebWidgetsException("failed to find submitButton with id " + Poco::NumberFormatter::format(id)); | ||||
| 		 | ||||
| 	it->second->buttonClicked(this); | ||||
| 	_submitButtons.erase(it); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| Form::Ptr WebApplication::insideForm(const View* pChild) | ||||
| { | ||||
| 	Form::Ptr ptr; | ||||
|  | ||||
| 	while (pChild && !ptr) | ||||
| 	{ | ||||
| 		View::Ptr ptrView = pChild->parent(); | ||||
| 		ptr = ptrView.cast<Form>(); | ||||
| 		pChild = ptrView; | ||||
| 	} | ||||
|  | ||||
| 	return ptr; | ||||
| } | ||||
|  | ||||
|  | ||||
| } } // namespace Poco::WebWidgets | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Peter Schojer
					Peter Schojer