Link to media files on file server

Hi everyone!

I had a client a little while ago that had this requirement.

  • In a list it should be as simple as possible for the users to add a link to a media file that is located on a file server.
  • They did have a mapped net work drive and they were only connected to their Intranet while at office or through VPN.
  • The installation is a SharePoint Foundation

My first thought was to add a default value to a URL column so that they only had to add the last part, but that was not possible.

Then I tried to add the default value to a text column and that worked if it was an http-link but not a file-link.

My friend jQuery came to rescue and offered me a solution that came to be like this.

The idea is that the user, besides adding a few other things in this form, only should have to add the file name and file type e.g. “MyMovie.mov” in a field to build a link to the file on the server.

Ok, so I found a snippet of a JavaScript (I can’t remember where, sorry) that should be added to an aspx-file and when called, would open up a folder on a shared drive. And that my friends was almost what I was looking for, now I only needed to add the functionality to pick up a parameter and open a file in that folder instead.

First I added a new column “MediaLink” of the type URL. This column should be set to be hidden in the forms, but do that a little bit later.

Then I added a new column “MediaFile” of the type Text with a description of what they should be adding, name and type.

By adding this jQuery code to the edit and new forms, the URL to the JavaScript snippet file, and the value of the “MediaFile” is added to “MediaLink”. At the same time it checks if “MediaFile” is empty, if it is it won’t add the text “Link to media” in the column for that item.

<script type="text/javascript">
$(document).ready(function() {
$('input[title=MediaFile]').change(function() {
var value = $(this).val();
$('input[title=MediaLink]').attr({value: 'http://companyweb/SiteName/SitePages/media.aspx?fileName='+(value)});
if ($(value).length < 1){
$('input[name*="ff81$ctl00$ctl00$UrlFieldDescription"]').attr({value: 'Link to media'});
}
});
});
</script>

Be sure to change the URL to media.aspx if you will put it somewhere else. The last part of the attribute “name” you could find by viewing the source of the page, that is before you hide it of course 🙂

Ok so what about that JavaScript snippet, what should we do with that and where is it?

As you can see in the code above I add the parameter “fileName” to the URL of the “media.aspx“. This is the file that should have this snippet that I have been talking so much about 🙂

It looks like this.

<html>
 <body>
  <script type="text/javascript">
//Get querystring
var queryString = window.location.href.split("?")[1];
    var fileName = queryString.split("=")[1];
    // mapped network drive
    var drive = "file://Server/share"
    // folder within the mapped network drive
var folder = "/Folder1/Folder2/Folder3"

    window.open(drive + folder + fileName, "File");
    history.back();
  </script>
 </body>
</html>

So, simply add this code to a file called “media.aspx” and put the file in “SitePages”. Be sure to change the variables “drive” and “folder” so that they fit your environment.

I had a talk to Marc D Anderson about this and he gave me a few ideas that I will try to improve this further. When I have, I will update this post with these improvements.

I hope this will help someone!

CU in Vegas in a couple of weeks!


What to do with trailing zeros from SharePoint

Hi everyone!

It’s been a long time since the last post, but sometimes one has to take care of things like the family. Ok, so now when that is done we could start having some fun again 🙂

I would like to start with a small and quick one.

Let’s say you have a drop down (field2) in your form that lists objects from a list in SharePoint. The list has got two columns, Title and Number.

The value for the drop down is set to Number and the Display name is set to Title.

Then you need to set another field (field3) in your form to the value of the chosen object,.

Set the Value of field3 to be same as field2

that’s when you will see that the number of the object will have lots of trailing zeros.

An easy way to get rid of these zeros is to insert a formula in front of the field2 value of sum.

this way the zeros will be gone.

Happy InfoPathing!

CU!

/SPNIAX


Working with Lookup columns in SharePoint list forms with InfoPath

Hi everyone!

I would like to show you how to work with lookup columns between lists when you i.eg. would like to summarize the amount of orders that a sales person have made.

So we have a list called “Sales persons” with five columns, “Name”, “Region”, “Office”, “Sales ID” and “TotalAmount”.

We also have a list called “Sales orders” with three columns, “Product”, “Amount” and “Sales ID”.

In this list the column “Sales ID” is a lookup column to “Sales ID” in “Sales person”.

