rep.jpg

Blog

Feb 23
Als anderer Benutzer anmelden in SharePoint 2013
Dez 08
Implement Global Navigation with Managed Metadata Termstore in Sharepoint 2013

The requirements were to create an overall global navigation containing links to other company and application sites.

In addition

  • each entry should be provided with an icon
  • submenus should open as flyouts
  • optional tool-tips should appear for further explanations


Proceeding:

  • Creating of a Navigation Termset in the Managed Metadata Termstore
  • Implementing a Navigation Control in your Masterpage using JQuery and Knockout functionality


Step 1: Create a Navigation Term Set in the Managed Metadata Termstore

Using Managed Metadata in SharePoint 2013 we first create a new Global Term Group 'Global Navigation'.

In this group, we create a new Term Set 'Global Navigation'.

Set the intended use to 'Use this Term Set for Site Navigation'.

Next step we create the navigation terms.

For every Term, on the Navigation tab, select the Simple Link or Header option and provide the URL to the corresponding Site.

On the Custom Properties Tab, we use the 'Local Properties' to set the values for icons and tooltips.

I suggest to store the icon files in the Sharepoint 15 hive, as they will be accessable from all sites.

Last but not least it's possible to set a custom sort order for every Term Set or Sub Term Set.

 

Now, our Navigation Term Set is ready for use.

 

Last thing... click on Global Navigation Term Set and copy the Unique ID. This is needed to set the reference in the Navigation Control.

 

Step 2: Implement the Navigation Control in your Masterpage using JQuery and Knockout functionality

I found some useful entries in the net and brought them into line for my requirements. As result I got 5 files which we need to reference to. I suggest to save these files in the Sharepoint 15 hive, as they will be accessable from all sites.

/_layouts/15/ManagedGlobalNav/styles/GlobalNav.css
/_layouts/15/ManagedGlobalNav/js/ManagedGlobalNavigation.js
/_layouts/15/ManagedGlobalNav/js/knockout-2.2.1.js
/_layouts/15/ManagedGlobalNav/js/jQuery.js
/_layouts/15/ManagedGlobalNav/js/superfish.js

** Download script files  **

Open the masterpage in edit mode (e.g. in Sharepoint Designer) and place the CSS Reference in the head section:

<SharePoint:CssRegistration name="/_layouts/15/ManagedGlobalNav/styles/GlobalNav.css" After="corev15.css" runat="server"/>

Then find the following lines…

<SharePoint:AjaxDelta runat="server" id="DeltaSuiteLinks" BlockElement="true" CssClass="ms-core-deltaSuiteLinks">
<div id="suiteLinksBox">

… and place the Navigation Code between them:  

<!-- Managed Metadata Navigation -->
<div style="clear:both;">
   <script src="/_layouts/15/ManagedGlobalNav/js/ManagedGlobalNavigation.js"></script>
   <script src="/_layouts/15/ManagedGlobalNav/js/knockout-2.2.1.js"></script>
   <script src="/_layouts/15/ManagedGlobalNav/js/jQuery.js"></script>
   <script src="/_layouts/15/ManagedGlobalNav/js/superfish.js"></script>

   <script>
       // set TermSet ID
       MMN.Termset.getTermSetAsTree('b7d5d223-dae3-4104-a428-cc913c194b0b', callbackfunction);

       // call GlobalNavigation function
       function callbackfunction(tree) {
           ManagedGlobalNavigation.init(tree);
       }

       // call superfish funcion for flyout navigation
       jQuery(document).ready(function () {
           jQuery('ul.sf-menu').superfish();
       });
   </script>

   <script id="itemTmpl" type="text/html">
      // First Level Liste Items
      <li>
             <a data-bind="attr: { href: url, title: tooltip }"><span  class="TopNavIcons"  data-bind="    attr: { style: icon }, text: title"></span></a>
             // Second Level Liste Items as Flyouts
             <ul data-bind="foreach: children">
                <li>
                   <span data-bind="if: url"><a data-bind="    attr: { href: url, title: tooltip }" ><div data-bind="    text: title"></div></a></span>
                   <span data-bind="ifnot: url"><span class="sf-title" data-bind="    text: title"></span></span>
               </li>
              </ul>
       </li>
   </script>
   <div>
      <ul class="sf-menu" data-bind="template: { name: 'itemTmpl', foreach: ManagedGlobalNavigation.viewModel.globalMenuItems }"></ul>
   </div>
</div>

Finally, replace the ID with the one from your TermSet and customize the styles with your needs.

Please notice
The feature 'Minimal Download Strategie' may cause some problems when sites are customized. In this case I consider to deactivate it.

