Blog

You are browsing the archive for MOSS Help.

Using Google Search Appliance on Your SharePoint Site

March 12, 2010

Adding a Google search to a web page is pretty simple. Just drop in the search form code. Something like this:

<form id="search-form" method="get" action=http://search.yoursitehere.com/search>
        <input type="text" name="q" size="25" maxlength="255" value=""/>
        <input type="submit" id="search-submit" name="btnG" value="Search"/>
        <input type="hidden" name="site" value="default_collection"/>
        <input type="hidden" name="client" value="default_frontend"/>
        <input type="hidden" name="proxystylesheet" value="default_frontend"/>
        <input type="hidden" name="output" value="xml_no_dtd"/>
</form>

The fact that the search code is in a form tag is a problem. Basically the entire body of your SharePoint page is in an ASP .NET form and you cannot have nested form tags as the inner <form> will not be processed. Some have tested ways of nesting form tags but it is pretty messy and not consistent across browsers.

I found this post that addressed the issue and his code was a great starting place. In fact it worked great on my virtual machine but was giving me issues on the production site. The problem turned out to be the code that was specifying the background image for the search box. A white background was preferred anyway so the code was simplified a bit to the following:

<div>
    <input id="q" type="text" size="25" style="border: solid 1px #999999" onkeydown="searchkeydown();" />
    <button onclick="googlesearch();return false;">Search</button>
</div>
<script type="text/javascript">
     searchkeydown = function() {
         if (window.event) {
             key = window.event.keyCode;     //IE
         }
         else {
            key = e.which;     //firefox
         }
         if (key == 13) {
            event.returnValue = false;
             event.cancel = true;
             googlesearch();
         }
     }
    googlesearch = function() {
    window.location=’http://search.yoursitehere.com/search?q=’ + escape(document.getElementById(’q').value);
      }
</script>

That should get your Google Appliance (CSE) working in your SharePoint site.

Use Multiple Selection Columns in Calculated Fields

February 22, 2010

I recently had a need to create a hyperlink in a custom list and the hyperlink needed to contain parameters that came from a Choice type column that allowed multiple selections. I’m very comfortable using Excel’s string functions (LEFT, RIGHT, MID, LEN, and FIND) to parse strings and I’ve done so many times. However, when I tried to write a formula using the Multiple Selection field, I got an error that said, “One or more column references are not allowed, because the columns are defined as a data type that is not supported in formulas.” Rats! I thought that we might need to write an event receiver with Visual Studio to accomplish my task, but I really wanted to find a way to do it without writing any code. Here is what I did to solve the problem.

The Problem

In this particular scenario, a department stores information about events in a custom list. There may be one or two people from the department who attend the event. The names of these employees are stored in a column of type Choice that has been set to display as Checkboxes (allow multiple selections).

They use a web based program as part of managing the event. Information about the event is passed to web application as variables in the URL. Two of those parameters are the employees who are attending the event. They want SharePoint to automatically create the URL and modify it if the item changes.

Here is a simplified example of what they want to see in their SharePoint list:
image

The Solution

This customer is using our Workflow Essentials product that adds 24 more activities to SharePoint Designer workflows. I decided to make use of two of the Text Capture activity to extract the parts of the string I needed (if you are interested, you can watch a short video on how the Text Capture, Text Replace, and Text Validate actions work).