We also have a data connection to retrieve these three fields from “Sales orders”.

When we open a form for a sales person we want to see the total amount of orders that’s been made by that person. When we first look at this it looks quite simple. The “TotalAmount” should be the sum of “Amount” where “Sales ID” equals “Sales ID”, right?

The problem here is when we work with lookup columns it is not actually the value of the look up that is brought to your repeating table by your data connection, it is in fact the “ID” of the item in that list.

So to filter which amounts to summarize we should do like this:

The “TotalAmount” should be the sum of “Amount” where “ID” equals “Sales ID”.

Now when we open the form of a sales person, we could see the total amount that person has sold for.

Hope this helps someone!

CU

/SPNiax


Multiple submits

Hi everyone!

I thought I would give you a way to handle multiple submits in a form. Lets say you have a form that should be filled by both students and ordinary attendees. There are some fields that are specific to the students like name of school and name of education and for the attendee we might have fields like title and name of company. When they make the submit we want to make sure all required fields are filled, but only the required fields for that kind of person.

First of all the person should make a decision if he is a student or an attendee, the form could look like this.

When the person clicks one of the buttons a field named listener is set to Attendee or Student. This decides which fields (or sections) that are displayed on the form. To handle the submit and validation of fields I have two submit buttons that looks the same but have different rules applied to them. They are both hidden if listener is blank or is set to the other buttons value.

Here is how it looks in design mode where both submit buttons can be seen and you also can see the message that is thrown if not all required fields are filled.

I think it’s a pretty easy way to accomplish what I was looking for and should be pretty simple for any one to use as well.

CU!

/Niax


Add a button to a repeating table to copy row data

Hi everyone!

I will show you how to add a button to a repeating table and be able to copy information from that row to other fields.

Create a list in SharePoint and name it Location with three columns, Title, Region and City.

Add a data connection to your form to receive information from this list in SharePoint. Now when you have your repeating table as a secondary source, highlight it and drag it to your form.

Put your cursor somewhere in the column for ID, right click and choose DeleteColumns, now you only have the Title, Region and City columns left.

Now put the cursor somewhere in the City column, right click and choose Insert – Columns to the right.

It should now look like this

Now add a button in the field next to the City field.

Add three Text Box fields somewhere in your form and name them MyTitle, MyRegion and MyCity.

Highlight the button and click Manage Rules in the ribbon. Create a new Action rule to set a field’s value. It should look like this.

The Value is built by adding the function current(), then a slash “/” and lastly, add the field Title from your secondary source Location.

Repeat this step twice so that you get a value for each of your three fields. You should now have three actions in your rule, like this.

That’s it, this is how it could look.

CU

/Niax

 


Need a link to create a new document from an Office template?

Hi everyone!

I found this blog post the other day and you can’t imagine the thrill I felt 🙂

This is something I have wanted to be able to do so many times and didn’t know how to, now I do and I want you to do as well.

As you can see (and read in the blog post) the saveLocation is set from where the template is located. I did a little change to route the save location to a place I decided. I also added a little change to wait until the page is loaded before the function is executed, always a good thing to do.

This is the original code:

<script type="text/javascript" src="/_layouts/jquery.min.js"></script>
<script type="text/javascript">
$( function () {
$("a[href$='.dot'], a[href$='.dotx'], a[href$='.xlt'], a[href$='.xltx']").attr("onclick", "").click( function () {
saveLocation = $(this).attr("href").split("/").slice(0, -2).join("/")
createNewDocumentWithProgID(window.location.protocol + '//' + window.location.host + $(this).attr("href"), window.location.protocol + '//' + window.location.host + saveLocation, 'SharePoint.OpenDocuments', false)
return false
})
})
</script>

and this is my modified one with a hard coded save location:

<script type="text/javascript" src="/Style%20Library/Scripts/jquery-1.4.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("a[href$='.dot'], a[href$='.dotx'], a[href$='.xlt'], a[href$='.xltx']").attr("onclick", "").click( function () {
createNewDocumentWithProgID(window.location.protocol + '//' + window.location.host + $(this).attr("href"), makeAbsUrl('http://MyIntranet/sitename/sitename/librar%20name'), 'SharePoint.OpenDocuments', false)
return false
})
})
</script>

Here is another one that prompts to save the document in the logged in users local Document library.

