-
Notifications
You must be signed in to change notification settings - Fork 898
Port OneNote hero sample to this repo #991
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AlexJerabek
wants to merge
17
commits into
OfficeDev:main
Choose a base branch
from
AlexJerabek:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
682df06
Add sample to local fork (#1)
AlexJerabek aadad59
Add top level link and description (#2)
AlexJerabek 96789dd
Fix manifest URL
AlexJerabek eff14aa
Merge branch 'main' of https://github.com/AlexJerabek/Office-Add-in-s…
AlexJerabek de19fdc
Refresh hosted site (#3)
AlexJerabek 34d7d5a
Reverting HTML
AlexJerabek e74aa5a
Merge branch 'github-hosting' into main
AlexJerabek 16dcdb7
Merge pull request #4 from AlexJerabek/main
AlexJerabek 784fffc
Add localhost manifest
AlexJerabek f4543e6
Update image
AlexJerabek 8d6597b
Merge pull request #5 from AlexJerabek/github-hosting
AlexJerabek 7139c57
Case sensitive
AlexJerabek eb2e027
Update readme with localhost instructions
AlexJerabek dd00261
Merge pull request #6 from AlexJerabek/github-hosting
AlexJerabek b63348e
Update Samples/onenote-add-in-rubric-grader/manifest.xml
AlexJerabek 23008bf
Apply suggestions from code review
AlexJerabek 5c5c3b2
PR Feedback
AlexJerabek File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
bower_components/ | ||
node_modules/ | ||
.vscode/ | ||
npm-debug.log | ||
localhost.crt | ||
localhost.key |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) Microsoft Corporation | ||
All rights reserved. | ||
|
||
MIT License: | ||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
--- | ||
title: "Rubric grader task pane add-in for OneNote on the web" | ||
page_type: sample | ||
urlFragment: onenote-add-in-rubric-grader | ||
products: | ||
- m365 | ||
- office | ||
- office-onenote | ||
languages: | ||
- javascript | ||
extensions: | ||
contentType: samples | ||
technologies: | ||
- Add-ins | ||
createdDate: 6/17/2025 4:00:00 PM | ||
description: Explore the basics of OneNote add-ins with a sample tool for teachers. | ||
--- | ||
|
||
# Rubric grader task pane add-in for OneNote on the web | ||
|
||
## Summary | ||
|
||
The Rubric Grader sample shows you how to use the OneNote JavaScript API in a OneNote task pane add-in. The add-in gets page content, adds an outline to the page, and opens a different page. | ||
|
||
The add-in helps teachers grade writing assignments based on a grading rubric. | ||
|
||
 | ||
|
||
## Features | ||
|
||
- Interact with OneNote through a custom task pane | ||
|
||
## Applies to | ||
|
||
- OneNote on the web | ||
|
||
## Prerequisites | ||
|
||
- A Microsoft 365 tenant | ||
|
||
## Solution | ||
|
||
| Solution | Author(s) | | ||
|---------|----------| | ||
| Rubric grader task pane add-in for OneNote on the web | Microsoft | | ||
|
||
## Version history | ||
|
||
| Version | Date | Comments | | ||
|---------|------|---------| | ||
| 1.0 | 6-17-2025 | Initial release | | ||
|
||
## Run the sample | ||
|
||
You can run this sample in Onenote in a browser. The add-in web files are served from this repo on GitHub. | ||
|
||
1. Download the **manifest.xml** file from this sample to a folder on your computer. | ||
1. Open [Office on the web](https://office.live.com/). | ||
1. Under **Apps**, choose **OneNote**. | ||
1. Open a notebook that contains a couple of pages. Make sure at least one page has a paragraph of content. | ||
1. Open the **Insert** tab on the ribbon and choose **Office Add-ins**. | ||
1. On the **Office Add-ins** dialog, select the **MY ADD-INS** tab, choose **Upload My Add-in**. | ||
AlexJerabek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
1. Browse to the add-in manifest file, and then select **Upload**. | ||
1. Verify that the add-in loaded successfully. You will see a **Show Taskpane** button on the **Home** tab on the ribbon. | ||
AlexJerabek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Once the add-in is loaded use the following steps to try out the functionality. | ||
|
||
## Run the sample from localhost | ||
|
||
If you prefer to configure a web server and host the add-in's web files from your computer, use the following steps. | ||
|
||
1. Install a recent version of [npm](https://www.npmjs.com/get-npm) and [Node.js](https://nodejs.org/) on your computer. To verify if you've already installed these tools, run the commands `node -v` and `npm -v` in your terminal. | ||
AlexJerabek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
1. You need http-server to run the local web server. If you haven't installed this yet, you can do this with the following command. | ||
|
||
```console | ||
npm install --global http-server | ||
``` | ||
|
||
1. You need Office-Addin-dev-certs to generate self-signed certificates to run the local web server. If you haven't installed this yet, you can do this with the following command. | ||
|
||
```console | ||
npm install --global office-addin-dev-certs | ||
``` | ||
|
||
1. Clone or download this sample to a folder on your computer, then go to that folder in a console or terminal window. | ||
|
||
1. Run the following command to generate a self-signed certificate to use for the web server. | ||
|
||
```console | ||
npx office-addin-dev-certs install | ||
``` | ||
|
||
This command will display the folder location where it generated the certificate files. | ||
AlexJerabek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
1. Go to the folder location where the certificate files were generated, then copy the **localhost.crt** and **localhost.key** files to the cloned or downloaded sample folder. | ||
|
||
1. Run the following command. | ||
|
||
```console | ||
http-server -S -C localhost.crt -K localhost.key --cors . -p 3000 | ||
``` | ||
|
||
The http-server will run and host the current folder's files on localhost:3000. | ||
|
||
1. Now that your localhost web server is running, you can sideload the **manifest-localhost.xml** file provided in the sample folder. Using this file, follow the steps in [Run the sample](#run-the-sample) to sideload and run the add-in. | ||
|
||
## Questions and feedback | ||
|
||
- Did you experience any problems with the sample? [Create an issue](https://github.com/OfficeDev/Office-Add-in-samples/issues/new/choose) and we'll help you out. | ||
- We'd love to get your feedback about this sample. Go to our [Office samples survey](https://aka.ms/OfficeSamplesSurvey) to give feedback and suggest improvements. | ||
- For general questions about developing Office Add-ins, go to [Microsoft Q&A](https://learn.microsoft.com/answers/topics/office-js-dev.html) using the office-js-dev tag. | ||
|
||
## Copyright | ||
|
||
Copyright (c) 2025 Microsoft Corporation. All rights reserved. | ||
|
||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments. | ||
|
||
<img src="https://pnptelemetry.azurewebsites.net/pnp-officeaddins/samples/onenote-add-in-rubric-grader" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* Common app styling */ | ||
|
||
.padding-header { | ||
padding: 30px 30px 20px 20px; | ||
} | ||
|
||
.padding-body { | ||
padding: 5px 20px; | ||
} | ||
|
||
.padding-top { | ||
padding: 25px 0px 0px 0px; | ||
} | ||
|
||
#notification-message { | ||
background-color: #818285; | ||
color: #fff; | ||
position: absolute; | ||
width: 100%; | ||
min-height: 80px; | ||
right: 0; | ||
z-index: 100; | ||
bottom: 0; | ||
display: none; /* Hidden until invoked */ | ||
} | ||
|
||
#notification-message #notification-message-header { | ||
font-size: medium; | ||
margin-bottom: 10px; | ||
} | ||
|
||
#notification-message #notification-message-close { | ||
background-image: url("../Images/Close.png"); | ||
background-repeat: no-repeat; | ||
width: 24px; | ||
height: 24px; | ||
position: absolute; | ||
right: 5px; | ||
top: 5px; | ||
cursor: pointer; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
const app = (function(){ // jshint ignore:line | ||
AlexJerabek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'use strict'; | ||
|
||
let self = {}; | ||
|
||
// Common initialization function (to be called from each page) | ||
self.initialize = function(){ | ||
jQuery('body').append( | ||
'<div id="notification-message">' + | ||
'<div class="padding">' + | ||
'<div id="notification-message-close"></div>' + | ||
'<div id="notification-message-header"></div>' + | ||
'<div id="notification-message-body"></div>' + | ||
'</div>' + | ||
'</div>'); | ||
|
||
jQuery('#notification-message-close').click(function(){ | ||
jQuery('#notification-message').hide(); | ||
}); | ||
|
||
// After initialization, expose a common notification function | ||
self.showNotification = function(header, text){ | ||
jQuery('#notification-message-header').text(header); | ||
jQuery('#notification-message-body').text(text); | ||
jQuery('#notification-message').slideDown('fast'); | ||
}; | ||
}; | ||
|
||
return self; | ||
})(); |
146 changes: 146 additions & 0 deletions
146
Samples/onenote-add-in-rubric-grader/app/home/grader.fabricdropdownhelper.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* | ||
* Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. | ||
* See LICENSE in the project root for license information. | ||
*/ | ||
|
||
// Helper based on Office UI Fabric dropdown, which hides the original 'select' dropdown and | ||
// creates a "fake" dropdown that can be more easily styled across browsers. | ||
// http://dev.office.com/fabric/components/dropdown | ||
function useFabricDropdown (id) { | ||
var $dropdownWrapper = $('#' + id), | ||
$originalDropdown = $dropdownWrapper.children('.ms-Dropdown-select'), | ||
$originalDropdownOptions = $originalDropdown.children('option'), | ||
newDropdownTitle = '', | ||
newDropdownItems = '', | ||
newDropdownSource = ''; | ||
|
||
/** Go through the options to fill up newDropdownTitle and newDropdownItems. */ | ||
$originalDropdownOptions.each(function (index, option) { | ||
|
||
/** If the option is selected, it should be the new dropdown's title. */ | ||
if (option.selected) { | ||
newDropdownTitle = option.text; | ||
} | ||
|
||
/** Add this option to the list of items. */ | ||
newDropdownItems += '<li class="ms-Dropdown-item' + ( (option.disabled) ? ' is-disabled"' : '"' ) + '>' + option.text + '</li>'; | ||
|
||
}); | ||
|
||
/** Insert the replacement dropdown. */ | ||
newDropdownSource = '<span class="ms-Dropdown-title">' + newDropdownTitle + '</span><ul class="ms-Dropdown-items">' + newDropdownItems + '</ul>'; | ||
$dropdownWrapper.append(newDropdownSource); | ||
|
||
function _openDropdown(evt) { | ||
if (!$dropdownWrapper.hasClass('is-disabled')) { | ||
|
||
/** First, let's close any open dropdowns on this page. */ | ||
$dropdownWrapper.find('.is-open').removeClass('is-open'); | ||
|
||
/** Stop the click event from propagating, which would just close the dropdown immediately. */ | ||
evt.stopPropagation(); | ||
|
||
/** Before opening, size the items list to match the dropdown. */ | ||
var dropdownWidth = $(this).parents(".ms-Dropdown").width(); | ||
$(this).next(".ms-Dropdown-items").css('width', dropdownWidth + 'px'); | ||
|
||
/** Go ahead and open that dropdown. */ | ||
$dropdownWrapper.toggleClass('is-open'); | ||
$('.ms-Dropdown').each(function(){ | ||
if ($(this)[0] !== $dropdownWrapper[0]) { | ||
$(this).removeClass('is-open'); | ||
} | ||
}); | ||
|
||
/** Temporarily bind an event to the document that will close this dropdown when clicking anywhere. */ | ||
$(document).bind("click.dropdown", function() { | ||
$dropdownWrapper.removeClass('is-open'); | ||
$(document).unbind('click.dropdown'); | ||
}); | ||
} | ||
} | ||
|
||
/** Toggle open/closed state of the dropdown when clicking its title. */ | ||
$dropdownWrapper.on('click', '.ms-Dropdown-title', function(event) { | ||
_openDropdown(event); | ||
}); | ||
|
||
/** Keyboard accessibility */ | ||
$dropdownWrapper.on('keyup', function(event) { | ||
var keyCode = event.keyCode || event.which; | ||
// Open dropdown on enter or arrow up or arrow down and focus on first option | ||
if (!$(this).hasClass('is-open')) { | ||
if (keyCode === 13 || keyCode === 38 || keyCode === 40) { | ||
_openDropdown(event); | ||
if (!$(this).find('.ms-Dropdown-item').hasClass('is-selected')) { | ||
$(this).find('.ms-Dropdown-item:first').addClass('is-selected'); | ||
} | ||
} | ||
} | ||
else if ($(this).hasClass('is-open')) { | ||
// Up arrow focuses previous option | ||
if (keyCode === 38) { | ||
if ($(this).find('.ms-Dropdown-item.is-selected').prev().siblings().size() > 0) { | ||
$(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').prev().addClass('is-selected'); | ||
} | ||
} | ||
// Down arrow focuses next option | ||
if (keyCode === 40) { | ||
if ($(this).find('.ms-Dropdown-item.is-selected').next().siblings().size() > 0) { | ||
$(this).find('.ms-Dropdown-item.is-selected').removeClass('is-selected').next().addClass('is-selected'); | ||
} | ||
} | ||
// Enter to select item | ||
if (keyCode === 13) { | ||
if (!$dropdownWrapper.hasClass('is-disabled')) { | ||
|
||
// Item text | ||
var selectedItemText = $(this).find('.ms-Dropdown-item.is-selected').text(); | ||
|
||
$(this).find('.ms-Dropdown-title').html(selectedItemText); | ||
|
||
/** Update the original dropdown. */ | ||
$originalDropdown.find("option").each(function(key, value) { | ||
if (value.text === selectedItemText) { | ||
$(this).prop('selected', true); | ||
} else { | ||
$(this).prop('selected', false); | ||
} | ||
}); | ||
$originalDropdown.change(); | ||
|
||
$(this).removeClass('is-open'); | ||
} | ||
} | ||
} | ||
|
||
// Close dropdown on esc | ||
if (keyCode === 27) { | ||
$(this).removeClass('is-open'); | ||
} | ||
}); | ||
|
||
/** Select an option from the dropdown. */ | ||
$dropdownWrapper.on('click', '.ms-Dropdown-item', function () { | ||
if (!$dropdownWrapper.hasClass('is-disabled')) { | ||
|
||
/** Deselect all items and select this one. */ | ||
$(this).siblings('.ms-Dropdown-item').removeClass('is-selected'); | ||
$(this).addClass('is-selected'); | ||
|
||
/** Update the replacement dropdown's title. */ | ||
$(this).parents().siblings('.ms-Dropdown-title').html($(this).text()); | ||
|
||
/** Update the original dropdown. */ | ||
var selectedItemText = $(this).text(); | ||
$originalDropdown.find("option").each(function(key, value) { | ||
if (value.text === selectedItemText) { | ||
$(this).prop('selected', true); | ||
} else { | ||
$(this).prop('selected', false); | ||
} | ||
}); | ||
$originalDropdown.change(); | ||
} | ||
}); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.