In this article I will cover how we can enable and disable the controls from ribbon based on any specific column value. For an instance I have a list column "State", if selected row is having status "active" then and then button should be enable in Ribbon, otherwise ribbon button should remain disable.
For how to write Ribbon declaration please refer my previous articles.
In above image you can see we have one button "New" in ribbon within group "Console". Please refer the source code for Ribbon's declaration. We are going to use delegate control for injecting ECMA script on fly for desired list.
Below are the events causes ribbons to refresh so button can be turned enable/disable.
- Checkbox from every row
- SelectAll/DeselectAll checkbox from header row
- On every row select
On each of above events after executing their respective functionality they instruct the ribbon to refresh. On received of refresh event ribbon calls Enable script for each of its control. Enable Script is the attribute which points to JavaScript function which can contain the logic for deciding button to be enabled or disable. You can mention the JavaScript function name to Enable Script attribute while declaring the Ribbon XML element.
Now let's see how sample is going to work.
- On page loads and when no row is selected button will be disable
- When user clicks checkbox of row and that row is having "Active" as status value then button will get enable
- When user clicks row and that row is having "Active" as status value then button will get enable
- If row is selected and button is enable and user click select all checkbox then ribbon will get refresh and button will be disable
So to achieve required functionality what we need is,
- A function which will return a Boolean flag for ribbon to enable/disable button
- We need to attach our own events on row click, row checkbox click and header checkbox click
- So in our own functions we will retrieve the row and it's all cell values
- Based on status cell value we will set the global flag true/false.
- Then we will call Ribbon refresh, which eventually will enable/disable the button
Let's see how we can attach our own functions to various click events,
This is one of the core functions from this implementation. The final HTML of any ListViewWebPart is table and its id is always in the form of {ListGuid}-{WebPartGuid}. So this function retrieves all Html tables from the page and hooks the exact table based on ListGuid. To compare Table id for list GUID we know in advance the list GUID.
How we can do that?
Buy looking into current context. Whenever page gets rendered current SPContext gets injected into page. That can be desterilize into JavaScript object by calling
GetCurrentCtx() function. You can find this function in
Core.js file. The context is having all information like current list, web application information, selected row items and so on. You can inspect contains of context by doing client side debugging. [Debugging through IE and Visual Studio is the handiest approach for this]
Finally once you get the exact table then iterate through all its row and cell and attach the click events of Checkbox on each row, row and Checkbox of header row. So now we have function
rowClicked for every row select, function
rowCbxClicked for every checkbox of each row and
selectAllClicked for header row's checkbox.
In
selectAllClicked() function we are setting _isButtonEnable to false because whenever Select/Deselect all checkbox gets clicked we want our button should be disable. One we done with this we will call
RefreshCommandUI(), this function again an intrinsic function from Microsoft's Js file suite. You can find this function in
Core.Js file. This function causes Ribbon to refresh herself, so eventually all EnableScript functions of ribbon buttons get called and hence our
isButtonEnablefn gets called. Which just return the _isButtonEnable. Since we have set this variables value to false our button gets disable.
Now you have got an idea how to enable and disable ribbon button.
J It's really fun to work with Ribbon.
Now let's see what we will do in
rowClicked & rowCbxClicked ,
- First retrieve the element that causes the event.
- Then check whether that element contains any link by calling another intrinsic function ElementContainsLink(). If that element contains the link it means you have select the cell value which is having Hyperlink so we shouldn't do anything just allow Hyperlink to do its own work so we will return from that point.
- Then we will close the ECB menu if that is open on any of earlier action.
- Then we will call again an intrinsic function GetItemRow() to get item row which causes this event. We need this row for our other calculations Why? We will see that in our next steps.
- Now time to get current context, so we will call an intrinsic function CtxFromRow(), which will return us the current client context.
- As I told you earlier this client context keeps all information about current spcontext. Along with that it also keeps the information about selected rows. context.dictSel is the
array which holds all selected row item information. There are two intrinsic functions CountSelectedItems & GetSelectedItemsDict which return the selected item count and selected items respectively.
- At this point we have row which cause the event and selected item count. So if selected count is 1, then and then we will check the row's State value if that is "Active" then we will set the _isButtonEnable flag to true else we will set it to false.
- Now we will call RefreshCommandUI() which will fire the ribbon refresh event that causes to each ribbon button to fire their own EnableScript function. In our case that one is isButtonEnablefn.
- As we have set the flag true or false based on our business logic. The button will get enable or disable based upon the value of _isButtonEnable flag.
- All intrinsic functions I have used in this method you will find that into Core.JS file.
Note: Please create a custom list, add choice column with "Active" & "Cancel" values as i have shown in image above. So you can play with sample.
I hope this will help you.
Download: Source Code
Further Articles:
I am going to explore more with ribbon and going to post all my findings with source code. So keep a track of below articles.