Sharing data between slides
Related links:
- Customising preso creation guide
- Context overview
- Fieldsets overview
- Fieldsets reference
- Testing context data guide
In order to share data between slides, we will be using the deck's context. This is a source of data that holds information specific to the appointment, this data can be queried and used by your slides, as well as updated by them throughout a presentation - making it the perfect medium for sharing data between the slides of your deck.
Now let's get stuck in and learn how to use the context!
Generating your context
First up, we'll need to generate the context, to do this, we'll be using fieldsets. Read on to learn how to import the fieldsets hook and get started.
Add fieldsets interface to hooks
Let's set it up so that the CDK and LivePreso recognise that you want
to deal with fieldsets. First you will want to create a hooks file, use
the hooks
object in the project.yaml
to define where in your deck your
hooks.js
file is located.
project.yaml
hooks: js/hooks.js
Second, we'll need a fieldsets file. In general, you place this
in js/hooks/fieldsets.js
. To this file you will add the bare minimum
for fieldsets to be loaded.
fieldsets.js
export default function (options) {
const { Fieldset } = options;
return new Fieldset({});
}
hooks.js
Going back to our hooks.js
file, you need to export the hook:
import Fieldsets from "./hooks/fieldsets.js";
export default {
fieldsets: Fieldsets,
};
That's it! The CDK and LivePreso now read fieldsets.
Generating the context
The context is almost entirely generated by fieldsets, and is only
added to as your deck needs it. Modifying context can be
done globally on three separate events: onLoad
, and onSave
, at least
while there are no fields available.
export default function (options) {
const { Fieldset } = options;
return new Fieldset({
onLoad() {
return {
context: {
onLoadField: true,
},
};
},
onSave() {
return {
context: {
onSaveField: true,
},
};
},
});
}
If you test this in the CDK or LivePreso app, you will notice on load the
onLoadField
key has been added to the context. When you press Run
(analogous to pressing save in the preso create screen), it will add the
onSaveField
key to the context as well.
Note how the context in each function is merged together, rather than
overwriting each other.
The result of our context after save is:
{
"fields": {},
"onLoadField": true,
"onSaveField": true
}
Populating the context on preso creation
Now that you know how to add context, it's probably a good idea to start adding useful information to your presentations. Each function exposed by fieldsets exposes an object containing useful information about the state of fieldsets and the preso at different stages of its creation. From field state, to customers and contacts selected, this can be used to create useful context.
Let's make use of data associated with the appointment - specifically adding the names of the contacts to our context, as this is something that might be done often.
export default function (options) {
const { Fieldset } = options;
return new Fieldset({
onSave({ data }) {
return {
context: {
attendees: data.contacts.map((contact) => contact.fullName),
},
};
},
});
}
Generally it's best to only add the data you need into your context, keeping it simpler to navigate and access what you need.
Now if you were wanting to access to the list of your attendees in your presentation, you could use:
Bridge.Context.get("attendees");
See the fieldsets options reference for more information on the data available.
Accessing context data from your deck
Once you've finished generating your context, you'll be wanting to access that data from a slide.
Your first option is to use Bridge.Context.get
.
This function includes the ability to supply an optional default value,
which is returned if nothing is found for your supplied key.
// fetch the toggle state, or default to 'on' if it is not set.
var state = Bridge.Context.get("toggle-button-state", "on");
If you choose not to supply a default, be extra careful to add validation and tests to the data you receive. You may otherwise find yourself with broken content in the wild.
Robust selection
Similar to accessing data from feeds, we highly
recommend the use of robust selection to help prevent null
values from being returned by your queries, and
breaking your content.
To make use of JSONSelect's robust selection when querying the context, there are only two things you need to do:
- First, you must decide whether you expect a single value or multiple
values every time you select something from the
context, then use
Bridge.Context.match
orBridge.Context.match_many
appropriately. - Second, you must provide a default value whenever you use either of these functions, in case there are unexpected problems with the feed.
See jsonselect for the documentation on how these selectors work.
Logging
Unlike feeds logging - which provides
a stream of results for each call (failures and successes included), context
use only logs warnings to the console - ie. when a key is missing, no default
was supplied for a match
or match_many
, or when a key returned more
results than expected.
Saving data to the context from your deck
In the calculator and questionnaire example we mentioned in the
context overview, you will want to
save certain updated values to the context in order for them to be
referenced again in a later viewing. In order to do this, you will use
Bridge.Context.set(key, value)
, where key
references the context variable you wish to updates, and value
is its
new value.
// switch the toggle state manually
state = state === "on" ? "off" : "on";
// write back to the context
Bridge.Context.set("toggle-button-state", state);
To write to a specific location in the
context, which may or may not exist, you can use
Bridge.Context.setPath(path, value)
,
where path
is a string of selectors.
// write the visibility of the first row in the table "newtable" to the context
Bridge.Context.setPath(".tables .newtable .rows .0 .visible", false)
// result in the context
{
"tables": {
"newtable": {
"rows": [{
"visible": false
}]
}
}
}
Fetch presentation agenda
You would like to create an agenda slide which lists all sections/slides
in the created presentation, no problem!
Bridge.Context.getAgenda()
returns a nested set of decks suitable for producing an agenda slide.
Example response:
Returns an array of decks assigned to the presentation.
[{
"enabled": false,
"path": "awesome",
"sections": [{
"path": "awesome/were_innovative",
"title": "We're innovative",
"visible": true,
"slides": [{
"path": "awesome/were_innovative/introduction",
"title": "Introduction",
"visible": true,
"subslides:" []
}, {
"path": "awesome/were_innovative/super_stats",
"title": "Super stats",
"visible": true,
"subslides:" []
}, {
"path": "awesome/were_innovative/fancy_infographic",
"title": "Fancy infographic",
"visible": true,
"subslides:" [{
"title": ""
"visible": true
}, {
"title": ""
"visible": true
}]
}, {
"..."
}]
}, {
"..."
}],
"title": "Digital is awesome"
}]
LivePreso's current configuration only allows one deck assigned per presentation. This is planned to be expanded on in the future.
As a result of how our screenshot server currently works, sending multiple PDFs of the same presentation may result in conflicting agendas. PDFs are unique per-snapshot, so unless the change also updates the snapshot (eg. editing an appointment) the screens will not be regenerated.
This affects instances where an appointment is created, shared, slides are sorted (slide sorting does not update the snapshot) before it is shared again - in this example the agenda will appear the same as the first share. However, if the salesperson then performs an action that updates the snapshot (edits the appointment, updates the context etc.) the next PDF share will be resolved.
This is planned to be fixed in the future, and documentation will be updated accordingly.