Use an h:commandButton to toggle rich:dataScroller - xhtml

Has anyone used a commandButton to toggle a rich:dataScroller on and off? Would I need to make a bean to keep track of if the rich:dataScroller is active or not and make the action of the commandButton to toggle the bean?

What do you mean by on/off? Does it means show/hide? If so, you can do something like this.
Assume that you have following table which has a datascroller and a commandButton below the table.
<h:form>
<rich:dataTable var="_usr" value="#{myBean.users}" rows="5">
<rich:column>
#{_usr.userName}
</rich:column>
<f:facet name="footer">
<rich:datascroller id="myScroller" />
</f:facet>
</rich:dataTable>
<a4j:commandButton value="Show/Hide" onclick="toggleScroller(#{rich:element('myScroller')});"/>
</h:form>
The javascript function which shows/hides the datascroller is as below.
<script>
function toggleScroller(scroller) {
if(scroller.style.display == 'none') {
scroller.style.display = ''
} else {
scroller.style.display = 'none'
}
}
</script>
Or you can use the rendered property of the <rich:datascroller> to render it according to a bean property.

Related

Recursive composite component causes StackOverflow

Introduction
Hello,
Before I start, I just want to say I already tried to solve the issue by visiting other posts here, and I didn't find anything right for me.
I saw this post stating "composite components unfortunately do not support recursion.". But the post is from 2011, so I am assuming it's possible now.
I read and tried to use this BalusC explaination, but it didn't work.
The problem and code snippets
So here's my problem. I want to have a recursive table of DTOs objects (using datatables of Primefaces, but I doesn't matter I think). My component looks like this :
<cc:interface componentType="recursiveDomainsTable">
<cc:attribute name="domains_list" type="java.util.List" required="true" />
</cc:interface>
<cc:implementation>
<p:dataTable var="domain" value="#{cc.getDomainsList()}">
<p:column>
<!-- allow a row to be expanded -->
<p:rowToggler rendered="#{domain.hasSubDomains()}"/>
<!-- some text here for the demo -->
<h:outputText value="#{domain.someText()}" />
</p:column>
<p:rowExpansion>
<!-- some that shows that #{domain.getSubdomains()} is NOT null when the recursion is removed -->
<p>#{domain} -> #{domain.getSubdomains()}</p>
<!-- The recursion -->
<efr:recursiveDomainsTable
domains_list="#{domain.getSubdomains()}"
/>
</p:rowExpansion>
</p:dataTable>
</cc:implementation>
And I simply get a StackOverflowError when I try to render this :
<efr:recursiveDomainsTable domains_list="#{domains_bean.domains}" />
Note that I tried to create a composite with a bean to see what's happening here :
#FacesComponent("recursiveDomainsTable")
public class RecursiveDomainsTableComposite extends UINamingContainer {
#lombok.Getter #lombok.Setter private List<?> domainsList;
#Override
public void setValueExpression(String name, ValueExpression expression) {
Log.debug("name="+name);
Log.debug("expression="+expression.getExpressionString() + " -> "+ expression.getValue(getFacesContext().getELContext()));
if ("domains_list".equals(name)) {
List<?> l = (List<?>) expression.getValue(getFacesContext().getELContext());
setDomainsList(l);
} else {
super.setValueExpression(name, expression);
}
}
}
And, when the StackOverflow is occuring, I have messages (in a loop) stating :
name=domains_list
expression=#{domain.getSubdomains()} -> null
So when I don't use the recursion, #{domain.getSubdomains()} is properly displayed, but when I use it the stackoverflows happens BEFORE the value is event interpreted.
Does someone knows what I did wrong ? Why can't JSF use the cc.domainsList value ?

CRM2011 subgrid button enable rule