The Text actions in Workflow Essentials use Regular Expressions to look for values within text (a great place to learn more about Regular Expressions is: http://www.regular-expressions.info/).

When a column is set to allow multiple items to be selected, SharePoint stores them in a plain text format with the items separated by semicolons; you can see this in the example above.

The first Regular Expression I wrote extracted the first word in the My Persons string. The That regular expression is: ^\b[A-Za-z]+\b
The second Regular Expression I wrote extracted the second word in the My Persons string. That regular expression is: \b[A-Za-z]+\b$

Note that regular expressions don’t actually extract anything, but rather returns the part of the original string that matches the given regular expression. These two expressions worked in my case because my strings consisted of single words that consisted only of singe letters and there was a maximum of two words total. If my string had different qualities, I would have to have written totally different regular expressions to match my particular criteria. Writing Regular Expressions is a very valuable, and often under valued, job skill. I’m not an expert at it so I won’t likely be a good source for writing a regular expression for your particular case. Sorry.

Once I had written my Regular Expressions, I was ready to create my solution. I launched SharePoint Designer and created a new workflow on my list that would run when a new item was added or when an item changed.

I added the Text Capture activity first, used my first Regular Expression as pattern and output the captured text to a variable named FirstChoice. Then I added another Text Capture activity where I used my second Regular Expression and captured the matched text to a variable named SecondChoice. Next I added a Build Dynamic String activity where I composed the URL and inserted the two variables in the appropriate place for the URL parameters. Finally, I added a Set Field in Current Item activity where I set the My URL field to the string I had just created. Here is the entire workflow.
image

As you can tell, Workflow Essentials is a powerful product that can greatly increase the power of your SharePoint Designer workflows. Check it out!

InfoPath Form with Multiple, Dynamic Approvers

February 19, 2010

A question came in to the MOSS Help and How To forum about creating a form that allowed multiple approvers to be specified at the time the form is being filled out.

I went ahead and created a form in InfoPath and a simple workflow in SharePoint Designer to allow the selection of the approvers and assign tasks for the approvers. It is a simple form and workflow both. For production you would want a more robust solution. If you have ideas for a better solution, please let me know in the comments.

Instead of writing out all of the steps I created this short video to demonstrate how the form, workflow, and SharePoint library work.

MOSSHelpPlay

Hiding SharePoint List Action Menu Items

February 12, 2010

A question came up about how to go about hiding list action menu items on SharePoint lists. There were some actions that either didn’t make sense for their extranet users or they didn’t want to support.

For example they would like to hide the “Edit in Datasheet” and “Alert Me” buttons.

image

A number of people have posted different types of solutions. Some requiring development, some recommending editing core.js, but the solution I liked the best was a bit of Java Script that could be deployed for a single list with a content editor web part or called from a master page if the desired results were more global.

The script was written by Ayman El-Hattab and posted on his blog. When I first deployed it in a CEWP it wasn’t working. I suspected that it was not running last and therefore not overriding the script used to create the links. Talking with Ricky Spears confirmed this. He had run into the same thing when trying to add JavaScript in SharePoint pages. SharePoint has a list of JavaScripts that fire after the page loads. He showed me how to add our script to the end of that list. More info on adding JavaScript can be found in this post.

Here’s how we get ours to load last:

// Our script needs to run last
_spBodyOnLoadFunctionNames.push("hideListActions");

function hideListActions() {

// Add menu items by name, separated by commas
hideListViewToolbarItems("Edit in Datasheet", "Alert Me"); 

}

 Here is the entire script:

// Our script needs to run last
_spBodyOnLoadFunctionNames.push("hideListActions");

function hideListActions() {

// Add menu items by name, separated by commas
hideListViewToolbarItems("Edit in Datasheet", "Alert Me"); 

}
function hideListViewToolbarItems() 

    /// <summary> 
    /// By : Ayman M. El-Hattab ( ayman.elhattab@gmail.com ) 
    /// http://ayman-elhattab.blogspot.com
    /// </summary> 
    var menuItem;    
    var menuItemName; 
    var menuItemIndex=-1; 
    var menuItemNames=new Array("edit in datasheet","open with windows explorer", "connect to outlook",’export to spreadsheet’,'view rss feed’,'alert me’,"create column","settings:create view","list settings", "document library settings","explorer view","all documents","all items","modify this view","view:create view","new document","new item","new folder","upload document","upload multiple documents"); 
    var menuItems = new Array("EditInGridButton","OpenInExplorer","OfflineButton","ExportToSpreadsheet","ViewRSS","SubscribeButton","AddColumn","AddView","ListSettings","ListSettings","View1","DefaultView","DefaultView","ModifyView","CreateView","New0","New0","NewFolder","Upload","MultipleUpload"); 
    var allMenuItems = document.getElementsByTagName(’ie:menuitem’); 
    for(var i = 0; i < hideListViewToolbarItems.arguments.length; i++ )  
    {                                
        menuItemName= hideListViewToolbarItems.arguments[i].toLowerCase(); 
        for (j=0; j < menuItemNames.length; j++)  
        { 
            if(menuItemNames[j]==menuItemName) 
            {                
                menuItemIndex = j; 
                break; 
            } 
        } 
        menuItem=menuItems[menuItemIndex]; 
        for (var l = 0; l < allMenuItems.length; l++) 
        {        
            if(menuItemName.indexOf(":")!=-1) 
            { 
                menuItemName = menuItemName.split(":")[1]; 
            } 
            if (allMenuItems[l].id.indexOf(menuItem)!=-1 && allMenuItems[l].text.toLowerCase() == menuItemName) 
            {        
                // For FireFox Compatibility 
                var parentNodeOfMenuItem = allMenuItems[l].parentNode; 
                parentNodeOfMenuItem.removeChild(allMenuItems[l]); 
                break; 
            } 
        } 
    } 
}