References and many thank's for these usefull posts:

Building global navigation in SharePoint 2013
Returning a SharePoint 2013 termset in a tree structure using JavaScript 
Superfish enhanced style menu jQuery plugin for CSS drop-down

Nov 19
Customize keyfilter and treeview navigation bar with dragable border

If you enable keyfilters and or treeview, Sharepoint 2013 applies a larger leftnavbar with dragable borders. This functionality is handled out in a jquery file called navresizer.js.

To apply your own branding, espacially if your leftnav has another width , you need to override the prototype functions.

CustomNavResizer.js

ExecuteOrDelayUntilScriptLoaded(customNav, "NavResizer.js");

function customNav() {
// sets max. width for sideNavBox
Microsoft.Office.Server.Ajax.NavResizer.prototype.$1N_0 = function() {
 ULS4S1:;if(this.$7_0)this.$I_0=210;else if(this.get_$B_0())this.$I_0=210;else this.$I_0=210
};

// sets starting width for sideNavBox
Microsoft.Office.Server.Ajax.NavResizer.prototype.$1M_0 = function() {
ULS4S1:;if(this.get_$B_0()){this.$Y_0=210;if(this.$Y_0>this.get_$C_0()){this.set_$C_0(this.set_$A_0(this.$K_0=this.$M_0(this.$Y_0)));this.$H_0()}}
};
// calculates left margin for contentBox
Microsoft.Office.Server.Ajax.NavResizer.$U = 20;
//calculates width for idKeyFiltersContainer
Microsoft.Office.Server.Ajax.NavResizer.prototype.$s_0 = 20;
}


For more customizations, enjoy the study of navresizer.js...

Include the js-file in the head section in your masterpage:

<SharePoint:ScriptLink language="javascript" name="pathtoyourfile/CustomNavResizer.js" runat="server" />

If you want the grippy-gif back (as in SP2010), just add it in your styles:

.ms-navresizer-vertical{
cursor:e-resize;
width:5px;
border-left:1px solid #C6C6C6;
margin-left:1px;
background-image: url("/_layouts/15/images/MDNGrippy.gif");
background-position: center center;
background-repeat: no-repeat;
}

Nov 19
Display the Title Row in the Search Center

In Sharepoint 2013 there's no more separate masterpage for a search site, but instead there are styles applied in pagelayout files like SearchResults.aspx, which hides the titlerow in a searchresult page. Furthermore the SiteIcon is shown in the LeftNavBar and your Branding may be messed up.

To prevent this, add the following style to your css:

​#s4-bodyContainer .s4-showtitleinsearch {
 display:block !important;
}


Add a script ad the end of your masterpage

​<script type="text/javascript">
    // show Titlerow/hide SearchIcon in Searchresult
 var checksearch = document.getElementById('searchIcon');
    if (checksearch != null){
    document.getElementById('s4-titlerow').setAttribute('class', 's4-showtitleinsearch');
    document.getElementById('searchIcon').setAttribute('style', 'display: none;');
    }
</script>

 

Apr 10
Links auf einen File Share in einem Textfeld eintragen

Um einen Link auf einen File Share einzutragen, würde ich üblicherweise davon ausgehen, dass dieser folgendermassen eingegeben wird:

file://\\w:\files\...

Sobald der Text gespeichert wird, wird der Link jedoch umgewandelt und der href-Eintrag aus dem <a>-Tag entfernt.

Nach x vergeblichen Versuchen, den Pfad auf allen nur erdenklichen Wegen einzutragen, ist die Lösung am Ende eigentlich zu einfach, um wahr zu sein:

Einfach nur \\w:\file.pdf (also ohne file://) im Textfenster eingegeben werden und beim Speichern wird automatisch der Link (<a href="file:///w:/file.pdf">\\w:\file.pdf</a>) generiert.

Happy Sharepointing!

Mrz 12
Show Sharepoint Picture Library with JQuery Galleriffic PhotoGallerie

Mit galleriffic JQuery können Bilder in einer Bildergalerie mit verschiedenen Funktionen angezeigt werden können.

Anstatt die Bilder mittels einer 'ordered list' aufzurufen, welche manuell erstellt werden muss, möchte ich die Anzeige dynamisch aus einer Sharepoint Bild Bibliothek generieren. Hierfür erstelle ich ein neues PageLayout mit einem DataFormWebPart, in welchem ich zusätzliche Möglichkeiten habe, die Daten zu sortieren und zu filtern.

Verwendungs-Beispiel:
Verwaltung von Events in einer Liste mit Detailangaben sowie Verknüpfung zu Bildern in einer BildBibliothek.

galleriffic1.jpg 

Vorgehen:

  1. Erstellen einer Liste ‚Events' für das Erfassen aller gewünschten Informationen wie Titel, Inhalt,  Links etc.

  2. Erstellen einer BildBibliothek in Sharepoint mit dem Template ‚Bildbibliothek'.
    Bei diesem Template werden für jedes hochgeladene Bild im Hintergrund zwei weitere Bilder mit Thumbnail- resp. WebPreview-Grösse erstellt.
    Für die Anzeige in der Galerie werden diese beiden ‚kleineren Formate' angezeigt, während für die Ansicht in Originalgrösse einen Download-Link zur Verfügung steht.

  3. Lookup-Feld ‚Events' hinzufügen, welche mit dem Titel aus der Liste ‚Events' verknüpft ist.

  4. Bilder hochladen, wobei für jedes Bild ein zugehöriger Event im Lookup-Feld eingetragen wird.

  5. Je ein PageLayout für eine Event-Übersicht sowie für die Detailansicht pro Event erstellen.

  6. In der Event-Übersicht wird ein DataFormWebPart für die Liste ‚Events' eingefügt. Der Aufruf der Detailansicht erfolgt über einen Link mit einer Queriestring-Variable, z.B. ‚Item-ID', um den Wert der Event-ID zu übergeben.

  7. In der Detailansicht kann nun ein DataFormWebPart für die Liste ‚Events' eingefügt und wunschgemäss gestaltet werden.

  8. Ein weiteres DataFormWebPart für die BildBibliothek einfügen und mittels WebPartVerknüpfung mit den Events verknüpfen:
    Events – Titel = Bildgalerie – Events (Lookup-Feld)

  9. JQuery einbinden:

a)      Script-Aufruf im PlaceHolderAdditionalPageHead einfügen 

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="/_layouts/15/custom.branding/galleriffic-2.0/css/basic.css" type="text/css" />
<link rel="stylesheet" href="/_layouts/15/custom.branding/galleriffic-2.0/css/galleriffic-3.css" type="text/css" />
<script type="text/javascript" src="/_layouts/15/custom.branding/galleriffic-2.0/js/jquery-1.3.2.js"></script>
<script type="text/javascript" src="/_layouts/15/custom.branding/galleriffic-2.0/js/jquery.history.js"></script>
<script type="text/javascript" src="/_layouts/15/custom.branding/galleriffic-2.0/js/jquery.galleriffic.js"></script>
<script type="text/javascript" src="/_layouts/15/custom.branding/galleriffic-2.0/js/jquery.opacityrollover.js"></script>

<!-- We only want the thunbnails to display when javascript is disabled -->
<script type="text/javascript">
   document.write('<style>.noscript { display: none; }</style>');
</script>

b)     xsl-Templates anpassen

<xsl:template name="dvt_1">
...
<!-- Anstelle des Aufrufs der HTML-Table -->
<div id="page">
   <div id="container">
      <!-- Start Advanced Gallery Html Containers -->
      <div id="gallery" class="content">
         <div id="controls" class="controls"></div>
         <div class="slideshow-container">
            <div id="loading" class="loader"></div>
            <div id="slideshow" class="slideshow"></div>
         </div>
         <div id="caption" class="caption-container"></div>
      </div>
      <div id="thumbs" class="navigation" style="width:374px;">
         <ul class="thumbs noscript">
            <xsl:call-template name="dvt_1.body">
               <xsl:with-param name="Rows" select="$Rows"/>
            </xsl:call-template>
         </ul>
      </div>
      <!-- End Advanced Gallery Html Containers -->
      <div style="clear: both;"></div>
   </div>
</div>
...
</xsl:template>
<xsl:template name="dvt_1.body">...</xsl:template>

<!-- Anstelle der ItemView in einer HTML-Tablerow -->
<xsl:template name="dvt_1.rowview">
   <li>
      <div style="height:104px;width:164px;overflow:hidden;border: 1px solid #AEAEAE;">
         <a class="thumb" name="leaf" href="{@FileDirRef}/_w/{@FileLeafRef.Name}_{@FileLeafRef.Suffix}.jpg" title="Title">
            <img src="{@FileDirRef}/_t/{@FileLeafRef.Name}_{@FileLeafRef.Suffix}.jpg" alt="Title" style="max-width:160px;max-height:100px;" />
         </a>
      </div>
      <div class="caption">
         <div class="image-desc" style=" text-align:center;"><xsl:value-of select="@Description" disable-output-escaping="yes"/></div>
         <div class="download"><a href="{@FileRef}">Ansicht Originalgrösse</a></div>
      </div>
   </li>
