Disable System Ribbon in CRM 2011 - ribbon

I would like to conditionally disable a System Ribbon = AddNew in a CRM 2011 form with javascript. That means if the statusCode is X or Y disable the Ribbon, how could I do this?
I tryed to get the ID of the Ribbon in order to change the classname of the Ribbon to disabled, but I got Null because the Ribbons are loaded asychronously!

To expand on Anwar's answer, the key to getting this to work is to intercept and repurpose the functionality of the AddNew ribbon button, but once you do, there won't be any need for hacking the Ribbon DOM. Below are a few steps that you can take to get there.
1) Create a solution with the Application Ribbon included.
2) Find in the SDK the sample ribbon for the Application Ribbon or build it yourself using the solution included in the SDK.
\sdk\resources\exportedribbonxml
\sdk\samplecode\cs\client\ribbon\exportribbonxml\exportedribbonxml
3) Find in the Application Ribbon template the control you're interested in, which I assume in this case is the AddNew button in entity subgrids. Repurpose this control in a CustomAction and make the location of the CustomAction the same name as the control you want to repurpose.
<CustomAction Id="YourOrg.SubGrid.{!EntityLogicalName}.AddNewStandard"
Location="Mscrm.SubGrid.{!EntityLogicalName}.AddNewStandard">
<CommandUIDefinition>
<Button Id="Mscrm.SubGrid.{!EntityLogicalName}.AddNewStandard"
Command="Mscrm.AddNewRecordFromSubGridStandard" Sequence="20"
LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.AddNew"
Alt="$Resources(EntityDisplayName):Ribbon.SubGrid.AddNew"
Image16by16="/_imgs/ribbon/NewRecord_16.png"
Image32by32="/_imgs/ribbon/newrecord32.png" TemplateAlias="o1"
ToolTipTitle="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddNewStandard_ToolTipTitle"
ToolTipDescription="$Resources(EntityDisplayName):Mscrm_SubGrid_EntityLogicalName_MainTab_Management_AddNewStandard_ToolTipDescription" />
</CommandUIDefinition>
</CustomAction>
4) Find in the Application Ribbon template the definition of the command of this button, and using the exact definition as the basis of a new CommandDefinition, add in your own custom rule (in this case, a new EnableRule).
<CommandDefinition Id="Mscrm.AddNewRecordFromSubGridStandard">
<EnableRules>
<EnableRule Id="Mscrm.AppendToPrimary" />
<EnableRule Id="Mscrm.EntityFormIsEnabled" />
<EnableRule Id="YourOrg.DisableNewStuff" /> <!--your custom rule-->
</EnableRules>
<DisplayRules>
<DisplayRule Id="Mscrm.ShowForOneToManyGrids" />
<DisplayRule Id="Mscrm.AppendToPrimary" />
<DisplayRule Id="Mscrm.CreateSelectedEntityPermission" />
<DisplayRule Id="Mscrm.AppendSelected" />
<DisplayRule Id="Mscrm.HideAddNewForChildEntities" />
</DisplayRules>
<Actions>
<JavaScriptFunction FunctionName="Mscrm.GridRibbonActions.addNewFromSubGridStandard"
Library="/_static/_common/scripts/RibbonActions.js">
<CrmParameter Value="SelectedEntityTypeCode" />
<CrmParameter Value="PrimaryEntityTypeCode" />
<CrmParameter Value="FirstPrimaryItemId" />
<CrmParameter Value="PrimaryControl" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
5) Here is where Anwar's answer comes in: using both the OrRule and the ValueRule, define your EnableRule to check on the statuscodes of the entity. The linked demonstration relates to a new ribbon button, but the same rules work for repurposed ribbon controls as well.
Publish your changes when you're done and your ribbon should be all set. Because I'm not sure how familiar you are with RibbonXml, I'll also mention that Microsoft has some comprehensive walkthroughs that are pretty helpful (after much time studying them!) in picking it up.

