refactored JSEvents for easier server callbacks

This commit is contained in:
Peter Schojer
2008-06-09 09:09:02 +00:00
parent db640711d1
commit 515c64faea
15 changed files with 323 additions and 77 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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> &params, 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;