<script type="text/javascript">
$(document).ready(function(){
$("a[href$='.dot'], a[href$='.dotx'], a[href$='.xlt'], a[href$='.xltx']").attr("onclick", "").click( function () {
createNewDocumentWithProgID(window.location.protocol + '//' + window.location.host + $(this).attr("href"),'C:\Users\{login}\Documents' , 'SharePoint.OpenDocuments', false)
return false
})
})
</script>

As always when we are working with jQuery you have to make sure that you reference the location of that .js-file

CU

/Niax


Add customizable information to a library page

Hi everyone!

As you know when you add a web part to a library page, like Allitems.aspx or a page of a custom view that you’ve made, the ribbon gets wacky. That’s because it doesn’t know which web part it should have its focus on.

So what could we do if we really want some information, let’s say above the library web part?

And the information should be able to edit in an easy manner without using SharePoint Designer (SPD).

In this example I have a top site and underneath this I have some sub sites that are created from a site template I made. The things we are going to do now is made to that template so it could be reused.

First of all we have to edit the page’s code a bit, so bring up the page in your favorite editing tool SPD!

Find where the web part zone for the library begins and add two DIV’s right before it starts, like this:

PlaceHolderMain" runat="server">
<div id="success"></div>
<div id="error"></div>
<WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main">

As you can see I have added two DIV’s right after PlaceHolderMain with the ID’s of success and error. Don’t close this page, we are coming back here real soon.

What we are going to do now is to add some content to the success DIV.

First we need to have some content, right?

On the top site, let’s create a new Web Part Page, call it content.aspx and choose Full Page, Vertical.

Add a Content Editor to the page, click inside it, choose to Edit HTML Source…

…and paste this code:

</pre>
<div id="<span class=">MyDiv"></div>
<pre>
The content within this DIV will be shown above the document library.
<div>
<ol>
<li>To think about...</li>
<li>And this as well...</li>
</ol></div></div>

Ok, so now we have som content and as you can see the content is kept inside a DIV with the ID of MyDiv.

Now we are going back to the first page (where we have the library and added the two DIV’s) to add this information to the success DIV.

Let’s add som jQuery!

Find AdditionalPageHeader and add this code:

<asp:content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
 <SharePoint:RssLink runat="server"/>
<script type="text/<span class=">// <![CDATA[
javascript</span>" src="/sitename/Shared%20documents/jquery-1.6.2.min.js">
// ]]></script>
<script type="text/javascript">
 $(document).ready(function() {
 $("#success").load("/sitename/sitename/SitePages/content.aspx #MyDiv",
 function(response, status, xhr) {
 if (status == "error") {
 var msg = "Page is missing: ";
 $("#error").html(msg + xhr.status + " " + xhr.statusText);
 }
 });
});
</script>
</asp:content>

As you can see, first I have a reference to my jQuery file, you should replace the URL so that it corresponds to your environment.
Then in the next section we are loading the content in MyDiv into the DIV with the ID of success.

Now we are done!

Save all pages and try it, it should look something like this:

This way you can create new sites from this site template and just by editing the Content Editors in the page content.aspx you could update the contents on all sites.

Isn’t that nice?

CU!

/Niax


Open an InfoPath form in a dialog

Hi everyone!

I would like to share with you how you could open a form in a dialog in SharePoint.

  • Add a Form web part on a page of your choise.
  • Replace the code with this:
<div> <a href="javascript:{ SP.UI.ModalDialog.OpenPopUpPage('/sitename/_layouts/FormServer.aspx?XsnLocation=/sitename/library/forms/template.xsn&OpenIn=browser&SaveLocation=/sitename/library', null, 1000); };">Open form</a></div>
  • Replace sitename and library with the ones in your environment.
  • Click Save and OK in the web part and try it out!

Thats it!

/Niax


Get a link in a CQWP to edit an item

Hi everyone!

I hope this could be of some use for you 🙂

I want:

An audiense filtered list of links where by clicking the link, I should end up being able to edit the item, not open the page it points to. After I have finished editing I should return to the page with links targeted to me (or any other page for that matter).

Ok this is what we have:

A links list called OrgLinks where we have activated Audience targeting settings. This list also has a custom column called Box that is of the type Managed metadata which is connected to a Term store called Linkboxes.
So each item is tagged with which box it should belong to and which part of the organization that should see it.

I have a page that consists of a number of CQWP that is querying this links list. Audience targeting is activated on these web parts and they are filtered on the values of the Term store Linkboxes.

On the same page, I have added a couple of buttons (targeted to editors) to make it easier to create new items in this list and navigate to a page where you could edit items already created. This is actually the list that this blog is all about 🙂

The thing is that even if you enable Audience targeting for a list, you can’t OOTB filter a lists view on audiences.

This is where the template I came up with for ItemStyles.xsl comes in. It could be that I am crossing the brook for water in my template but it gives me the result I want 🙂

It was actually this template from Marc’s blog that got me in the right direction.

What it does is that it concatenate the link to the edit form of the item, the Item-ID and the URL to the page the user should go to after he or she is finished.

<xsl:template name="LinkListEdit" match="Row[@Style='LinkListEdit']" mode="itemstyle">
     <xsl:variable name="SafeLinkUrl">
         <xsl:call-template name="OuterTemplate.GetSafeLink">
             <xsl:with-param name="UrlColumnName" select="@URL"/>
         </xsl:call-template>
     </xsl:variable>
     <xsl:variable name="DisplayTitle">
         <xsl:call-template name="OuterTemplate.GetTitle">
             <xsl:with-param name="Title" select="@URL"/>
             <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
         </xsl:call-template>
     </xsl:variable>
     <xsl:variable name="TheList">
     <xsl:text disable-output-escaping="yes"> /alltomoss/_layouts/listform.aspx?PageType=6&amp;ListId={675357B2-D33C-4626-A61B-0FC978C0C09C}&amp;ID=</xsl:text>
     </xsl:variable>
     <xsl:variable name="Source">
     <xsl:text disable-output-escaping="yes">&amp;Source=/alltomoss/sidor/aoolankar.aspx</xsl:text>
     </xsl:variable>
          <xsl:variable name="TheLink">
          <xsl:value-of select="concat($TheList, @ID, $Source)" />
          </xsl:variable>
     <div id="linkitem">
         <xsl:call-template name="OuterTemplate.CallPresenceStatusIconTemplate"/>
         <a href="{$TheLink}" title="Redigera länken">
         <xsl:value-of select="substring-after($DisplayTitle,',')"/>
         </a>
     </div>
 </xsl:template>

Before we actually could use this template and use it it in our CQWP we need to export the webpart and add a couple of things to it. Change CommonViewFields to look like this:

 <property name="CommonViewFields" type="string">URL,Text; </property> 

Then as “usual” import it again and add it to the page.

CU!

/Niax


Working with the Visio Web Part

Hi everyone!

Ok, so a client had these requests:

1. We want to be able to navigate to different processes in an easy manner

2. We want to be able to bring up information about a process step

2b.Without loosing focus from the process we are currently at

3. Reuse instructions that we already have about the steps in our processes

This is what we will be working with:

  • A Visio file for the master process file that will be used to navigate to the different processes.
  • A Visio file for the process Customer Complaints, this process will contain two steps.
  • A PDF-file that will contain information about each step.
  • Two pages that will show the Visio-files.

First I would like to add that I am no expert in Visio so there might be better or different ways to attack this 🙂

As a matter of fact, I wonder if there is something that I am an expert in…

But anyway, this is how I did.

First of all I have these settings for Adobe Reader.

  • Set Adobe Reader to open PDF-files in the browser
  • Uncheck to open in Read mode as default

To accommodate request 1 (navigate to different processes)

A main process is created in Visio with links to the pages that holds a Visio web part for each process like Sales and Customer complaints and so on.

Main process

The link for the Customer complaints object looks like this:

http://server/site/pages/customerc.aspx

This Visio-file is uploaded to http://server/site/processdiagrams as MainProcess.vdw

On the start page for http://server/site/start.apsx a Visio web part will be showing this Main process.

I also added a Go back button above this web part so that they in an easy manner could go back to the page that holds the Main process.

To accomodate request 3 (reusing information that we have)

First I made sure that the information about each process step started on a new page in the document. Then I saved the Word-file as a PDF letting Word create bookmarks in the PDF-file from the headings in the document while it was beeing published. That way we get a table of contents in the left navigation of the PDF.

