Sharepoint 2013 ISSUES with the .Net Framework 4.6

In this article i would share a problem encoured during the installation of “Sharepoint 2013” on the server with : Windows Server 2012 Standard.

After the phase of “Prerequisites”, completed with successful the installation was interrupt with this message:

blog

It’s no possibile.. The framework required is installed and the features are enabled!

The problem ?… Windows Update…

Before to start the installation i have completed “windows update” on the server; but now is included the update of the framework at version 4.6.X… and the SharePoint Setup program does not recognize the .NET Framework 4.6, 4.6.1, or 4.6.2 as a supported version of the .NET Framework.

The solution is unistall the updates, install Sharepoint and after re-install the windows update.

Here the link with the details:

https://support.microsoft.com/en-us/kb/3087184

 Good Work!

Pubblicato in Configurazione Sharepoint 2013 | Lascia un commento

SharePoint 2013 : How optmize the resourse usage for the “Search Service Application”

In this short article, i’ll describe as optmize the performance for the search service application.

The search service introduced with Sharepoint 2013 is…powerfull but it require resources : cpu and memory; it is normal but you can manage : how many resources to use.

If you open the task manager, you can see the process : “noderunner.exe” that consuming a lot of CPU. You can’t kill them, it is required for the search service application, the optmizzation consist in two step:

1.Set the performance level with the cmdlet :

Get-SPEnterpriseSearchService | Set-SPEnterpriseSearchService –PerformanceLevel “Level”*

*Level =

  • Reduced: Total number of threads = number of processors, Max Threads/host = number of processors
  • PartlyReduced: Total number of threads = 4 times the number of processors , Max Threads/host = 16 times the number of processors
  • Maximum: Total number of threads = 4 times the number of processors , Max Threads/host = 16 times the number of processors (threads are created at HIGH priority)

2.Configure the RAM usage, modifying the file : “noderunner.exe.config.” placed in the location (default):

C:\Program Files\Microsoft Office Servers\15.0\Search\Runtime\1.0\noderunner.exe.config.

The property to modify is : memoryLimitMegabytes, set to ‘0’ for default. With this value the RAM used is unlimited..set a limit.

After this operation you must restart the search service “Sharepoint Search Server 15” from “Control panel – > Services”.

After the modifiy, open the task manager and check the CPU and Memory usage from “noderunner.exe”.

 

Pubblicato in Configurazione Sharepoint 2013, Performance and Configure farm Sharepoint, Search | Lascia un commento

PowerShell : Come eliminare un “content type custom”

In questo breve articolo, vediamo uno script powerhsell da mettere nella ‘cassetta degli attrezzi’.
Scenario: abbiamo definito un ‘content type’ custom e lo vogliamo eliminare; come prerequisito dobbiamo verificare che non ci siano Liste o Raccolta documenti che lo utilizzino, perché in questo caso non sarà possbile eliminarlo.

Il primo pensiero potrebbe essere : lo elimino, ma non basta perché SharePoint ha il “cestino”…. anzi due! e i contenuti presenti nel cestino oltre a occupare spazio (particolare fondamentale!) sono elementi attivi.

Dopo aver eliminato l’elemento, questo andrà a finire nel primo cestino (quello dell’utente) ma questo non basta ancora..l’amministratore della raccolta siti (dovresti essere tu che hai voglia di leggere questo articolo) deve selezionare le ‘Impostazioni del sito’ e quindi nella sezione ‘Amministrazione raccolta siti’; selezionare la voce ‘Cestino’.

Da questo menu è possibile gestire i file cancellati dagli utenti (primo cestino) e quelli presenti nel cestino gestito dall’amministratore del sito

Immagine

Verificato che non ci siano elementi che usano il nostro content type, passiamo allo script:

Add-PSSnapin "Microsoft.SharePoint.PowerShell"

 $siteURL = <http://NomeRaccoltaSiti>

$contentType = "NomeContentType"

$web = Get-SPWeb $siteURL
 $ct = $web.ContentTypes[$contentType]

