Ok, so this is really a follow up to my previous post where I outlined how to build jQuery Tabs that Open and Close. I did end that post with a small TODO for myself: integrate the close capability into the tab itself so the user didn’t have to click a button to close that tab.

Now after doing a bit of digging, I learned that this is actually functionality that is in the works for future releases of jQuery UI. Ticket 3924 is currently open and in development, which is a good sign. Further investigation landed me on this page: http://jsbin.com/uqage which is a fantastic example of how the Closable Tabs concept could work.

My final solution involved me tweaking the above to work as follows:

Setting Up the HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="mytabs"> 
   <ul>
      <li><a href="#tabs-home">My Projects Home</a></li>
   </ul>
   <div id="tabs-home">
      <h3>Welcome to My Projects Home</h3>
      <p><a href="#" onclick="addTab('myActiveProjects', 'My Active Projects', 'RadGrid1')">My Active Projects</a></p>
      <p><a href="#" onclick="addTab('mySalesActivities', 'My Sales Activities', 'RadGrid2')">My Sales Activities</a></p>
   </div>
</div>
<div id="tabs-myActiveProjects" style="display:none;">
<h3>My Active Projects</h3>
 
</div>
<div id="tabs-mySalesActivities" style="display:none;">
<h3>My Sales Activities</h3>
 
</div>

Wiring Up the Javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$(document).ready(init);
 
function init() {
 
    // tabs init with a custom tab template and an "add" callback filling in the content
    var $tabs = $("#mytabs").tabs({
        tabTemplate: '<li><a href="#{href}">#{label}</a> <span class="ui-test"><img src="images/cross.png" /></span></li>'
    });
 
    // close icon: removing the tab on click
    // note: closable tabs gonna be an option in the future - see http://dev.jqueryui.com/ticket/3924
    $('#mytabs span.ui-test').live('click', function() {
        var index = $('li',$tabs).index($(this).parent());
        $('#mytabs span.ui-test').parent().remove();
        $("#mytabs").tabs('select', 0);
    });
}
 
function addTab(tabID, tabName, grid) 
{
    // double check to see if tab is already open
    if($("a[href^=#tabs-"+ tabID +"]").length > 0)
    {
        $("a[href^=#tabs-"+ tabID +"]").parent().show();
    } else {
        currentTabID = tabID;
 
        // this will add a tab via the standard method
        $("#mytabs").tabs("add","#tabs-" + tabID,tabName);
        $("#tabs-" + tabID).css("display","block");
    }
 
    $("#mytabs").tabs('select', tabID);
}

Finalizing the Styles

1
2
3
4
5
6
7
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery-ui-1.7.2.custom.min.js"></script>
<link type="text/css" href="styles/smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
<style type="text/css">
    #mytabs { margin-top: 1em; }
    #mytabs li .ui-test { float: left; margin: 0.5em 0.4em 0 0; cursor: pointer; }
</style>

Please, please leave a comment if you have any difficulty with this and I’ll do my best to help!

Tagged with:  

Building jQuery Tabs That Open & Close

On October 27, 2009, in ASP.NET, SharePoint 2007, by shereen

jQuery is obviously a really powerful tool. If you’ve done any work with it, you don’t need convincing. My latest project involving jQuery was a bit tricky because I couldn’t find anything that detailed how to generate a tab once a user clicked on a link, and then how to close that tab if the user clicked the close button. Here is my setup:

  1. I needed to create a page with some static links, that when clicked on would spawn a new tab.
  2. The content area for each tab would contain a Close button that would remove the tab and hide the div contents. I didn’t want the div contents removed because I wanted users to be able to open the tabs again if they wanted to.

NOTE: I did attempt to dynamically generate the div contents by using a jQuery append statement on the content divs, but I ran into issues with this when placing a Telerik RadGrid onto the page and had to abandon that approach.

Building the above with the jQuery UI Tabs library took me part of the way there. In the end, my solution looks as follows:

Building the UI Tabs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id="mytabs"> 
   <ul>
      <li><a href="#tabs-home">My Projects Home</a></li>
   </ul>
   <div id="tabs-home">
      <h3>Welcome to My Projects Home</h3>
      <p><a href="#" onclick="showTab('myActiveProjects', 'My Active Projects')">My Active Projects</a></p>
      <p><a href="#" onclick="showTab('mySalesActivities', 'My Sales Activities')">My Sales Activities</a></p>
   </div>
