Skip to content

Commit

Permalink
Moved sample around and added a little more documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Russell Edens committed Feb 15, 2019
1 parent 4a75d34 commit 313dddf
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 84 deletions.
15 changes: 15 additions & 0 deletions lib/voom/presenters/plugins/foo/bar.js
@@ -0,0 +1,15 @@
// This event callback pushes its results into the results array and returns a promise.
function bar(_options, params, _event, results) {
var promiseObj = new Promise(function(resolve) {
console.log('Bar called');
// Reload iFrame: https://stackoverflow.com/questions/86428/what-s-the-best-way-to-reload-refresh-an-iframe
document.getElementById('random_fact').src += '';
results.push({
action: 'bar',
content: JSON.stringify({data: params.text}),
statusCode: 200,
});
resolve(results);
});
return promiseObj;
}
21 changes: 21 additions & 0 deletions lib/voom/presenters/plugins/foo/foo.css
@@ -0,0 +1,21 @@
/* Custom CSS for this component - defines a fade in animation*/
#random_fact {
opacity: 0;
}

#random_fact.load {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
}

@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
14 changes: 12 additions & 2 deletions lib/voom/presenters/plugins/foo/foo.erb
@@ -1,4 +1,14 @@
<iframe id="random_fact" class='v-plugin v-input' data-plugin-callback='RandomFacts'
src="<%= comp.random_fact %>" height=512 <%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>></iframe>
<!--Custom markup.
If the plugin defines a component then it should set v-plugin and data-plugin-callback to the class of the component
If the plugin posts data then it should define the v-input class.
That will cause its validate and prepareSubmit methods in the component to be called
If the plugin has events it publishes then the erb :"components/event" needs to be invoked to
hookup the event handling markup
Any additional data you want to pass to your component javascript should be setup here as data attributes.
-->
<iframe id="<%= comp.id %>" class='v-plugin v-input' data-plugin-callback='RandomFacts'
src="<%= comp.random_fact %>" height=512
<%= erb :"components/event", :locals => {comp: comp, events: comp.events, parent_id: comp.id} %>></iframe>
39 changes: 39 additions & 0 deletions lib/voom/presenters/plugins/foo/foo.js
@@ -0,0 +1,39 @@
// Optional Javascript callback class. You typically need to define this when you have data to submit, or special
// event handling to bind to.
// To hook this up you need to provide the `v-plugin` class and
// data-plugin-callback='RandomFacts' on the element.
class RandomFacts {
// passed the DOM element that has the .v-plugin class on it.
constructor(element) {
// This is where you might pull data elements into your
// component from the markup. Like so:
// this.data = element.dataset.someDataICareAbout;
}

// Optional
// Called before the component is submitted via post/put. Allows the component to add its key/value pairs to the
// submitted data.
// If you provide this you need to add the v-input class to your DOM element to get called.
// Containers iterate their elements that have the v-input class defined on them and invoke the prepareSubmit
// function for each.
prepareSubmit(params) {
// params is a key,value pair. Add name/value like so:
// params.push(['some_name', 'some_value']);
}

// Optional
// Called whenever a container is about to be submitted, before prepareSubmit.
// returns true on success
// returns on failure return an error object that can be processed by VErrors:
// { email: ["email must be filled", "email must be from your domain"] }
// { page: ["must be filled"] }
// Returning an error stops the submission.
validate(formData) {
return true;
}

// Optional
// Clear's the control
clear() {
}
}
89 changes: 7 additions & 82 deletions lib/voom/presenters/plugins/foo/foo_header.erb
@@ -1,95 +1,20 @@
<style>
#random_fact {
opacity: 0;
}

#random_fact.load {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 2s;
}

@keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<%= File.read(File.expand_path('foo.css', __dir__) ) %>
</style>

<script>
// This event callback pushes its results into the results array and returns a promise.
function bar(_options, params, _event, results) {
// Reload iFrame: https://stackoverflow.com/questions/86428/what-s-the-best-way-to-reload-refresh-an-iframe
var promiseObj = new Promise(function(resolve) {
console.log('Bar called');
document.getElementById('random_fact').src += '';
results.push({action: 'bar', content: JSON.stringify({data: params.text}), statusCode: 200});
resolve(results);
});
return promiseObj;
}
// This file is defining the callback method that will be invoked when the custom plugin action `bar` is encountered
<%= File.read(File.expand_path('bar.js', __dir__) ) %>
// This file is defining the plugin component that will be delegated to by the WebClient.
<%= File.read(File.expand_path('foo.js', __dir__) ) %>

// Custom javascript specific to this sample plugin - sets the class name that causes the initial load to
// animate a transition (defined in the foo.css file)
function load() {
document.getElementById('random_fact').className = ' load';
}

window.onload = load;

// Optional Javascript callback class. You typically need to define this when you have data to submit, or special
// event handling to bind to.
// To hook this up you need to provide the `v-plugin` class and
// data-plugin-callback='RandomFacts' on the element.
class RandomFacts {
// passed the DOM element that has the .v-plugin class on it.
constructor(element) {
}

// optional.
// Called before the component is submitted via post/put. Allows the component to add its key/value pairs to the
// submitted data.
// If you provide this you need to add the v-input class to your DOM element to get called.
// Containers iterate their elements that have the v-input class defined on them and invoke the prepareSubmit
// function for each.
prepareSubmit(params) {
// params is a key,value pair. Add name/value like so:
// params.push(['some_name', 'some_value']);
}

// optional.
// Called whenever a container is about to be submitted, before prepareSubmit.
// returns true on success
// returns on failure return an error object that can be processed by VErrors:
// { email: ["email must be filled", "email must be from your domain"] }
// { page: ["must be filled"] }
// Returning an error stops the submission.
validate(formData) {
return true;
}

// optional.
// Clear's the control
clear() {
}

// called to add an event listener to the component
// this only needs to be defined if you need the event handler to be bound to the component
// in a different manner. Here is the default implementation you get if you don't define this method:
initEventListener(eventName, eventHandler) {
if (typeof this.eventsHandler === 'undefined') {
this.eventsHandler = {};
}
if (!this.eventsHandler[eventName]) {
// Delegate to the component if possible
this.eventsHandler[eventName] = eventHandler;
this.element.addEventListener(eventName, eventHandler);
}
}
}
</script>


0 comments on commit 313dddf

Please sign in to comment.