if ($ct) {
 $ctusage = [Microsoft.SharePoint.SPContentTypeUsage]::GetUsages($ct)
 foreach ($ctuse in $ctusage) {
 $list = $web.GetList($ctuse.Url)
 $contentTypeCollection = $list.ContentTypes;
 $contentTypeCollection.Delete($contentTypeCollection[$ContentType].Id);
 Write-host "Deleted $contentType content type from $ctuse.Url"
 }
 $ct.Delete()
 Write-host "Deleted $contentType from site."

} else { Write-host "Nothing to delete." }
$web.Dispose()
Pubblicato in PowerShell, Senza categoria | Lascia un commento

PowerShell : Come ottenere la lista dei file in ‘Check-out’

In questo breve articolo, voglio condividere uno script “powershell” che ritengo utile perché recupera l’elenco dei file che si trovano nello stato di “CheckOut”; per una specifica raccolta siti, compresi i sotto-siti.

Add-PSSnapin “Microsoft.SharePoint.PowerShell”

$webAppURL = http://NomeRaccoltaSiti

function ReportCheckedOutItems() {
$webapp = Get-SPWebApplication $webAppURL

foreach ($site in $webapp.Sites)
{
write-host “Site Collection: $($site.Url)”
$allwebs = $site.allwebs
foreach($web in $allwebs)
{
$count = 0
write-host “–>Site: $($web.Url)”
foreach ($list in ($web.Lists | ? {$_ -is [Microsoft.SharePoint.SPDocumentLibrary]})) {
Write-Host “—>–>List: $($list.RootFolder.ServerRelativeUrl)…”
foreach ($item in $list.CheckedOutFiles)
{
if (!$item.Url.EndsWith(“.aspx”))
{
continue
}
write-host “File: $($item.Url) – checked out by $($item.CheckedOutBy)” -ForeGroundColor Red
$count++
}
foreach ($item in $list.Items)
{
if ($item.File.CheckOutStatus -ne “None”)
{
if (($list.CheckedOutFiles | where {$_.ListItemId -eq $item.ID}) -ne $null)
{
continue
}
write-host “File: $($item.Url) – checked out by $($item.CheckedOutBy)” -ForeGroundColor Red
$count++
}
}
}
if ($count -gt 0)
{
write-host “Found $count checked out files for site $web” -ForeGroundColor Red
}
}
}
}

ReportCheckedOutItems

Pubblicato in PowerShell | Lascia un commento

Come attivare la “Developer Dashboard”

Per la serie “Lo sviluppo è nulla senza il controllo”, in questo articolo introduco uno strumento molto utile per la diagnostica delle pagine, soprattutto quando si riscontrano delle anomali, bloccanti o meno. Come vedremo tra poco, questo strumento riporta tutta una serie di informazioni raggruppate per tipologie, comprendendo anche le informazioni scritte nel LOG di SharePoint (ULS); permettendo di correlare tutte le informazioni di diagnostica utili a risalire alle cause : di un problema che provoca il malfunzionamento della pagina o anche solo un comportamento non previsto (ad esempio un eccessivo rallentamento al Load).

Un aspetto da sottolineare è il seguente : questo strumento non è da utilizzare solo per il ‘troubleshooting’ della pagina quando si verifica eccezioni bloccanti, ma è utile anche per l’analisi delle performance; che possono deteriorare se ad esempio aggiungiamo più ‘web part’ soprattutto di tipo ‘custom’ (non tutti gli sviluppatori gestiscono bene il ‘dispose degli oggetti SpWeb, SpSite etc.. ).

Vediamo innanzitutto quali sono i principali indici di prestazioni che misura questo strumento, nel contesto della richiesta che stiamo analizzando:

  1. Tempo di esecuzione del Thread
  2. Informazioni sullo stack di chiamate e sul testo della query inviate al DB, generate dalla pagina.
  3. Numero, durata e informazioni sullo Stack, di ogni chiamata WCF.
  4. Informazioni sull’utente corrente
  5. Informazioni sui tempi di esecuzione della pagina

Queste informazioni sono riportate in più Tab divisi per tipologie.

Iniziamo alla parte pratica, attivando la “Dashboard” attivando una sessione di “PowerShell” e digitando i comandi:

Modalità
Commando
On
(Get-SPFarm).PerformanceMonitor.DeveloperDashboardLevel = 
”On”
OnDemand
(Get-SPFarm).PerformanceMonitor.DeveloperDashboardLevel = 
”OnDemand”

Utilizzando la modalità ‘OnDemand’ avremo come conseguenza la possibilità di visualizzare in alto a desta della pagina una nuova icona:

