The flyout element that contains the repeater that will be displayed, populated with options
<!-- Flyout Control -->
<div id="flyout-control" data-win-control="WinJS.UI.Flyout">
<div id="flyout-repeater" data-win-control="XboxJS.UI.Repeater"></div>
</div>
Creates a button with a label, which when clicked will invoke the flyout with its values
<div id="flyout-invoker-template" data-win-control="WinJS.Binding.Template">
<div data-win-control="XboxJS.UI.ItemContainer" class="flyout-invoker">
<div class="flyout-invoker-layout-grid">
<div class="flyout-invoker-image-container"><img data-win-bind="src: imageUrl"></div>
<div class="flyout-invoker-label black-text white-stroke cap-first" data-win-bind="innerText: label"></div>
<div class="flyout-invoker-selected-container black-text white-stroke cap-first" data-win-bind="innerText: selected"></div>
</div>
</div>
</div>
When a flyout appears on screen, each item in the flyout should use this template
<!-- Flyout Option Item Template -->
<div id="flyout-option-template" data-win-control="WinJS.Binding.Template" class="win-hidden" data-win-options="{extractChild: 'true'}">
<!-- extractChild: https://msdn.microsoft.com/en-us/library/windows/apps/dn301970.aspx -->
<div data-win-control="XboxJS.UI.ItemContainer" class="flyout-option-container">
<div class="flyout-layout-grid">
<div class="flyout-option-image-container win-hidden"><img data-win-bind="src: flyoutOptionImage"></div>
<div class="flyout-option-name" data-win-bind="innerText: flyoutOptionText"></div>
</div>
</div>
</div>
Sets template and data for flyout, then shows flyout anchored to the specified item
Flyout Parameters | Notes |
---|---|
.control | Flyout Control element that will be shown/hidden |
.repeater | Repeater HTML control inside the flyout |
.templates.invoker | Template to display for the button to show/invoke the flyout |
.templates.option | Template to display for each item in the flyout |
_createFlyoutInvokerControl: function (flyout, sourceData, callback) {
// Create a button, with sourceData
// Wire up the invoked event for the button
// Button Invoked displays the flyout control with the sourceData values
// Option Invoked sets the invoker value to sourceData.selected, hides the flyout and calls the callback if provided
// Flyout config object:
// var flyout = {
// control: '#flyout-control',
// repeater: '#flyout-repeater',
// templates: {
// invoker: '#flyout-invoker-template',
// option: '#flyout-option-template'
// }
// }
// sourceData is in object that is bound to the flyoutInvoker
// Contains name, **imageUrl** and anything else to be data-win-bound into the invoker control
// **values** - Contains a list of data to populate the flyout
// **selected** - Contains a field for the selected parameter
var baseErrorMessage = "Error creating flyout invoker: ";
if(!flyout) throw new Error(baseErrorMessage + "no flyout");
if(!flyout.control || !flyout.control.winControl) throw new Error(baseErrorMessage + "no flyout control");
if(!flyout.repeater) throw new Error(baseErrorMessage + "no flyout repeater");
if(!flyout.templates.invoker || !flyout.templates.invoker.winControl) throw new Error(baseErrorMessage + "no invoker template");
if(!flyout.templates.option || !flyout.templates.option.winControl) throw new Error(baseErrorMessage + "no option template");
if(!sourceData) throw new Error(baseErrorMessage + "no source data");
if(!sourceData.values) throw new Error(baseErrorMessage + "no source data values");
if(!sourceData.label) throw new Error(baseErrorMessage + "no source data label");
// Create the button & render the invoker template
var invokerControl = document.createElement('div');
flyout.templates.invoker.winControl.render(sourceData, invokerControl);
// Create an instance template by rendering the option template with invoked event to: set selected, hide, callback
var optionTemplate = function (sourceDataValue) {
var optionErrorMessage = "Error creating flyout option: ";
if(!sourceDataValue) throw new Error(optionErrorMessage + "no source data value");
if(!sourceDataValue.flyoutOptionText) throw new Error(optionErrorMessage + "no source data value flyoutOptionText");
// Create the div & render the option template
var optionElement = document.createElement('div');
flyout.templates.option.winControl.render(sourceDataValue, optionElement);
// Add invoked event to option to set selected, hide and call callback
optionElement.addEventListener('invoked', function (event) {
sourceData.selected = sourceDataValue.flyoutOptionText;
flyout.control.winControl.hide();
if (callback) callback(sourceDataValue, sourceData);
});
// Return the instance of the template
return optionElement;
};
// Create the binding list of values for the repeater
var bindingData = new WinJS.Binding.List(sourceData.values);
// Create the button invoked event to show the flyout & data
invokerControl.addEventListener('invoked', function () {
if (!flyout.repeater.winControl) return;
flyout.repeater.winControl = null; // Resets the repeater winControl
flyout.repeater.winControl = new XboxJS.UI.Repeater(flyout.repeater); // Creates a new winControl in place of the old one
flyout.repeater.winControl.template = optionTemplate; // Binds the template for the repeater to the provided template
flyout.repeater.winControl.data = bindingData; // Bind the data to the repeater
flyout.control.winControl.show(invokerControl); // Show the flyout
});
// Return button
return invokerControl;
}
// Define the flyout control elements
var flyout = {
control: document.querySelector('#flyout-control'),
repeater: document.querySelector('#flyout-repeater'),
templates: {
invoker: document.querySelector('#flyout-invoker-template'),
option: document.querySelector('#flyout-option-template')
}
}
// Define the data
var cardTypes = {
label: "Card Type",
imageUrl: undefined,
selected: undefined,
values: [
{
flyoutOptionImage: undefined,
flyoutOptionText: "Visa"
},
{
flyoutOptionImage: undefined,
flyoutOptionText: "MasterCard"
},
{
flyoutOptionImage: undefined,
flyoutOptionText: "American Express"
}
]
}
// Create the button, option templates and click events
_createFlyoutInvokerControl(flyout, cardTypes, function cardTypeClicked(cardType){
console.log("User clicked on " + cardType.flyoutOptionText);
console.log("Card Types has .selected " + cardTypes.selected);
});