</xsl:template>

c)      Unterhalb des DataFormWebParts folgendes Script einfügen:

<script type="text/javascript">
   jQuery(document).ready(function($) {
   // We only want these styles applied when javascript is enabled
   $('div.navigation').css({'width' : '554px', 'float' : 'left'});
   $('div.content').css('display', 'block');

   // Initially set opacity on thumbs and add
   // additional styling for hover effect on thumbs
   var onMouseOutOpacity = 0.67;
   $('#thumbs ul.thumbs li').opacityrollover({
      mouseOutOpacity:   onMouseOutOpacity,
      mouseOverOpacity:  1.0,
      fadeSpeed:         'fast',
      exemptionSelector: '.selected'
   });
  
   // Initialize Advanced Galleriffic Gallery
   var gallery = $('#thumbs').galleriffic({
      delay:                     3000,
      numThumbs:                 12,
      preloadAhead:              12,
      enableTopPager:            true,
      enableBottomPager:         true,
      maxPagesToShow:            7,
      imageContainerSel:         '#slideshow',
      controlsContainerSel:      '#controls',
      captionContainerSel:       '#caption',
      loadingContainerSel:       '#loading',
      renderSSControls:          true,
      renderNavControls:         true,
      playLinkText:              'Slideshow abspielen',
      pauseLinkText:             'Slideshow stoppen',
      prevLinkText:              '&lsaquo; Vorheriges Bild',
      nextLinkText:              'Nächstes Bild &rsaquo;',
      nextPageLinkText:          'weiter &rsaquo;',
      prevPageLinkText:          '&lsaquo; zurück',
      enableHistory:             true,
      autoStart:                 false,
      syncTransitions:           true,
      defaultTransitionDuration: 900,
      onSlideChange:             function(prevIndex, nextIndex) {
           // 'this' refers to the gallery, which is an extension of $('#thumbs')
           this.find('ul.thumbs').children()
           .eq(prevIndex).fadeTo('fast', onMouseOutOpacity).end()
           .eq(nextIndex).fadeTo('fast', 1.0);
           },
      onPageTransitionOut:       function(callback) {
           this.fadeTo('fast', 0.0, callback);
           },
      onPageTransitionIn:        function() {
           this.fadeTo('fast', 1.0);
           }
   });

function getUrlParams() { 
var params = {}; 
window.location.search.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(str,key,value) {   
params[key] = value;  });  
return params;
}
 
/**** Functions to support integration of galleriffic with the jquery.history plugin ****/
// PageLoad function
// This function is called when:
// 1. after calling $.historyInit();
// 2. after calling $.historyLoad();
// 3. after pushing "Go Back" button of a browser
function pageload(hash) {
   // alert("pageload: " + hash);
   // hash doesn't contain the first # character.
   if(hash) {
      $.galleriffic.gotoImage(hash);
      var params = getUrlParams();
      } else {
      gallery.gotoIndex(0);
      }
}
// Initialize history plugin.
// The callback is called at once by present location.hash.
$.historyInit(pageload, "advanced.html");
 
// set onlick event for buttons using the jQuery 1.3 live method
$("a[rel='history']").live('click', function(e) {
   if (e.button != 0) return true;
      var hash = this.href;
      hash = hash.replace(/^.*#/, '');
      // moves to a new page.
      // pageload is called at once.
      // hash don't contain "#", "?"
      $.historyLoad(hash);
      return false;
   });
});
</script>

Weitere Beschreibung der Konfigurationsmöglichkeiten unter http://www.twospy.com/galleriffic/

Mrz 12
Searching in number column

Number fields are not automatically included in search index.

For including number fields in search index go to search service application, metadata properties, crawled properties and for your number column, check the option "Include values for this property in the search index and do a full crawl.

You should then be able to search on the number.

Jan 14
Cross Site Collection Connections via WebServices

Cross Site Publishing Funktionen sind in der Standard Edition von Sharepoint 2013 nicht verfügbar. Um trotzdem Inhalt von einer Site Collection auf einer anderen Site Collection anzuzeigen kann mittels WebServices auf Inhalte zugegriffen werden.

Beispiel:
ListItems aus drei verschiedenen Site Collections sollen in einer Ansicht zusammengefasst werden.

Vorgehen:
Im Sharepoint Designer die Datenquellen mittels Webservices integrieren und in einem PageLayout mittels DataFormWebPart zusammenführen

1.    Site Collection im Designer öffnen, auf welcher die Items angezeigt werden sollen

2.    Unter Datenquellen eine neue SOAP-Dienstverbindung erstellen

  • Mit http://[Site Collection]/_vti_bin/lists.asmx?WSDL für jede Liste eine Verbindung herstellen
    Da die Listen später in einer verknüpften Ansicht dargestellt werden sollen, muss auch für die Liste in der anzeigenden Site die Datenquelle auf die gleiche Weise erstellt werden

ID2_1.jpgID2_2.jpgID2_3.jpg 

  • Allgemein: Name für die Datenquelle eintragen
  • Quelle:
    Anschluss:       ListsSoap oder ListsSoap12
    Vorgang:          GetListItems
    Parameter:       listName = Interner Name der Liste
  • Anmeldung:
    Authentifizierung wählen.
    z.B. Benutzername und Kennwort eintragen
    Achtung: Kennwort wird in DataFormWebPart als Text angezeigt – ev. einen eigenen Account nur für diesen Zweck erstellen, welcher nur über die notwendigen Leserechte verfügt.

3.    Layoutpage erstellen und erste Liste einfügen

  • Einfügen – Formular zum Anzeigen eines Eintrages – SOAP-Dienste – Datenquelle auswählen – DataFormWebPart wird erstellt
    Unter Datenquellendetails sollten nun die Colums der Liste ersichtlich sein
  • Zugehörige Datenquelle – Mit einer anderen Datenquelle verknüpfen wählen
    Meldung betr. Einfügen von Datenwerten mit ok bestätigen

ID2_4.jpgID2_5.jpgID2_6.jpgID2_7.jpg 

Achtung: Unter DataSources können die Verbindungsdaten als Text gelesen werden:
<DataSources><SharePointWebControls:AggregateDataSource runat="server" IsSynchronous="false"><sources><SharePointWebControls:SoapDataSource runat="server"
AuthType="Basic" WsdlPath=http://[Site Collection]/_vti_bin/lists.asmx?WSDL SelectUrl=http://[Site Collection]/_vti_bin/lists.asmx
SelectAction=http://schemas.microsoft.com/sharepoint/soap/GetListItems  SelectPort="ListsSoap12" SelectServiceName="Lists"
AuthUserName="[UserAccount]" AuthPassword="[Password]"><SelectCommand...

4.    Die Daten können nun gemäss Projektspezifikation im DataFormWebPart konfiguriert und formatiert werden.

Aug 20
Managed Metadata wird nicht im Refinement Panel angezeigt

Ursache: Die hidden Columns ‚ows_taxId_Fieldname' und 'owstaxidFieldname' werden nicht erstellt.

Lösung: Das Feature TaxonomyFieldAdded muss auf der Site Collection de- und wieder re-aktiviert werden.

Details:

In einer Site Collection wurde eine Library mit mehreren Managed Metadata Fields erstellt. Die dazugehörigen TermSets wurden in einem lokalen Term Store abgelegt.

Nach einer gewissen Zeit wurde bemerkt, dass die Metadaten nicht im Refinement-Panel angezeigt wurden, obwohl diese dort automatisch hinzugefügt hätten werden sollen.

Die Recherchen ergaben, dass dies über Crawled resp. Managed Properties in Search Application geregelt wird. Sobald ein Item mit entsprechenden Values, also crawl-baren Values, vorhanden ist, wird eine zusätzliche Crawled Property mit dem Namen ows_taxID_Fieldname sowie eine zugehörige Managed Property mit dem Name owstaxidFieldname erstellt. Im Refinement Panel werden diese dann aufgrund des speziellen Fieldtypes angezeigt.

ID3_1.jpgDiese Funktionalität wird über das Feature TaxonomyFieldAdded abgehandelt. Obwohl das Feature aktiviert war, wurden diese Felder jedoch nicht nicht erstellt.

Lösung:

Das Feature TaxonomyFieldAdded muss auf der Site Collection de- und wieder reaktiviert werden.

stsadm -o deactivatefeature -name TaxonomyFieldAdded -url [SITE_URL]
stsadm -o activatefeature -name TaxonomyFieldAdded -url [SITE_URL]

Anschliessend muss ein neues Managed Metadata Feld erstellt werden (ev. genügt auch ein Umbenennen). Ein Item muss mit einem Value in mind. einem Managed Metadata Feld erfasst werden. Nach dem nächsten Full Crawl sollten sämtliche Managed Metadata Fields die entsprechenden Crawled und Managed Properties erstellt worden sein und im Refinement Panel angezeigt werden.