dev1

 

 

Portiamoci nella pagina da analizzare e clicchiamo sull’icona per visualizzare il risultato:

Dev2

Buon Lavoro.

Pubblicato in Log e Diagnostica, Senza categoria | Lascia un commento

Come creare un Result Sources / Origine dei risultati in Sharepoint 2013

In questo articolo, vedremo come è possibile creare un “Result Source” per limitare l’ambito di una ricerca ad un sottoinsieme di elementi voluti. In “Sharepoint 2013” i “Result Sources” sostituiscono i “Search Scopes” e cosa più importante; la possibilità di creare dei “Result Sources” è stata ‘concessa’ anche agli amministratori della Site Collection e ai proprietari del sito. La creazione di un “Result Sources” richiede 5 passaggi.

  • Compilare le informazioni generali
  • Specificare un protocollo
  • Selezionare un ‘result type’
  • Scrivere una query
  • Specificare le credenziali

Supponiamo di voler creare un ‘result type’ a livello di FARM che mi restituisca solo i documenti di tipo Excel.

Come prima cosa è necessario avere quindi accesso alla FARM, come amministratore della FARM o come utente che appartiene al gruppo di Amministratori della FARM (sono due cose diverse, ma non è oggetto di questo breve articolo).

Premessa : come di solito farò riferimento alle sezioni della configurazione nella versione Inglese.

Accediamo alla Central Administration e dalla sezione : Application Management selezionare : Manage Service Applications. Da qui cliccare sul nome del Servizio di ricerca; nel caso in esame : Search Service Application:

Cliccando sul link si accede alla sezione di configurazione del servizio, dove nella colonna di sinistra sono presenti le varie sezioni; a noi interessa accedere alla sezione “Queries and Result”:

Nella pagina successiva sarà visibili in alto a tutto il link : New Result Sources, cliccando si attiva la Form di gestione del nuovo Result Sources; diviso nelle 5 sezioni anticipate sopra.General information : diamo un nome significativo, nel nostro caso :Excel Files ed eventualmente una descrizione : Restituisce i file di tipo Excel.Protocol : abbiamo le opzioni in figura:

3
Nel caso in esame stiamo cercando degli elementi presenti nella FARM.
Type : questa sezione successiva si adatta al tipo di protocollo selezionato e nel nostro caso possiamo scegliere tra due tipi :
2
Nel primo caso (che selezioniamo) avremo a disposizione tutti i risultati presenti nella FARM; mentre nel secondo caso avremo solo i risultati inerenti alla informazioni degli utenti.
Query Transform : entriamo nel “cuore” della configurazione; per le informazioni inserite fin ora non c’è nessuna discriminante che mi possa limitare i risultati della ricerca ai soli file Excel. Aprendo il tool : Query Builder avrò a disposizione un editor nel quale specificare il tipo di “query” da usare per il nostro “result sources”:*
2
Una volta creata l’espressione: {searchTerms} (FileExtension=xlsx OR FileExtension=xls)
, possiamo testarla cliccando sull’apposito pulsante:

2

* in questo articolo non sarà approfondita la sintassi (KQL : Key Query Language) in uso; per dettagli fare riferimento all’articolo seguente : https://msdn.microsoft.com/en-us/library/office/ff394509(v=office.14).aspxCredential information : l’ultima sezione riguarda la sicurezza, anche questa dipende dal protocollo selezionato. Nel caso in esame selezioniamo l’opzione in figura:

2
Dopo aver confermato l’opzione, cliccando su ‘Save’, il nostro ‘Content Sources’ sarà visibile nell’elenco iniziale:
2
Terminata la definizione, passiamo alla raccolta siti dove vogliamo utilizzare il “result source” e aggiungiamo una “Wiki Page” che utilizzerà le “Web Part” di ricerca e chiamiamola ad esempio : Ricerca File Excel.
Nella pagina appena creata, aggiungiamo in sequenza 3 Web Part della sezione ‘Search’:
• Search Box
• Search Result
• Search NavigationLa pagina avrà questo aspetto:
2

Portiamo in modifica la “Search Result” e clicchiamo sul tastoNella form di configurazione, simile a quella presentata in pecedenza, posso selezionare nella parte alta un ‘Result Sources’ andando quindi a restringere il campo di ricerca ai soli elementi che rispettano le regole di base. Nel caso in esame selezionerò : Excel Files.

