Skip to content

Instantly share code, notes, and snippets.

@kayyali18
Last active December 20, 2019 22:54
Show Gist options
  • Select an option

  • Save kayyali18/989410f5321144cedd2bc2e117e29806 to your computer and use it in GitHub Desktop.

Select an option

Save kayyali18/989410f5321144cedd2bc2e117e29806 to your computer and use it in GitHub Desktop.
PIPE-24 [Pricing][Desktop] Info blocks for product features

Hello Pipefy Devs,

We ran this experiment in VWO, and found that it produced higher conversions.

Hypothesis

The list of features contains many items that are not self-explanatory. Offering tool tips on these that further explain the feature will help users better understand the product and value offerings, and will be more likely to sign up and convert.

Target Audience

Desktop

Winning variation

v2: Variation2

Current State

The test is currently being shown to 100% of traffic on the following pages:

Screenshots

v2
V2 Pricing Page Info Blocks Exposed

Description

Code samples below describe what we did to create this experiment.

This code may include ECMAScript 2015 features not natively supported by all browsers (such as Internet Explorer). In order to support older browsers, we run all source code through Babel before deploying to the testing platform. You may use the online conversion tool if you don't already have Babel integrated into your development workflow.

The provided code may not be 1-to-1 with what was originally deployed via the testing platform. We may omit irrelevant code in order to best convey the code's true intentions.

As always: This code was created to run a lean, cost effective experiment, and should be used as a starting point to accelerate your efforts, not as something to directly copy/paste and deploy without running this through your standard production styleguide and QA processes.

We are happy to answer whatever questions you might have along the way!

undefined