I have 2 issues.
First issue: Trying to hide OOB button in subgrid(Ribbon), based on user role(by calling javascript). Is it possible?
Second issue: Hiding OOB button is not possible through "enablerule"javascript, so alternative I tried to disable button by using "enablerule"/javascript. Here is following code which reflects above. Still is NOT working, but for main form Ribbon button, the below code is working.
Can anyone please help me?
<Groups Id="Mscrm.SubGrid.quote.MainTab.Groups">
<Group Id="Mscrm.SubGrid.quote.MainTab.Management" Command="Mscrm.Enabled" Sequence="10" Title="$Resources:Ribbon.HomepageGrid.MainTab.Management" Description="$Resources:Ribbon.HomepageGrid.MainTab.Management" Image32by32Popup="/_imgs/ribbon/newrecord32.png" Template="Mscrm.Templates.Flexible2">
<Controls Id="Mscrm.SubGrid.quote.MainTab.Management.Controls">
<Button Id="Mscrm.SubGrid.quote.NewRecord" ToolTipTitle="$Resources(EntityDisplayName):Ribbon.SubGrid.MainTab.New" ToolTipDescription="$Resources(EntityDisplayName):Ribbon.Tooltip.New" Command="Mscrm.NewRecordFromGrid" Sequence="10" LabelText="$Resources(EntityDisplayName):Ribbon.SubGrid.MainTab.New" Image16by16="/_imgs/ribbon/NewRecord_16.png" Image32by32="/_imgs/ribbon/newrecord32.png" TemplateAlias="o1" />
<Button Id="Mscrm.SubGrid.quote.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" />
</Controls>
</Group>
<CommandDefinitions>
<CommandDefinition Id="Mscrm.AddNewRecordFromSubGridStandard">
<EnableRules>
<EnableRule Id="new.quote.EnableRule2.EnableRule" />
</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>
<EnableRule Id="new.quote.EnableRule2.EnableRule">
<CustomRule FunctionName="IsUserRoleAdmin" Library="$webresource:Quote_main_library.js" Default="false" InvertResult="true" />
</EnableRule>
//Javascript
function IsUserRoleAdmin()
{
var currentUserRoles = Xrm.Page.context.getUserRoles();
var isAdmin = false;
for (var i = 0; i < currentUserRoles.length; i++)
{
var userRole = currentUserRoles[i];
//check admin role
// if(userRole == "admin guid")
// {
// isAdmin = true;
// }
}
return isAdmin;
}
Yes you can hide or disable OOB buttons. This blog post provides some information.
Your js code is incorrect as Xrm.Page.context.getUserRoles() returns an array of GUIDs not the role names so isAdmin will always be false.
you can use Value Rule to Hide the Button on Ribbon..
to Disable you can use Custom Rule
check this link

Fex- Datagrid- custom header

I want to put a textinput box on the header of a datagrid in flex, whose values changes dynamically according to the no of data or value present in that perticular column.
Please any one help me, am posting the image acctually what I want.
Thanks in advance.
I'll assume you can use Spark DataGrid. In that case you just need to create a custom headerRenderer. To keep things simple we'll start from the default headerRenderer. In your Flex SDK sources, find the class spark.skins.spark.DefaultGridHeaderRenderer. Copy this file into your project and rename it appropriately.
Inside this class, find the components labelDisplayGroup and sortIndicatorGroup (they're at the bottom). They're inside an HGroup, so we can simply add our counter component in between.
<!-- I removed the original comments for brevity -->
<s:HGroup left="7" right="7" top="5" bottom="5" gap="2" verticalAlign="middle">
<s:Group id="labelDisplayGroup" width="100%" />
<!-- our counter component -->
<s:Label id="numRowsDisplay" />
<s:Group id="sortIndicatorGroup" includeInLayout="false" />
</s:HGroup>
So far for the visual component; now we have to update its text property appropriately. In the script block add the following snippet:
private var dp:IList;
override public function set owner(value:DisplayObjectContainer):void {
if (dp) dp.removeEventListener(CollectionEvent.COLLECTION_CHANGE, updateNumRows);
if (super.owner) super.owner.removeEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onPropertyChange);
super.owner = value;
dp = value ? DataGrid(value).dataProvider : null;
updateNumRows();
if (dp) dp.addEventListener(CollectionEvent.COLLECTION_CHANGE, updateNumRows);
if (value) value.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, onPropertyChange);
}
private function onPropertyChange(event:PropertyChangeEvent):void {
if (event.property == 'dataProvider') {
dp = event.newValue as IList;
updateNumRows();
}
}
private function updateNumRows(event:CollectionEvent=null):void {
numRowsDisplay.text = (dp ? dp.length : 0) + "";
}
What happens here? the owner property of the renderer refers to the data component that holds this renderer; in this case a DataGrid. So when the owner is assigned to the renderer, we access its dataProvider and use its length to update the counter component.
So what are those listeners for? There are two cases you might want to foresee.
The number of items in the dataprovider changes: that's why we listen on the dataprovider for CollectionChange events.
The entire dataProvider is changed or nullified: for this we listen for PropertyChangeEvents on the DataGrid and update the counter only when the 'dataProvider' property changes

How add a global "IsReadOnly" style to all DataGridTextColumns

I currently have a ResourceDictionary file for my WPF application, which pretty much adds every style that I could possibly want throughout all of my application's DataGrids.
Except one.
How can I add a global "IsReadOnly" setter, for all of my DataGrid's DataGridTextColumn columns ?
Basically, I use a few DataGrids, and if I want to display read-only data in a particular column, I'll just display the data using a DataGridTextColumn:
<WPFtoolkit:DataGridTextColumn Binding="{Binding Path=DOB,StringFormat='dd/MMM/yyyy'}" Header="DOB" Width="120" />
However, if I have a column which has editable data, then I'll use a DataGridTemplateColumn instead.
<WPFtoolkit:DataGridTemplateColumn xHeader="Department Name" >
<WPFtoolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Width="175"
ItemsSource="{Binding Source={StaticResource AllDepartmentsDataSource}}"
SelectedValue="{Binding DepartmentID}" SelectedValuePath="DepartmentID" DisplayMemberPath="DepartmentName"
VerticalAlignment="Center"
>
</ComboBox>
</DataTemplate>
</WPFtoolkit::DataGridTemplateColumn.CellTemplate>
</tWPFtoolkit:DataGridTemplateColumn>
The problem is, for every one of my DataGridTextColumns, I specifically need to add the IsReadOnly parameter, otherwise the user can (incorrectly) edit that data:
<WPFtoolkit:DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=DOB,StringFormat='dd/MMM/yyyy'}" Header="DOB" Width="120" />
Is there a way to add this "IsReadOnly" setting globally, in the ResourceDictionary file, to all of my DataGridTextColumns...?
I can add global styles to DataGrid, DataGridColumnHeader, DataGridRow, and DataGridCell, but if I try to define a style with a TargetType of DataGridTextColumn, then Visual Studio complains that DataGridTextColumn is not derived from a FrameworkElement or FrameworkContentElement.
<Style TargetType="{x:Type WPFToolkit:DataGridTextColumn}">
<Setter Property="IsReadOnly" Value="True"/>
</Style>
I can add IsReadOnly to the Grid style, but this makes all columns uneditable !
Can anyone think of an quick and easy way to add this simple property to the DataGridTextColumns ?
Update:
My solution has been (reluctantly) to add a Loaded handler to each of my DataGrids, which runs this code:
void grdGrid_Loaded(object sender, RoutedEventArgs e)
{
DataGrid dg = (DataGrid)sender;
foreach (DataGridColumn col in dg.Columns)
{
DataGridTextColumn textCol = col as DataGridTextColumn;
if (textCol != null)
{
textCol.IsReadOnly = true;
}
else
{
// This DataGridColumn isn't of type "DataGridTextColumn", so do nothing.
}
}
}
You could, of course, put this in your own DataGrid-inherited control, rather than repeating it for each of your DataGrids.
(Sigh.)
Why didn't MS make IsReadOnly an attachable property..? It would've made life so much easier!

detect change in Flex Form elements (textinput, textarea, combobox, checkbox..)

I have various (read lots of..) flex forms in my app, and I now want to create a system by which the user is notified that he hasn't saved if he modifies anything in the form...
now.. I don't want to rewrite every form I have.. is there some nice way to implement this?
Extending the TextInput (and others..) classes somehow?
thanks
This is not really thought through but should work.
You could create a custom component, let's call it FormWatcher which you would than put next to your Form. What the form watcher would do is wait for the CreationComplete event from the form.
So now, as we have the Form ready you can use the getChildren() method of the form to get all the FormItems in it. Than look inside each of them, and you will get TextInputs, Comboboxes, etc. to which you can add event listeners (as individual components), eg.
// THIS IS WHERE THE COMPONENT SHOULD START
protected function changeHandler(event:Event):void
{
trace ("something is dirty");
}
protected function startWatching(passTheFormHere:Form):void
{
for each (var O:Object in passTheFormHere.getChildren())
{
if (O is FormItem)
{
// Let's assume you only have a single child in one FormItem
// and always one child for simplicity
addChangeHandlerFor((O as FormItem).getChildAt(0));
}
}
}
protected function addChangeHandlerFor(someComponent:Object):void
{
// Most regular flex components send a Event.CHANGE event
// when their value is changing
// keep in mind you should check stuff, this is a simple example
(someComponent).addEventListener(Event.CHANGE,changeHandler);
}
// THIS IS WHERE THE COMPONENT SHOULD END
Just paste this code next to some form, and call the startWatching(nameOfYourForm), you should see the changeHandler is being called.
A few more notes:
1) You should clean up the event listeners once you're done.
2) I would create a component out of it so that you would use it like this:
<mx:Form id="form1" >
[...]
</mx:Form>
<FormWatcher form="{form1}" />
Where FormWatcher would have a Boolean var called "clean" or something.
3) The example is very simple, so it will only work for forms similiar to this one:
<mx:Form id="myForm" >
<mx:FormItem>
<mx:TextInput id="someComponent1" />
</mx:FormItem>
<mx:FormItem>
<mx:CheckBox id="someComponent2" />
</mx:FormItem>
<mx:FormItem>
<mx:TextArea id="someComponent3" />
</mx:FormItem>
</mx:Form>
You could go into the TextInput class (and others) and add that event listener and function, but then you would be changing the SDK itself, which is kind of a bad idea. I would create custom classes extending the ones your using and do a find/replace to make it faster.

Resources