2
Confermiamo, eventualmente dopo aver testato la query con l’apposito pulsante; confermiamo le modifiche alla web part e salviamo la pagina per testare la ricerca. Nel caso in esame inserisco il testo :Demo1 e ottengo il mio file Excel (unico) come risultato:
2
Come controprova che il filtro stia realmente funzionando, ripeto la ricerca in un’altra pagina dove si usa il “result source” di default ed inserisco la stessa parola chiave:
2

Buon Lavoro!

Pubblicato in Configurazione Sharepoint 2013, Search | Contrassegnato , , , | Lascia un commento

Come creare i Gruppi Standard di Sharepoint

Iniziamo l’anno nuovo con una piccola ‘tips’, più che con un articolo..

Come ampiamente noto, quando si crea una raccolta siti in automatico vengono aggiunti anche 3 gruppi standard :

  • Visitatori / Visitors
  • Membri / Members
  • Proprietari / Owners

Questo è vero quando si usa l’interfaccia Web, se invece utilizzo “PowerShell” con i comandi : New-SPSite i gruppi non saranno aggiunti.

Qualcuno potrebbe chiedersi perché complicarsi la vita usando “PowerShell” ?; perché ad esempio se volessi gestire le raccolte siti con la nuova modalità ‘Host Named’ posso farlo Solo da “PowerShell”!

Quindi se volessi comunque creare questi tre gruppi standard posso sempre farlo dopo aver creato la raccolta siti aggiungendo

_layouts/15/permsetup.aspx

all’URL del nostro sito e ci verrà mostrata la “form” di creazione dei gruppi standard.

Buon lavoro.!

Pubblicato in Senza categoria | Lascia un commento

Impostare o Reimpostare da PowerShell la proprietà ‘RichText Mode’

Scenario:

Dobbiamo aggiungere ad una raccolta documenti una colonna custom di tipo testo ma con la proprietà : Richtext abilitata, per inserire tag HTML. Dopo averla creata e aggiunta al nostro sito decidiamo di aggiungerla ad una raccolta documenti.

La procedura su come creare la colonna custom e aggiungerla alla raccolta documenti è fuori argomento, passiamo oltre e arriviamo al punto : la colonna che ho aggiunto non presenta la proprietà di ‘Richtext’ abilitata ed inoltre se entro nella modifica della colonna (nella raccolta documenti dove è stata aggiunta) non posso riattivarla….come fare a riattivarla? Tra le soluzioni che ho trovato (adattando una soluzione per un altro problema) la migliore per me, rimane lo script in PowerShell che consente di reimpostare la proprietà a ‘True’. Di seguito lo script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

Function RepairListRichTextColumns($webURL, $listName, $columnGUID)
{
    #Get web, list and column objects
    $web = Get-SPWeb $webURL
    $list = $web.Lists[$listName]
    $column = $list.Fields[[Guid]$columnGUID]       
    write-host "Schema="  $column.SchemaXml
    $column.RichText=$true
    $column.Update()
    write-host "Schema="  $column.SchemaXml
    $web.Dispose()
}
$webURL= "http://UrlDelSito/"
$listName = "Nome Della Lista"
$columnGUID = "GUID della colonna"
RepairListRichTextColumns -webURL $webURL -listName $listName -columnGUID $columnGUID
Pubblicato in Senza categoria, Tips & Trick | Lascia un commento

REST Api : Come recuperare le informazioni utente con il metodo “SiteUserInfoList”.

Come riportato in un articolo precedente, tra le maggiori novità introdotte con SharePoint 2013 c’è il supporto alle operazioni REST che restituiscono dati nel formato Odata (Open Data Protocoll).

Le soluzioni basate su REST usano lo standard HTTP con i verbi: GET,PUT,POST,DELETE permettendoci quindi di sviluppare una vera e propria libreria per i metodi CRUD.

La funzione che prenderemo in considerazione in questo caso ci consente di recuperare le informazioni (User Properties) dell’utente corrente o più in generale di un dato utente , passando come argomento l’ID.  Le applicazioni pratiche sono tante, ad esempio potremmo creare una piccola rubrica da visualizzare nella “Home Page”. Il metodo in esame è compatibile con le piattaforme : “Shaepoint Online”, “SharePoint 2013” e “SharePoint 2013 Foundation”.