// Text Data to be injected into HTML
const generalFeauturesCopy = [
"Pipe is the name of a process in Pipefy. Each pipe represents a different process.",
"Pipes only visible to your company admins and to the company members you invite into the pipe.",
"Members can create new cards and access all of the pipe’s existing cards to edit/move them across the pipe.",
"Can only access the start form of public pipes to create cards. They can't view or edit any cards.",
"Activity log showing everything that's happened to a card in a timeline view.",
"Number of records across all of your databases.",
"Attachments across pipes and databases.",
"Number of cards you can create per month.",
"Connections enable users to connect a pipe to another pipe or to a database.",
"Create external facing forms to collect data.",
"Enables users to view all the information extracted from the fields of all the cards in an organized, customizable spreadsheet format.",
"Measure your team's productivity and lead time, visualizing the summaries of card status and activities by time period.",
"Get notified by an alert when your card exceeds the maximum lead-time established for a pipe or a phase.",
"Customize your process with different types of fields.",
"Hide and show fields based on a users selections in prior fields.",
"Automatically trigger an action when a specific event occurs in one of your pipes.",
"Number of total jobs performed by automation rules per month."
];
const automationCopy = [
"Trigger automation jobs based on certain specified criteria.",
"Automatically create cards in a pipe when emails are sent to its unique email address.",
"Customizable messages created to be sent from a specific phase of your pipe, manually or automatically.",
"Have access to our API and plug Pipefy to your stack.",
"500+ plug & play process templates to get inspired.",
"Connect Pipefy with more than 1,500 other applicaitons using Zapier.",
"Import cards into your pipes from a spreadsheet."
];
const securityCopy = [
"Setup different roles and permissions to the members of your organization.",
"Users only allowed to view/edit cards created by or assigned to them.",
false,
false,
false,
false,
"Confirm each user's identity using a combination of two different methods."
];
// Polling function - like shared.init
(function poll() {
if (
!(
document.readyState === "complete" ||
document.readyState === "interactive"
)
)
return setTimeout(poll, 50);
applyChanges();
})();
/**
* Apply changes function
* Where the magic happens
*/
function applyChanges() {
// Add unique class to body
document.body.classList.add("cro-24");
// Get the elements we need
const generalFeautures = document.querySelector(".general-features");
const automation = document.querySelector(".automation");
const security = document.querySelector(".security");
// Get all Table heads in the table body as an iterable (technically not) node list
let generalFeauturesTitles = generalFeautures.querySelectorAll("tbody th");
let automationTitles = automation.querySelectorAll("tbody th");
let securityTitles = security.querySelectorAll("tbody th");
// Add an identifiable class to each
addClass(generalFeauturesTitles, ["cro-title"]);
addClass(automationTitles, ["cro-title"]);
addClass(securityTitles, ["cro-title"]);
// Inject our HTML and copy
generalFeauturesTitles.forEach((title, i) =>
title.insertAdjacentHTML("afterbegin", dropdown(generalFeauturesCopy[i]))
);
automationTitles.forEach((title, i) =>
title.insertAdjacentHTML("afterbegin", dropdown(automationCopy[i]))
);
securityTitles.forEach((title, i) => {
let html = securityCopy[i] ? dropdown(securityCopy[i]) : false;
html ? title.insertAdjacentHTML("afterbegin", html) : null;
});
// Select the accordion header - first of type
let accordionHeader = document.querySelector(".rs-accordion__header");
// Select the body - first of type
let accordionBody = document.querySelector(".rs-accordion__body");
// Remove the header and remove maxheight from body;
accordionHeader.click();
accordionHeader.remove();
}
// Utility Functions
/**
* Adds all classess passed to all nodes in the node list passed
*
* @param {NodeList} nodelist An HTML nodelist
* @param {Array} classes Array of classes to be added to each node in the node list
*/
function addClass(nodelist, classes) {
nodelist.forEach(node => node.classList.add(...classes));
}
/**
*
* @param {String} text Text to place inside the html
*
* @returns {String} An HTML string with the text inserted inside
*/
function dropdown(text) {
return `
<div class="link">
<div class="arrow">
<div class="drop">
<!--Content Here-->
<div class="line one">${text}</div>
</div>
</div>
</div>
`;
}
$black: #343434;
.cro-24 {
.cro-title {
align-items: center;
display: flex;
justify-content: left;
}
/*Notification link*/
div.link {
color: white;
background: gray;
width: 15px;
height: 15px;
border-radius: 50%;
text-align: center;
font-family: "Avenir", Helvetica, Verdana, sans-serif;
font-size: 1.1em;
cursor: pointer;
position: relative;
margin-right: 25px;
&::before {
bottom: 8px;
content: "i";
font-family: "Times New Roman", Helvetica, Verdana, sans-serif;
font-size: 10px;
font-weight: bold;
position: relative;
}
}
/*Notification Info-Box outer frame*/
.arrow {
position: absolute;
content: "";
margin-top: 10px;
margin-left: 10px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
margin-top: 5px;
}
.drop {
position: absolute;
content: "";
margin-top: 20px;
margin-top: 55px;
width: 0px;
height: 0px;
border-radius: 0px;
box-shadow: 0px 0px 0px black;
}
.pic {
background: grey;
width: 0px;
height: 0px;
margin-top: 60px;
margin-left: 60px;
}
.drop .line {
font-size: 13px;
opacity: 0;
}
/*End Notification Info-Box outer frame*/
/*On-Hover Animation*/
.cro-title:hover,
div.link:hover {
// width: 15px;
// height: 15px;
}
.cro-title:hover .arrow,
.link:hover .arrow {
bottom: -20px;
position: absolute;
width: 0px;
height: 0px;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 15px solid $black;
margin-top: 0px;
margin-left: -2px;
}
.cro-title:hover .drop,
.link:hover .drop {
background: $black;
height: max-content;
left: -23px;
margin-top: 13px;
padding: 1rem;
position: relative;
width: calc(223px + 5.3vw);
z-index: 123;
max-width: 320px;
}
.cro-title:hover .pic,
.link:hover .pic {
background: #dedede;
width: 80px;
height: 80px;
margin-top: 10px;
margin-left: 10px;
border-radius: 5px;
transition: 0.5s ease all;
}
.cro-title:hover .drop .line,
.link:hover .drop .line {
position: relative;
height: 8px;
margin: 0;
margin-left: 0;
border-radius: 4px;
transition: 0.5s ease all;
height: min-content;
opacity: 1;
width: auto;
font-size: 13px;
}
.cro-title:hover .one,
.link:hover .one {
transition: 0.5s ease all;
}
.cro-title:hover .two,
.link:hover .two {
margin-top: -50px;
width: 90px;
transition: 0.5s ease all;
}
.cro-title:hover .three,
.link:hover .three {
margin-top: -30px;
width: 75px;
transition: 0.5s ease all;
}
.cro-title:hover .four,
.link:hover .four {
margin-top: -10px;
width: 50px;
transition: 0.5s ease all;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment