Mega Menu using SharePoint Framework (SPFx) Extensions

For make mega menu in Morden SharePoint, we can use SharePoint framework’s application customizer under extension category. Mega menu is one of the most important user interfaces in the SharePoint Internet.

SPFx maga menu
For build this mega menu I have used the SharePoint Framework version of 1.8. while create SharePoint project using yeoman generator we have to select No for this question of “Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant?” then select Extension after that select Application Customizer.

SPFx maga menu yo

After the project created, edit the file under src ->extensions then select the TS extension file and import following modules BaseApplicationCustomizer, PlaceholderContent, and PlaceholderName from @microsoft/sp-application-base. After that import files which are required build your mega menu example images or CSS or JS files. Here I just imported one CSS file and one Image file.

I’m using Bulma CSS for build mega menu, in the onInit event bind the changed event into the place holder provider and call the _renderPlaceHolders function in that event.
I using static content of HTML, it can be changed as dynamic content like getting menu link and title from a SharePoint list.

import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import {
  BaseApplicationCustomizer,
  PlaceholderContent,
  PlaceholderName
} from '@microsoft/sp-application-base';


import * as strings from 'MegaMenuSpFxApplicationCustomizerStrings';

const LOG_SOURCE: string = 'MegaMenuSpFxApplicationCustomizer';

require('./bulma.css');
const logo: any = require('./ravilogo.png');


export interface IMegaMenuSpFxApplicationCustomizerProperties {
  Top: string;
}