Passiamo ai ‘fatti’ ma prima una  premessa : la soluzione è a titolo di esempio.

Pagina ASPX.

Apriamo con “SharePoint Designer” la pagina dove vogliamo mostrare le informazioni e in corrispondenza dell’elemento “PlaceHolder” con ID=’PlaceHolderAdditionalPageHead’ aggiungiamo i riferimenti ai file javascript seguenti:

  • /_layouts/15/MicrosoftAjax.js
  • /_layouts/15/sp.runtime.js
  • /_layouts/15/sp.js
  • /_layouts/15/sp.requestexecutor.js
  • /Style Library/jquery-1.9.1.min.js
  • /Style Library/RESTUser.js

I primi 4 file sono standard, “jquery-1.9.1.min.js” si trova disponibile  in rete ed infine “RESTUser.js” è il file che aggiungeremo per eseguire tutto il codice di interesse. Per concludere, aggiungiamo in un punto qualunque della pagina questo elemento HTML di tipo DIV con ID=’infoUser’.

In questo div, mostreremo il risultato.

File Javascript : RESTUser.

Aggiungiamo quindi nella ‘Style Library’ un file con esenstensione ‘JS’ e copiamo all’interno il codice seguente:

'use strict';
var context = SP.ClientContext.get_current();
var user = context.get_web().get_currentUser();
var idUser = 0;

// Questa codice viene eseguito quando DOM è pronto e crea un oggetto contesto necessario per utilizzare il modello a oggetti di SharePoint
$(document).ready(function () {
    getUserId();
});
// Con questa funzione recuperiamo l'ID dell'utente corrente
function getUserId() {    
    context.load(user);
    context.executeQueryAsync(onGetUserIdSuccess, onGetUserIdFail);
}
// Questa funzione viene eseguita se la chiamata sopra indicata ha esito positivo e prosegue con la chiamata alla funzione che recupera le informazioni utente tramite chiamata REST.

function onGetUserIdSuccess() {
    idUser = user.get_id();   
    getinfo(idUser); //recupero le Info con l'ID passato
    
}
// Questa funzione viene eseguita se la chiamata precedente ha esito negativo
function onGetUserIdFail(sender, args) {
    alert('Failed to get user ID. Error:' + args.get_message());
}

function getinfo(id) {
    //Eseguo il metodo 'SiteUserInfoList' compatibile con tutte le //versioni, anche la Foundation 
    jQuery.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/SiteUserInfoList/Items(" + id + ")?$select=Title,Name,EMail",
        type: "GET",                
        headers: {
            "accept": "application/json;odata=verbose",
        },
        success: function (data) {
            ShowData(data);
        },
        error: function (err) {
            alert(JSON.stringify(err));
        }
    });
}

//Per concludere, la funzione che mostra le info recuperate
 function ShowData(data) {     
var html = [];     html.push("<table>");     
var results = data.d.results;     
html.push("<tr>");      
html.push("<td>");      
html.push("Benvenuto,<strong>" +data.d.Title+"</strong>");      
html.push("</td>");     
html.push("</tr>");  
html.push("<tr>");   
html.push("<td>");      
html.push("Email:" +data.d.EMail);      
html.push("</td>");     
html.push("</tr>");                
html.push("</table>");     
$('#infoUser').html(html.join('')); }

 

A video vedremo al posto del div, le informazioni riportate nella tabella HTML:

Benvenuto, Amministratore
Email : amm@email.it

Buon lavoro!

Pubblicato in Senza categoria | Lascia un commento

Custom Action – Modificare il menu contestuale (ECB) di una lista Sharepoint

Come ci può suggerire il titolo  con questo articolo vedremo come sia possibile modificare o estendere l’interfaccia utente (UI) di SharePoint. Diciamo subito che  la personalizzazione dei menu, del ribbons, delle pagine e dei controlli in generale è un passaggio quasi obbligatorio per chi lavora con la piattaforma SharePoint e gli scenari possibili sono tanti, per cui caliamoci in un esempio concreto dandoci queste ‘specifiche’ :