This article explains exactly what your are looking for.
Please follow this link
How To Use "ValueRule" and "OrRule" in Ribbon Customizations - CRM 2011

This is how i hide the delete button on invoice form, based on status code, onload of the form:
var statusVal = Xrm.Page.getAttribute("statuscode").getValue();
if (statusVal==4 || statusVal==6) {
//Disable delete button
var x =top.document.getElementById("invoice|NoRelationship|Form|Mscrm.Form.invoice.Delete-Medium");
x.style.display='none';
You can get the id of the element span, which you want to hide from the source of the page.

Related

Dynamically adding/removing TabViewItem in NativeScript tabs project

I have a NativeScript 8.1 JavaScript project that uses the tabs template, so that the app-root.xml file looks like this:
<TabView tabTextFontSize="16" androidOffscreenTabLimit="0" androidTabsPosition="bottom"
id="tabview" class="ns-light" loaded="onLoaded" >
<TabViewItem title="Riders" iconSource="res://biking_solid" >
<Frame id="main" defaultPage="views/main-page" />
</TabViewItem>
<TabViewItem title="Volunteers" iconSource="res://hands_helping_solid" >
<Frame id="vol" defaultPage="views/volunteers-page" />
</TabViewItem>
<TabViewItem title="Director" iconSource="res://user_ninja_solid" >
<Frame id="director" defaultPage="views/director-page" />
</TabViewItem>
</TabView>
The catch here is that the third tab needs to be conditional and only visible if the user is authorized. I've tried pop'ing the TabView's item's array. I've tried creating a new TabViewItem and pushing it onto the items array. I've tried using the visibility property, and none of these work.
I'll know at startup time whether the third tab should be displayed, so handling this in app-root.js is fine. I'm OK with creating all of the tabs dynamically but I can't get that to work either. I could live with disabling the third tab but the enabled property on TabViewItem is ignored.
In short, I've tried everything I can think of and I'm unable to change the TabViewItem's in any way. I realize the underlying implementations are likely imposing some restrictions, but still, is there any way I can control whether the third tab is visible?
This doesn't really answer the question, but it does solve my problem. I can have two separate app-root files, say app-root2 and app-root3, then in app.js I can apply logic and start the appropriate one:
if (<condition>)
application.run({ moduleName: "app-root2" });
else
application.run({ moduleName: "app-root3" });
Edit 4/10/2022: I ended up switching to the BottomNavigation component and dealt with the same issue. That, and the accompanying solution, is described in this post.

Toggle inputTextarea editable with ajax but can not submit its value

I have encounter a problem on First toggle inputTextarea editable with Ajax, how to submit typed in value after toggle The UI build on JSF 2 and RichFaces, the backing bean is #ManagedBean /#RequestScoped for now, contain all necessary properties(indicator/reason) and corresponding get/set methods. The app is running on IBM websphere. I was first taken example from here and here.
The myPage.xhtml related section is
<h:form id="myPage">
<td>
<h:selectOneMenu value="#{myPage.indicator}">
<f:selectItem itemValue="Y" itemLabel="YES" />
<f:selectItem itemValue="N" itemLabel="NO" />
<f:ajax render="reason" />
</h:selectOneMenu>
</td>
<td><h:inputTextarea id="reason" value="#{myPage.reason}" disabled="#{fn:toLowerCase(myPage.indicator) != 'y'}">
</h:inputTextarea>
</td>
<td>
<h:commandButton value="Update" id="update"
action="#{myPage.update}">
</h:commandButton>
</td>
</h:form>
The function here is using selectItem "indicator" to toggle whether inputTextarea "reason" is editable or not. I use <f:ajax> to render, the effect can be seen directly when I toggle on GUI.
When I set "indicator" as Yes, "reason" becomes editable, then I type in some words and click "upload" button(which is a normal post method contain logic to commit form value to database), but the words in "reason" not commit to database.
What I suppose is <f:ajax> set render attribute point to inputTextarea "reason", which means a request already generated when I toggle the selectItem "indicator", but this request hold nothing, because the sequence here is first toggle then available to type in words, the "reason" contain no words at toggle time. And as this inputTextarea "reason" set as ajax render, the normal submit form way trigger by "upload" button also cannot commit its value even I click after type in words. Is this a right guess ?
If this is the right guess, how to solve this issue(e.g how to collect this inputTextarea "reason" value after its become available by ajax toggle) ? Create backing bean listener method with <f:ajax render="reason" listener="...">(and if yes, please show some detail actions I should add for this listener) ? OR any other way(e.g should I go with JavaScript or JQuery to solve) ? If what I did wrong way, please help me to figure out(initial goal is to toggle inputTextarea to editable like ajax effect and then submit the value later typed in).
Maybe this question is a little fuzzy, I want to re-declare it here as: There is an indicator control a related inputTextarea editable or not, but if I just use Ajax render attribute to control this, I cannot use Ajax to retrieve the later typed in words in this inputTextarea, as ajax is acutally a request send from client to server side, when i toggle the indicator to make inputTextarea editable, the request already send out, but no words contained in request at this time, so I stuck here, can not find way to use Ajax to toggle and send later typed in words.
Still welcome if anyone come to an idea with JSF Ajax way.
I fix the issue with using javascript instead of Ajax, the fixed way is a little interesting, as to simulate Ajax effect, need to trigger javascript function in different cases(a combination usage of same javascript function):
1. First, the javascript to toggle "reason" inputTextarea based on indicator, retrieve these DOM elements based on 'formname:element_id', in my question, already show "indicator" as h:selectOneMenu, and "reason" as h:inputTextarea.
<script type="text/javascript">
function handleDisabledOrNot() {
var currVal = document.getElementById('myPage:indicator').value;
if(currVal == "N") {
document.getElementById('myPage:reason').disabled = true;
} else {
document.getElementById('myPage:reason').disabled = false;
}
}</script>
2. Then call this function on indicator with onclick event
<td align="left"><!-- Use onclick event to control whether reason disabled or not -->
<h:selectOneMenu id="indicator" value="#{myPage.indicator}" onclick="handleDisabledOrNot()">
<f:selectItem itemValue="Y" itemLabel="YES" />
<f:selectItem itemValue="N" itemLabel="NO" />
</h:selectOneMenu></td>
3. Finally check the status when load page or work in the page on reason with onblur / onfocus event, to make sure full-scale detect indicator status in the view, otherwise, it will miss status checking in either way. E.g, when first time load the page, if missing check status with onfocus event, if you move mouse into reason inputTextarea, no matter what indicator is Y or N, it is editable initially, to avoid such case, should use onfocus event to check, and vice versa to use onblur event.
<!-- Use both onblur and onfocus event to detect indicator status full-scale on view -->
<h:inputTextarea id="reason" value="#{myPage.reason}" onblur="handleDisabledOrNot()" onfocus="handleDisabledOrNot()">
</h:inputTextarea></td>
Finally, it shows the same effect as Ajax render way. As the link i quote in my question, I know in JSF, the best solution is using Ajax to work with backing bean, but as I don't know how to implement after Ajax toggle, how to collect data in inputTextArea later typed in, I can not come with solution on Ajax way now. So, still welcome some idea based on Ajax, if not, just show purely javascript way here.

Primefaces and selectors

I have a tabView component and in each tab panel, I have a form.
I have also a flag image to change locale in my application and when it's clicked, I want to reload all tabView with new locale changes.
In one form in a tab panel, I use captcha component and I don't want to reload it because...it's impossible without all reload page (doesn't support partial Ajax reloading, I will use Recaptcha.reload() JS to do the job of reloading).
So I want to reload all my tabView component nested in panel component named...panel without my captcha.
my tabView is nested in panel named panel
my captcha has id captcha
My 2 locale change buttons are these one :
<p:commandLink update="#(:panel:not(captcha))" rendered="#{locale.locale != 'fr'}">
<h:graphicImage url="resources/images/flags/flag_fr.png" width="30" height="30" />
<f:setPropertyActionListener target="#{locale.locale}" value="fr" />
</p:commandLink>
<p:commandLink update=":panel" rendered="#{locale.locale != 'en'}">
<h:graphicImage url="resources/images/flags/flag_en.png" width="30" height="30" />
<f:setPropertyActionListener target="#{locale.locale}" value="en" />
</p:commandLink>
I have tested much combinaisons of selectors inside update attribute but without success.
Any selector idea please ? Thanks a lot
When you are using PFS you are referencing client id of the componenets. For example if client id of your panel is :panel, your selector will be #(#\\:panel) (you have to escape semicolon). Inspect your generated html and find out real client ids of your components. If the component is in naming container id of container is concatenated before id of child compoenent. For example if panel is naming container of your captcha it would be something like: #(#\\:panel:not(#\\:panel\\:captcha)). Forms are also naming container so probably your ids will have something more near this.

flex DateChooser needs to not be selectable

I'm sure this is pretty easy but I'm at a loss with this one. I have a DateChooser that I'm using to highlight dates when things are being released. And that's all I want it for. I want to turn off the ability for users to click on anything. I don't see how to have selectable false. Anyone know?
Thanks
There are actually two properties that you can use to turn off user interaction:
First is the enabled property, set it enabled="false" in mxml and user
interaction will be disabled. However, Flex will render the
DateChooser dim (kind of faded away).
<mx:DateChooser id="date1" enabled="false" />
Another option is the mouseChildren property, if you set it to
mouseChildren="false" as well all children of the display object will not be enabled, in the case of the DateChooser it disables all user interaction too.
<mx:DateChooser id="date1" mouseChildren="false" />
Try placing it behind a Group that has a fill with alfa 0. That way the group will take the clicks and do nothing with them.
If i understand you correctly, then you could use the disabledDays, disabledRange or selectableRange properties of the DateChooser. E.g. such as in the code from the adobe website:
<mx:DateChooser
selectableRange="{{rangeStart: new Date(2006,0,1),
rangeEnd: new Date(2006,2,15)}}"
disabledRanges="{[new Date(2006,0,11),
{rangeStart: new Date(2006,0,23), rangeEnd: new Date(2006,1,10)}]}"
disabledDays="{[0,6]}"/>
Use this to disable all other dates than the one(s) you want highlighted. I was actually just wondering if i should do something similar, but I just ended opp using a disabled DateField(enabled=false) to display the date. I hope this helps :)

PrimeFaces DataTable - Row Selection inquiry

How does this code in the PrimeFaces DataTable row selection work?
<p:commandButton update=":form:display" oncomplete="confirmation.show()" image="ui-icon ui-icon-close" title="Delete">
<f:setPropertyActionListener value="#{car}" target="#{tableBean.selectedCar}" />
</p:commandButton>
I am confused by the following: update=":form:display", and image="ui-icon ui-icon-close".
Is this inbuilt into Primefaces? or do I need to create an additional form, or have an external image mapped to it?
update=":form:display" refers to a specific element on the page. The first ':' goes to the root of the page, so there needs to be a component with the id "form" (probably a form) and inside that a component with the id "display". This means after the button actions has completed :form:display will be updated. Note that it's generally not a great idea to use absolute paths as they can be hard to keep up to date when you change the page structure. If the button is on the same level as the "display" component you could just do update="display", or you can do things like update="#form" to update the entire current form.
image="ui-icon ui-icon-close" refers to style classes in your css. These two comes predefined with primeface, but if you want to use custom graphics you can also define your own style classes for them.