/** A Custom Action which can be run during execution of a Client Side Application */
export default class MegaMenuSpFxApplicationCustomizer
  extends BaseApplicationCustomizer {
  // These have been added
  private _topPlaceholder: PlaceholderContent | undefined;
  private _bottomPlaceholder: PlaceholderContent | undefined;

  @override
  public onInit(): Promise {
    Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);

    this.context.placeholderProvider.changedEvent.add(this, this._renderPlaceHolders);
    this._renderPlaceHolders();
    return Promise.resolve();
  }

  private _renderPlaceHolders(): void {
    console.log("HelloWorldApplicationCustomizer._renderPlaceHolders()");
    console.log(
      "Available placeholders: ",
      this.context.placeholderProvider.placeholderNames
        .map(name => PlaceholderName[name])
        .join(", ")
    );

    // Handling the top placeholder
    if (!this._topPlaceholder) {
      this._topPlaceholder = this.context.placeholderProvider.tryCreateContent(
        PlaceholderName.Top,
        { onDispose: this._onDispose }
      );

      // The extension should not assume that the expected placeholder is available.
      if (!this._topPlaceholder) {
        console.error("The expected placeholder (Top) was not found.");
        return;
      }

      if (this.properties) {
        let topString: string = this.properties.Top;
        if (!topString) {
          topString = "(Top property was not defined.)";
        }

        if (this._topPlaceholder.domElement) {
          this._topPlaceholder.domElement.innerHTML = `
          
        <div class="navbar-brand">
            <a class="navbar-item" href="https://ravichandran.blog/">
                <img src="${logo}" alt="Bulma: a modern CSS framework based on Flexbox" width="112" height="28">
            </a>
            <div class="navbar-burger burger">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </div>

        <div id="navMenubd-example" class="navbar-menu">
            <div class="navbar-start">
                <div class="navbar-item has-dropdown is-hoverable">
                    <a class="navbar-link  is-active" href="#">
                        Docs
                    </a>
                    <div class="navbar-dropdown ">
                        <a class="navbar-item " href="#">Overview</a>
                        <a class="navbar-item " href="#">Modifiers</a>
                        <a class="navbar-item " href="#">Columns</a>
                        <a class="navbar-item " href="#">Layout</a>
                        <a class="navbar-item " href="#">Form</a>
                        <a class="navbar-item " href="#">Elements</a>
                        <a class="navbar-item is-active" href="#">Components</a>
                        <hr class="navbar-divider">
                        <div class="navbar-item">
                            <div>
                                <p class="is-size-6-desktop">
                                    <strong class="has-text-info">0.5.1</strong>
                                </p>
                                <small>
                                    <a class="bd-view-all-versions" href="/versions">View all versions</a>
                                </small>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="navbar-item has-dropdown is-hoverable is-mega">
                    <div class="navbar-link">
                        Blog
                    </div>
                    <div id="blogDropdown" class="navbar-dropdown ">
                        <div class="container is-fluid">
                            <div class="columns">
                                <div class="column">
                                    <h1 class="title is-6 is-mega-menu-title">Sub Menu Title</h1>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                </div>
                                <div class="column">
                                    <h1 class="title is-6 is-mega-menu-title">Sub Menu Title</h1>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">

                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Overview
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Modifiers
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Columns
                                    </a>
                                </div>
                                <div class="column">
                                    <h1 class="title is-6 is-mega-menu-title">Sub Menu Title</h1>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>
                                    <a class="navbar-item" href="#">
                                        <div class="navbar-content">
                                            <p>
                                                <small class="has-text-info">03 Aug 2017</small>
                                            </p>
                                            <p>New feature: list of tags</p>
                                        </div>
                                    </a>

                                </div>
                                <div class="column">
                                    <h1 class="title is-6 is-mega-menu-title">Sub Menu Title</h1>
                                    <a class="navbar-item " href="#">
                                        Overview
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Modifiers
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Columns
                                    </a>
                                    <a class="navbar-item " href="#">
                                        Layout
                                    </a>
                                </div>
                            </div>
                        </div>

                        <hr class="navbar-divider">
                        <div class="navbar-item">
                            <div class="navbar-content">
                                <div class="level is-mobile">
                                    <div class="level-left">
                                        <div class="level-item">
                                            <strong>Stay up to date!</strong>
                                        </div>
                                    </div>
                                    <div class="level-right">
                                        <div class="level-item">
                                            <a class="button bd-is-rss is-small" href="#">
                                                <span class="icon is-small">
                                                    <i class="fa fa-rss"></i>
                                                </span>
                                                <span>Subscribe</span>
                                            </a>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="navbar-item has-dropdown is-hoverable">
                    <div class="navbar-link">
                        More
                    </div>
                    <div id="moreDropdown" class="navbar-dropdown ">
                        <a class="navbar-item " href="#">
                            <div class="level is-mobile">
                                <div class="level-left">
                                    <div class="level-item">
                                        <p>
                                            <strong>Extensions</strong>
                                            <br>
                                            <small>Side projects to enhance Bulma</small>
                                        </p>
                                    </div>
                                </div>
                                <div class="level-right">
                                    <div class="level-item">
                                        <span class="icon has-text-info">
                                            <i class="fa fa-plug"></i>
                                        </span>
                                    </div>
                                </div>
                            </div>
                        </a>
                    </div>
                </div>
                <a class="navbar-item " href="https://ravichandran.blog/">
                     Blog
                </a>
            </div>
        </div>
    `;
        }
      }
    }
  }

  private _onDispose(): void {
    console.log('[HelloWorldApplicationCustomizer._onDispose] Disposed custom top and bottom placeholders.');
  }

}

While you run the application in workbench you will below warning message, click “Load debug scrips” for run our scrips. if you want to install this add-in permanently in the SharePoint check my previous article for deploy in SharePoint

SPFx debug warning

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!

Happy coding!!

Graph API in SharePoint custom page layout

Azure Active Directory App
We have to create an Azure AD app for access graph API, this app will help to access from particular URL and limit the permission to access the particular data, let we see the steps to create the new Azure AD app, we don’t have pay for Azure AD app and It’s always free.

result
Step 1
Sign in to your Azure account https://portal.azure.com, if you don’t have an Azure account the sign-up for a free account.
Step 2
Navigate to Azure Active Directory > App Registration > New application registration

Azure01
Step 3
In the create form give any name for your app and application type is Web app and enter your SharePoint tenet URL in the sign-on URL section then click Create button in the bottom
Step 4
Once app created select the app and click settings then select required permissions, click add and select permission based on your requirement after selected permission don’t forgot click grant permission, this button located next to the Add button
Step 5
Back to select newly created app and click Manifest, in the manifest file oauth2AllowImplicitFlow to true

If you have any questions about creating new custom page layout please refer my previous article Create custom page layout in SharePoint Online

We are used Active Directory Authentication Library (ADAL) JS for authentication, so we have add “adal.min.js” reference in the page layout. In the below JavaScript function we have to pass the Client ID as the Azure AD app ID and subscription id is <your tenant name>.onmicrosoft.com.
Even you want to get or post only while clicking any button, you have to get token once in the document ready event.