Supponiamo di avere due liste personalizzate con le quali si vuole gestire l’anagrafica degli ordini con il classico modello ‘master-details’. Per prima cosa aggiungiamo due liste ‘custom’ : ‘Ordini testata’ e ‘Ordini dettaglio’ rispettivamente così composte:

5

6

 

 

 

 

 

 

 

 

 

Non soffermiamoci sulla struttura e sottoliniamo solo la presenza del campo di LookUp nella lista di dettaglio ‘Ordine numero’.
La personalizzazione ci deve permettere di ottenere questa funzionalità:
Selezionando un ordine nella lista ‘Testata’ si deve visualizzare il ‘Dettaglio’ corrispondente della lista ‘Dettaglio’.
Questi i macro-step da realizzare:

  1. Sviluppare con Visual Studio una Feature che modifichi l’ ‘Edit Control Block’ (ECB) della lista ‘Testata’ per indirizzare l’utente in una pagina intermedia.
  2. Aggiungere una vista sull’elenco ‘Dettaglio’ con un filtro sul campo ‘Ordine numero’, il cui valore è passato tramite query string.
  3. Aggiungere con SharePoint Designer una pagina “aspx” e un file ‘.jasvascript’ che conterrà del codice che fa uso del ‘Client-Object Modell’.

Iniziamo aggiungendo delle risorse che ci serviranno più avanti.

  1. Aggiungiamo la pagina ‘RecuperaNumeroOrdine.aspx’ in ‘SitePages’.
  2. Aggiungiamo una ‘Style Library’ e aggiungiamo un file di tipo ‘Javascript’ che chiameremo ad esempio :MyFunction.js, inizialmente vuoto.
  3. Procuriamoci il file : jquery-1.9.1.min.js da qui Jquery e aggiungiamo anche questo alla libreria.

Step 1: Custom Action sulla lista ‘Ordini Testata’.
Premessa : Esistono diversi modi per modificare l’ECB della lista, in questo esercizio svilupperemo una soluzione ‘Sandbox’ che conterrà una Feature per installare la personalizzazione. Nello specifico la personalizzazione non è altro che un file ‘XML’ contenente appunto l’elemento ‘Custom Action’. Questo elemento con tutti gli attributi è descritto bene qui : Custom Action – MSDN.
Nel caso in esame non utilizzeremo tutti gli attributi, ma è sempre bene conoscere l’elemento che si utilizza nella sua completezza e in questo la documentazione in linea è molto precisa. Fine Premessa.
Per configurare la “custom action” partiamo con il crere un nuovo progetto in Visual Studio, selezionando : SharePoint 2013 -> Progetto vuoto.
Diamogli un nome significativo, come ad esempio : CustomActionsOrdini e selezioniamo come tipo di distribuzione ‘Sandbox Solution’.
Fatto questo, aggiungiamo alla soluzione  un elemento seguendo queste indicazioni : tasto destro sul nome del progetto -> Aggiungi -> Nuovo Elemento.
Selezioniamo un elemento di tipo : Modulo e diamogli un nome del tipo :TestataCustomActions.
Visual Studio aggiungerà in automatico due file:
-Elements.xml
-Sample.txt

A questo punto la “solution” sarà questa:

4

 

 

 

 

 

 

Eliminiamo il secondo file e apriamo il primo, che conterrà la nostra Custom Action.
All’interno di ‘Elements.xml’ copiamo il codice seguente:

<?xml version="1.0" encoding="utf-8"?>
 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
 <CustomAction
  Location="EditControlBlock"
  RegistrationType="List"
  RegistrationId="{499BA418-228E-499C-A322-943BF6B6BC86}"
   GroupId="GestioneOrdini"
  Id="MS.CustomOrdini"
  Title="Dettaglio dell' ordine"
  Rights="ViewListItems,EditListItems"
  Description="Visualizza il dettaglio dell'ordine."
  >
     <UrlAction Url="/SitePages/RecuperaNumeroOrdine.aspx?ItemId={ItemId}&amp;ListId={ListId}" />
   </CustomAction>
 </Elements>

