mirror of
https://github.com/pocoproject/poco.git
synced 2025-02-21 06:37:42 +01:00
refactored form handling
This commit is contained in:
parent
b9fa3377a0
commit
dd3f43c37d
@ -43,10 +43,11 @@
|
||||
#include "Poco/WebWidgets/ExtJS/ExtJS.h"
|
||||
#include "Poco/WebWidgets/Renderer.h"
|
||||
#include "Poco/WebWidgets/Form.h"
|
||||
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
class Form;
|
||||
namespace ExtJS {
|
||||
|
||||
|
||||
@ -68,6 +69,10 @@ public:
|
||||
|
||||
static std::string formVariableName(const Form* pForm);
|
||||
/// Creates the variable name for the form
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createReloadFunction(const std::string& fctName, const Form* pForm);
|
||||
/// Creates a function with the given fctName (can be empty) that reloads the form
|
||||
/// E.g.: add the returned JSDelegate to pReload->buttonClicked
|
||||
};
|
||||
|
||||
|
||||
|
@ -38,7 +38,9 @@
|
||||
#include "Poco/WebWidgets/Form.h"
|
||||
#include "Poco/WebWidgets/Button.h"
|
||||
#include "Poco/WebWidgets/WebApplication.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
#include "Poco/NumberFormatter.h"
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -83,6 +85,7 @@ void FormRenderer::renderHead(const Renderable* pRenderable, const RenderContext
|
||||
}
|
||||
ostr << "]})";
|
||||
theApp.endForm(*pForm);
|
||||
WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pForm->id()), const_cast<Form*>(pForm));
|
||||
}
|
||||
|
||||
|
||||
@ -98,4 +101,18 @@ std::string FormRenderer::formVariableName(const Form* pForm)
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate FormRenderer::createReloadFunction(const std::string& fctName, const Form* pForm)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "function ";
|
||||
out << fctName << "(){" << std::endl;
|
||||
out << "var theForm = Ext.getCmp('" << pForm->id() << "');" << std::endl;
|
||||
out << "var uri = '" << pForm->getURI().toString() << "/;" << RequestHandler::KEY_EVID << "=" << Form::EV_RELOAD << "&";
|
||||
out << RequestHandler::KEY_ID << "=" << pForm->id() << "';" << std::endl;
|
||||
out << "theForm.load({url:uri,method:'GET'});" << std::endl; // success, failure handlers
|
||||
out << "}" << std::endl;
|
||||
return jsDelegate(out.str());
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::WebWidgets::ExtJS
|
||||
|
@ -58,11 +58,8 @@ class WebWidgets_API Button: public Control
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<Button> Ptr;
|
||||
typedef Event<Button> ButtonEvent;
|
||||
|
||||
JavaScriptEvent<AjaxParameters> ajaxButtonClicked;
|
||||
|
||||
JavaScriptEvent<ButtonEvent> buttonClicked;
|
||||
JavaScriptEvent<AjaxParameters> buttonClicked;
|
||||
|
||||
Button(const std::string& name);
|
||||
/// Creates a Button with the given name.
|
||||
@ -73,11 +70,8 @@ public:
|
||||
Button();
|
||||
/// Creates an anonymous Button.
|
||||
|
||||
void fireAjaxButtonClicked(void* pSender, AjaxParameters& params);
|
||||
void fireButtonClicked(void* pSender, AjaxParameters& params);
|
||||
/// Fires the ajaxButtonClicked event.
|
||||
|
||||
void fireButtonClicked(void* pSender);
|
||||
/// Fires the buttonClicked event.
|
||||
|
||||
protected:
|
||||
Button(const std::string& name, const std::type_info& type);
|
||||
|
@ -57,9 +57,7 @@ public:
|
||||
|
||||
static const std::string EV_BUTTONCLICKED;
|
||||
|
||||
AjaxDelegate ajaxButtonClicked;
|
||||
|
||||
Delegate buttonClicked;
|
||||
AjaxDelegate buttonClicked;
|
||||
|
||||
ButtonCell(View* pOwner);
|
||||
/// Creates a ButtonCell.
|
||||
@ -68,6 +66,8 @@ public:
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response);
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~ButtonCell();
|
||||
@ -79,6 +79,12 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
inline bool ButtonCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -102,6 +102,8 @@ public:
|
||||
/// the Formatter. If no Formatter has been set, sets the value
|
||||
/// to the given string.
|
||||
|
||||
bool hasValue() const;
|
||||
|
||||
void setString(const std::string& value);
|
||||
/// Sets the value for this Cell to the given string.
|
||||
|
||||
@ -281,6 +283,12 @@ inline Cell::EditMode Cell::getEditMode() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Cell::hasValue() const
|
||||
{
|
||||
return !getValue().empty();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -124,6 +124,8 @@ public:
|
||||
void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response);
|
||||
/// Handles a complete AJAX request submitted by the client.
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~ComboBoxCell();
|
||||
/// Destroys the ComboBoxCell.
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
const Poco::DateTime& getDate() const;
|
||||
/// returns the date if set, otherwise an exception, use getValue().empty() to check if it is valid
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
private:
|
||||
std::string _format;
|
||||
};
|
||||
|
@ -41,20 +41,34 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/ContainerView.h"
|
||||
#include "Poco/WebWidgets/RequestProcessor.h"
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/FIFOEvent.h"
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace Net {
|
||||
class HTMLForm;
|
||||
}
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
class WebWidgets_API Form: public ContainerView
|
||||
class WebWidgets_API Form: public ContainerView, public RequestProcessor
|
||||
/// A Form represents a HTML form.
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<Form> Ptr;
|
||||
|
||||
static const std::string FORM_ID;
|
||||
static const std::string FORM_ID; /// form name to
|
||||
static const std::string EV_RELOAD; /// event name for reloading the form
|
||||
static const std::string METHOD_GET;
|
||||
static const std::string METHOD_POST;
|
||||
|
||||
static const std::string ENCODING_URL; /// "application/x-www-form-urlencoded"
|
||||
static const std::string ENCODING_MULTIPART; /// "multipart/form-data"
|
||||
|
||||
Poco::FIFOEvent<Form*> beforeReload; /// triggered before a Form is reloaded so that you can update form fields with recent values
|
||||
|
||||
Form(const Poco::URI& uri);
|
||||
/// Creates an anonymous Form.
|
||||
@ -76,12 +90,26 @@ public:
|
||||
|
||||
const Poco::URI& getURI() const;
|
||||
/// Returns the URL of the form
|
||||
|
||||
static const std::string METHOD_GET;
|
||||
static const std::string METHOD_POST;
|
||||
|
||||
static const std::string ENCODING_URL; /// "application/x-www-form-urlencoded"
|
||||
static const std::string ENCODING_MULTIPART; /// "multipart/form-data"
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
/// Handles a form field submitted by the client.
|
||||
|
||||
void handleForm(const Poco::Net::HTMLForm& form);
|
||||
/// Handles a complete form submit
|
||||
|
||||
void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response);
|
||||
/// Handles a complete AJAX request submitted by the client.
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string&);
|
||||
|
||||
void serializeJSONImpl(std::ostream& out);
|
||||
|
||||
RequestProcessor* getFormProcessor(const std::string& name);
|
||||
/// Returns the requestprocessor or null
|
||||
|
||||
void registerFormProcessor(const std::string& name, RequestProcessor* pProc);
|
||||
/// Registers a RequestProcessor for a request.
|
||||
|
||||
|
||||
protected:
|
||||
Form(const std::string& name, const std::type_info& type, const Poco::URI& uri);
|
||||
@ -94,9 +122,11 @@ protected:
|
||||
/// Destroys the Form.
|
||||
|
||||
private:
|
||||
std::string _method;
|
||||
std::string _encoding;
|
||||
Poco::URI _uri;
|
||||
typedef std::map<std::string, RequestProcessor* > RequestProcessorMap;
|
||||
std::string _method;
|
||||
std::string _encoding;
|
||||
Poco::URI _uri;
|
||||
RequestProcessorMap _namedChildren;
|
||||
};
|
||||
|
||||
|
||||
@ -121,6 +151,13 @@ inline const Poco::URI& Form::getURI() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Form::serializeJSON(std::ostream& out, const std::string&)
|
||||
{
|
||||
serializeJSONImpl(out);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -116,6 +116,8 @@ public:
|
||||
|
||||
// Cell
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~ListBoxCell();
|
||||
|
@ -59,6 +59,8 @@ public:
|
||||
|
||||
virtual ~NumberFieldCell();
|
||||
/// Destroys the NumberFieldCell.
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
};
|
||||
|
||||
|
||||
|
@ -97,6 +97,9 @@ public:
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
/// Dummy implementation
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
/// Dummy implementation
|
||||
|
||||
void addDynamicFunction(const std::string& jsCode);
|
||||
/// Adds a JavaScript function to the page. Static functions should be written to a JS file
|
||||
/// and included via the ResourceManager, only dynamic fucntions (ie. functions that are generated
|
||||
@ -189,6 +192,12 @@ inline void Page::appendPostRenderCode(const std::string& js)
|
||||
}
|
||||
|
||||
|
||||
inline bool Page::serializeJSON(std::ostream&, const std::string&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -58,6 +58,8 @@ public:
|
||||
|
||||
virtual ~PasswordFieldCell();
|
||||
/// Destroys the PasswordFieldCell.
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/WebWidgets.h"
|
||||
#include <ostream>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -65,6 +66,8 @@ public:
|
||||
virtual void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response) = 0;
|
||||
/// Handles a complete AJAX request submitted by the client.
|
||||
|
||||
virtual bool serializeJSON(std::ostream& out, const std::string& name) = 0;
|
||||
/// Serializes a form field to the client.
|
||||
protected:
|
||||
RequestProcessor();
|
||||
/// Creates the RequestProcessor.
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/Button.h"
|
||||
#include "Poco/FIFOEvent.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -55,6 +56,8 @@ class WebWidgets_API SubmitButton: public Button
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<SubmitButton> Ptr;
|
||||
|
||||
FIFOEvent<SubmitButton*> afterSubmit; /// thrown whenever all form values are assigned and the submit is done
|
||||
|
||||
SubmitButton();
|
||||
/// Creates an anonymous SubmitButton.
|
||||
|
@ -208,6 +208,8 @@ public:
|
||||
bool autoEdit() const;
|
||||
// Returns if autoEdit is on/off
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
Table(const std::string& name, const std::type_info& type, const TableColumns& tc, TableModel::Ptr pModel);
|
||||
/// Creates a Table and assigns it the given name.
|
||||
|
@ -79,6 +79,8 @@ public:
|
||||
|
||||
// Cell
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~TextEditCell();
|
||||
|
@ -75,6 +75,8 @@ public:
|
||||
|
||||
// Cell
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~TextFieldCell();
|
||||
|
@ -73,6 +73,8 @@ public:
|
||||
const Poco::DateTime& getTime() const;
|
||||
/// returns the time if set, otherwise an exception, use getValue().empty() to check if it is valid
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
private:
|
||||
std::string _format;
|
||||
TimeField::Format _fmt;
|
||||
|
@ -73,6 +73,9 @@ public:
|
||||
|
||||
// Cell
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
|
||||
|
||||
bool serializeJSON(std::ostream& out, const std::string& name);
|
||||
|
||||
protected:
|
||||
~ToggleButtonCell();
|
||||
|
@ -140,7 +140,7 @@ private:
|
||||
|
||||
typedef std::map<std::string, RequestProcessor* > RequestProcessorMap;
|
||||
typedef std::map<Renderable::ID, SubmitButtonCell*> SubmitButtons;
|
||||
typedef std::map<Renderable::ID, RequestProcessorMap> FormMap;
|
||||
typedef std::map<Renderable::ID, Form*> FormMap;
|
||||
typedef std::stack<Renderable::ID> OpenForms;
|
||||
|
||||
ResourceManager::Ptr _pResource;
|
||||
|
@ -101,8 +101,7 @@ void Button::init(Cell::Ptr ptrCell)
|
||||
{
|
||||
ButtonCell::Ptr pCell = ptrCell.cast<ButtonCell>();
|
||||
poco_check_ptr (pCell);
|
||||
pCell->buttonClicked = delegate(*this, &Button::fireButtonClicked);
|
||||
pCell->ajaxButtonClicked = ajaxDelegate(*this, &Button::fireAjaxButtonClicked);
|
||||
pCell->buttonClicked = ajaxDelegate(*this, &Button::fireButtonClicked);
|
||||
setCell(pCell);
|
||||
}
|
||||
|
||||
@ -114,16 +113,9 @@ void Button::init()
|
||||
}
|
||||
|
||||
|
||||
void Button::fireAjaxButtonClicked(void* pSender, AjaxParameters& params)
|
||||
void Button::fireButtonClicked(void* pSender, AjaxParameters& params)
|
||||
{
|
||||
ajaxButtonClicked(pSender, params);
|
||||
}
|
||||
|
||||
|
||||
void Button::fireButtonClicked(void* pSender)
|
||||
{
|
||||
ButtonEvent clickedEvent(this);
|
||||
buttonClicked(this, clickedEvent);
|
||||
buttonClicked(pSender, params);
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,10 +76,9 @@ void ButtonCell::handleAjaxRequest(const Poco::Net::NameValueCollection& args, P
|
||||
if (ev == EV_BUTTONCLICKED)
|
||||
{
|
||||
bool handled(false);
|
||||
ajaxButtonClicked(this, args, response, handled);
|
||||
buttonClicked(this, args, response, handled);
|
||||
if (!handled)
|
||||
response.send();
|
||||
buttonClicked(this);
|
||||
}
|
||||
else
|
||||
response.send();
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "Poco/WebWidgets/ComboBoxCell.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
#include "Poco/DateTime.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -133,4 +134,20 @@ void ComboBoxCell::setSelected(const Any& elem)
|
||||
selected(this, aPair);
|
||||
}
|
||||
|
||||
|
||||
bool ComboBoxCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (hasSelected())
|
||||
{
|
||||
const Poco::Any& sel = getSelected();
|
||||
if (sel.type() == typeid(std::string) || sel.type() == typeid(Poco::DateTime))
|
||||
out << ":'" << getFormatter()->format(sel) << "'";
|
||||
else
|
||||
out << ":" << getFormatter()->format(sel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -63,4 +63,15 @@ void DateFieldCell::setFormat(const std::string& dateFormat)
|
||||
}
|
||||
|
||||
|
||||
bool DateFieldCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":'" << getFormatter()->format(getValue()) << "'";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -35,6 +35,9 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/Form.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
#include "Poco/NumberParser.h"
|
||||
#include "Poco/Net/HTMLForm.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -42,6 +45,7 @@ namespace WebWidgets {
|
||||
|
||||
|
||||
const std::string Form::FORM_ID("__form__");
|
||||
const std::string Form::EV_RELOAD("reload");
|
||||
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");
|
||||
@ -52,7 +56,8 @@ Form::Form(const Poco::URI& uri):
|
||||
ContainerView(typeid(Form)),
|
||||
_method(METHOD_POST),
|
||||
_encoding(ENCODING_MULTIPART),
|
||||
_uri(uri)
|
||||
_uri(uri),
|
||||
_namedChildren()
|
||||
{
|
||||
}
|
||||
|
||||
@ -61,7 +66,8 @@ Form::Form(const std::string& name, const Poco::URI& uri):
|
||||
ContainerView(name, typeid(Form)),
|
||||
_method(METHOD_POST),
|
||||
_encoding(ENCODING_MULTIPART),
|
||||
_uri(uri)
|
||||
_uri(uri),
|
||||
_namedChildren()
|
||||
{
|
||||
}
|
||||
|
||||
@ -70,7 +76,8 @@ Form::Form(const std::string& name, const std::type_info& type, const Poco::URI&
|
||||
ContainerView(name, type),
|
||||
_method(METHOD_POST),
|
||||
_encoding(ENCODING_MULTIPART),
|
||||
_uri(uri)
|
||||
_uri(uri),
|
||||
_namedChildren()
|
||||
{
|
||||
}
|
||||
|
||||
@ -79,7 +86,8 @@ Form::Form(const std::type_info& type, const Poco::URI& uri):
|
||||
ContainerView(type),
|
||||
_method(METHOD_POST),
|
||||
_encoding(ENCODING_MULTIPART),
|
||||
_uri(uri)
|
||||
_uri(uri),
|
||||
_namedChildren()
|
||||
{
|
||||
}
|
||||
|
||||
@ -101,4 +109,92 @@ void Form::setEncoding(const std::string& encoding)
|
||||
}
|
||||
|
||||
|
||||
void Form::handleForm(const std::string& field, const std::string& value)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Form::handleForm(const Poco::Net::HTMLForm& form)
|
||||
{
|
||||
Renderable::ID formID = Poco::NumberParser::parse(form.get(Form::FORM_ID));
|
||||
poco_assert (formID == id());
|
||||
|
||||
Poco::Net::NameValueCollection::ConstIterator it = form.begin();
|
||||
RequestProcessorMap processors = _namedChildren; // copy so that a second submit works too!
|
||||
for (;it != form.end(); ++it)
|
||||
{
|
||||
const std::string& key = it->first;
|
||||
RequestProcessorMap::iterator itR = processors.find(key);
|
||||
if (itR != processors.end())
|
||||
{
|
||||
itR->second->handleForm(key, it->second);
|
||||
processors.erase(itR);
|
||||
}
|
||||
}
|
||||
//those that are not included are either deselected or empty
|
||||
RequestProcessorMap::iterator itR = processors.begin();
|
||||
std::string empty;
|
||||
for (; itR != processors.end(); ++itR)
|
||||
{
|
||||
itR->second->handleForm(itR->first, empty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Form::handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response)
|
||||
{
|
||||
//a form only supports the refresh event
|
||||
const std::string& ev = args[RequestHandler::KEY_EVID];
|
||||
if (ev == EV_RELOAD)
|
||||
{
|
||||
Form* pThis = this;
|
||||
beforeReload.notify(this, pThis);
|
||||
/// send the JS presentation of the page
|
||||
response.setContentType("text/javascript");
|
||||
response.setChunkedTransferEncoding(true);
|
||||
serializeJSONImpl(response.send());
|
||||
}
|
||||
response.send();
|
||||
}
|
||||
|
||||
|
||||
void Form::serializeJSONImpl(std::ostream& out)
|
||||
{
|
||||
// FIXME: ExtJs specific
|
||||
out << "{";
|
||||
out << "success: true,";
|
||||
out << "data: { ";
|
||||
// serialize children
|
||||
RequestProcessorMap::iterator it = _namedChildren.begin();
|
||||
bool writeComma = false;
|
||||
for (; it != _namedChildren.end(); ++it)
|
||||
{
|
||||
if (writeComma)
|
||||
out << ",";
|
||||
writeComma = it->second->serializeJSON(out, it->first);
|
||||
}
|
||||
out << "}";
|
||||
out << "}";
|
||||
}
|
||||
|
||||
|
||||
void Form::registerFormProcessor(const std::string& fieldName, RequestProcessor* pProc)
|
||||
{
|
||||
// per default we register everything that has a name as form processor
|
||||
std::pair<RequestProcessorMap::iterator, bool> res = _namedChildren.insert(std::make_pair(fieldName, pProc));
|
||||
if (!res.second)
|
||||
res.first->second = pProc;
|
||||
}
|
||||
|
||||
|
||||
RequestProcessor* Form::getFormProcessor(const std::string& fieldName)
|
||||
{
|
||||
RequestProcessorMap::iterator it = _namedChildren.find(fieldName);
|
||||
if (it == _namedChildren.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/ListBoxCell.h"
|
||||
#include "Poco/DateTime.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -168,4 +169,19 @@ const Any& ListBoxCell::getSelected() const
|
||||
}
|
||||
|
||||
|
||||
bool ListBoxCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (hasSelected())
|
||||
{
|
||||
const Poco::Any& sel = getSelected();
|
||||
if (sel.type() == typeid(std::string) || sel.type() == typeid(Poco::DateTime))
|
||||
out << ":'" << getFormatter()->format(sel) << "'";
|
||||
else
|
||||
out << ":" << getFormatter()->format(sel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -54,4 +54,15 @@ NumberFieldCell::~NumberFieldCell()
|
||||
}
|
||||
|
||||
|
||||
bool NumberFieldCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":" << getFormatter()->format(getValue());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -52,4 +52,15 @@ PasswordFieldCell::~PasswordFieldCell()
|
||||
}
|
||||
|
||||
|
||||
bool PasswordFieldCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":'" << getFormatter()->format(getValue()) << "'";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -181,12 +181,7 @@ 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);
|
||||
|
@ -352,4 +352,10 @@ Table::LoadData::LoadData(Poco::Net::HTTPServerResponse* pR, Table* pT, int row,
|
||||
}
|
||||
|
||||
|
||||
bool Table::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -73,4 +73,15 @@ void TextEditCell::handleForm(const std::string& field, const std::string& value
|
||||
}
|
||||
|
||||
|
||||
bool TextEditCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":'" << getFormatter()->format(getValue()) << "'";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -85,4 +85,15 @@ void TextFieldCell::handleForm(const std::string& field, const std::string& valu
|
||||
}
|
||||
|
||||
|
||||
bool TextFieldCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":'" << getFormatter()->format(getValue()) << "'";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -77,4 +77,15 @@ void TimeFieldCell::setFormat(TimeField::Format fmt)
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool TimeFieldCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
out << name;
|
||||
if (this->hasValue())
|
||||
{
|
||||
out << ":'" << getFormatter()->format(getValue()) << "'";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -85,4 +85,16 @@ void ToggleButtonCell::setChecked(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ToggleButtonCell::serializeJSON(std::ostream& out, const std::string& name)
|
||||
{
|
||||
//FIXME: this is extjs specific
|
||||
out << name << ":";
|
||||
if (isChecked())
|
||||
out << "'on'";
|
||||
else
|
||||
out << "'off'";
|
||||
return true;
|
||||
}
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -113,20 +113,19 @@ void WebApplication::beginForm(const Form& form)
|
||||
if (!_forms.empty())
|
||||
throw WebWidgetsException("nested forms not allowed");
|
||||
_forms.push(form.id());
|
||||
_formMap.insert(std::make_pair(form.id(), RequestProcessorMap()));
|
||||
_formMap.insert(std::make_pair(form.id(), const_cast<Form*>(&form)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void WebApplication::registerFormProcessor(const std::string& fieldName, RequestProcessor* pProc)
|
||||
{
|
||||
// per default we register everyting that has a name as form processor
|
||||
// per default we register everything that has a name as form processor
|
||||
if (!_forms.empty())
|
||||
{
|
||||
FormMap::iterator itForm = _formMap.find(_forms.top());
|
||||
poco_assert (itForm != _formMap.end());
|
||||
std::pair<RequestProcessorMap::iterator, bool> res = itForm->second.insert(std::make_pair(fieldName, pProc));
|
||||
if (!res.second)
|
||||
res.first->second = pProc;
|
||||
|
||||
itForm->second->registerFormProcessor(fieldName, pProc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,10 +136,7 @@ RequestProcessor* WebApplication::getFormProcessor(Renderable::ID formId, const
|
||||
if (itForm == _formMap.end())
|
||||
return 0;
|
||||
|
||||
RequestProcessorMap::iterator it = itForm->second.find(fieldName);
|
||||
if (it == itForm->second.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
return itForm->second->getFormProcessor(fieldName);
|
||||
}
|
||||
|
||||
|
||||
@ -184,27 +180,8 @@ void WebApplication::handleForm(const Poco::Net::HTMLForm& form)
|
||||
FormMap::iterator itForm = _formMap.find(formID);
|
||||
if (itForm == _formMap.end())
|
||||
throw Poco::NotFoundException("unknown form id");
|
||||
|
||||
Poco::Net::NameValueCollection::ConstIterator it = form.begin();
|
||||
RequestProcessorMap& processors = itForm->second;
|
||||
for (;it != form.end(); ++it)
|
||||
{
|
||||
const std::string& key = it->first;
|
||||
RequestProcessorMap::iterator itR = processors.find(key);
|
||||
if (itR != processors.end())
|
||||
{
|
||||
itR->second->handleForm(key, it->second);
|
||||
processors.erase(itR);
|
||||
}
|
||||
}
|
||||
//those that are not included are either deselected or empty
|
||||
RequestProcessorMap::iterator itR = processors.begin();
|
||||
std::string empty;
|
||||
for (; itR != processors.end(); ++itR)
|
||||
{
|
||||
itR->second->handleForm(itR->first, empty);
|
||||
}
|
||||
processors.clear();
|
||||
|
||||
itForm->second->handleForm(form);
|
||||
}
|
||||
|
||||
|
||||
@ -219,8 +196,7 @@ void WebApplication::notifySubmitButton(Renderable::ID id)
|
||||
SubmitButton* pSubmit = dynamic_cast<SubmitButton*>(pOwner);
|
||||
if (pSubmit)
|
||||
{
|
||||
Button::ButtonEvent clickedEvent(pSubmit);
|
||||
pSubmit->buttonClicked.notify(pSubmit, clickedEvent);
|
||||
pSubmit->afterSubmit.notify(pSubmit, pSubmit);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user