$( document ).ready(function() {
"use strict";
var subscriptionId = "ravichandran.onmicrosoft.com"; /* [AzureTenantname] from azure */
var clientId = "6cf00073-3103-4af8-84a4-ee2229e3e83e"; /* [AzureADClientID] from azure */
window.config = {
subscriptionId: subscriptionId,
clientId: clientId,
postLogoutRedirectUri: window.location.origin,
endpoints: {
graphApiUri: 'https://graph.microsoft.com'
},
cacheLocation: 'localStorage' // enable this for IE, as sessionStorage does not work for localhost.
};
var authContext = new AuthenticationContext(config);
// Check For &amp; Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
if (isCallback &amp;&amp; !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
// If not logged in force login
var user = authContext.getCachedUser();
if (user) {
// Logged in already
}
else {
authContext.login();
}
authContext.acquireToken(config.endpoints.graphApiUri, function (error, token) {
if (error || !token) {
console.log('ADAL error occurred: ' + error);
return;
}
var TeamUri = config.endpoints.graphApiUri + "/v1.0/sites/root/lists";
$.ajax({
type: "GET",
url: TeamUri,
headers: { "Authorization": "Bearer " + token, "Content-Type": "application/json" }
}).done(function (response) {
$.each(response.value,function(i,v){
$('#main').append('<p>' + v.displayName + '</p>');
});
}).fail(function (xhr, textStatus, errorThrown) {
if (xhr.responseJSON.error.code.indexOf('AccessDenied') !== -1) {
console.log('Access Denied.');
}
else {
console.log(xhr.responseJSON.error.code);
}
});
});
});

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!

Fabric React DatePicker in SPFx

Fabric React DatePicker in SPFx

As we know Office UI Fabric which is official front-end framework for building a user interface that fits seamlessly into SharePoint modern experience. In this article, we going to see more detail about the Date picker component. Also, we saving and retrieving data into the SharePoint list. Herewith you can find the complete project download link.

Fabric React DatePicker in SPFx

Creating a new SharePoint Framework web part
The first step we have to create new SharePoint framework web part project, I have used SharePoint Framework version 1.8, if you have any question for you then you can refer my one of the previous article where I explained simple steps to set up a new development environment and create the new project. While creating a project in the PowerShell you have to select react framework.

Fabric React DatePicker in SPFx create web part

Important files
In the new SharePoint framework web part solution contains tons of files, understanding each file’s purpose is really awesome, but in this articale we going take look only four files, because making changes in those four files is enough
1. src\webparts\fabricDatePicker\FabricDatePickerWebPart.ts
2. src\webparts\fabricDatePicker\components\IFabricDatePickerProps.ts
3. src\webparts\fabricDatePicker\components\FabricDatePicker.tsx
4. src\webparts\fabricDatePicker\components\FabricDatePicker.module.scss

Web part TS file (FabricDatePickerWebPart.ts)
In this file, we just calling create react element and created element assigned to the react DOM, also we passing web part context as props so we can access this props in while create react component.

 

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import FabricDatePicker from './components/FabricDatePicker';
import { IFabricDatePickerProps, IFabricDatePickerWebpartProps } from './components/IFabricDatePickerProps';
export default class FabricPeoplePickerWebPart extends BaseClientSideWebPart<IFabricDatePickerWebpartProps> {
    public render(): void {
        const element: React.ReactElement<IFabricDatePickerProps> = React.createElement(
          FabricDatePicker,
            {
                spcontect: this.context
            }
        );
        ReactDom.render(element, this.domElement);
    }
}

 

Property file (IFabricDatePickerProps.ts)
In the props file we just created two interfaces, one is IFabricDatePickerProps will pass the props which are read-only, so we only passing context and another one is IFabricDatePickerWebpartProps will carry all states for the react components. so we can set and get values to the controls.

//Set all read only values
export interface IFabricDatePickerProps {
  spcontect?:any|null
}

//Set all read and write only values
export interface IFabricDatePickerWebpartProps {
  birthday?:any|null;
  message:string
}

Component file (FabricDatePicker.tsx)
In this file we do most of the things like building date picker, retiring data from SharePoint and assign that value to the date picker and save changes back into the SharePoint list.
In the constructor, we retrieve the value from SharePoint and assign the value to the date picker also we injecting props to the button click event for accessing all props inside the click event.
In the render event, we returning the HTML content for the user interface,
In the select date event, we receive the value and assign back to the component state
In the format date event, we can set which format date picker have to display the value,
In the button click event, we updating value into the SharePoint list

import * as React from 'react';
import { IFabricDatePickerProps, IFabricDatePickerWebpartProps } from './IFabricDatePickerProps';
import { Environment, EnvironmentType } from '@microsoft/sp-core-library';
import { SPHttpClient, SPHttpClientResponse, ISPHttpClientOptions, IHttpClientOptions } from '@microsoft/sp-http'
import { DatePicker } from 'office-ui-fabric-react/lib/DatePicker';
import { Label } from 'office-ui-fabric-react/lib/Label';
import { PrimaryButton } from 'office-ui-fabric-react/lib/Button';
import styles from './FabricDatePicker.module.scss';

export default class FabricDatePicker extends React.Component<IFabricDatePickerProps, IFabricDatePickerWebpartProps> {

    private etag: String = undefined;
    public constructor(props: IFabricDatePickerProps, state: IFabricDatePickerWebpartProps) {
        super(props);
        this.state = {
            birthday: null,
            message:''
        };

        if (Environment.type === EnvironmentType.SharePoint) {
            this.props.spcontect.spHttpClient.get(this.props.spcontect.pageContext.web.absoluteUrl + '/_api/web/lists/getbytitle(\'sampleLIST\')/items(1)', SPHttpClient.configurations.v1).then
                ((Response: SPHttpClientResponse) => {
                   // this.etag = Response.headers.get('ETag');
                    Response.json().then((listItem: any) => {
                        this.setState({ birthday: new Date(listItem.Birthday) });
                    });
                });

        }
        else if (Environment.type === EnvironmentType.Local) {
            // return (<div>Whoops! you are using local host...</div>);
        }

        this._alertClicked = this._alertClicked.bind(this);
    }

    public render(): React.ReactElement<IFabricDatePickerProps> {
        return (
            <div className={styles.fabricDatePicker}>
                <div id="DivLocalHost"></div>
                <div className={styles.container}>
                    <div className={styles.row}>
                        <Label>Birthday</Label>
                        <DatePicker placeholder="Select a date..."
                            onSelectDate={this._onSelectDate}
                            value={this.state.birthday}
                            formatDate={this._onFormatDate}
                        />
                        <div>
                        <div className={styles.label}>
                        <label>{this.state.message}</label>
                        </div>
                        <div className={styles.button}>                     
                            <PrimaryButton data-automation-id="test"
                                text="Save"
                                onClick={this._alertClicked} />
                        </div>
                        </div>
                    </div>
                </div>
            </div>
        );

    }

    private _onSelectDate = (date: Date | null | undefined): void => {
        this.setState({ birthday: date });
    };

    private _onFormatDate = (date: Date): string => {
        return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear();
    };

    private _alertClicked(): void {
        const body: string = JSON.stringify({
            '__metadata': {
                'type': 'SP.Data.SampleLISTListItem'
            },
            'Birthday': this.state.birthday
        });
        this.props.spcontect.spHttpClient.get(this.props.spcontect.pageContext.web.absoluteUrl + '/_api/web/lists/getbytitle(\'sampleLIST\')/items(1)', SPHttpClient.configurations.v1).then
        ((Response: SPHttpClientResponse) => {
          this.props.spcontect.spHttpClient.post(this.props.spcontect.pageContext.web.absoluteUrl + `/_api/web/lists/getbytitle('sampleLIST')/items(1)`,
          SPHttpClient.configurations.v1,
          {
              headers: {
                  'Accept': 'application/json;odata=nometadata',
                  'Content-type': 'application/json;odata=verbose',
                  'odata-version': '',
                  'IF-MATCH': Response.headers.get('ETag'),
                  'X-HTTP-Method': 'MERGE'
              },
              body: body
          }).then((response: SPHttpClientResponse) => {
              // Access properties of the response object. 
              this.setState({ message: 'Successfully saved' });
              console.log(`Status code: ${response.status}`);
              console.log(`Status text: ${response.statusText}`);

              //response.json() returns a promise so you get access to the json in the resolve callback.
              response.json().then((responseJSON: JSON) => {
                  console.log(responseJSON);
              });
          });
        });

    }

}

Style file (FabricDatePicker.module.scss)
This file contains the CSS module, but we using sass because we wanted to call the CSS class name from javascript as a javascript object.

Date Picker properties
We can customize the date picker using date picker properties, you can find the many properties in the official documentation, here we take look some of them, by default date picker looks like this,

isMonthPickerVisible true

isMonthPickerVisible
this property by default is true, we can make false if we don’t need month picker in the calendar. example

<DatePicker placeholder="Select a date..." isMonthPickerVisible={false}/>

isMonthPickerVisible

minDate
Using this property we can set the minimum date for the date picker, so date picker does not allow to chose less than that. Example

<DatePicker placeholder="Select a date..." minDate={new Date(2000,12,30)}/>

minDate

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!
Source Code Download link

174https://code.msdn.microsoft.com/Fabric-React-DatePicker-in-d25382bb

Simple steps to create a new web part using the SharePoint framework

Microsoft provided extremely detail documentation for setup an environment for SharePoint Framework development, but if you already work in SharePoint then below simple steps pretty enough to set up a development environment and create your first web part using SharePoint framework.

Set up your development environment.

Step 1:

Using below link to sign up for Office 365 Enterprise E3 Trial

http://go.microsoft.com/fwlink/p/?LinkID=403802

Step 2:

For create new create a new app catalog site, go to the SharePoint Admin Centre (https://admin.sharepoint.com) → Apps → App catalog

Step 3:

Create a site collection using  the Developer Site template

Step 4:

Install node JS and Visual Studio code using below like

https://nodejs.org/dist/latest-v8.x/

https://code.visualstudio.com/Download

Step 5:

In the file explorer goto, any folder where you want to create a new project then click shift + right button in the mouse, in the menu select “Open PowerShell window here”

Step 6:

Enter the following command in PowerShell to install Yeoman, gulp, SharePoint web part generator and SSL certificate


npm install -g yo gulp

npm install -g @microsoft/generator-sharepoint

To create a new web part project


md helloworld-webpart

cd helloworld-webpart

yo @microsoft/sharepoint

gulp trust-dev-cert

gulp serve

now you can access your web part in localhost and in the SharePoint /_layouts/workbench.aspx

but still, files are referred from the local host

Enable SharePoint CDN

run below comment in PowerShell to make ready for SharePoint CDN deployment, below PowerShell comments required to run only once for a SharePoint portal.


Connect-SPOService -Url https://-admin.sharepoint.com

Get-SPOTenantCdnEnabled -CdnType Public

Get-SPOTenantCdnOrigins -CdnType Public

Get-SPOTenantCdnPolicies -CdnType Public

Set-SPOTenantCdnEnabled -CdnType Public

Get-SPOTenantCdnOrigins -CdnType Public

Deploy into SharePoint

below PowerShell comments will create a SharePoint package file, file extension will be .sppkg


gulp bundle --ship

gulp package-solution --ship

under SharePoint/solution folder can find the .sppkg extension file, upload that file into the SharePoint’s app catalog and deploy it. Now web part ready to use by everyone.

Weather Add-In for SharePoint

SharePoint weather Add-In can be added on the SharePoint home page (dashboard),  this add-in automatically fetch geolocation from the browser. And based on the location it will retrieve the Temperature, humidity and wind speed etc… you can see the step by step instructions to develop this SharePoint Add-In. Also, the complete project source code is available for download,

Souce Code Download link,

https://code.msdn.microsoft.com/Weather-Add-In-for-9635e488

Weather AddIn

Create new Project in the Visual Studio using “App for SharePoint” template, here I’m using visual studio 2015 version. In the new project wizard select SharePoint-Hosted and rest you can select based on your requirements. The provider-hosted application can also be selected.

I have used the Local-weather GitHub project to implement this Add-In, In the project, you can find the script in the ASPX file.

Add new “Client Web Part (Host Web)” and select “Create a new app web page for the client web part content” (If you want this add-in in the Home page then we have to use new ASPX file instead of default one because it uses SharePoint master page), Edit newly created an ASPX page which is located in the Pages folder and replace with HTML which you find in my project.

        $(document).ready(function () {
            // get location from user's IP address
            $.getJSON('https://ipinfo.io', function (info) {
                var locString = info.loc.split(', ');
                var latitude = parseFloat(locString[0]);
                var longitude = parseFloat(locString[1]);
                $('#location').html('Location: ' + info.city + ', ' + info.region + ', ' + info.country)

                // get weather using OpenWeatherMap API
                $.getJSON('https://cors.5apps.com/?uri=http://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric&APPID=c3e00c8860695fd6096fe32896042eda', function (data) {
                    var windSpeedkmh = Math.round(data.wind.speed * 3.6);
                    var Celsius = Math.round(data.main.temp)
                    var iconId = data.weather[0].icon;
                    var weatherURL = "http://openweathermap.org/img/w/" +
                            iconId + ".png";

                    var iconImg = "<img src='" + weatherURL + "'>";
                    $('#sky-image').html(iconImg);
                    $('#weather-id').html('Skies: ' + data.weather[0].description);

                    $('#temperature').html(Celsius);
                    $('#toFahrenheit').click(function () {
                        $('#temperature').html(Math.round((9 / 5) * Celsius + 32));
                        $('#wind-speed').html(Math.round(windSpeedkmh * 0.621) + ' mph')
                    })
                    $('#toCelsius').click(function () {
                        $('#temperature').html(Celsius);
                        $('#wind-speed').html(windSpeedkmh + ' km/hr')
                    })

                    $('#wind-speed').html(windSpeedkmh + ' km/h');
                    $('#humidity').html('Humidity: ' + data.main.humidity + ' %');

                })
            })
        })
<div class="row">
<div class="col-6">
<div id="sky-image"></div>
<div id="location"></div>
<div id="weather-id"></div>
<div>Temperature: <span id="temperature"></span>&deg<a href="#" id="toCelsius">C</a> | &deg<a href="#" id="toFahrenheit">F</a></div>
<div>Wind speed: <span id="wind-speed"></span></div>
<div id="humidity"></div>
</div>
</div>

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!

Souce Code Download link

https://code.msdn.microsoft.com/Weather-Add-In-for-9635e488

3D Tag cloud links from SharePoint List

3D Tag cloud Add-In can be used on the SharePoint home page to show important links with cool animation, links are retrieved from the Sharepoint list. so users can easily update or add links. In the below, you can see the step by step instructions to develop this SharePoint Add-In. Also, the complete project source code is available for download,

Souce Code Download link

https://code.msdn.microsoft.com/3D-Tag-cloud-links-from-b5fe9220

3D cloud Tag

Create new Project in the Visual Studio using “App for SharePoint” template, here I’m using visual studio 2015 version. In the new project wizard select SharePoint-Hosted and rest you can select based on your requirements. The provider-hosted application can also be selected.

I have used jquery.svg3dtagcloud.min.js to implement this add-in and link data retrieved from SharePoint Links list, So in the SharePoint select “Add a new app” option and filter link, you can find the app called “Links” select that app and you can name whatever you want, I have named as 3DTags, so we don’t have to change anything on this list just directly start to add links on that list.

Links App

Links List

Also, we have to configure the permission on the AppManifest to access the SharePoint list with edit permission.

Add new “Client Web Part (Host Web)” and select “Create a new app web page for the client web part content” (If you want this add-in in the Home page then we have to use new ASPX file instead of default one because it uses SharePoint master page), Edit newly created an ASPX page which is located in the Pages folder and replace with HTML which you find in my project. Add below JS code in the app.js file.


'use strict';

ExecuteOrDelayUntilScriptLoaded(initializePage, "sp.js");

function initializePage()
{
var context = SP.ClientContext.get_current();

// This code runs when the DOM is ready and creates a context object which is needed to use the SharePoint object model
$(document).ready(function () {
getlinks();
});
var linkItems;
// This function prepares, loads, and then executes a SharePoint query to get the current users information
function getlinks() {
var website = context.get_site().get_rootWeb();
var linklist = website.get_lists().getByTitle("3DTags");
var camlQuery = new SP.CamlQuery();
linkItems = linklist.getItems(camlQuery);
context.load(linkItems);
context.executeQueryAsync(onGetLinkSuccess, onGetLinkFail);
}

// This function is executed if the above call is successful
// It replaces the contents of the 'message' element with the user name
function onGetLinkSuccess() {
var entries = [];
var linkEnumerator = linkItems.getEnumerator();
while (linkEnumerator.moveNext()) {
var oListItem = linkEnumerator.get_current();
entries.push({ label: oListItem.get_item('URL').get_description(), url: oListItem.get_item('URL').get_url(), target: '_top' })
}
var settings = {
entries: entries,
width: 480,
height: 480,
//width: '100%',
//height: '100%',
radius: '65%',
radiusMin: 75,
bgDraw: true,
bgColor: '#fff',
opacityOver: 1.00,
opacityOut: 0.05,
opacitySpeed: 6,
fov: 800,
speed: 2,
fontFamily: 'Oswald, Arial, sans-serif',
fontSize: '15px',
fontColor: '#111',
fontWeight: 'normal',
fontStyle: 'normal',
fontStretch: 'normal',
fontToUpperCase: true
};
$('#holder').svg3DTagCloud(settings);
}

// This function is executed if the above call fails
function onGetLinkFail(sender, args) {
console.log('Failed to get links. Error:' + args.get_message());
}
}

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!

Souce Code Download link

174https://code.msdn.microsoft.com/3D-Tag-cloud-links-from-b5fe9220

Text to speech Add-In for SharePoint

Text to speech add-in can be used to speak text contents of the textarea in the SharePoint dashboard. Below you can see step by step instructions to develop this SharePoint Add-In. Also, the complete project source code is available for download,

Souce Code Download link

174https://code.msdn.microsoft.com/Text-to-speech-Add-In-for-af5abf7f

SharePoint Text to Speak

Create new Project in the Visual Studio using “App for SharePoint” template, here I’m using visual studio 2015 version. In the new project wizard select SharePoint-Hosted and rest you can select based on your requirements. The provider-hosted application can also be selected.

I have used articulate.js to implement this add-in, you can find this JavaScript file in the project which is modified by me for fix some issues and some changes, and this JS file implemented using SpeechSynthesis, The SpeechSynthesis interface of the Web Speech API is the controller interface for the speech service;

 

Add new “Client Web Part (Host Web)” and select “Create a new app web page for the client web part content” (If you want this add-in in the Home page then we have to use new ASPX file instead of default one because it uses SharePoint master page), Edit newly created an ASPX page which is located in the Pages folder. Add below JS code and HTML.

</div>
<div>

<%@ Page Language="C#" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<WebPartPages:AllowFraming ID="AllowFraming" runat="server" />

<html>
<head>
<title></title>

<script type="text/javascript" src="../Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/_layouts/15/MicrosoftAjax.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="../Scripts/articulate.js"></script>
<script type="text/javascript">
// Set the style of the client web part page to be consistent with the host web.
(function () {
'use strict';

var hostUrl = '';
if (document.URL.indexOf('?') != -1) {
var params = document.URL.split('?')[1].split('&');
for (var i = 0; i < params.length; i++) {
var p = decodeURIComponent(params[i]);
if (/^SPHostUrl=/i.test(p)) {
hostUrl = p.split('=')[1];
document.write('	<link rel="stylesheet" href="' + hostUrl + '/_layouts/15/defaultcss.ashx" />');
break;
}
}
}
if (hostUrl == '') {
document.write('	<link rel="stylesheet" href="/_layouts/15/1033/styles/themable/corev15.css" />');
}
})();

</script>
</head>
<body>
<textarea id="texttospeck" style="height:200px;width:500px"></textarea>

<input type="button" id="btnSpeak" onclick="javascript: $('#texttospeck').articulate('speak');" value="Speak" />
<input type="button" id="btnPause" onclick="javascript: $('#texttospeck').articulate('pause');" value="Pause" />
<input type="button" id="btnResume" onclick="javascript: $('#texttospeck').articulate('resume');" value="Resume" />
<input type="button" id="btnStop" onclick="javascript: $('#texttospeck').articulate('stop');" value="Stop" />
</body>
</html>

</div>
<div>

Please feel free to let me know if you have any queries in the comment section, I’m happy to help you!!

Souce Code Download link

174https://code.msdn.microsoft.com/Text-to-speech-Add-In-for-af5abf7f