Vediamo  nel dettaglio le proprietà che abbiamo utilizzato

  • Location-> indica l’oggetto da modificare, in questo caso appunto l’ECB
  • RegistrationType-> la custom action può essere attivata su un oggetto specifico, una lista specifica o un content type specifico. Nel caso in esame voglio modificare l’ECB solo di una specifica lista, quindi questa proprietà combinata alla successiva, fa in modo che la modifica si attivi solo per la lista ‘Ordini Testata’.
  • RegistrationId-> indico la lista specificando il GUID. Per ricavare il valore si può, ad esempio, aprire la lista con SharePoint Designer e tra le proprietà visibili c’è anche l’ID.
  • Id->identificativo univico.
  • Title->Testo da visualizzare nel menu
  • Description->Descrizione visibile passando il mouse sull’opzione del menu.
  • Rights->Indica quali permessi siano necessari per visulizzare l’opzione. E’ una proprietà molto importante perché ci permette di condizionare la personalizzazione in maniera coerente rispetto i permessi che ha l’utente.
  • UrlAction-> Questo elemento è un ‘child’, può essere presente solo uno di questo elemento nella custom action. Nell’esempio in esame ho indicato la pagina : RecuperaNumeroOrdine.aspx che sarà spiegata nel dettaglio più avanti. L’aspetto da sottolineare è il seguente : la query string contiene queste informazioni:
    • ItemId={ItemId}
    • ListId={ListId}

La prima variabile conterrà l’ID delle’elemento nella lista ed il secondo conterrà l’ID della lista. Con queste due informazioni posso recuperare l’elemento dalla lista e accedere a tutti i valori; anticipo che è quello che faremo nella pagina :RecuperaNumeroOrdine.aspx

Installiamo e attiviamo la feature, facendo il ‘Deploy’ da Visual Studio e verifichiamo la personalizzazione! Se ha funzionato vedremo questo:

2

 

 

 

 

Completiamo la prova cliccando sul link, in questo momento dovremo solo visualizzare la pagina che abbiamo aggiunto all’inizio.

3

 

 

Step 2: Vista sull’elenco di dettaglio.
Aggiungiamo una vista sulla lista di dettaglio, includendo tutti i campi personali e con queste caratteristiche:
Filtro
Filtro

 

 

 

Come filtro abbiamo aggiunto la variabile : {Param1} che vedremo dopo a cosa serve.

Group by
GB

 

 

 

 

Totali
Totali

 

 

Salviamo la vista e proviamola inserendo nella URL alla fine dell’indirizzo un espressione per il filtro valido cioè : Param1=AB100 (avendo inserito un dettaglio su questo ordine):

Dtt

 

 

 

 

 

Riepiloghiamo.
Abbiamo le due liste collegate tra loro tramite il campo di ‘LookUp’ ‘Ordine numero’.
Abbiamo modificato l’ECB della lista ‘Ordine Testata’ per andare in una pagina intermedia.
Abbiamo aggiunto una Vista sulla liste ‘Ordine Dettaglio’ che mi consente di filtrare sul campo ‘Ordine numero’, passando un valore in query string.
A questo punto potrebbe sorgere un dubbio : perché non  uso l’ActionUrl per andare direttamente nella vista passando il valore del numero di ordine? Rivediamo l’ActionUrl:
/SitePages/RecuperaNumeroOrdine.aspx?ItemId={ItemId}&amp;ListId={ListId}
Il motivo è il seguente : nella query string non posso accedere a qualunque campo della lista sono ‘limitato’ ad alcuni attributi. Il compito della pagina intermedia è quindi quella di accedere alla lista ‘Ordini Testata’ recuperando la riga dell’ordine dalla lista ‘Testata’ (in base al valore di ‘ItemId’) e con un redirect ‘client-side’ passare alla nostra vista aggiungendo nella query string il valore del campo ‘Ordine numero’.

Ci manca questo ultimo pezzo…procediamo!

Step 3: Funzioni client-side e pagina intermedia.
Apriamo il sito con “SharePoint Designer”  e iniziamo con modificare la pagina ‘aspx’ :RecuperaNumeroOrdine.aspx.

In corrispondenza del TAG : PlaceHolderAdditionalPageHead; aggiungiamo i riferimenti alle risorse che dovremmo già aver aggiunto in precedenza e inseriamo la chiamata alla funzione client-side ‘ RecuperaNumOrdine()’ che vedremo più avanti:

<asp:Content ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">
 <meta name="CollaborationServer" content="SharePoint Team Web Site" />
 <SharePoint:ScriptBlock runat="server">
 var navBarHelpOverrideKey = &quot;WSSEndUser&quot;; </SharePoint:ScriptBlock>
 <SharePoint:RssLink runat="server"/>
  <script type="text/javascript" src="../Style Library/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.runtime.js"></script>
    <script type="text/javascript" src="/_layouts/15/sp.js"></script>
 <script type="text/javascript" src="../Style Library/MyFunction.js"></script>
 <!--Chiamo la funzione-->
 <script type="text/javascript">
 $(document).ready(function () {
     RecuperaNumOrdine();
 });
 </script>
 </asp:Content>

Passiamo quindi al contenuto del file Javascript e apriamo il file ‘MyFunction.js’. Quello che ci serve è accedere tramite il ‘client-object modell’ alla lista e all’elemento specifico della lista per recuperare l’ordine e accedere finalmente alla proprietà che ci interessa:
Funzione JS principale:RecuperaNumOrdine.

//Definizioni variabili
var titleList="Ordini Testata";
var idItem="";
var itemID;
//Definizioni variabili:Fine

function RecuperaNumOrdine(){
 try {
 //recuperiamo dalla query string la ID della lista e dell'elemento in lista
 idItem=getUrlVars()["ItemId"];
 //
 var ctx = new SP.ClientContext.get_current();
 var list = ctx.get_web().get_lists().getByTitle(titleList);
var query = "<View><ViewFields><FieldRef Name='ID'/></ViewFields></View>";
 var camlQuery = new SP.CamlQuery();
 //Query CAML per recuperare l'elemento
 camlQuery.set_viewXml(
 '<View><Query><Where>' +
 '<Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + 
idItem+ '</Value></Eq>' +
 '</Where></Query></View>'
 );
 itemID= list.getItems(camlQuery);
 ctx.load(itemID, 'Include(ID,Numero_x0020_Ordine)');
 ctx.executeQueryAsync(Function.createDelegate(this, this.queryDettaglio), 
Function.createDelegate(this, this.error));
} catch (e) {
 alert('OPS!Si è verificato un errore :-(. ' +'\n'+e.get_message());
 }
 }

In questa funzione, ci sono da evidenziare un paio di aspetti:

  • ctx.get_web().get_lists().getByTitle(titleList) -> accediamo alla lista in base al titolo.
  • camlQuery.set_viewXml -> impostiamo la query che rispetta la sintassi CAML per filtrare sulla colonna di sistema “ID” che rappresenta la chiave nella lista.
  • ctx.load(itemID, ‘Include(ID,Numero_x0020_Ordine)’) -> con questo passaggio stiamo chiedendo di farci restituire solo i campi specificati. Questo passaggio è fondamentale per l’aspetto delle prestazioni. Riducendo il numero di campi che ci facciamo restituire, diminuisce il “peso” della struttura del file  XML restituito e aumentano quindi le prestazioni.

Funzione per recuperare il parametro dalla Query String.

function getUrlVars() {
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for (var i = 0; i < hashes.length; i++) {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;


}

Funzioni: “queryDettaglio” ed “error”.

function queryDettaglio() {
	var NumeroOrdine;
    try {       
        NumeroOrdine= itemID.getItemAtIndex(0).get_item('Numero_x0020_Ordine')
		//Con il numero di ordine passao alla lista del dettaglio 
		//con la vista parametrizzata
       window.location.replace('/Lists/Ordini%20Dettaglio/Dettaglio.aspx?Param1='
+NumeroOrdine);

    } catch (e) {
       alert('OPS!Si è verificato un errore :-(. ' +'\n'+e.get_message());
    }
}
//
function error(sender, args) {

    alert('OPS!Si è verificato un errore :-(. ' + args.get_message()
 + '\n' + args.get_stackTrace());

}

La funzione “queryDettaglio” viene eseguita solo se la richiesta ‘client-side’ va a buon fine e accedendo al primo elemento nell’oggetto ‘itemID’ (abbiamo filtrato sulla chiave) e da qui prendiamo il valore del campo che ci interessa.

Finalmente con una banale istruzione ‘window.location.replace..’ andiamo nella lista eseguendo la vista che accetta il filtro in query string.

Alla prossima!

Pubblicato in Personalizzare la UI di Sharepoint | Contrassegnato , | Lascia un commento