-
Rendered into HTML
-
Rendered into PDF
-
Rendered into CSV
Top level DSL that is responsible for arranging page graphical elements and update ajaxBlocks altogether. In case we are rendering a complete page, we also have to specify the page menu description via the Menu DSL.
This DSL is also responsible for managing modal windows stack. Open a modal using modal or close modal using closeModalAndUpdateBlock (and other variants).
Block Building Code Sample
def editSlideshow(CmsPage slideshow) {
Boolean createNew = slideshow == null
if (!slideshow)
slideshow = new CmsPage(pageType: CmsPageType.SLIDESHOW)
UiBlockSpecifier b = new UiBlockSpecifier().ui {
if (createNew)
modal {
form buildCmsSlideshowForm(slideshow)
}
else {
row { (1)
col {
form buildCmsSlideshowForm(slideshow)
}
col {
tabs {
tab "Images", buildImagesTab(slideshow) (2)
tab "Videos", buildVideosTab(slideshow)
}
}
}
}
}
taackUiService.show(b, buildMenu()) (3)
}
| 1 | 1 row 2 columns |
| 2 | Declare 2 tabs inside, the first one is displayed when the page appear |
| 3 | Send the block along with the menu description to the browser. |
Modal Stack Code Sample
After processing a form, you can refresh the content of the page, or another modal below the current one. You also can reload the page, or display another page. Reloading the page allows the code to be reusable, since it does not depend on the current URL (remember the redirectAction params you see in First App (Adding buttons to a table block) .
Usually a modal is closed after processing a form. Either it is not valid, and errors are shown into the browser directly into the form, either we save the object and refresh the content.
Close Modal and reload the page
@Transactional
@Secured(["ROLE_CMS_MANAGER", "ROLE_CMS_DIRECTOR"])
def saveCmsInsert() {
taackSaveService.saveThenReloadOrRenderErrors(CmsInsert)
}
If no error is detected saving CmsInsert, the page is simply reloaded.
Close Modal and load a page
@Transactional
@Secured(["ROLE_ADMIN", "ROLE_CMS_MANAGER", "ROLE_CMS_DIRECTOR"])
def saveCmsPage() {
taackSaveService.saveThenRedirectOrRenderErrors( (1)
CmsPage, this.&pages as MethodClosure
)
}
| 1 | The method closure in this controller will be loaded (respecting URL Mappings) |
Close Modal and refresh the modal below
@Transactional
@Secured(['ROLE_ADMIN'])
def saveLlmRag() {
taackSaveService.saveOrCloseModalAndRefresh(LlmRag) (1)
}
| 1 | If no error is detected, the last modal is closed and the content below (page or previous modal) is refreshed |
Close Modal and refresh page ajax blocks
@Transactional
def saveProjects() {
EngineeringChangeRequest ecr = taackSaveService.save(EngineeringChangeRequest) (1)
taackSaveService.displayBlockOrRenderErrors(ecr,
new UiBlockSpecifier().ui { (2)
closeModalAndUpdateBlock { (3)
show buildShowProjects(ecr), {
menuIcon ActionIcon.ADD, Ecr2Controller.&projectsForm as MC, ecr.id
}
}
}
)
}
| 1 | Bind the parameters and save the object |
| 2 | displayBlockOrRenderErrors takes a UiBlockSpecifier as parameter, rendered only if the object has no error |
| 3 | closeModalAndUpdateBlock will first close the last opened modal and then apply the modification |
Replace the content of a modal
taackUiService.show(new UiBlockSpecifier().ui {
replaceModal { (1)
custom "<h1>Done.</h1>"
}
})
| 1 | The content of the current modal is replaced, without opening a new one |
Layout Elements
new UiBlockSpecifier().ui {
row {
col BlockSpec.Width.TWO_THIRD, { (1)
card 'Customers', { (2)
menu 'Export', this.&export as MC
}, {
scrollPanel '512px', { (3)
table buildCustomerTable()
}
}
}
col BlockSpec.Width.THIRD, {
accordion { (4)
accordionItem 'Filter', true, {
form buildFilterForm()
}
}
}
}
}
| 1 | col width, from BlockSpec.Width: MAX, THREE_QUARTER, TWO_THIRD, HALF (default), THIRD, QUARTER or FLEX |
| 2 | card with an optional title, an optional menu closure and its content |
| 3 | scrollPanel limits the height of its content, adding a scrollbar if needed |
| 4 | accordion contains accordionItem, the second parameter tells if the item is opened by default |
pokedef topCustomerSalesCard(StatsParams statsParams) {
boolean p0 = statsParams.v == 0
boolean p1 = statsParams.v == 1
boolean p2 = statsParams.v == 2
taackUiService.show(new UiBlockSpecifier().ui {
poke p0, {
table statsService.buildTable() (1)
}
row {
poke p1, { (2)
col BlockSpec.Width.HALF, {
card({ (3)
label 'Sales1'
menu 'Yearly', StatsController.&topCustomerSalesCard as MC,
new StatsParams(showMonthlyGraph1: false, v: 1)
menu 'Monthly', StatsController.&topCustomerSalesCard as MC,
new StatsParams(groupPerMonth1: false, v: 1)
}, {
diagram statsService.&buildChart1 as MC (4)
})
}
}
poke p2, {
col BlockSpec.Width.HALF, {
diagram(statsService.&buildChart2 as MC) { (5)
label 'Sales2'
menu 'Yearly', StatsController.&topCustomerSalesCard as MC,
new StatsParams(showMonthlyGraph2: false, v: 2)
}
}
}
}
}, RootController.buildMenu(), statsParams) (6)
}
| 1 | Table rows link to this action with v: 1 or v: 2, refreshing only one of the diagrams |
| 2 | p1 and p2 are booleans. If true, blocks inside the poke block are refreshed |
| 3 | card with a menu closure and a content closure |
| 4 | diagram can take a MethodClosure returning an UiDiagramSpecifier |
| 5 | Any leaf can take a menu closure, displayed in its header |
| 6 | StatsParams is a Validateable, its values are kept when clicking on links |
pokeBlock DSL Elements
Containers
-
modal: open a modal window,modal(true) {}reloads the page when the modal is closed -
replaceModal: replace the content of the current modal -
closeModalAndUpdateBlock: close the last modal and update blocks of the page (or of the previous modal) -
closeModal: close the modal and transmit an id and a value to the form that opened it (used byajaxFieldselections) -
ajaxBlock: surround other elements and allows to update only a portion of the page -
row,col: arrange elements horizontally, seeBlockSpec.Width -
tabs,tab: tabs, the first one is displayed by default -
accordion,accordionItem: collapsible elements -
card: card with a title and a menu -
scrollPanel: element with a maximum height -
poke: refresh the content only if the condition is true
Leaves
All leaves can take an optional closure describing a menu (see Menu DSL) displayed in the block header.
-
form: see Form DSL -
show: see Show DSL -
table,tableFilter: see FilterTable DSL -
diagram,diagramFilter: see Diagram DSL -
kanban,kanbanFilter: see Kanban DSL -
custom: custom HTML code -
iframe: display an URL into an iframe
Block DSL Symbols Hierarchy
ajaxBlock can surround other elements and allows to update only a portion of the page.