Here is the resulting list actions menu:

image

Thanks Ayman for a nice script and thank you Ricky for your help too!

I am sure there are other good ways to accomplish this. Please share them in the comments.

Use SharePoint Lists to Create a Filtered Drop Down in InfoPath 2007

January 27, 2010

While teaching our online class on InfoPath and SharePoint Designer Workflows (Essentials of InfoPath and SharePoint Workflows), I was asked about using SharePoint list data to populate InfoPath drop-down list controls and filtering a list control based on the selection of another drop-down.

Goal: To create an InfoPath form that includes two drop down lists populated from an external source (SharePoint lists) with the result of the first list selection filtering the second.

Scenario: Adventure Works has four types of bikes that they manufacturer:

· BMX
· Mountain
· Racing
· Touring

They have many bike models for each type of bike (Mountain bikes for example are comprised of the following: MX-100, MX-200, MX-220, MX-300, etc.)

Customer service has a form to track issues from customers. They need to select the model from a list but would like to be able to filter the list of bike models based on the type of bike.

Overview of the steps

In SharePoint:

Create a custom list to maintain the bike types
Create a custom list to maintain the current bike models (with a lookup to the Bike Types list)

In InfoPath:

Create a form
Add a drop down list control and connect it to the bike types list
Add a list (or drop down list) control and connect it to the Bike Models list
Set a filter to filter the models based on the selection from the first control

Detailed directions

1. At the top-level site in the site collection (portal.awbikes.local in the classroom environment) create a custom list named BikeTypes

2. Change the ‘Title’ column name to ‘BikeType’

3. Add the following four items to the list: BMX, Mountain, Racing, Touring

clip_image002

4. Create another custom list named ‘BikeModels’

5. Rename the ‘Title’ column ‘ModelNumber’

6. Add a lookup column named BikeType and lookup to the Biketypes list, BikeType column

7. Populate the list with a number of model numbers and choose a type for each
clip_image004

8. In InfoPath, design a new form using a blank template

9. In the Layout task pane add a Table with Title then add a two-column table in the body

10. Resize the rows and columns and hit the tab key a few times to create more rows in the two-column table as follows:
clip_image006

This list will contain many fields including date, customer contact info, issue type, issue description, etc. We are only going to work with the bike type and model fields here.

11. Switch to the Data Source task pane and rename the ‘myFields’ group to CustomerService

12. Under Actions, click Add a Field or Group and add a Text type Field named BikeType
clip_image008

13. Add another text field named BikeModel
clip_image010

14. Drag the two fields into the form
clip_image012

15. Right-click the BikeType control and change to a Drop-Down List Box
clip_image014

16. Right-click the BikeModel control and change to a List Box

17. Double-click the BikeType control and under the section titled List box entries, select the radio button for ‘Look up values from an external data source’ and click Add
clip_image016

18. Select Create a new connection to: and Receive data, Next

19. Select SharePoint library or list, Next

20. Enter the URL of your site where you created the custom lists above (in class, http://portal.awbikes.local), Next

21. Choose the BikeTypes list, Next

22. Select the BikeType field, Next

23. Select ‘Store a copy of the data…’, Next

24. Enter a name for the connection, BikeTypes, select the ‘Automatically retrieve data…’, Finish

25. Click the XPath button for Entries
clip_image018

26. Expand the folders and select BikeType, OK, OK again to finish
clip_image020

27. Preview the form to test the connection to the Bike Types list
clip_image022

28. Close the preview and double-click the BikeModel list control and under the section titled List box entries, select the radio button for ‘Look up values from an external data source’ and click Add

29. Select Create a new connection to: and Receive data, Next

30. Select SharePoint library or list, Next

31. Enter the URL of your site where you created the custom lists above (in class, http://portal.awbikes.local), Next

32. Choose the BikeModels list, Next

33. Select both the ModelNumber and BikeType fields, Next
(you will just display the ModelNumber but you will use the type in the filter below)

clip_image024

34. Select ‘Store a copy of the data…’, Next

35. Enter a name for the connection, BikeModels, select the ‘Automatically retrieve data…’, Finish

36. Click the XPath button for Entries

37. Expand the folders and select ModelNumber, click Filter Data
clip_image026

38. Click Add

39. Set the filter to BikeType, is equal to, Select a field or group…

clip_image028

40. On the Data Source drop-down, select Main, Bike Type, OK, OK, OK, OK, OK already!
clip_image030

41. Preview the form to test the filtering
clip_image032

You can create the filtering using only one list (just BikeModels) by selecting the Show only entries with unique names option. For very large lists this may impact performance.

Happy filtering!