</div>
<div id="tabs-myActiveProjects" style="display:none;">
    <h3>My Active Projects</h3>
    <p><input type="button" name="killTab" value="Close" onclick="hideTab('myActiveProjects')" /></p>
</div>
<div id="tabs-mySalesActivities" style="display:none;">
    <h3>My Sales Activities</h3>
    <p><input type="button" name="killTab" value="Close" onclick="hideTab('mySalesActivities')" /></p>
</div>

Wiring Up The Javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function init()
{
    $("#mytabs").tabs();
}
 
function showTab(tabID, tabName)
{
    currentTabID = tabID;
 
    // this will add a tab via the standard method
    $("#mytabs").tabs("add","#tabs-" + tabID, tabName);
    $("#tabs-" + tabID).css("display","block");
 
    $("#mytabs").tabs('select', tabID);
}
 
function hideTab(tabID) 
{
    $("#tabs-" + tabID).css("display","none");
    $("a[href^=#tabs-"+ tabID +"]").parent().remove();
    $("#mytabs").tabs('select', 0);
}
 
$(document).ready(init);

Don’t forget to include the jQuery UI JS file and the corresponding CSS. You’ll also need to include the jQuery JS file as well. If you have any troubles with this, drop me a note.

1
2
3
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery-ui-1.7.2.custom.min.js"></script>
<link type="text/css" href="styles/smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" />

My next step with the above is to relocate the Close button so that it is an ‘X’ image on the tab itself that when clicked on would close the tab. I’ll update once I figure that out! Good times!

Tagged with:  

SharePoint 2010 Keynote Overview

On October 19, 2009, in SharePoint 2007, by shereen

Hi all, I wanted to put together a summary of some of the things I felt were worthy of noting at this mornings SharePoint Conference 2009 Keynote. Not all of these may be 100% accurate, I did my best to jot things down as they were thrown out there. Any questions or comments, feel free to ping me.

General

  1. No more hand coding web parts, Visual Studio 2010 now has a visual interface for developing web parts
  2. SharePoint navigation is integrated into Visual Studio, so you don’t have to leave VS to browse the contents of your SharePoint site
  3. You can now map folders in Visual Studio to SharePoint so when you deploy, for example, a image library, the files on the file system are transferred into SharePoint for you
  4. One click deploy and debug, it’s no longer a ’10′ click process
  5. New Developer Dashboard that loads on the page so you can debug your solution and review performance factors — You have to run an stsadm command to enable the dashboard, otherwise you won’t see it
  6. Line of Business systems are greatly improved and the connectivity is a lot easier to implement
  7. Built in spell check for draft items
  8. SharePoint Designer 2010 and Visual Studio 2010 will NOT work with SharePoint 2007
  9. 1,000,000 items to a list or folder, the 2,000 item limit is dead
  10. New Technologies: Microsoft PowerPivot for Excel and PowerPivot for SharePoint
  11. New Ribbon interface is context sensitive
  12. Changes, such as page edits, preview live as you make them
  13. NO MORE PAGE REFRESHES!!
  14. Document Sets is a new concept that is being introduced
  15. All Office desktop apps now have a web version. SharePoint item context menu has a new link called View In Browser that opens files in the web version of desktop app
  16. 2010 is 64 bit only, it will not support anything else

New SharePoint Terminology

  1. SharePoint Foundation – replacement for WSS 4.0
  2. SharePoint Server
  3. FAST SharePoint Search
  4. SharePoint for Internet Sites, Standard Edition
  5. SharePoint for Internet Sites, Enterprise Edition
  6. SharePoint ’12′ hive is now ’14′ hive, but referred to as SharePoint Root

Great first day, looking forward to tomorrow! I spent an hour or so working with the hands on labs and I have to say this new version is pretty darn exciting!

 

Live Blogger Stream SharePoint Conf 2009

On October 16, 2009, in SharePoint 2007, by shereen

Hey everyone! I’ll be headed down to SharePoint Conf on Sunday, very excited to finally get my feet wet with SP 2010. I’ll be contributing to the live blogger stream that Mark Miller has setup over at EndUserSharePoint.com so keep an eye out for content being posted there. The keynote sessions will also be broadcast live, so for those not able to attend this year, that’ll be something to check out.

Live Blogger Stream from SharePoint Conf 2009 – I’ll be a contributor!

