form fixes

This commit is contained in:
Peter Schojer 2008-08-28 06:02:11 +00:00
parent cdab287496
commit 716d71c833
10 changed files with 90 additions and 3 deletions

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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);

View File

@ -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));
}
}

View File

@ -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));
}
}

View File

@ -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.

View File

@ -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;
};

View File

@ -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");

View File

@ -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);

View File

@ -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