mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-29 21:30:04 +01:00
refactored JSEvents for easier server callbacks
This commit is contained in:
parent
db640711d1
commit
515c64faea
@ -41,6 +41,7 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/CellRenderer.h"
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -75,13 +76,15 @@ public:
|
||||
static void renderButton(const ButtonCell* pCell, const std::string& content, bool writeId, bool submitButton, std::ostream& ostr, bool showText = true);
|
||||
/// Renders button properties
|
||||
|
||||
static void addClickServerCallback(Button* pCombo, const std::string& onSuccess="", const std::string& onFailure="");
|
||||
static Poco::WebWidgets::JSDelegate createClickServerCallback(const Button* pCombo);
|
||||
/// Adds a server callback for the buttonClicked event. The JS method signature for click is
|
||||
/// click : ( Button this, EventObject e )
|
||||
|
||||
|
||||
protected:
|
||||
virtual ~ButtonCellRenderer();
|
||||
/// Destroys the ButtonCellRenderer.
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/ExtJS.h"
|
||||
#include "Poco/WebWidgets/Renderer.h"
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
|
||||
@ -72,14 +73,14 @@ public:
|
||||
void renderBody(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr);
|
||||
/// Emits code for the page body to the given output stream.
|
||||
|
||||
static void addSelectedServerCallback(ComboBox* pCombo, const std::string& onSuccess, const std::string& onFailure);
|
||||
/// Adds a server callback for the selected event. The method signature for select is
|
||||
/// select : ( Ext.form.ComboBox combo, Ext.data.Record record, Number index )
|
||||
|
||||
private:
|
||||
static void onLoad(void* pSender, Poco::Net::HTTPServerResponse* &pResponse);
|
||||
|
||||
static void serialize(const ComboBoxCell* pCell, std::ostream& out);
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createSelectedServerCallback(const ComboBox* pCombo);
|
||||
/// Adds a server callback for the selected event. The method signature for select is
|
||||
/// select : ( Ext.form.ComboBox combo, Ext.data.Record record, Number index )
|
||||
};
|
||||
|
||||
|
||||
|
@ -41,11 +41,15 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/ExtJS/ExtJS.h"
|
||||
#include "Poco/WebWidgets/JSDelegate.h"
|
||||
#include "Poco/WebWidgets/Renderer.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
|
||||
class Page;
|
||||
|
||||
namespace ExtJS {
|
||||
|
||||
|
||||
@ -67,6 +71,14 @@ public:
|
||||
|
||||
void renderBody(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr);
|
||||
/// Emits code for the page body to the given output stream.
|
||||
|
||||
protected:
|
||||
static Poco::WebWidgets::JSDelegate createBeforeRenderCallback(const Page* pPage);
|
||||
/// JS signature: beforerender : ( Ext.Component this )
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createAfterRenderCallback(const Page* pPage);
|
||||
/// JS signature: show : ( Ext.Component this )
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -79,24 +79,6 @@ public:
|
||||
|
||||
void renderBody(const Renderable* pRenderable, const RenderContext& context, std::ostream& ostr);
|
||||
/// Emits code for the page body to the given output stream.
|
||||
|
||||
static void addCellValueChangedServerCallback(Table* pTable, const std::string& onSuccess=std::string(), const std::string& onFailure=std::string());
|
||||
/// Adds a javascript callback to inform the WebServer that the client has changed a value in the Table
|
||||
/// The Extjs handler offers a method signature of "function(obj)" where obj is a complex element containing members (column, row, value)
|
||||
|
||||
static void addCellClickedServerCallback(Table* pTable, const std::string& onSuccess=std::string(), const std::string& onFailure=std::string());
|
||||
/// Adds a javascript callback to inform the WebServer that the client has clicked on a cell in the Table
|
||||
/// Method signature is cellclick : ( Grid this, Number rowIndex, Number columnIndex, Ext.EventObject e )
|
||||
|
||||
static void addRowClickedServerCallback(Table* pTable, const std::string& onSuccess=std::string(), const std::string& onFailure=std::string());
|
||||
/// Adds a javascript callback to inform the WebServer that the client has clicke don a row
|
||||
/// This event will only be added if the Table uses a Row selection model!
|
||||
/// Single cell selection will trigger an exception!
|
||||
/// Method signature is rowselect : ( SelectionModel this, Number rowIndex, Ext.Data.Record r )
|
||||
|
||||
static void addAfterLoadServerCallback(Table* pTable, const std::string& onSuccess=std::string(), const std::string& onFailure=std::string());
|
||||
/// Adds a javascript callback to inform the WebServer that the client has finished loading data
|
||||
/// Method signature is ( Store this, Ext.data.Record[] records, Object options )
|
||||
|
||||
protected:
|
||||
static void renderProperties(const Table* pTable, const RenderContext& context, std::ostream& ostr);
|
||||
@ -112,6 +94,24 @@ protected:
|
||||
/// Renders the data store of the table
|
||||
|
||||
static void onBeforeLoad(void* pSender, Table::LoadData& ld);
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createCellValueChangedServerCallback(const Table* pTable);
|
||||
/// Adds a javascript callback to inform the WebServer that the client has changed a value in the Table
|
||||
/// The Extjs handler offers a method signature of "function(obj)" where obj is a complex element containing members (column, row, value)
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createCellClickedServerCallback(const Table* pTable);
|
||||
/// Adds a javascript callback to inform the WebServer that the client has clicked on a cell in the Table
|
||||
/// Method signature is cellclick : ( Grid this, Number rowIndex, Number columnIndex, Ext.EventObject e )
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createRowClickedServerCallback(const Table* pTable);
|
||||
/// Adds a javascript callback to inform the WebServer that the client has clicke don a row
|
||||
/// This event will only be added if the Table uses a Row selection model!
|
||||
/// Single cell selection will trigger an exception!
|
||||
/// Method signature is rowselect : ( SelectionModel this, Number rowIndex, Ext.Data.Record r )
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createAfterLoadServerCallback(const Table* pTable);
|
||||
/// Adds a javascript callback to inform the WebServer that the client has finished loading data
|
||||
/// Method signature is ( Store this, Ext.data.Record[] records, Object options )
|
||||
};
|
||||
|
||||
|
||||
|
@ -109,6 +109,8 @@ public:
|
||||
/// writes all JS Delegates for a single named JSEvent.
|
||||
/// Returns true if data was written, false if no delegates were present and no event handler was written.
|
||||
|
||||
static bool writeJSEvent(std::ostream& out, const std::string& eventName, const std::list<JSDelegate>& delegates, const Poco::WebWidgets::JSDelegate& serverCallback, std::size_t serverCallPos);
|
||||
/// writes all JS Delegates for a single named JSEvent. plus the server callbacb, Always returns true.
|
||||
|
||||
static std::string createURI(const std::map<std::string, std::string>& addParams, Renderable::ID id);
|
||||
/// Creates the url from the function parameters, adds the id parameter automatically
|
||||
@ -141,6 +143,13 @@ public:
|
||||
ev.add(jsDelegate(code));
|
||||
|
||||
}
|
||||
|
||||
static Poco::WebWidgets::JSDelegate createServerCallback(
|
||||
const std::string& signature,
|
||||
const std::map<std::string, std::string>& addServerParams,
|
||||
Renderable::ID id,
|
||||
const std::string& onSuccessJS,
|
||||
const std::string& onFailureJS);
|
||||
|
||||
private:
|
||||
static void convertPocoDateToPHPDate(char in, std::string& result);
|
||||
|
@ -91,25 +91,33 @@ void ButtonCellRenderer::renderProperties(const ButtonCell* pButtonCell, const s
|
||||
Form::Ptr pForm = Utility::insideForm(pButtonCell);
|
||||
ostr << "handler: function(){Ext.getCmp('" << pForm->id() << "').getForm().submit();},";
|
||||
}
|
||||
Button* pOwner = dynamic_cast<Button*>(pButtonCell->getOwner());
|
||||
poco_check_ptr (pOwner);
|
||||
View* pView = pButtonCell->getOwner();
|
||||
poco_check_ptr (pView);
|
||||
Button* pOwner = dynamic_cast<Button*>(pView);
|
||||
// a buttoncell inside a table will have no parent of type button!
|
||||
|
||||
if (writeId)
|
||||
Utility::writeRenderableProperties(pOwner, ostr);
|
||||
Utility::writeRenderableProperties(pView, ostr);
|
||||
if (!pButtonCell->isEnabled())
|
||||
ostr << ",disabled:true";
|
||||
|
||||
if (!pView->getName().empty())
|
||||
ostr << ",name:'" << pOwner->getName() << "'";
|
||||
if (pView->getWidth() != 0)
|
||||
ostr << ",minWidth:" << pOwner->getWidth();
|
||||
if (!pView->isVisible())
|
||||
ostr << ",hidden:true";
|
||||
|
||||
if (pOwner)
|
||||
{
|
||||
if (!pOwner->getName().empty())
|
||||
ostr << ",name:'" << pOwner->getName() << "'";
|
||||
if (pOwner->getWidth() != 0)
|
||||
ostr << ",minWidth:" << pOwner->getWidth();
|
||||
if (!pOwner->isVisible())
|
||||
ostr << ",hidden:true";
|
||||
if (!pOwner->buttonClicked.jsDelegates().empty())
|
||||
if (pOwner->buttonClicked.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates());
|
||||
if (pOwner->buttonClicked.willDoServerCallback())
|
||||
Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates(),
|
||||
createClickServerCallback(pOwner), pOwner->buttonClicked.getServerCallbackPos());
|
||||
else
|
||||
Utility::writeJSEvent(ostr, EV_CLICK, pOwner->buttonClicked.jsDelegates());
|
||||
ostr << "}";
|
||||
}
|
||||
}
|
||||
@ -120,7 +128,7 @@ void ButtonCellRenderer::renderProperties(const ButtonCell* pButtonCell, const s
|
||||
if (!toolTip.empty())
|
||||
ostr << ",tooltip:'" << Utility::safe(toolTip) << "'";
|
||||
|
||||
WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pButtonCell->id()), const_cast<ButtonCell*>(pButtonCell));
|
||||
WebApplication::instance().registerAjaxProcessor(Poco::NumberFormatter::format(pView->id()), const_cast<ButtonCell*>(pButtonCell));
|
||||
}
|
||||
|
||||
|
||||
@ -139,13 +147,13 @@ void ButtonCellRenderer::writeConfigData(const Cell* pCell, const RenderContext&
|
||||
|
||||
|
||||
|
||||
void ButtonCellRenderer::addClickServerCallback(Button* pButton, const std::string& onSuccess, const std::string& onFailure)
|
||||
JSDelegate ButtonCellRenderer::createClickServerCallback(const Button* pButton)
|
||||
{
|
||||
//click : ( Button this, EventObject e )
|
||||
static const std::string signature("function(but,e)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ButtonCell::EV_BUTTONCLICKED));
|
||||
Utility::addServerCallback(pButton->buttonClicked, signature, addParams, pButton->getCell()->id(), onSuccess, onFailure);
|
||||
return Utility::createServerCallback(signature, addParams, pButton->id(), pButton->buttonClicked.getOnSuccess(), pButton->buttonClicked.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,14 +65,14 @@ ComboBoxCellRenderer::~ComboBoxCellRenderer()
|
||||
}
|
||||
|
||||
|
||||
void ComboBoxCellRenderer::addSelectedServerCallback(ComboBox* pCombo, const std::string& onSuccess, const std::string& onFailure)
|
||||
JSDelegate ComboBoxCellRenderer::createSelectedServerCallback(const ComboBox* pCombo)
|
||||
{
|
||||
//select : ( Ext.form.ComboBox combo, Ext.data.Record record, Number index )
|
||||
static const std::string signature("function(combo,rec,idx)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(ComboBoxCell::FIELD_VAL, "+rec.get('d')"));
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, ComboBoxCell::EV_SELECTED));
|
||||
Utility::addServerCallback(pCombo->selected, signature, addParams, pCombo->id(), onSuccess, onFailure);
|
||||
return Utility::createServerCallback(signature, addParams, pCombo->id(), pCombo->selected.getOnSuccess(), pCombo->selected.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
@ -100,10 +100,13 @@ void ComboBoxCellRenderer::renderHead(const Renderable* pRenderable, const Rende
|
||||
|
||||
std::string tooltip (pCell->getToolTip());
|
||||
|
||||
if (pComboOwner && !pComboOwner->selected.jsDelegates().empty())
|
||||
if (pComboOwner && pComboOwner->selected.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected.jsDelegates());
|
||||
if (pComboOwner->selected.willDoServerCallback())
|
||||
Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected.jsDelegates(), createSelectedServerCallback(pComboOwner), pComboOwner->selected.getServerCallbackPos());
|
||||
else
|
||||
Utility::writeJSEvent(ostr, EV_SELECTED, pComboOwner->selected.jsDelegates());
|
||||
if (!tooltip.empty())
|
||||
ostr << ",render:function(c){Ext.QuickTips.register({target:c.getEl(),text:'" << Utility::safe(tooltip) << "'});}";
|
||||
ostr << "}";
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "Poco/WebWidgets/RenderContext.h"
|
||||
#include "Poco/WebWidgets/LookAndFeel.h"
|
||||
#include "Poco/WebWidgets/WebApplication.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -125,14 +126,20 @@ void PageRenderer::renderHead(const Renderable* pRenderable, const RenderContext
|
||||
|
||||
// always nest a panel around, so we can get rid of dynamic casts to check for parent type
|
||||
ostr << "new Ext.Panel({renderTo:'p" << pPage->id() << "',border:false,bodyBorder:false";
|
||||
if (!pPage->beforeRender.jsDelegates().empty() || !pPage->afterRender.jsDelegates().empty())
|
||||
if (pPage->beforeRender.hasJavaScriptCode() || pPage->afterRender.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
bool written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender.jsDelegates());
|
||||
bool written = false;
|
||||
if (pPage->beforeRender.willDoServerCallback())
|
||||
written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender.jsDelegates(), createBeforeRenderCallback(pPage), pPage->beforeRender.getServerCallbackPos());
|
||||
else
|
||||
written = Utility::writeJSEvent(ostr, EV_BEFORERENDER, pPage->beforeRender.jsDelegates());
|
||||
if (written)
|
||||
ostr << ",";
|
||||
|
||||
Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender.jsDelegates());
|
||||
if (pPage->afterRender.willDoServerCallback())
|
||||
Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender.jsDelegates(), createAfterRenderCallback(pPage), pPage->afterRender.getServerCallbackPos());
|
||||
else
|
||||
Utility::writeJSEvent(ostr, EV_AFTERRENDER, pPage->afterRender.jsDelegates());
|
||||
ostr << "}";
|
||||
}
|
||||
if (pPage->getHeight() > 0)
|
||||
@ -190,4 +197,24 @@ void PageRenderer::renderBody(const Renderable* pRenderable, const RenderContext
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate PageRenderer::createBeforeRenderCallback(const Page* pPage)
|
||||
{
|
||||
// JS signature: beforerender : ( Ext.Component this )
|
||||
static const std::string signature("function(p)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Page::EV_BEFORERENDER));
|
||||
return Utility::createServerCallback(signature, addParams, pPage->id(), pPage->beforeRender.getOnSuccess(), pPage->beforeRender.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate PageRenderer::createAfterRenderCallback(const Page* pPage)
|
||||
{
|
||||
// JS signature: show : ( Ext.Component this )
|
||||
static const std::string signature("function(p)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Page::EV_AFTERRENDER));
|
||||
return Utility::createServerCallback(signature, addParams, pPage->id(), pPage->afterRender.getOnSuccess(), pPage->afterRender.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
} } } // namespace Poco::WebWidgets::ExtJS
|
||||
|
@ -99,9 +99,8 @@ void TableRenderer::renderBody(const Renderable* pRenderable, const RenderContex
|
||||
}
|
||||
|
||||
|
||||
void TableRenderer::addCellValueChangedServerCallback(Table* pTable, const std::string& onSuccess, const std::string& onFailure)
|
||||
Poco::WebWidgets::JSDelegate TableRenderer::createCellValueChangedServerCallback(const Table* pTable)
|
||||
{
|
||||
poco_check_ptr (pTable);
|
||||
static const std::string signature("function(obj)");
|
||||
//extract the true row index from the last column!
|
||||
std::string origRow("+obj.record.get('");
|
||||
@ -112,28 +111,27 @@ void TableRenderer::addCellValueChangedServerCallback(Table* pTable, const std::
|
||||
addParams.insert(std::make_pair(Table::FIELD_ROW, origRow));
|
||||
//problem: I need the displayed string from teh renderer, not the value!
|
||||
// date fields cause problems here, and I only habe one cellclick event per table not per column!
|
||||
// from the tabel get the TableCOlumn, from thsi get the renderer for the given col and render obj.value
|
||||
// from the table get the TableColumn, from this get the renderer for the given col and render obj.value
|
||||
// {(var r=obj.grid.getColumnModel().getRenderer(obj.column))?r(obj.value);:obj.value;}, hm renderer exists for everthing
|
||||
addParams.insert(std::make_pair(Table::FIELD_VAL, "+obj.grid.getColumnModel().getRenderer(obj.column)(obj.value)"));
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Table::EV_CELLVALUECHANGED));
|
||||
Utility::addServerCallback(pTable->cellValueChanged, signature, addParams, pTable->id(), onSuccess, onFailure);
|
||||
pTable->cellValueChanged.add(jsDelegate("function(obj){obj.grid.getStore().commitChanges();}"));
|
||||
const std::string& success = pTable->cellValueChanged.getOnSuccess();
|
||||
|
||||
return Utility::createServerCallback(signature, addParams, pTable->id(), pTable->cellValueChanged.getOnSuccess(), pTable->cellValueChanged.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TableRenderer::addAfterLoadServerCallback(Table* pTable, const std::string& onSuccess, const std::string& onFailure)
|
||||
Poco::WebWidgets::JSDelegate TableRenderer::createAfterLoadServerCallback(const Table* pTable)
|
||||
{
|
||||
poco_check_ptr (pTable);
|
||||
static const std::string signature("function(aStore, recs, op)");
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Table::EV_AFTERLOAD));
|
||||
Utility::addServerCallback(pTable->afterLoad, signature, addParams, pTable->id(), onSuccess, onFailure);
|
||||
return Utility::createServerCallback(signature, addParams, pTable->id(), pTable->afterLoad.getOnSuccess(), pTable->afterLoad.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TableRenderer::addCellClickedServerCallback(Table* pTable, const std::string& onSuccess, const std::string& onFailure)
|
||||
Poco::WebWidgets::JSDelegate TableRenderer::createCellClickedServerCallback(const Table* pTable)
|
||||
{
|
||||
poco_check_ptr (pTable);
|
||||
static const std::string signature("function(theGrid,row,col,e)");
|
||||
@ -145,12 +143,11 @@ void TableRenderer::addCellClickedServerCallback(Table* pTable, const std::strin
|
||||
addParams.insert(std::make_pair(Table::FIELD_COL, "+col"));
|
||||
addParams.insert(std::make_pair(Table::FIELD_ROW, origRow));
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Table::EV_CELLCLICKED));
|
||||
Utility::addServerCallback(pTable->cellClicked, signature, addParams, pTable->id(), onSuccess, onFailure);
|
||||
return Utility::createServerCallback(signature, addParams, pTable->id(), pTable->cellClicked.getOnSuccess(), pTable->cellClicked.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TableRenderer::addRowClickedServerCallback(Table* pTable, const std::string& onSuccess, const std::string& onFailure)
|
||||
Poco::WebWidgets::JSDelegate TableRenderer::createRowClickedServerCallback(const Table* pTable)
|
||||
{
|
||||
poco_check_ptr (pTable);
|
||||
poco_assert (pTable->getSelectionModel() != Table::SM_CELL);
|
||||
@ -164,7 +161,7 @@ void TableRenderer::addRowClickedServerCallback(Table* pTable, const std::string
|
||||
std::map<std::string, std::string> addParams;
|
||||
addParams.insert(std::make_pair(Table::FIELD_ROW, origRow));
|
||||
addParams.insert(std::make_pair(RequestHandler::KEY_EVID, Table::EV_ROWCLICKED));
|
||||
Utility::addServerCallback(pTable->rowClicked, signature, addParams, pTable->id(), onSuccess, onFailure);
|
||||
return Utility::createServerCallback(signature, addParams, pTable->id(), pTable->rowClicked.getOnSuccess(), pTable->rowClicked.getOnFailure());
|
||||
}
|
||||
|
||||
|
||||
@ -183,11 +180,26 @@ void TableRenderer::renderProperties(const Table* pTable, const RenderContext& c
|
||||
ostr << ",listeners:{";
|
||||
bool written = false;
|
||||
if (editable)
|
||||
written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, pTable->cellValueChanged.jsDelegates());
|
||||
{
|
||||
JSDelegate jsDel("function(obj){obj.grid.getStore().commitChanges();}");
|
||||
std::list<JSDelegate> modList(pTable->cellValueChanged.jsDelegates());
|
||||
modList.push_back(jsDel);
|
||||
if (pTable->cellValueChanged.willDoServerCallback())
|
||||
written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, modList,
|
||||
TableRenderer::createCellValueChangedServerCallback(pTable),
|
||||
pTable->cellValueChanged.getServerCallbackPos());
|
||||
else
|
||||
written = Utility::writeJSEvent(ostr, EV_AFTEREDIT, modList);
|
||||
}
|
||||
if (written)
|
||||
ostr << ",";
|
||||
|
||||
written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked.jsDelegates());
|
||||
if (pTable->cellClicked.willDoServerCallback())
|
||||
written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked.jsDelegates(),
|
||||
TableRenderer::createCellClickedServerCallback(pTable),
|
||||
pTable->cellClicked.getServerCallbackPos());
|
||||
else
|
||||
written = Utility::writeJSEvent(ostr, EV_CELLCLICKED, pTable->cellClicked.jsDelegates());
|
||||
|
||||
|
||||
|
||||
@ -203,10 +215,15 @@ void TableRenderer::renderProperties(const Table* pTable, const RenderContext& c
|
||||
ostr << ",selModel:new Ext.grid.RowSelectionModel({singleSelect:true";
|
||||
else if (pTable->getSelectionModel() == Table::SM_MULTIROW)
|
||||
ostr << ",selModel:new Ext.grid.RowSelectionModel({singleSelect:false";
|
||||
if (!pTable->rowClicked.jsDelegates().empty())
|
||||
if (pTable->rowClicked.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked.jsDelegates());
|
||||
if (pTable->rowClicked.willDoServerCallback())
|
||||
Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked.jsDelegates(),
|
||||
TableRenderer::createRowClickedServerCallback(pTable),
|
||||
pTable->rowClicked.getServerCallbackPos());
|
||||
else
|
||||
Utility::writeJSEvent(ostr, EV_ROWCLICKED, pTable->rowClicked.jsDelegates());
|
||||
ostr << "}";
|
||||
}
|
||||
ostr << "})"; //close selModel
|
||||
@ -334,9 +351,16 @@ void TableRenderer::renderStore(const Table* pTable, std::ostream& ostr)
|
||||
std::string url(Utility::createURI(addParams, pTable->id()));
|
||||
ostr << url << "}),";
|
||||
ostr << "reader:new Ext.data.ArrayReader()";
|
||||
ostr << ",listeners:{";
|
||||
Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad.jsDelegates());
|
||||
ostr << "}";
|
||||
if (pTable->afterLoad.hasJavaScriptCode())
|
||||
{
|
||||
ostr << ",listeners:{";
|
||||
if (pTable->afterLoad.willDoServerCallback())
|
||||
Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad.jsDelegates(), createAfterLoadServerCallback(pTable), pTable->afterLoad.getServerCallbackPos());
|
||||
else
|
||||
Utility::writeJSEvent(ostr, EV_AFTERLOAD, pTable->afterLoad.jsDelegates());
|
||||
ostr << "}";
|
||||
}
|
||||
|
||||
ostr << "})";
|
||||
}
|
||||
|
||||
|
@ -479,6 +479,27 @@ bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, cons
|
||||
}
|
||||
|
||||
|
||||
bool Utility::writeJSEvent(std::ostream& out, const std::string& eventName, const std::list<JSDelegate>& delegates, const Poco::WebWidgets::JSDelegate& serverCallback, std::size_t serverCallPos)
|
||||
{
|
||||
// TODO: we can optimize here a bit by avoiding the copy
|
||||
std::list<JSDelegate> dels;
|
||||
std::list<JSDelegate>::const_iterator it = dels.begin();
|
||||
bool written = false;
|
||||
for (; it != dels.end(); ++it, --serverCallPos)
|
||||
{
|
||||
if (serverCallPos == 0)
|
||||
{
|
||||
dels.push_back(serverCallback);
|
||||
written = true;
|
||||
}
|
||||
dels.push_back(*it);
|
||||
}
|
||||
if (!written)
|
||||
dels.push_back(serverCallback);
|
||||
return writeJSEvent(out, eventName, dels);
|
||||
}
|
||||
|
||||
|
||||
void Utility::writeFunction(std::ostream& out, const std::string& fctName, const std::vector<std::string> ¶ms, const std::string& code)
|
||||
{
|
||||
out << fctName << "(";
|
||||
@ -583,6 +604,18 @@ std::string Utility::createCallbackFunctionCode(const std::string& signature, co
|
||||
}
|
||||
|
||||
|
||||
Poco::WebWidgets::JSDelegate Utility::createServerCallback(
|
||||
const std::string& signature,
|
||||
const std::map<std::string, std::string>& addServerParams,
|
||||
Renderable::ID id,
|
||||
const std::string& onSuccessJS,
|
||||
const std::string& onFailureJS)
|
||||
{
|
||||
std::string code(createCallbackFunctionCode(signature, addServerParams, id, onSuccessJS, onFailureJS));
|
||||
return (jsDelegate(code));
|
||||
|
||||
}
|
||||
|
||||
int Utility::detectMaxParamCount(const std::list<JSDelegate>& delegates)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
@ -63,6 +63,9 @@ public:
|
||||
bool operator<(const JSDelegate& del) const;
|
||||
|
||||
bool operator ==(const JSDelegate& del) const;
|
||||
|
||||
bool operator !=(const JSDelegate& del) const;
|
||||
|
||||
|
||||
private:
|
||||
std::string _jsCode;
|
||||
@ -75,12 +78,24 @@ inline const std::string& JSDelegate::jsCode() const
|
||||
}
|
||||
|
||||
|
||||
inline bool JSDelegate::operator<(const JSDelegate& del) const
|
||||
{
|
||||
return (_jsCode < del._jsCode);
|
||||
}
|
||||
|
||||
|
||||
inline bool JSDelegate::operator ==(const JSDelegate& del) const
|
||||
{
|
||||
return jsCode() == del.jsCode();
|
||||
}
|
||||
|
||||
|
||||
inline bool JSDelegate::operator !=(const JSDelegate& del) const
|
||||
{
|
||||
return jsCode() != del.jsCode();
|
||||
}
|
||||
|
||||
|
||||
static JSDelegate jsDelegate(const std::string& jsCode);
|
||||
|
||||
|
||||
|
@ -53,6 +53,14 @@ namespace Poco {
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
enum ServerCallback
|
||||
{
|
||||
SC_NO = 0,
|
||||
SC_YES,
|
||||
SC_ONLOCALHANDLERS
|
||||
};
|
||||
|
||||
|
||||
template <class TArgs>
|
||||
class JavaScriptEvent: public Poco::AbstractEvent <
|
||||
TArgs, Poco::DefaultStrategy<TArgs, Poco::AbstractDelegate<TArgs>, Poco::p_less<Poco::AbstractDelegate<TArgs> > >,
|
||||
@ -61,11 +69,17 @@ class JavaScriptEvent: public Poco::AbstractEvent <
|
||||
/// Event class used to handle JavaScriptEvents. Allows to register two different types
|
||||
/// of delegates. The standard delegates, as known from Poco::BasicEvent and JSDelegates
|
||||
/// which will be embedded into the WebPage when the Parser generates the site.
|
||||
/// Per default a server callback happens only when local listeners are registered.
|
||||
{
|
||||
public:
|
||||
typedef typename std::list<JSDelegate> JSDelegates;
|
||||
|
||||
JavaScriptEvent()
|
||||
JavaScriptEvent():
|
||||
_jsHandlers(),
|
||||
_serverCallback(SC_ONLOCALHANDLERS),
|
||||
_callbackPos(0),
|
||||
_onSuccess(),
|
||||
_onFailure()
|
||||
/// Creates the JavaScriptEvent.
|
||||
{
|
||||
}
|
||||
@ -113,9 +127,73 @@ public:
|
||||
{
|
||||
_jsHandlers = all;
|
||||
}
|
||||
|
||||
void setServerCallback(ServerCallback sc, const std::string& onSuccess = "", const std::string& onFailure = "")
|
||||
/// Sets the server callback. onSuccess and onFailure must either be a JavaScript function pointer or a complete
|
||||
/// anonymous function. The server callback position will be set after the currently defined jsHandlers.
|
||||
/// If you want to set the server callback as the very first jsHandler, call setServerCallback before
|
||||
/// any event->add.
|
||||
/// Note that with most renderers you should not worry about the position of the server callback due to its
|
||||
/// asynchronous nature! If you require to execute JS code after the server callback, you must use onSuccess or
|
||||
/// onFailure!
|
||||
{
|
||||
FastMutex::ScopedLock lock(this->_mutex);
|
||||
_serverCallback = sc;
|
||||
_callbackPos = _jsHandlers.size();
|
||||
_onSuccess = onSuccess;
|
||||
_onFailure = onFailure;
|
||||
}
|
||||
|
||||
bool willDoServerCallback() const
|
||||
/// Checks if servercallback is set to true or to DEPENDS and if localHandlers exist
|
||||
{
|
||||
return (_serverCallback == SC_YES || (_serverCallback == SC_ONLOCALHANDLERS && hasLocalHandlers()));
|
||||
}
|
||||
|
||||
ServerCallback getServerCallback() const
|
||||
/// Returns the server callback value
|
||||
{
|
||||
return _serverCallback;
|
||||
}
|
||||
|
||||
std::size_t getServerCallbackPos() const
|
||||
/// Returns how many jsHandlers are executed before the serverCallback
|
||||
{
|
||||
return _callbackPos;
|
||||
}
|
||||
|
||||
void setServerCallbackPos(std::size_t pos) const
|
||||
/// Sets how many jsHandlers are executed before the serverCallback. Set to 0 to guarantee that the server callback is the first
|
||||
{
|
||||
_callbackPos = pos;
|
||||
}
|
||||
|
||||
const std::string& getOnSuccess() const
|
||||
/// Returns the onSuccess value
|
||||
|
||||
{
|
||||
return _onSuccess;
|
||||
}
|
||||
|
||||
const std::string& getOnFailure() const
|
||||
/// Returns the onFailure value
|
||||
{
|
||||
return _onFailure;
|
||||
}
|
||||
|
||||
bool hasJavaScriptCode() const
|
||||
/// Returns true if any JSCode (incl, the server callback) is attached to this event
|
||||
{
|
||||
return (willDoServerCallback() || !_jsHandlers.empty());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
JSDelegates _jsHandlers;
|
||||
JSDelegates _jsHandlers;
|
||||
ServerCallback _serverCallback; /// Set to SC_YES if a server callback should be done always
|
||||
std::size_t _callbackPos; /// Sets when the server callback should happen (the number defines how many jsHandlers are executed before the server callback)
|
||||
std::string _onSuccess; /// code to execute when the server callback succeeds
|
||||
std::string _onFailure; /// code to execute when the server callback fails
|
||||
};
|
||||
|
||||
|
||||
|
@ -43,18 +43,23 @@
|
||||
#include "Poco/WebWidgets/ContainerView.h"
|
||||
#include "Poco/WebWidgets/JavaScriptEvent.h"
|
||||
#include "Poco/WebWidgets/ResourceManager.h"
|
||||
|
||||
#include "Poco/WebWidgets/RequestProcessor.h"
|
||||
#include "Poco/Net/NameValueCollection.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
class WebWidgets_API Page: public ContainerView
|
||||
class WebWidgets_API Page: public ContainerView, public RequestProcessor
|
||||
/// A Page displays a HTML Page
|
||||
{
|
||||
public:
|
||||
typedef Poco::AutoPtr<Page> Ptr;
|
||||
|
||||
static const std::string EV_BEFORERENDER;
|
||||
static const std::string EV_AFTERRENDER;
|
||||
|
||||
JavaScriptEvent<Page*> beforeRender;
|
||||
/// event thrown before GUI rendering.
|
||||
|
||||
@ -77,6 +82,12 @@ public:
|
||||
|
||||
const ResourceManager& resourceManager() const;
|
||||
/// Returns the ResourceManager
|
||||
|
||||
void handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response);
|
||||
/// Handles a complete AJAX request submitted by the client.
|
||||
|
||||
void handleForm(const std::string& field, const std::string& value);
|
||||
/// Dummy implementation
|
||||
|
||||
protected:
|
||||
Page(const std::string& name, const std::type_info& type);
|
||||
@ -110,6 +121,11 @@ inline const ResourceManager& Page::resourceManager() const
|
||||
}
|
||||
|
||||
|
||||
inline void Page::handleForm(const std::string& , const std::string& )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
||||
|
||||
|
@ -52,10 +52,4 @@ JSDelegate::~JSDelegate()
|
||||
}
|
||||
|
||||
|
||||
bool JSDelegate::operator<(const JSDelegate& del) const
|
||||
{
|
||||
return (_jsCode < del._jsCode);
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
@ -35,12 +35,17 @@
|
||||
|
||||
|
||||
#include "Poco/WebWidgets/Page.h"
|
||||
#include "Poco/WebWidgets/RequestHandler.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace WebWidgets {
|
||||
|
||||
|
||||
const std::string Page::EV_BEFORERENDER("beforeRender");
|
||||
const std::string Page::EV_AFTERRENDER("afterRender");
|
||||
|
||||
|
||||
Page::Page():
|
||||
ContainerView(typeid(Page)),
|
||||
_text(),
|
||||
@ -90,4 +95,22 @@ std::string Page::getText() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Page::handleAjaxRequest(const Poco::Net::NameValueCollection& args, Poco::Net::HTTPServerResponse& response)
|
||||
{
|
||||
const std::string& ev = args[RequestHandler::KEY_EVID];
|
||||
Page* pPage = this;
|
||||
if (ev == EV_BEFORERENDER)
|
||||
{
|
||||
beforeRender.notify(this, pPage);
|
||||
}
|
||||
else if (ev == EV_AFTERRENDER)
|
||||
{
|
||||
afterRender.notify(this, pPage);
|
||||
}
|
||||
|
||||
response.send();
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::WebWidgets
|
||||
|
Loading…
x
Reference in New Issue
Block a user