button command action from Ribbon Workbench for crm 2013 - dynamics-crm-2013

I have a button "add new " in my form, and there is a command action written (/_static/_common/scripts/RibbonActions.js) as per Ribbon workbench to create a new record.
Now i want to add my another function in as another command action which return true or false.
If it returns true then and then the default create function will execute.
How can i do this, anyone have idea ?

Try updating your New button command with following function from your script:
function MyAddNewAction(entityTypeName){
var bContinue = true;
// your validation code here, and update bContinue
//
if(bContinue){
Mscrm.RibbonActions.openNewRecord(entityTypeName);
}
}
Hope it helps!

Related

Cannot enable a Ribbon button programmatically

I developed a VSTO 4 add-in for Excel. It works perfect, however, I have a button placed in the custom tab of its Ribbon control that is initially disabled.
After clicked other ribbon button in my custom tab, I need to enable the initially disabled button.
I tried with:
btnCancelar.Visible = true;
In the Click event of a button, but button is not shown. The strange thing is that when debugging, it still does not appear, but if a MessageBox is shown, the button get visible at last.
I don't understand this behaviour. How can I enable or disable a ribbon button dynamically by code?
I'm not sure what your language is used in your project, but I guess you can tranform it to your own language used. I'll show the example here in C#:
First you need to implement a so called Callback function in the RibbonXML definition:
<button id="buttonSomething" label="Content" size="large" getVisible="EnableControl"/>
then the next step is to implement the Callback function:
public bool EnableControl(IRibbonControl control)
{
return true; // visible ... false = invisible
}
VSTO will trigger the getVisible Callback and depending on the return value enable or disable the visible state (don't forget to remove any Visible property from the RibbonXML, otherwise the Callback is not triggered)
In case of the Ribbon Designer you need to make sure your Click signature is correct, the easies way to do that is by double clicking the button on the ribbon designer. This will create the Click method for you, for instance:
I created a Ribbon with the Ribbon designer and added two buttons. Double clicked the first button to get an empty method like below, and added the code.
private void button1_Click(object sender, RibbonControlEventArgs e)
{
// Toggle button visibility and make sure the button is enabled
// Visible (obviously) makes it visible, while Enabled is grayed if
// false. You don't need this it is Enabled by default, so just for
// demo purposes
button2.Visible = !button2.Visible;
button2.Enabled = button2.Visible;
// Force Ribbon Invalidate ...
this.RibbonUI.Invalidate();
// Long running proces
}
This worked perfectly for me, so if it doesn't work for you please provide more details of your coding.
I have created a workaround to this.
It was simple. Just started the long running process in different thread. That way, cancel button is shown when it should and then hidden after the process ends.
I used this code to launch the process in the Ribbon.cs code:
btnCancelar.Visible = true;
Action action = () => {
Formatter.GenerateNewSheet(Formatter.TargetType.ImpresionEtiquetas, frm.CustomerID, workbook, btnCancelar);
};
System.Threading.Tasks.Task.Factory.StartNew(action);
And inside the process method I have this code:
public static bool GenerateNewSheet(TargetType type, string customerID, Excel.Workbook workbook, Microsoft.Office.Tools.Ribbon.RibbonButton btnCancelar)
{
try
{
_cancelled = false;
InfoLog.ClearLog();
switch (type)
{
case TargetType.ImpresionEtiquetas:
return GenerateTagPrinting(customerID, workbook);
}
return false;
}
finally
{
btnCancelar.Visible = false;
}
}
The interesting thing here I have discovered is that Excel is thread safe, so it was not necessary to add a synchronization mechanism neither when adding rows in the new sheet nor when setting Visible property to false again.
Regards
Jaime

Open Method of Worksheet fails [duplicate]

I am trying to create a new instance of Excel using VBA using:
Set XlApp = New Excel.Application
The problem is that this new instance of Excel doesn't load all the addins that load when I open Excel normally...Is there anything in the Excel Application object for loading in all the user-specified addins?
I'm not trying to load a specific add-in, but rather make the new Excel application behave as though the user opened it themself, so I'm really looking for a list of all the user-selected add-ins that usually load when opening Excel.
I looked into this problem again, and the Application.Addins collection seems to have all the addins listed in the Tools->Addins menu, with a boolean value stating whether or not an addin is installed. So what seems to work for me now is to loop through all addins and if .Installed = true then I set .Installed to False and back to True, and that seems to properly load my addins.
Function ReloadXLAddins(TheXLApp As Excel.Application) As Boolean
Dim CurrAddin As Excel.AddIn
For Each CurrAddin In TheXLApp.AddIns
If CurrAddin.Installed Then
CurrAddin.Installed = False
CurrAddin.Installed = True
End If
Next CurrAddin
End Function
Using CreateObject("Excel.Application") would have the same result as using New Excel.Application, unfortunately.
You will have to load the Addins that you need individually by file path & name using the Application.Addins.Add(string fileName) method.
I'm leaving this answer here for anyone else who ran into this problem, but using JavaScript.
A little background... In my company we have a 3rd party web app that used JavaScript to launch Excel and generate a spreadsheet on the fly. We also have an Excel add-in that overrides the behavior of the Save button. The add-in gives you the option of saving the file locally or in our online document management system.
After we upgraded to Windows 7 and Office 2010, we noticed a problem with our spreadsheet-generating web app. When JavaScript generated a spreadsheet in Excel, suddenly the Save button no longer worked. You would click save and nothing happened.
Using the other answers here I was able to construct a solution in JavaScript. Essentially we would create the Excel Application object in memory, then reload a specific add-in to get our save button behavior back. Here's a simplified version of our fix:
function GenerateSpreadsheet()
{
var ExcelApp = getExcel();
if (ExcelApp == null){ return; }
reloadAddIn(ExcelApp);
ExcelApp.WorkBooks.Add;
ExcelApp.Visible = true;
sheet = ExcelApp.ActiveSheet;
var now = new Date();
ExcelApp.Cells(1,1).value = 'This is an auto-generated spreadsheet, created using Javascript and ActiveX in Internet Explorer';
ExcelApp.ActiveSheet.Columns("A:IV").EntireColumn.AutoFit;
ExcelApp.ActiveSheet.Rows("1:65536").EntireRow.AutoFit;
ExcelApp.ActiveSheet.Range("A1").Select;
ExcelApp = null;
}
function getExcel() {
try {
return new ActiveXObject("Excel.Application");
} catch(e) {
alert("Unable to open Excel. Please check your security settings.");
return null;
}
}
function reloadAddIn(ExcelApp) {
// Fixes problem with save button not working in Excel,
// by reloading the add-in responsible for the custom save button behavior
try {
ExcelApp.AddIns2.Item("AddInName").Installed = false;
ExcelApp.AddIns2.Item("AddInName").Installed = true;
} catch (e) { }
}

ShowDialog() in Mono

I have 2 form in Mono.In OnClickEvent of a button in Form1, i want to showDialog Form2 and fetch a answer from Form2.In C# i have this code
Form2 F=new Form2();
F.ShowDialog();
int MyAnswer=F.Answer;
But in Mono ShowDialog() function does not exist.
this question mean: i want to show Form2 but Form1 wait for result of Form2
Instead of using Gtk.Window you can use Gtk.Dialog and use this code.
ResponseType response = ResponseType.None;
using (var dlg = new YesNoDialog ("Title", "Question", "Yes Button", "No Button"))
response = (ResponseType) dialog.Run ();
if (response == ResponseType.Yes)
OverwriteFile ();
It looks like you are trying to use System.Windows.Forms.Form.ShowDialog() in a Gtk# application.
The equivalent Gtk# function is called Gtk.Dialog.Run, see Is there a Form.Showdialog equivalent for Gtk# Windows?
You also need to create a Dialog, not a Form - ie. when you add the new class in MonoDevelop, you choose "Gtk / Dialog", not "Gtk / Widget".

on(release) {...} or myButton.onRelease = function() {...} - action script 2 issues

I am having real confusion with some flash banners I'm creating and making the button into a clickable object which opens a web page.
I have been using this code for a while below, which works...
on(release){
getURL("http://www.the-dude.co.uk", "_blank");
}
And I placed this code on actual button within the actions panel
However I have been told the code above is very old and that I should use action script like below...
buttonInstance.onRelease = function() {
getURL("http://www.the-dude.co.uk", "_blank");
}
So I've tried to get this method below to work but nothing happens when I click the button, and I get one error, this...
So in a nutshell I cannot get this newer code to work! Ahh
Can anyone please help me understand where I am going wrong?
I have tried placing the new code in the Scene 1 of my actions. No worky..
And I've also tried placing the code below, actually on my button within the actions panel...
this.onRelease = function() {
getURL("http://www.the-dude.co.uk", "_blank");
}
Still not working.
My scene settings are alway this...
Any help would be great thanks.
You need to place the code below on the same timeline as the instance of the button (as you tried). And the instancename of the button must be "buttonInstance".
You can set the instance name in the properties panel when the button is selected.
buttonInstance.onRelease = function() {
getURL("http://www.the-dude.co.uk", "_blank");
}

How to start SharePoint 2010 workflow from Infopath 2010 code behind?

I have an Infopath 2010 template with 2 buttons: submit and cancel. When the submit button is clicked I the form is saved to a document library in SharePoint 2010 and the corresponding workflow is clicked off. The user can then open the form and cancel the request by clicking on cancel. I would like to start a different workflow when cancel is clicked. Any ideas as to how that could be done?
Thanks
I have not found a method to kick off a workflow specifically from an Infopath form. I did however find a workaround; here's how I set it up:
Added a column to my list/library that will be set to true when the cancel button is selected.
In my infopath form, add my "cancel" button.
Open the control properties for the button, and select the "Rules" action. Close out of the properties dialog.
I added a fomatting rule for the cancel button so it will only display if the first workflow has started. I also disabled all other editing controls as I only wanted the cancel option to be available.
On the Control Tools contextual tab, in the Button group, click Manage Rules.
Add a new Action rule, it should run two actions: first set the value of the column we created in the first step to true; second submit data using the main data connection.
The workflow you want to run when it is cancelled should be set to run on change. As a first step, evaluate the column created above, and if true, continue the worflow. Make sure you set the value back to false so the workflow doesn't run unintentionally.
Hope that helps.
That is not a bad workaround Nostromo but we actually ended up using the out of the box SharePoint web services to start the workflow from InfoPath code behind. Here is the method we developed to do that.
public static void StartWorkflow(string siteUrl, string docUrl,string workflowName, List<string> approvers,string description)
{
var workflow = new Workflow();
workflow.Url = siteUrl+ "/_vti_bin/workflow.asmx";
workflow.Credentials = System.Net.CredentialCache.DefaultCredentials;
XmlNode assocNode = workflow.GetTemplatesForItem(docUrl);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
nsmgr.AddNamespace("wf", "http://schemas.microsoft.com/sharepoint/soap/workflow/");
XmlDocument doc = new XmlDocument();
Guid templateID = new Guid();
bool workflowFound = false;
XPathNodeIterator rows = assocNode.CreateNavigator().Select("//wf:WorkflowTemplate", nsmgr);
while (rows.MoveNext())
{
if (rows.Current.GetAttribute("Name", "").ToLower() == workflowName.ToLower())
{
doc.LoadXml(rows.Current.SelectSingleNode("wf:AssociationData/wf:string", nsmgr).Value);
XPathNavigator idNode = rows.Current.SelectSingleNode("wf:WorkflowTemplateIdSet", nsmgr);
templateID = new Guid(idNode.GetAttribute("TemplateId", ""));
workflowFound = true;
break;
}
}
if(!workflowFound)
throw new Exception("System couldn't location the workflow with name: " +workflowName);
XmlElement xmlRoot = doc.DocumentElement;
nsmgr = new XmlNamespaceManager(assocNode.OwnerDocument.NameTable);
nsmgr.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD");
xmlRoot.SelectSingleNode("/my:myFields/my:Description", nsmgr).InnerText = description;
XmlNode reviewersNode = xmlRoot.SelectSingleNode("/my:myFields/my:Reviewers", nsmgr);
reviewersNode.InnerXml = "";
foreach (var user in approvers)
{
XmlNode personNode = reviewersNode.AppendChild(doc.CreateElement("my:Person"));
XmlNode accountIdNode = personNode.AppendChild(doc.CreateElement("my:AccountId"));
accountIdNode.InnerText = user;
XmlNode accountTypeNode = accountIdNode.AppendChild(doc.CreateElement("my:AccountType"));
accountTypeNode.InnerText = "User";
}
XmlNode workflowNode = workflow.StartWorkflow(docUrl, templateID, doc.DocumentElement);
}