Version 15.1 by Raluca Stavro on 2019/02/15

Show last authors
1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
4
5 Explains how to implement adding and removing objects in XWiki when editing application entries.
6
7 We are going to create a simple application built with [[Application Within Minutes>>extensions:Extension.App Within Minutes Application]], called 'Stores'. Since a store can have many headquarters, what we want is to allow the user to add / remove headquarters when editing a Store entry.
8
9 = Step 1. Create the Store Application =
10
11 The first step is to create the application with AWM. So, create an app called "Stores" and when designing the form use one Short Text field and one Long Text field, as shown in the following screenshot:
12
13 {{image reference="stores-form.png"/}}
14
15 = Step 2: Modify the Stores Class Sheet =
16
17 Let's now modify ##Stores.Code.StoresSheet## to implement dynamically adding / removing headquarters. Modify the default content to be:
18
19 {{code}}
20 {{velocity}}
21 {{html wiki="true"}}
22 #set($class = 'Stores.Code.StoresClass')
23 #set ($discard = $doc.use($class))
24 (% class="xform" %)
25 (((
26 #foreach($obj in $doc.getObjects($class))
27 #set($objNumber = $obj.number)
28 #set($index = $foreach.index + 1)
29 (% id="xwikiobjects" class="xclass" %)(((
30 (% class="xobject" %)(((
31 #if($xcontext.action == 'edit')
32 (% class="xobject-title" %)(((
33 <h3>Headquarter $index
34 <a href="$doc.getURL('objectremove', "form_token=$!{services.csrf.getToken()}&amp;classname=${escapetool.url($class)}&amp;classid=${objNumber}&amp;xredirect=${escapetool.url($doc.getURL('edit'))}")" class="xobject-action delete" title="$services.localization.render('core.editors.object.removeObject.tooltip')">$services.localization.render('core.editors.object.removeObject')</a>
35 </h3>
36 )))
37 #end
38 (% class="xobject-content" %)(((
39 ; <label#if ($xcontext.action == 'edit') for="${class}_${objNumber}_0_name"#end>$escapetool.xml($doc.displayPrettyName('name', false, false))</label>
40 : $doc.display('name', $obj)
41 ; <label#if ($xcontext.action == 'edit') for="${class}_${objNumber}_0_address"#end>$escapetool.xml($doc.displayPrettyName('address', false, false))</label>
42 : $doc.display('address', $obj)
43 )))
44 )))
45 )))
46 #end
47
48 #if($xcontext.action == 'edit')
49 (% id="add_xobject_${escapetool.xml($class)}" class="add_xobject" style="display: block;" %)(((
50 (% id="add_xobject_${escapetool.xml($class)}_title" class="add_xobject-title" style="display: block;" %)((( ## Have to overwrite a CSS rule from dataeditors.css
51 <a href="$doc.getURL('edit', "xpage=editobject&amp;xaction=addObject&amp;className=$escapetool.url(${class})&amp;xredirect=$escapetool.url(${doc.getURL('edit')})")" class="xobject-add-control" title="$services.localization.render('core.editors.object.add.label')">$services.localization.render('core.editors.object.add.label')</a>
52 )))
53 )))
54 $xwiki.jsfx.use('js/xwiki/editors/dataeditors.js', true)##
55 $xwiki.ssfx.use('js/xwiki/editors/dataeditors.css', true)##
56 #end
57 )))
58 {{/html}}
59 {{/velocity}}
60 {{/code}}
61
62 You're all set! Let's now try it!
63
64 = Step 3: Create an entry in the Stores Application =
65
66 Navigate back to the Stores Application and Create an entry. You should now have the options to expand the object that was added by default, to remove this object and to add a new object. When loading the edit form, the objects are collapsed because this is the default behavior of the dataeditors application that we reused to make our feature work.
67
68 {{image reference="stores-results1.png"/}}
69
70 This is what the form looks like when you add a new object :
71
72 {{image reference="stores-results2.png"/}}
73
74 And when viewing the page:
75
76 {{image reference="stores-results3.png"/}}
77
78 = A simplified version of edit form =
79
80 You can personalize even more your application by updating translations, by changing the styles, by removing the elements that don't suit your use case (like the expand / collapse feature, for example).
81
82 This is a simplified UI, that doesn't contain icons or the expand/collapse feature, but contains the basic elements that are needed in order to make it possible to add / remove objects in the application entries. This code is meant to be put in the Stores Class Sheet (##Stores.Code.StoresSheet## document).
83
84 {{code}}
85 {{velocity}}
86 {{html wiki="true"}}
87 #set($class = 'Stores.Code.StoresClass')
88 #set ($discard = $doc.use($class))
89 (% class="xform" %)
90 (((
91 #foreach($obj in $doc.getObjects($class))
92 #set($objNumber = $obj.number)
93 #set($index = $foreach.index + 1)
94 (% id="xwikiobjects" class="xclass" %)(((
95 (% class="xobject" %)(((
96 <span class="xobject-title"></span> ## We need this line, because we base our code on dataeditors.js and for now, this class is mandatory
97
98 ; <label#if ($xcontext.action == 'edit') for="${class}_${objNumber}_0_name"#end>$escapetool.xml($doc.displayPrettyName('name', false, false))</label>
99 : $doc.display('name', $obj)
100 ; <label#if ($xcontext.action == 'edit') for="${class}_${objNumber}_0_address"#end>$escapetool.xml($doc.displayPrettyName('address', false, false))</label>
101 : $doc.display('address', $obj)
102
103 #if($xcontext.action == 'edit')
104 <a href="$doc.getURL('objectremove', "form_token=$!{services.csrf.getToken()}&amp;classname=${escapetool.url($class)}&amp;classid=${objNumber}&amp;xredirect=${escapetool.url($doc.getURL('edit'))}")" class="xobject-action delete" title="$services.localization.render('core.editors.object.removeObject.tooltip')">$services.localization.render('core.editors.object.removeObject')</a>
105 #end
106 )))
107 )))
108 #end
109
110 #if($xcontext.action == 'edit')
111 $xwiki.jsfx.use('js/xwiki/editors/dataeditors.js', true)##
112 <a href="$doc.getURL('edit', "xpage=editobject&amp;xaction=addObject&amp;className=$escapetool.url(${class})&amp;xredirect=$escapetool.url(${doc.getURL('edit')})")" class="xobject-add-control button" title="$services.localization.render('core.editors.object.add.label')">$services.localization.render('core.editors.object.add.label')</a>
113 #end
114 )))
115 {{/html}}
116 {{/velocity}}
117 {{/code}}
118
119 {{warning}}
120 Note that if you edit the Stores Application after making the changes in ##Stores.Code.StoresSheet##, these changes will be lost. You will have to redo the steps above if you want to set back the add / remove objects feature in the application.
121 {{/warning}}

Get Connected