I'm attempting to update the Add New button on a grid to open in the current window, rather than a new one. I've edited the ribbon XML, and I'm correctly getting this function called on click of the "+" icon:
export function createCase(selectedEntityTypeCode: number, parentEntityTypeCode: number, firstPrimaryItemId: string, primaryControl: string, selectedControl: string): void {
window.top.location.replace(CommonLib.getCreateEntityFromParentUrl(firstPrimaryItemId, parentEntityTypeCode, selectedEntityTypeCode));
}
The call to getCreateEntityFromParentUrl creates this string:
etc=112&extraqs=%3f_CreateFromId%3d%257b999BA23A-B07A-E611-80DD-FC15B4286CB8 %257d%26_CreateFromType%3d10010%26etc%3d112&newWindow=false&pagetype= entityrecord
Which opens a new Case form, with the correct Parent entity already populated, so I know it's reading from the CreateFromID and CreateFromType correctly.
If you don't actually create the Case, and click refresh in the browser, you're taken back to the parent entity (A Custom entity, "Location", in this case).
If you save create the Case, and then click refresh in the browser, you get this error:
Unhandled Exception:
System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault,
Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35]]: System.Web.HttpUnhandledException:
Microsoft Dynamics CRM has experienced an error. Reference number for
administrators or support: #5B02AEE3Detail:
-2147220970 System.Web.HttpUnhandledException: Microsoft Dynamics
CRM has experienced an error. Reference number for administrators or
support: #5B02AEE3
2016-09-15T04:30:58.0199249Z
-2147220969
allgnt_location With Id = 3e10a729-fd7a-e611-80dd-fc15b4286cb8 Does Not Exist
2016-09-15T04:30:58.0199249Z
You also get this error if you create a phone call from this entity, and click the Complete Call button in the Command bar.
The Id listed is an id for the Case, but apparently, CRM is trying to load it as the Location instead, which is obviously failing. Am I doing it wrong?
Thanks #Polshgiant for getting me started down the right track. I needed to call Xrm.Utility.openEntityForm. This Typescript function works for me!
/**
* Opens a create form for a child entity of a parent. Useful if a subgrid add new button should redirect to the new page, rather than the default open in a new window.
* #param parentEntityId Id of the parent entity
* #param parentEntityTypeCode Object Type Code of the parent Entity
* #param childLogicalName Child Logical Name
* #param parameters Object whos properties will be added to the extraQs parameters
*/
export function openCreateChildFormInCurrentWindow(parentEntityId: string, parentEntityTypeCode: number, childLogicalName: string, parameters?: any) {
const params = {
formid: null,
["_CreateFromId"]: parentEntityId,
["_CreateFromType"]: parentEntityTypeCode.toString()
} as Xrm.Utility.FormOpenParameters;
if (parameters) {
for (const param in parameters) {
if (parameters.hasOwnProperty(param)) {
params[param] = parameters[param];
}
}
}
Xrm.Utility.openEntityForm(childLogicalName, null, params, { openInNewWindow: false } as Xrm.Utility.WindowOptions);
}
Related
I am using adempiere 380 webui, i would like to show error message on any failure of adempiere process or onComplete of any document.
The code which i have written to show error popup working in desktop application. But in webui - jboss it printing in console of jboss.
I have accomplished this using AbstractADWindowPanel.java where i am checking process id or table then execute particular code in that and if error codition is true then i am displaying FDialog.ask("Print Message"); .
Is there any generic way to do this by which it can be used for all classes.
Since processes can be fully automated and run on the server, your code needs to be aware of the GUI being used so that the correct dialog script can be called. There are three options, a server process (no dialog), swing (ADialog) or ZK (FDialog). Generally, its discouraged to use dialogs in this way. Certainly, you wouldn't want a server process to block waiting for user input. But, if you know what your doing and really need to...
In the most recent releases, the process code includes a flag that tests which of the states its in so it can display errors. An example of how this is used is with the Migration Script saves to XML format. In the process, the GUI info is used to open the correct file dialog in swing or, in ZK, pass the request to the browser.
Here is a snippet of how it works from ProcessInfo.java in the current release
/**
* Get the interface type this process is being run from. The interface type
* can be used by the process to perform UI type actions from within the process
* or in the {#link #postProcess(boolean)}
* #return The InterfaceType which will be one of
* <li> {#link #INTERFACE_TYPE_NOT_SET}
* <li> {#link #INTERFACE_TYPE_SWING} or
* <li> {#link #INTERFACE_TYPE_ZK}
*/
public String getInterfaceType() {
if (interfaceType == null || interfaceType.isEmpty())
interfaceType = INTERFACE_TYPE_NOT_SET;
return interfaceType;
}
/**
* Sets the Interface Type
* #param uiType which must equal one of the following:
* <li> {#link #INTERFACE_TYPE_NOT_SET} (default)
* <li> {#link #INTERFACE_TYPE_SWING} or
* <li> {#link #INTERFACE_TYPE_ZK}
* The interface should be set by UI dialogs that start the process.
* #throws IllegalArgumentException if the interfaceType is not recognized.
*/
public void setInterfaceType(String uiType) {
// Limit value to known types
if (uiType.equals(INTERFACE_TYPE_NOT_SET)
||uiType.equals(INTERFACE_TYPE_ZK)
||uiType.equals(INTERFACE_TYPE_SWING) )
{
this.interfaceType = uiType;
}
else
{
throw new IllegalArgumentException("Unknown interface type " + uiType);
}
}
The call to setInterfaceType() is made when the process is launched by the ProcessModalDialog in swing or the AbstractZKForm or ProcessPanel in zk.
For other processes, the value is set by the AbstractFormController which is used by both interfaces. If the interface type is not set the loadProcessInfo method will try to figure it out as follows:
// Determine the interface type being used. Its set explicitly in the ProcessInfo data
// but we will fallback to testing the stack trace in case it wasn't. Note that the
// stack trace test may not be accurate as it depends on the calling class names.
// TODO Also note that we are only testing for ZK or Swing. If another UI is added, we'll
// have to fix this logic.
if (processInfo == null || processInfo.getInterfaceType().equals(ProcessInfo.INTERFACE_TYPE_NOT_SET))
{
// Need to know which interface is being used as the events may be different and the proper
// listeners have to be activated. Test the calling stack trace for "webui".
// If not found, assume the SWING interface
isSwing = true;
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
for (int i=1; i<stElements.length; i++) {
StackTraceElement ste = stElements[i];
if (ste.getClassName().contains("webui")
|| ste.getClassName().contains("zk.ui")) {
isSwing = false;
break;
}
}
log.warning("Process Info is null or interface type is not set. Testing isSwing = " + isSwing);
}
else
{
isSwing = processInfo.getInterfaceType().equals(ProcessInfo.INTERFACE_TYPE_SWING);
}
Finally, this can be used to control the dialogs within your process with a call similar to
if (ProcessInfo.INTERFACE_TYPE_SWING.equals(this.getProcessInfo().getInterfaceType()))
{
... Do something on a swing...
}
else ...
I have created cascading dropdown. I need to load dropdown based on parent dropdown selection. I am trying to use onpropertychange event. but I am getting error on super.onpropertychange saying {Property 'onPropertyChange' does not exist on type 'BaseClientSideWebPart'.}
please let us know what I havve missed.
protected onPropertyChange(propertyPath: string, newValue: any):void{
if(propertyPath === "listDropDown"){
// Change only when drop down changes
super.onPropertyChange(propertyPath,newValue);
// Clears the existing data
this.properties.ItemsDropDown = undefined;
this.onPropertyChange('ItemsDropDown', this.properties.ItemsDropDown);
// Get/Load new items data
this.GetItems();
}
else {
// Render the property field
super.onPropertyChange(propertyPath, newValue);
}
}
Instead of onPropertyChange, perhaps you mean onPropertyFieldChanged from the BaseWebPart class?
The error message is accurate - web parts don't have a method called onPropertyChange. The above sounds like the closest match for what you are trying to do. Note that it takes not two arguments, but three: propertyPath, oldValue, and newValue.
I've configured a FileNet workflow subscription on Add, Update and Delete events. The workflow calls a Java component to send a notification message (to a third party).
We would like to see "before" and "after" property values in the notification message for "Update" events.
The "Event" object that triggers the subscription has a "Modified Properties" member, so I was hoping I could just create a corresponding "ModifiedProperties" string array in the workflow, and have the subscription map "Update.ModifiedProperties = ModifiedProperties". Unfortunately, the Event's "ModifiedProperties" only gives the NEW value, not the "before" value.
<= So I don't see any way to get "before/after" values directly from the subscription...
It looks like the "UpdateEvent" object also has an "OriginalObject" member ... and I might be able to use the Java API to get the "before" value from the OriginalObject.
Q: Does this sound plausible method for getting the before/after document property values?
Q: Any ideas how to pass the "OriginalObject" object from the subscription to the workflow, so the Java component can use it?
The target platform is P8 5.2.1; I'm developing on P8 5.5.
You are right, the only way to the original values is through the OriginalObject object. And the quickest way to get data to a workflow is using a subscribable object.
Therefore, a solution to your problem is to define a custom object containing the properties describing the new and the old property values. You create this custom object in a custom event handler triggered on an update event from the document. Here you can populate the properties of the custom object using the original object:
Document document = (Document) event.get_OriginalObject();;
Iterator<?> iterator = event.get_ModifiedProperties().iterator();
while (iterator.hasNext()) {
String modifiedProperty = (String) iterator.next();
// TODO: Fetch the values from the original object
// and set them on the custom object. The details depend
// on the data structure you choose.
}
Next you create a Workflow subscription triggered on the creation of the custom object. You can map the properties of your custom object to the data fields of your workflow. In the workflow that is started you can define an attachment and specify that the custom object is the initiating attachment. Using the CE_Operation queue methods you can now and delete the custom object when your processing is finished.
if(objEvent instanceof UpdateEvent) { try { String strModifiedProperties = ""; UpdateEvent updateEvent = (UpdateEvent) objEvent; StringList propertyNames = updateEvent.get_ModifiedProperties(); Iterator iterModifiedProps = propertyNames.iterator(); while(iterModifiedProps.hasNext()) { String modifiedProperty = (String) iterModifiedProps.next(); strModifiedProperties = strModifiedProperties+modifiedProperty+","; } strModifiedProperties = strModifiedProperties.substring(0, strModifiedProperties.lastIndexOf(",")); } catch (Exception e) { System.out.println("onEvent : Exception while executing UpdateEvent: "+e.getMessage()); } }
I want to disable make a copy option when user do right click on documents in m-files, until no body cant copy documents to other class to use,
is there anybody to help me to solve it?
You can achieve this with M-Files User Interface Extensibility Framework.
The needed function is shellFrame.Commands.SetCommandState(9, CommandLocation_All, 3).
1st parameter is command ID (list of built-in command IDs, 9 is BuiltinCommand_MakeCopy)
2nd parameter defines the parts of the UI where you want to set the new command state
3rd parameter defines the new state (3 is CommandState_Hidden)
You will need to set up the UI extension with some configuration files but there is a sample that comes close to your use-case: Alter Context Menu Depending on SelectedObject. The code to hide the context menu option in main.js would be:
"use strict";
function OnNewShellUI(shellUI) {
shellUI.Events.Register(
Event_NewNormalShellFrame,
handleNewNormalShellFrame);
}
function handleNewNormalShellFrame(shellFrame) {
shellFrame.Events.Register(
Event_Started,
getShellFrameStartedHandler(shellFrame));
}
function getShellFrameStartedHandler(shellFrame) {
return function () {
shellFrame.Commands.SetCommandState(9, CommandLocation_All, 3);
};
}
I am developing a wizard using eclipse plugin development.
Requirement:
I have to create a context menu that needs to get populated as soon as the user right clicks on the source folder in java project. once the User performs the first step my handler needs to get the selected src folder in my wizard. My wizard contains a treeviewer where i need to get the selected src folder packaged.
My analysis:
i have my handler class that gets the selected packages
SampleHandler.java
public Object execute(ExecutionEvent event) throws ExecutionException {
shell = HandlerUtil.getActiveShell(event);
// Initializing workbench window object
IWorkbenchWindow window = (IWorkbenchWindow) HandlerUtil.getActiveWorkbenchWindow(event);
ISelection sel = HandlerUtil.getActiveMenuSelection(event);
final IStructuredSelection selection = (IStructuredSelection) sel;
Object firstElement = selection.getFirstElement();
if (firstElement instanceof IPackageFragment) {
// Get the selected fragment
IPackageFragment packageFragment = (IPackageFragment) firstElement;
modelPackage = packageFragment.getElementName();
boolean a =!ProjectResourceHelper.isEntityBasePackage(modelPackage);
if(a == true){
MessageDialog.openInformation(shell, "Warning", "Please click from entity base package");
Shell shell = HandlerUtil.getActiveShell(event);
GreenWizard wizard = new GreenWizard();
WizardDialog dialog = new WizardDialog( part.getSite().getShell(), wizard);
dialog.create();
dialog.open();
return null;
}
try{
window.run(true, true, new IRunnableWithProgress(){
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Layer codes are being generated...", 1);
// Invocation of generate layers method
monitor.worked(1);
// Done with operation completion.
monitor.done();
}
});
}
catch(InvocationTargetException ite){
MessageDialog.openError(shell, "Greenfield Code Generation Exception", ite.getMessage());
}
catch (InterruptedException ie) {
MessageDialog.openError(shell, "Greenfield Code Generation Exception", ie.getMessage());
}
}
I have my main wizard class that is called within this method.
GreenWizard wizard = new GreenWizard();
and my main wizard in return calls my wizard page where i need to get the selection performed on right click by the user.
My Wizardpageclass
public GenerateGreenfieldLayer(IWorkbench workbench,
IStructuredSelection selection) {
super("Greenfield");
setImageDescriptor(ResourceManager
.getImageDescriptor("\\icons\\greenfield-new-wiz.png"));
setTitle("GreenField Generate layer");
setDescription("Select specfic class to grenerate Layers");
}
/**
* Create contents of the wizard.
*
* #param parent
*/
#Override
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
setControl(container);
container.setLayout(new GridLayout(2, false));
final CheckboxTreeViewer treeViewer = new CheckboxTreeViewer(container,
SWT.BORDER);
tree = treeViewer.getTree();
tree.setToolTipText("Choose package");
GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd_tree.widthHint = 280;
gd_tree.heightHint = 140;
tree.setLayoutData(gd_tree);
treeViewer.setContentProvider(new GreenfieldTreeContentProvider());
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
treeViewer.addSelectionChangedListener(new ISelectionChangedListener () {
public void selectionChanged(SelectionChangedEvent event) {
}
});
}
Can anyone please guide me how to get the selection from object method and pass as treeviewer initial input in my wizard page.
Please correct me if i am missing any steps as i am very new to this.
Thanks in advance
You should separate the code into the following pieces and dataflows:
Handler: get the selection and create the wizard and wizard dialog (as you do already)
Handler->Wizard: use the Wizard's constructor or a custom init(foo) method (which you call from the handler) to set the selected object (or whatever you want to pass as initial data) from the handler
Wizard->WizardPage: When creating the Wizard, instantiate the WizardPage(s) and pass the selection to the wizard pages. (If you need a more complex model which is shared between the Wizard and its pages consider creating an instantiating a simple value-holder class as your wizard model; i.e., a simple java class with your data and getters/setters. That object can then be shared across the pages if you pass it to every page's constructor)
WizardPage: create UI for wizard page, let user modify the model
WizardPage->Wizard: if you do not use the shared wizard model via a value-holder class, have a getXxx() method to let the wizard access the user's input from the page
Wizard: implement Wizard.performFinish() to do the work at the end of the wizard using getContainer().run() instead of having the window.run() call in your handler.