{"id":5186,"date":"2023-10-03T09:13:18","date_gmt":"2023-10-03T09:13:18","guid":{"rendered":"https:\/\/twproject.com\/support\/?page_id=5186"},"modified":"2023-10-05T08:51:20","modified_gmt":"2023-10-05T08:51:20","slug":"create-your-own-custom-form","status":"publish","type":"page","link":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/","title":{"rendered":"Create your own custom form"},"content":{"rendered":"<p>The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with projects, resources, or even appearing generically in the Twproject menu, depending on the context and user permissions. This is simply done by creating a single jsp file.<br \/>\nNo need to compile classes or modify the database schema, no matter how many new fields you wish to insert!<\/p>\n<p>In fact, the main feature of such components is that they allow the properties of a project to be extended without having to deal with the display\/saving\/editing\/deleting of data. These aspects are entirely managed by the Twproject framework and thus completely transparent to the user.<\/p>\n<p>Whereas forms are used to extend the properties of Twproject objects according to one&#8217;s own needs, plugins are usually intended for automated actions (e.g. wizards) or to extend the capacity of reports.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5056 size-full\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png\" alt=\"\" width=\"1601\" height=\"903\" \/><\/p>\n<p>Forms are displayed as tabs on the main project and resource page and, <strong>from version 7.1.009 of Twproject, they are also integrated into the Gantt chart view of the project.<\/strong><\/p>\n<h2>Use of customised forms<\/h2>\n<p>In the standard installation of Twproject there already are some examples of project and resource forms. The form for calculating relevance, complexity and project risk is an example from which you can draw inspiration for your own customisation!<\/p>\n<p>To see the list, in the project tab, click on the <em>forms<\/em> tab (if the conditions for displaying them are met).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5057 size-full\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form-menu.png\" alt=\"\" width=\"1594\" height=\"390\" \/><\/p>\n<p>Other examples only appear when a project or company type resource is called &#8220;<em>Twproject test form<\/em>&#8220;.<\/p>\n<h2>Create your form<\/h2>\n<pre>Please note: this section requires some Java programming skills.<\/pre>\n<p>Forms\/reports\/plugins only make sense if they are &#8220;customised&#8221; according to one&#8217;s needs, so in this section we will explain how they work and how to write new ones.<\/p>\n<p>This section is aimed at those with some programming skills, knowledge that is essential for creating forms from one of the examples provided without excessive difficulty.<\/p>\n<p>Custom forms are files with a &#8220;.jsp&#8221; (Java Servlet Pages) extension that are stored in specific folders on the server where the application has been installed, in particular<br \/>\n&#8211; the default ones are in the folder:<\/p>\n<pre>[root]\/applications\/teamwork\/plugins<\/pre>\n<p>&#8211; the customised ones, on the other hand, in order to be loaded by Twproject, must be placed in the folder:<\/p>\n<pre>[root]\/applications\/teamwork\/customers\/<em><strong>ACME<\/strong><\/em>\/plugins<\/pre>\n<p>Where <strong>ACME<\/strong> is the name\/short code of your company.<\/p>\n<p>When Twproject&#8217;s service starts up, the application analyses the files in these folders and, if they fulfil the requirements analysed below, they are &#8220;initialised&#8221; and made available where intended.<\/p>\n<p>To view the active plugins go to the Tools menu -&gt; Admin and in the &#8220;Customisation&#8221; box click on &#8220;forms, plugins and reports&#8221;.<br \/>\nBy clicking the &#8220;reload plugins&#8221; button you can compel a recheck, and load any new forms without having to restart the Twproject service.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-2138 size-full\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/adminCustomForms.png\" alt=\"adminCustomForms\" width=\"877\" height=\"164\" \/><\/p>\n<h2>How it works<\/h2>\n<p><strong>Loading<\/strong>: At start-up, Twproject invokes the initialise method in the detected jsp, and loads the list of available plugins into memory.<\/p>\n<p><b>Visibility<\/b>: a plugin may appear in the following contexts: in &#8220;Tools&#8221; menu, on the project editor and on the resource editor. Their display is subject to the conditions implemented in the &#8220;<em>isVisible<\/em>&#8221;\u00a0method in the forms jsp file (see following paragraphs).<\/p>\n<p><strong>Persistence<\/strong>: Where are data saved and how? Since by definition the fields of a form are arbitrary, its data are not subject to referential integrity. All data are saved in the <em>olpl_des_data<\/em> and <em>olpl_des_data_value<\/em> tables, but the developer does not have to do anything about their persistence; in fact, the fields on the form will be saved by the framework and automatically hooked into the project\/resource to which they refer.<br \/>\nSpecifically, the <em>referenceId<\/em> column of the olpl_des_data table contains the id of the project, the <em>referenceClassName<\/em> column is the name of the class to which the form is attached (Task in the example) and the <em>designerName<\/em> column is the name of the form (corresponding to the name of the jsp file).<\/p>\n<h2>Plugin analysis<\/h2>\n<p>And now it is time to move on to the actual code, the trickiest and most fun part&#8230;<\/p>\n<p>To get started, we recommend using <strong>simpleCustomForm.jsp<\/strong>: it is a well commented file with different types of fields (strings, dates, numbers, input files).<br \/>\nCopy the file into your customisation folder and start editing it by adding or removing fields as required. To check the interface for the changes you have made, remember to click on the &#8220;reload plugins&#8221; button on the &#8220;forms, plugins and reports&#8221; page (please note that if the form does not appear in the list, it means that it contains some error in the code that is blocking the loading).<\/p>\n<p>Let&#8217;s have a look at the code (extracted from simpleCustomForm.jsp).<\/p>\n<p>Each form has a rigid structure and must extend the abstract\u00a0<em>CustomForm\u00a0<\/em>class<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5191\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code01.jpg\" alt=\"\" width=\"721\" height=\"178\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code01.jpg 721w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code01-300x74.jpg 300w\" sizes=\"auto, (max-width: 721px) 100vw, 721px\" \/><\/p>\n<p>The abstract class mandatorily requires the implementation of two methods<\/p>\n<pre>public boolean <strong>isVisible<\/strong>(RestState restState) {....\r\n\r\npublic LinkedHashMap&lt;String, DesignerField&gt; <strong>getDesignerFields<\/strong> (RestState restState){...<\/pre>\n<p>The first is used to indicate the conditions under which the form is to be displayed:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5192\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code02.jpg\" alt=\"\" width=\"810\" height=\"227\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code02.jpg 810w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code02-300x84.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code02-768x215.jpg 768w\" sizes=\"auto, (max-width: 810px) 100vw, 810px\" \/><\/p>\n<p>This method, based on the data obtained from the page state (RestState and primarily from &#8220;mainObject&#8221; field) checks that the context is appropriate.<br \/>\nIn this case we are checking whether the mainObject, i.e. the object of the edited form, is a project (Task.class) and that its name corresponds to &#8220;Twproject test form&#8221;. Only if both conditions are true will the form be visible.<\/p>\n<p>The second method is the &#8220;heart&#8221; of the form and is where you define the data you want to insert, listing them as DesignerFields and specifying for each one the type of field you want: String, Date, Boolean, Integer, Currency, CodeValueList etc.<br \/>\nIt is the DesignerFields that know how to handle saving, serialising and representing the data.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5193\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code03.jpg\" alt=\"\" width=\"770\" height=\"72\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code03.jpg 770w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code03-300x28.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code03-768x72.jpg 768w\" sizes=\"auto, (max-width: 770px) 100vw, 770px\" \/><\/p>\n<p>You can have a selector as a radio button or as a list<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5194\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code04.jpg\" alt=\"\" width=\"986\" height=\"358\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code04.jpg 986w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code04-300x109.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code04-768x279.jpg 768w\" sizes=\"auto, (max-width: 986px) 100vw, 986px\" \/><\/p>\n<p>as a &#8220;short&#8221; text field or text area<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5195\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code05.jpg\" alt=\"\" width=\"904\" height=\"197\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code05.jpg 904w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code05-300x65.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code05-768x167.jpg 768w\" sizes=\"auto, (max-width: 904px) 100vw, 904px\" \/><\/p>\n<p>numeric fields in different formats<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5196\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code06.jpg\" alt=\"\" width=\"933\" height=\"174\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code06.jpg 933w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code06-300x56.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code06-768x143.jpg 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/p>\n<p>input for the management of dates and times<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5197\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code07.jpg\" alt=\"\" width=\"910\" height=\"146\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code07.jpg 910w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code07-300x48.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code07-768x123.jpg 768w\" sizes=\"auto, (max-width: 910px) 100vw, 910px\" \/><\/p>\n<p>fields for uploading files<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5198\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code08.jpg\" alt=\"\" width=\"845\" height=\"96\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code08.jpg 845w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code08-300x34.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code08-768x87.jpg 768w\" sizes=\"auto, (max-width: 845px) 100vw, 845px\" \/><\/p>\n<p>lookup on the people table<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5199\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code09.jpg\" alt=\"\" width=\"1108\" height=\"85\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code09.jpg 1108w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code09-300x23.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code09-768x59.jpg 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code09-1024x79.jpg 1024w\" sizes=\"auto, (max-width: 1108px) 100vw, 1108px\" \/><\/p>\n<p>or on that of projects<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5200\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code10.jpg\" alt=\"\" width=\"809\" height=\"93\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code10.jpg 809w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code10-300x34.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code10-768x88.jpg 768w\" sizes=\"auto, (max-width: 809px) 100vw, 809px\" \/><\/p>\n<p>checkbox<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5201\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code11.jpg\" alt=\"\" width=\"824\" height=\"86\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code11.jpg 824w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code11-300x31.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code11-768x80.jpg 768w\" sizes=\"auto, (max-width: 824px) 100vw, 824px\" \/><\/p>\n<p>drop-down menu whose values are the result of a query defined by you<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5202\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code12.jpg\" alt=\"\" width=\"1293\" height=\"94\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code12.jpg 1293w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code12-300x22.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code12-768x56.jpg 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code12-1024x74.jpg 1024w\" sizes=\"auto, (max-width: 1293px) 100vw, 1293px\" \/><\/p>\n<p>multiple fields that can be freely added from the user interface<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5203\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code13.jpg\" alt=\"\" width=\"768\" height=\"280\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code13.jpg 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code13-300x109.jpg 300w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/p>\n<p>Note that once all fields have been defined, the method must perform a &#8220;<em>return<\/em>&#8221;\u00a0of them<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5204\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code14.jpg\" alt=\"\" width=\"407\" height=\"42\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code14.jpg 407w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code14-300x31.jpg 300w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><\/p>\n<p>So far, we have analysed the structure of the inner class &#8220;PagePluginExt&#8221; which extends &#8220;CustomForm&#8221;.<\/p>\n<p>Each customised form is then composed of two parts called at different times in the application&#8217;s life-cycle.<br \/>\nThe first section is initialisation, invoked at the start of the service; it injects the form instance into the system, thus making it accessible.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5205\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code15.jpg\" alt=\"\" width=\"1006\" height=\"92\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code15.jpg 1006w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code15-300x27.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code15-768x70.jpg 768w\" sizes=\"auto, (max-width: 1006px) 100vw, 1006px\" \/><\/p>\n<p>In this case, we are creating a custom form in the &#8220;TASK_FORMS&#8221; group, so as to limit its display to the project section.<br \/>\nTwproject uses four groups: \u201c<strong>REPORTS<\/strong>\u201d, \u201c<strong>RESOURCE_FORMS<\/strong>\u201d, \u201c<strong>TASK_FORMS<\/strong>\u201d, \u201c<strong>TREND<\/strong>&#8220;:<br \/>\n&#8211; REPORTS: are transversal to the objects. and visible in the lists and project tabs, resources, documents, costs, worklog<br \/>\n&#8211; RESOURCE_FORMS: visible in the resource sheet only<br \/>\n&#8211; TASK_FORMS: visible in the project tab only<br \/>\n&#8211; TREND: so far visible in the project tab only (still under development)<\/p>\n<p><em>Please note that the fact that Twproject &#8220;invokes&#8221; plugins in these groups, however, does not imply that they are actually displayed; it depends on the conditions implemented in the isVisible(ResState resState) method of each plugin!<\/em><\/p>\n<p>The last section is the html formatting of the form, preceded by a standard block in which the objects indispensable for the form to function are instantiated<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5206\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code16.jpg\" alt=\"\" width=\"1067\" height=\"205\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code16.jpg 1067w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code16-300x58.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code16-768x148.jpg 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code16-1024x197.jpg 1024w\" sizes=\"auto, (max-width: 1067px) 100vw, 1067px\" \/><\/p>\n<p>We know that in this context the main object is a project so we can use it to extract some data to enrich the form<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5207\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code17.jpg\" alt=\"\" width=\"556\" height=\"53\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code17.jpg 556w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code17-300x29.jpg 300w\" sizes=\"auto, (max-width: 556px) 100vw, 556px\" \/><\/p>\n<p>and finally construct the HTML grid for displaying the form<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5208\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code18.jpg\" alt=\"\" width=\"661\" height=\"738\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code18.jpg 661w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code18-269x300.jpg 269w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/p>\n<p>We can add some calculations on the entered values<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-5209\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code19.jpg\" alt=\"\" width=\"832\" height=\"220\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code19.jpg 832w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code19-300x79.jpg 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/code19-768x203.jpg 768w\" sizes=\"auto, (max-width: 832px) 100vw, 832px\" \/><\/p>\n<p>The end result will be this interface<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5214 size-large\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/custom_form-1024x791.png\" alt=\"Custom form\" width=\"604\" height=\"467\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/custom_form-1024x791.png 1024w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/custom_form-300x232.png 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/custom_form-768x593.png 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/custom_form.png 1132w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/p>\n<p>That&#8217;s all&#8230; the &#8220;print&#8221; and &#8220;save&#8221; buttons are added automatically!<\/p>\n<h2>Displaying a custom form in the Gantt chart<\/h2>\n<p>Since version 7.1.009 of Twproject, the possibility of loading forms of type TASK_FORMS has been introduced not only in the project form, as illustrated here, but also in its Gantt view.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5215 size-large\" src=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/gantt-1024x260.png\" alt=\"Gantt diagram\" width=\"604\" height=\"153\" srcset=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/gantt-1024x260.png 1024w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/gantt-300x76.png 300w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/gantt-768x195.png 768w, https:\/\/twproject.com\/support\/wp-content\/uploads\/2023\/09\/gantt.png 1751w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/p>\n<p>This allows them to be compiled more quickly, as they can be managed, at the different stages in which a project is organised, from a single screen.<\/p>\n<p>Due to the strictly grid-based structure, not all field types can be displayed, but only the more standard ones, such as dates, strings, numbers, checkboxes, drop-down selection, calculated fields.<\/p>\n<p>For the guide on how to create a customised form for Twproject versions prior to 7.1.009 follow this link<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/twproject.s3.amazonaws.com\/resources\/custom-form-old.html\">Create your customised form &gt;&gt;<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with projects, resources, or even appearing generically in the Twproject menu, depending on the context and user permissions. This is simply done by creating a single jsp file. No [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":2309,"menu_order":58,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-5186","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Create your own custom form | Twproject support<\/title>\n<meta name=\"description\" content=\"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Create your own custom form | Twproject support\" \/>\n<meta property=\"og:description\" content=\"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with\" \/>\n<meta property=\"og:url\" content=\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/\" \/>\n<meta property=\"og:site_name\" content=\"Twproject support\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/twproject\" \/>\n<meta property=\"article:modified_time\" content=\"2023-10-05T08:51:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1601\" \/>\n\t<meta property=\"og:image:height\" content=\"903\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/\",\"url\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/\",\"name\":\"Create your own custom form | Twproject support\",\"isPartOf\":{\"@id\":\"https:\/\/twproject.com\/support\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png\",\"datePublished\":\"2023-10-03T09:13:18+00:00\",\"dateModified\":\"2023-10-05T08:51:20+00:00\",\"description\":\"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with\",\"breadcrumb\":{\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage\",\"url\":\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png\",\"contentUrl\":\"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png\",\"width\":1601,\"height\":903},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/twproject.com\/support\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Advanced usage\",\"item\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Customization\",\"item\":\"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Create your own custom form\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/twproject.com\/support\/#website\",\"url\":\"https:\/\/twproject.com\/support\/\",\"name\":\"Twproject support\",\"description\":\"Twproject documentation online\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/twproject.com\/support\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Create your own custom form | Twproject support","description":"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/","og_locale":"en_US","og_type":"article","og_title":"Create your own custom form | Twproject support","og_description":"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with","og_url":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/","og_site_name":"Twproject support","article_publisher":"https:\/\/www.facebook.com\/twproject","article_modified_time":"2023-10-05T08:51:20+00:00","og_image":[{"width":1601,"height":903,"url":"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png","type":"image\/png"}],"twitter_misc":{"Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/","url":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/","name":"Create your own custom form | Twproject support","isPartOf":{"@id":"https:\/\/twproject.com\/support\/#website"},"primaryImageOfPage":{"@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage"},"image":{"@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage"},"thumbnailUrl":"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png","datePublished":"2023-10-03T09:13:18+00:00","dateModified":"2023-10-05T08:51:20+00:00","description":"The idea behind custom forms, also called plugins, is that you can add a form with an arbitrary number of fields. The form can be associated with","breadcrumb":{"@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#primaryimage","url":"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png","contentUrl":"https:\/\/twproject.com\/support\/wp-content\/uploads\/custom-form.png","width":1601,"height":903},{"@type":"BreadcrumbList","@id":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/create-your-own-custom-form\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/twproject.com\/support\/"},{"@type":"ListItem","position":2,"name":"Advanced usage","item":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/"},{"@type":"ListItem","position":3,"name":"Customization","item":"https:\/\/twproject.com\/support\/twproject-advanced-usage\/customizations\/"},{"@type":"ListItem","position":4,"name":"Create your own custom form"}]},{"@type":"WebSite","@id":"https:\/\/twproject.com\/support\/#website","url":"https:\/\/twproject.com\/support\/","name":"Twproject support","description":"Twproject documentation online","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/twproject.com\/support\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/pages\/5186","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/comments?post=5186"}],"version-history":[{"count":0,"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/pages\/5186\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/pages\/2309"}],"wp:attachment":[{"href":"https:\/\/twproject.com\/support\/wp-json\/wp\/v2\/media?parent=5186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}