(If you don’t get one, make sure that you have unchecked the default value to open PDF in Read mode.)

This PDF-file is uploaded to http://server/site/documents as CCsteps.pdf

To accomodate request 2 (bring up information on each step)

The Customer complaints visio-file (that is saved as a .vdw-file) holds two different steps ACC CC and Qualify CC.

Customer complaints

The link for ACC CC is configured like this:

URL: http://server/site/documents/ccsteps.pdf

The sub adress is “Page=2” (because the instructions for the ACC CC step starts at page 2)

Description is set to ACC CC and I don’t use a relative path.

This Visio-file is uploaded to http://server/site/processdiagrams as CustomerC.vdw

To accomodate request 2b (navigate without loosing focus)

Ok, so this is something that I don’t like with the new vdw-type of file, you can not set a link for an object to open in a new window.

So to get around this I first got some help on MSDN forum here >> with some javaScript.

On the Visio web part you want to have this script active for edit the web part like this:

I did not get this to work OOTB, so I got some help from some collegues of mine, thanks guys 🙂

This code you could simply copy and paste and put in a CEWP or FormWP on the page where you have your Visio web part, to try it out.

It ended up with a JavaScript looking like this:

<script type="text/javascript">

// Declare the global variables for the script, for the Visio Web Access Web Part, the active page in the Web Part,
// and the shapes on the active page.
var vwaControl;
var vwaPage;
var vwaShapes;
var newURL;

// Add a handler to the AJAX Sys.Application.load event.
Sys.Application.add_load(onApplicationLoad)

function onApplicationLoad()
{
  try{
    // Capture a reference to the current instance of the Visio Web Access Web Part.
    // Add a handler to the 'diagramcomplete' event.
    vwaControl= new Vwa.VwaControl(getVWAWebPartID());
    vwaControl.addHandler("diagramcomplete", onDiagramComplete);
  }
  catch(err){
    alert(err);
  }
}

function getVWAWebPartID()
{
// Search all of the</pre>
<div>tags on the page to find the div tag with the ID of the VWA Web Part.</div>
<pre>
  var divArray = document.getElementsByTagName("div");
  var webPartElementID;
  for (var i = 0; i < divArray.length; i++) {
    var node = divArray[i];
    if (node.className == "VisioWebAccess")
    {
      webPartElementID = node.parentNode.parentNode.id;
      break;
    }
  }
  return webPartElementID;
}

function onDiagramComplete()
{
  try{
    // Set the vwaPage and vwaShapes variables to the active page and the shapes collection on that page, respectively.
    vwaPage = vwaControl.getActivePage();
    vwaShapes = vwaPage.getShapes();

    // Remove the handler from the shape selection changed event and then add it back to the event.
    vwaControl.removeHandler("shapeselectionchanged", onShapeSelectionChanged);
    vwaControl.addHandler("shapeselectionchanged", onShapeSelectionChanged);

  }
  catch(err)
  {
    alert(err);
  }
 }

function setNewPage(pageId) {
  // Set the active page in the drawing to the page ID passed in as argument.
  var indexOfAmp = pageId.indexOf("&");
  var page = pageId.slice(6, indexOfAmp);
 vwaControl.setActivePage(page);
}
onShapeSelectionChanged = function (source, args)
{
  try{
    // Get the array of hyperlinks from the selected shape.
    var vwaShape = vwaShapes.getItemById(args);
    var newURLArray = vwaShape.getHyperlinks();

    // Check to see whether the shape has any hyperlinks.
    if (newURLArray.length> 0)
    {
      newURL = newURLArray[0].value;

      // Check to see if the hyperlink goes to another page in the drawing.
      if (newURL.indexOf('vdw') < 0)
      {
        // Open the hyperlink in a new window.
           var newWindow = window.open(newURL, "", 'width=800,height=650')
      }
     else
      {
         //Set the active page to the new page.
        setNewPage(newURL);
      }
    }
  }
  catch(err)
  {
    alert(err);
  }
}
</script>

Now when you click on a process step, the actual page in the PDF-file should be brought up in a separate window and give you the instructions about that step. You should also have a table of contents in the left pane in AcrobatReader so that you could easily navigate between different instructions.

Well thats about it guys, I hope this will help you or give you some ideas.

CU

/Niax