Building Wizards to Edit a Single Object
Objective
You need to develop a wizard to allow a user to edit the attributes of a Windchill business object and update the object in the database.
Background
Object edit wizards are typically launched by an action labeled “Edit” or “Check Out and Edit.”
Developing a wizard to edit a business object is very similar to developing a wizard to create that business object. Many of the components you will use are the same. However, there are a few differences between create and edit wizards and some of these require different components or different component configuration. These differences include the following:
• Edit wizards do not allow users to change the container context, owning organization, folder location, or type of an object
• Some edit wizards do not allow the user to change the identity attributes on the master of an object (for example: name and/or number). Such changes must be made via a Rename or Edit Common Attributes client. Other master attributes may not be editable also.
• If the object being edited is a Workable and it is not checked out by the user when the edit wizard is launched, the wizard should check out the object automatically.
• The attribute input fields in edit wizards are pre-populated with the values that exist in the database for the object rather than the default values defined in the Java class or Attribute and Type and Attribute Management utility.
• Edit wizards for Workables have different navigation buttons. Instead of an OK button they have Save and Check In buttons. The former saves the changes to the working copy of the object without checking in or iterating it. The second creates and checks in a new iteration of the object. Also, the Cancel button pops up a message reminding the user that the object will remain checked out.
Components available specifically for editing include:
• jsp and jspf files for wizard steps that are common to multiple wizards
• custom HTML tags for managing wizard data and displaying elements on the page
• Java classes for processing the wizard data after the user submits the wizard
Scope/Applicability/Assumptions
This section assume you have created a custom Persistable business object class or subtype and you want to develop a wizard that will allow users to edit the attributes of one instance of that object type.
The information in this document is applicable to editing both Workable and non-Workable objects and both Typed and non-Typed objects.
This document describes the reusable common components upon which most Windchill edit wizards are based. If your custom type extends an existing Windchill business class, such as WTPart, WTDocument, or WTChangeIssue, there may be components more specific to those classes that could or should be used instead of the components described herein. These class-specific components are built on top of the common components described in this document. A discussion of those class-specific components is beyond the scope of this document.
Be aware that you do not necessarily need to develop your own wizard to edit instances of a custom type. If your type is a modeled or soft subtype of a Windchill business class such as WTPart, WTDocument, or Problem Report (WTChangeIssue) , you may be able to use the out-of-the-box edit wizard for your purposes. The out-of-the-box wizards will automatically display input fields for hard and global attributes of custom subtypes on the Set Attributes step.
Attributes in the table will be ordered as follows:
• Out-of-the-box attributes, ordered as listed in the JSP file
• Custom modeled attributes, ordered alphabetically by display name
• Custom global attributes, ordered alphabetically by display name
If you want to order the attributes on this step differently or require additional fields on this step, you will need to create a new jsp for this step specifically for your subtype. However, you can still use the Edit Part wizard.
If you want to add additional steps to an existing wizard , you will need to develop a custom wizard , but may be able reuse many of the steps/components of the existing wizard.
Intended Outcome
Add a single- or multi-step HTML wizard to the product that allows a user to update a business object in the database. The arrangement of steps and presentation of attributes within the wizard should be similar to that of other Windchill wizards to provide a consistent user experience.
Solution
Use common jsp, tag, JavaScript, and Java class components built on top of the jsp wizard framework to create a wizard for capturing user input and for processing that input and creating the object in the database.
Prerequisite knowledge
To achieve this objective, you need to be familiar with the
Building Wizards to Create a Single Object topic, especially "Prerequisite Knowledge" section.
Solution Elements
Element
|
Type
|
Description
|
Tags
|
autoCheckOutItem
|
Tag
|
Checks out the object to the current user if it is not already checked out. Adds an object reference to the working copy as an attribute of the current HTTPRequest, as a parameter in HTTPRequestData parameter map of the NmCommandBean, and as a hidden field in the DOM. The key to the working copy value is CreateAndEditWizBean.WORKING_COP Y_REF_PARAMETER_NAME.
This tag should be put in the main JSP for the wizard immediately below the initializeItem tag.
Tag library: <Windchill>/codebase/WEB-INF/tlds/wo rkinprogress.tld
Tag handler: com.ptc.windchill.enterprise.wip.tags.Auto CheckOutObjectTag
|
Beans
|
CreateAndEditWizBean
|
Java class
|
This bean is available to your jsps if you include the includeWizBean jspf file. It has getter methods for wizard data such as the operation (create or edit) and working copy object reference.
|
Java Classes
|
|
You can use the classes below to help create and process your wizard. They are located in the <Windchill>/codebase/WEB-INF/lib/wnc Web.jar file.
|
CreateAndEditModelGet ter
|
Java class
|
A class that may be called via a getModel tag to generate the data for property panels and attributes tables in edit wizards.
|
DefaultEditFormProcess or
|
Java class
|
A class that may be used or extended to process wizard form data for nonWorkable objects. Extends DefaultObjectFormProcessor.
|
EditWorkableFormProc essor
|
Java class
|
A class that may be used or extended to process wizard form data for Workable objects. Extends DefaultObjectFormProcessor.
|
Procedure — Creating an Edit Wizard
The following tasks need to be performed to create the wizard:
• Create an Action for the Wizard (Required).
• Create a Main jsp for Your Wizard (Required).
• Create Custom Steps as Needed
• Select Reusable Steps
The tasks shown as required are always required. The other tasks may or may not be needed, depending on the requirements of the wizard.
If there are attributes in your wizard that cannot be displayed by the standard Windchill dataUtilties, gui components, and renderers you also may need to write Java classes for those functions.
Create an Action for the Wizard
An action is needed to launch your wizard. This task is very similar to creating an action for a create wizard. The only difference is that your form processor, specified on the class attribute of the command tag, will typically be one of the processors listed in the section "Solution Elements" or a subclass of one of those classes.
For more details on the options available for this action, see the section <action>.xml attributes in
Windchill Client Architecture Wizard. A simple action could look like this:
<objecttype name="FakeLiterature">
<action name="editLiterature">
<command class="com.ptc.core.components.forms.EditWorkableFormProcessor"
method="execute"
url="netmarkets/jsp/carambola/customization/examples/
wizard/exampleLiteratureEdit.jsp"
windowType="popup"/>
</action>
</objecttype>
It is recommended that the action (and main wizard jsp file) be named “edit.” If there will be more than one edit action for the objecttype based on launch point or other criteria, add a suffix to the action name to qualify it, as shown below:
editFrom<launch page or table>
|
Ex: editFromAttributesTable
|
edit<name for a subset of attributes being edited>
|
Ex: editAnnotations
|
Add this action to an action model so that it can be accessed it on the Windchill system.
Create a Main jsp for Your Wizard
Next, create a jsp which describes the edit wizard. At a minimum it is generally necessary to put in just one step for editing attributes. For more details on advanced configuration of the edit attributes step see
Customizing Reusable Wizard Steps.
<%-- This wizard is an example of using a read-only attributes panel in
an Edit wizard. --%>
<%@ include file="/netmarkets/jsp/components/beginWizard.jspf"%>
<%@ include file="/netmarkets/jsp/components/includeWizBean.jspf"%>
<%@ taglib prefix="jca"
uri="http://www.ptc.com/windchill/taglib/components"%>
<%@ taglib prefix="wip"
uri="http://www.ptc.com/windchill/taglib/workinprogress"%>
<%-- This tag checks out the document and sets magical form inputs
and data on the command bean. This makes sure that the command
bean's get oid methods return the oid of the working copy. --%>
<wip:autoCheckOutItem />
<jca:initializeItem operation="${createBean.edit}"/>
<jca:wizard buttonList="EditWizardButtons"
helpSelectorKey="DocMgmtDocEdit"
title="Example Literature Edit with Attribute Panels">
<jca:wizardStep action="editAttributesWizStep"
type="object" embeddedHelp="This is an example of a
simple Edit wizard. This wizard demonstrates how to
change the attributes in the read only
attribute panel."/>
</jca:wizard>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
AutoCheckOutItem Tag
If your target object is a Workable and your wizard can be launched for an object that is not already checked out via a “Check Out and Edit” or other action, you should include an autoCheckOutItem tag in your main jsp immediately below the initializeItemTag.
<%@ taglib prefix="wip"
uri="http://www.ptc.com/windchill/taglib/workinprogress"%>
...
<wip:autoCheckOutItem/>
This tag will check out the object to the current user before opening the wizard.
Button Set
Typically, wizards for editing Workable objects will use one of the following two button sets:
• “EditWizardButtons” (multiple-step wizards)
• “NoStepsEditWizardButtons” (single step wizards)
These include Save and Check In buttons.
For editing nonWorkable objects one of the following is usually used:
• DefaultWizardButtonsNoApply (multiple-step wizards)
• NoStepsWizardButtons (single step wizards)
These are all defined in <Windchill>/codebase/config/actions/actionmodels.xml.
Create Custom Steps as Needed
Custom steps can also be created for edit wizards using the same techniques that are described in
Wizard Processing and
Building Wizards to Create a Single Object.
Select Reusable Steps
In the section "Create a Main jsp for Your Wizard" we already selected the reusable step to edit object attributes. For more details on customizing this step and for information on additional reusable steps available see
Reusable Wizard Steps.
Customization Points
Creating Your Form Processor and Form Processor Delegates
Two form processor classes are available for edit wizards:
com.ptc.core.components.forms.DefaultEditFormProcessor - for nonWorkable objects
com.ptc.core.components.forms.EditWorkableFormProcessor- for Workable objects
These classes may be extended as necessary to meet your purposes.
Both of these processors do the following:
preProcess() method
• same as the preprocess() method of the CreateObjectFormProcessor except that it creates a TypeInstance for a persisted object
doOperation() method
• calls super.doOperation() to call the doOperation() methods of any FormProcessorDelegates registered for the wizard
• calls PersistenceHelper.manager.save() to store the Persistable in the database
The setResultNextAction() method is deprecated. Instead, the FormProcessor should return a list of the Oids that were affected by the action (if any), and let the components displayed in the UI request updates from the server, as necessary.
If you are extending an existing Windchill business class, there may be a processor specific to that class that you should use or extend instead of the DefaultEditFormProcessor or EditWorkableFormProcessor. These are shown in the table below. Consult the javadoc for these classes for more information on their behavior.
If your class extends: | Use Processor Class: |
---|
WTChangeIssue | com.ptc.windchill.enterprise.change2.forms.processors.EditProblemReportFormProcessor |
WTChangeRequest2 | com.ptc.windchill.enterprise.change2.forms.processors.EditChangeRequestFormProcessor |
WTChangeOrder2 | com.ptc.windchill.enterprise.change2.forms.processors.EditChangeNoticeFormProcessor |
WTChangeActivity2 | com.ptc.windchill.enterprise.change2.forms.processors.EditChangeTaskFormProcessor |
WTVariance | com.ptc.windchill.enterprise.change2.forms.processors.EditVarianceFormProcessor |
If one of the provided form processors meets your needs, you do not need to write your own processor --- just specify that processor as the value of the class attribute of the command subtag of your wizard action. If they do not meet your needs, you should write a subclass of one of them to process the wizard form data. See "Creating Your Form Processor and Form Processor Delegates" section in
Building Wizards to Create a Single Object, for examples of cases where you may need to implement your own
processor.netmarkets/jsp/components/beginWizard.jspfIf you create your own processor, be aware that its preProcess() method will be called by the standard validator classes after each wizard step. Make sure you do not modify the database in this method.
Sample Code
Main JSP for the Edit Product Wizard
Filename: <Windchill>/codebase/netmarkets/jsp/product/editProductWizard.jsp
Notes: This is a one-step wizard
<%@ page
import="com.ptc.windchill.enterprise.product.ProductClientRB"
%>
<%@ taglib prefix="jca"
uri="http://www.ptc.com/windchill/taglib/components"%>
<%@ include file="/netmarkets/jsp/components/beginWizard.jspf"%>
<%@ include
file="/netmarkets/jsp/components/includeWizBean.jspf"%>
<%@ include
file="/netmarkets/jsp/components/createEditUIText.jspf"%>
<%--> Get resource bundle. <--%>
<fmt:setLocale value="${localeBean.locale}"/>
<fmt:setBundle
basename="com.ptc.windchill.enterprise.product.productResource
Client" />
<fmt:message var="attributeStepLabel"
key="product.editProductAttributesWizStep.title" />
<jca:initializeItem operation="${createBean.edit}"/>
<jca:wizard buttonList="NoStepsWizardButtons"
helpSelectorKey="PDMAdminProdEdit_help">
<%-->
This step uses the common action definition. The JSP file for
the step is, however, product-specific and hooked up using
PartManagement-typedservices-properties.xconf
<--%>
<jca:wizardStep action="editAttributesWizStep" type="object"
label="${attributeStepLabel}"/>
</jca:wizard>
%@include file="/netmarkets/jsp/util/end.jspf"%
Main JSP for the Edit Part Wizard
Filename: <Windchill>/codebase/netmarkets/jsp/part/edit.jsp
Notes:
• This can be a single- or multi-step wizard, depending on the product modules installed
• Illustrates how to include the Set Classification Attributes and Attachments steps.
• This page calls the js function “onloadEditPart” when the page loads. This function calls “loadClassificationStep” to load the classification step if the part is classified and may perform some other UI configurations depending on the wizard launch point.
<%@ page import="wt.content.ContentHolder" %>
<%@ page import="wt.access.AccessPermission" %>
<%@ page import="com.ptc.windchill.enterprise.attachments.server.AttachmentsHelper" %>
<%@ taglib prefix="jca" uri="http://www.ptc.com/windchill/taglib/components"%>
<%@ taglib prefix="wip" uri="http://www.ptc.com/windchill/taglib/workinprogress"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/fmt" prefix="fmt"%>
<%@ taglib prefix="wctags" tagdir="/WEB-INF/tags" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ include file="/netmarkets/jsp/components/beginWizard.jspf"%>
<%@ include file="/netmarkets/jsp/components/includeWizBean.jspf"%>
<%-->
PartHelper.js below is required dynamically insert/remove the classification step
<--%>
<script language="JavaScript" src="netmarkets/javascript/part/PartHelper.js"></script>
<fmt:setBundle basename="com.ptc.windchill.enterprise.part.partResource"/>
<%--> Reuse the same labels as for create part <--%>
<fmt:message var="editAttributesWizStepLabel" key="part.createPartWizard.SET_ATTRIBUTES_WIZ_STEP_LABEL" />
<%
if (InstalledProperties.isInstalled(InstalledProperties.PARTSLINK)) {
%>
<jca:initializeItem operation="${createBean.edit}" attributePopulatorClass="com.ptc.windchill.partslink.part.forms.EditPartAttributePopulator"/>
<%} else { %>
<jca:initializeItem operation="${createBean.edit}"/>
<% } %>
<% if (request.getParameter("newInWorkspace") == null) { %>
<%--> The part is not new in workspace. Do autoCheckout <--%>
<wip:autoCheckOutItem/>
<% } %>
<% if ((request.getParameter("newInWorkspace") != null) || (request.getParameter("checkedOutInWorkspace") != null)) { %>
<script language="Javascript">newOrCheckedOutInWorkspace=true</script>
<% } %>
<%
boolean bPermit = false;
Object context = commandBean.getPageOid().getRef();
bPermit = (context instanceof ContentHolder) && AttachmentsHelper.hasPermission((ContentHolder) context, AccessPermission.MODIFY_CONTENT);
%>
<%-->If SoftwareLink, PartsLink, or PDMLink is installed then use button set with Back and Next buttons<--%>
<% if (InstalledProperties.isInstalled(InstalledProperties.PARTSLINK) ||
InstalledProperties.isInstalled(InstalledProperties.PDMLINK) ){ %>
<c:set var="buttonSet" value="EditWizardButtons"/>
<% } else { %>
<c:set var="buttonSet" value="NoStepsEditWizardButtons"/>
<% } %>
<% if (bPermit) { %>
<jca:wizard buttonList="${buttonSet}" helpSelectorKey="PartEdit_help">
<%-->
The type for the editAttributes step below
must be 'object' and not 'part'. This needs to be done so that
we pick up the common component action definitions for this
step.
Updated the editAttributes step type to 'part' for adding attachments step. B-91021
<--%>
<jca:wizardStep action="editAttributesWizStep" label="${editAttributesWizStepLabel}" type="part"/>
<jca:wizardStep action="setClassificationAttributesWizStep" type="classification"/>
<jca:wizardStep action="attachments_step" type="attachments" />
</jca:wizard>
<% } else { %>
<jca:wizard buttonList="${buttonSet}" helpSelectorKey="PartEdit_help">
<jca:wizardStep action="editAttributesWizStep" label="${editAttributesWizStepLabel}" type="part"/>
<jca:wizardStep action="setClassificationAttributesWizStep" type="classification"/>
</jca:wizard>
<% } // end if bPermit %>
<%--- If we are not DTI then add the applet for doing file browsing and file uploads --%>
<wctags:fileSelectionAndUploadAppletUnlessMSOI forceApplet='${param.addAttachments != null }'/>
<%-- It will load classificationHelper.js file which used for classification functionality --%>
<wctags:loadEditClassificationScript isMultiObject="false"/>
<wctags:initClassification enforceAutonamingRule="true" notifySimilarObject="true"/>
<script lang="Javascript">
PTC.onReady(onloadEditPartWizard);
PTC.onReady(initClassificationOnEditWizard);
</script>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
Additional Resources
Related Package/Class Javadoc
com.ptc.core.components.forms.DefaultEditFormProcessor
com.ptc.core.components.forms.EditWorkableFormProcessor