Live Twitter Stream from SharePoint Conf 2009

 

If you’re working in a dev environment and you’ve implemented something like this to your web.config, then you’ll notice some odd behavior relating to survey responses.

If your surveys are set to allow only one response per user, and your web.config CallStack property is set to true, just be aware that you’ll encounter the standard ASP.NET server error:

Screen shot 2009-10-14 at 6.45.07 PM

Server Error in ‘/’ Application error: You are not allowed to respond again to this survey.

It’s just a bit uglier for users to see something like the above instead of the standard SharePoint error page. Just something to watch out for. Regardless, it’s probably  not a good idea to have CallStack set to true in your production environments.

Screen shot 2009-10-14 at 6.45.20 PM

 

Very excited to be a part of this and can’t wait for the conference next week!

EUSP-LiveBlogger



 

So this particular error seems to be quite common, based on posts I’ve read here and here. If you’ve built a SharePoint Designer workflow and utilized the Update List Item activity, you may have run into a workflow error that logs an Outcome of:

List Item Not Found

For this particular scenario, here was my setup:

  1. I have two lists: Survey and Customers
  2. Survey has a custom column called Customer that is of type Lookup. This column is configured to lookup on the Title column in Customers
  3. My custom SD workflow has a single activity, the Update List Item activity, configured to update the Customers list, on the Survey Status column, and the criteria for determining what item to update is based on the Customer lookup in the Survey list

Pretty straight forward stuff. I’ve done this a thousand times before and it’s worked without issue. However, I ran into a specific list where the workflow would error every single time, with the List Item Not Found message. Unfortunately, it’s very difficult to get any information other than what’s in the workflow history log. I attempted to read through the operations logs as well, but the information wasn’t really too helpful.

Doing some basic troubleshooting by adding an email activity and outputting the lookup variables in the body helped me determine that the Customer column in the Survey list was returning a blank value. That’s strange. Adding, editing and displaying items in the Customer list gives me no issue, I can select customers from my lookup and they read just fine. So why the heck does my workflow not properly record this value?

It gets a bit more puzzling when I grant myself Site Collection Administrator access to my site. Now all of a sudden, the workflow works and the lookup executes without issue. My entry in the Customers list is updated, all is happy for once. But granting users Site Collection Administration access is not a viable solution. It’s actually pretty crazy, so that’s not going to happen.

So after much frustration, I am sorry to report I don’t have much new information. What I did attempt to do however, was build my own version of the Update List Item activity in Visual Studio 2008. That turned out to be relatively straight forward. I used a bit of reflector to get the bits that I needed to successfully write this. That gave me the debugging capabilities that I desperately needed.

What I was now able to see with my custom activity was that the ListItem property was returning -1, and thus the GetItemById call on the Customers list was unable to find the item. Now why in the world was it returning -1? I’m still puzzled by this, and I’m not 100% sure if this is indeed a permissions related problem or if it’s something a entirely different.

I’m opening this up to anyone out there who might have some information regarding this particular issue. In the end, I wrote a custom Visual Studio sequential workflow, with literally 5 or so lines of code that essentially does the update for me and that runs without issue. I didn’t want to have to do that, but it was the only option I was left with for this particular list.

If anyone has any info, please drop me a line @ shereen at qumsieh dot ca. I would LOVE to get to the bottom of this.

Tagged with:  

Ran into an issue today with a custom SharePoint Designer workflow activity that I was building. Just to understand the background on this, the steps for deploying a custom activity are:

  1. Deploy dll to the GAC
  2. Drop your .ACTIONS file into the 12 hive TEMPLATE\Workflow\ folder
  3. Add an authorizedType entry into the web.config: <authorizedType Assembly=”CustomActivity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=07715169a6d99f74″ Namespace=”CustomActivity” TypeName=”*” Authorized=”True” />

After deploying my activity, I attempted to build a workflow utilizing this new functionality and was receiving the following error upon clicking FINISH:

Unexpected Error on Server Associating the Workflow

It’s also important to note that this error was occurring for ALL types of activities, including the ones that were out of the box. So what the heck had I done that was affecting all activities like this? Turns out there was a reference to an older authorizedType from a custom activity we had written that no longer existed in the Workflow folder. By simply removing this authorizedType from the web.config, everything was happy again.

So my advice? Make sure that whatever you’ve got configured under authorizedTypes in your web.config actually exists, otherwise you may encounter this issue.