Skip to content
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

Updated Hubspot Request-a-Demo form #35828

Merged
merged 11 commits into from
Feb 26, 2025
100 changes: 21 additions & 79 deletions corehq/apps/analytics/static/analytix/js/cta_forms.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,22 @@ hqDefine('analytix/js/cta_forms', [
'underscore',
'hqwebapp/js/initial_page_data',
'hqwebapp/js/assert_properties',
'intl-tel-input/build/js/intlTelInput.min',
'hqwebapp/js/bootstrap3/validators.ko', // needed for validation of startDate and endDate
], function (
$,
ko,
_,
initialPageData,
assertProperties,
intlTelInput,
) {
let hubspotCtaForm = function (config) {
let self = {};
assertProperties.assertRequired(config, [
'hubspotFormId',
'showContactMethod',
'showPreferredLanguage',
'useWhatsApp',
'useGoogleHangouts',
'nextButtonText',
'phoneNumberSelector',
'submitCallbackFn',
]);

self.showContactMethod = ko.observable(config.showContactMethod);
self.showPreferredLanguage = ko.observable(config.showPreferredLanguage);

self.useWhatsApp = ko.observable(config.useWhatsApp);
self.useGoogleHangouts = ko.observable(config.useGoogleHangouts);
self.nextButtonText = ko.observable(config.nextButtonText);

self.firstname = ko.observable()
Expand All @@ -56,6 +44,13 @@ hqDefine('analytix/js/cta_forms', [
params: true,
},
});
self.jobtitle = ko.observable()
.extend({
required: {
message: gettext("Please enter your job title."),
params: true,
},
});
self.email = ko.observable()
.extend({
required: {
Expand All @@ -67,55 +62,32 @@ hqDefine('analytix/js/cta_forms', [
emailRFC2822: true,
});

self.preferred_method_of_contact = ko.observable();

self.phone = ko.observable();

self.skype__c = ko.observable();
self.preferred_whatsapp_number = ko.observable();

self.showPhoneNumber = ko.computed(function () {
return self.preferred_method_of_contact() === "Phone";
});
self.showSkype = ko.computed(function () {
return self.preferred_method_of_contact() === "Skype";
});
self.showWhatsApp = ko.computed(function () {
return self.preferred_method_of_contact() === "WhatsApp";
});

self.language__c = ko.observable();
self.language = ko.observable();
self.discoverySource = ko.observable();
self.otherSource = ko.observable();

self.areMainFieldsValid = ko.computed(function () {
return _.every([
self.firstname,
self.lastname,
self.company,
self.jobtitle,
self.email,
], function (prop) {
return prop() !== undefined && prop.isValid();
});
});

self.areContactFieldsValid = ko.computed(function () {
if (!self.showContactMethod()) {
return true;
}
if (!self.preferred_method_of_contact()) {
return false;
}
let isWhatsAppValid = self.showWhatsApp() && !!self.preferred_whatsapp_number(),
isPhoneValid = self.showPhoneNumber() && !!self.phone(),
isSkypeValid = self.showSkype() && !!self.skype__c();
return isWhatsAppValid || isPhoneValid || isSkypeValid;
self.isLanguageFieldValid = ko.computed(function () {
return !!self.language();
});

self.isLanguageFieldValid = ko.computed(function () {
return !self.showPreferredLanguage() || !!self.language__c();
self.isDiscoverySourceValid = ko.computed(function () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this isn't being used anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying this bug. The discovery source is a new field, and it was intended to be checked prior to submitting the form. Fixed in 3ed301f

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused - it looks like c2ce697 intentionally removes the validity check. If you're restoring the validity check, shouldn't you also restore the asterisk so the user knows the field is required?

Copy link
Contributor Author

@mjriley mjriley Feb 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right :-( reverting (did a force push to remove the commit). e4b028e removes the unnecessary check

return !!self.discoverySource();
});

self.isFormReadyToSubmit = ko.computed(function () {
return self.areContactFieldsValid() && self.areMainFieldsValid() && self.isLanguageFieldValid();
return self.areMainFieldsValid() && self.isLanguageFieldValid();
});

self.isSubmitDisabled = ko.computed(function () {
Expand All @@ -127,53 +99,23 @@ hqDefine('analytix/js/cta_forms', [
return !!self.errorMessage();
});

var phoneNumberWidget = intlTelInput(config.phoneNumberSelector.get(0), {
containerClass: "w-100",
separateDialCode: true,
loadUtils: () => import("intl-tel-input/utils"),
initialCountry: "auto",
geoIpLookup: function (success) {
$.get("https://ipinfo.io", function () {}, "jsonp").always(function (resp) {
var countryCode = (resp && resp.country) ? resp.country : "";
if (!countryCode) {
countryCode = "us";
}
success(countryCode);
});
},
});

self.getFullPhoneNumber = function () {
return phoneNumberWidget.getNumber();
};

self.submitForm = function () {
let submitData = {
hubspot_form_id: config.hubspotFormId,
firstname: self.firstname(),
lastname: self.lastname(),
company: self.company(),
jobtitle: self.jobtitle(),
email: self.email(),
preferred_language: self.language(),
marketing_purposes___how_did_you_hear_about_us_: self.discoverySource(),
if_other___how_did_you_hear_about_us_: self.otherSource(),

// needed for hubspot context
page_url: window.location.href,
page_name: document.title,
};
if (self.showContactMethod()) {
submitData.preferred_method_of_contact = self.preferred_method_of_contact();
}
if (self.showPhoneNumber()) {
submitData.phone = self.phone();
}
if (self.showWhatsApp()) {
submitData.preferred_whatsapp_number = self.preferred_whatsapp_number();
}
if (self.showSkype()) {
submitData.skype__c = self.skype__c();
}
if (self.showPreferredLanguage()) {
submitData.language__c = self.language__c();
}

$.ajax({
method: 'post',
url: initialPageData.reverse("submit_hubspot_cta_form"),
Expand Down
17 changes: 2 additions & 15 deletions corehq/apps/analytics/static/analytix/js/hubspot.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,15 @@ hqDefine('analytix/js/hubspot', [
* Activates the Hubspot Request Demo form
*/
_utils.loadDemoForm = function () {
let isTrial = _get('isDemoTrial'),
isVariant = _get('demoABv2') && _get('demoABv2').version === 'variant',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you delete the A/B test altogether? That would include the test definition here, and then places that reference the test, like initial page data here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not feel comfortable doing this. When I investigated and saw that the test also affects Kissmetrics here, I felt this was outside the scope of this change and required context of what the test was meant to do.

$modal = $('#cta-form-get-demo'),
let $modal = $('#cta-form-get-demo'),
$form = $('#get-demo-cta-form-content'),
hasInteractedWithForm = false,
formId,
formId = "f6ebf161-fccf-4083-9a72-5839a0c8ac8c",
demoForm;

if (isTrial) {
formId = isVariant ? "c2381f55-9bd9-4f27-8476-82900e58bfd6" : "4474515e-fea6-4154-b3cf-1fe42b1c1333";
} else {
formId = isVariant ? "f6ebf161-fccf-4083-9a72-5839a0c8ac8c" : "d1897875-a5bb-4b63-9b9c-3d8fdbbe8274";
}

demoForm = ctaForms.hubspotCtaForm({
hubspotFormId: formId,
showContactMethod: isVariant,
showPreferredLanguage: false,
useWhatsApp: false,
useGoogleHangouts: true,
nextButtonText: gettext("Submit Request"),
phoneNumberSelector: $form.find('input[name="phone"]'),
submitCallbackFn: function () {
$('#get-demo-cta-success').fadeIn();
$('#get-demo-cta-form-content').addClass('hidden').addClass('d-none'); // todo after bootstrap 5 migration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,7 @@
</div>
<div class="form-group">
<label class="control-label">
{% trans "Organization" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<input type="text"
name="company"
data-bind="textInput: company"
class="form-control">
</div>
</div>
<div class="form-group">
<label class="control-label">
{% trans "Professional email address" %}<span class="asteriskField">*</span>
{% trans "Professional email" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<input type="email"
Expand All @@ -58,79 +47,77 @@
class="form-control">
</div>
</div>
<div class="form-group"
data-bind="visible: showContactMethod">
<label class="control-label">
{% trans "How should we contact you?" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<select name="preferred_method_of_contact"
data-bind="value: preferred_method_of_contact"
class="select form-control">
<option value="">{% trans "Please Select" %}</option>
<option value="Phone">{% trans "Phone" %}</option>
<option value="Skype">{% trans "Skype" %}</option>
<!-- ko if: useWhatsApp -->
<option value="WhatsApp">{% trans "WhatsApp" %}</option>
<!-- /ko -->
<!-- ko if: useGoogleHangouts -->
<option value="Google hangouts">{% trans "Google hangouts" %}</option>
<!-- /ko -->
</select>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label class="control-label">
{% trans "Organization" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<input type="text"
name="company"
data-bind="textInput: company"
class="form-control">
Copy link
Member

@biyeun biyeun Feb 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<input type="text"
name="company"
data-bind="textInput: company"
class="form-control">
<input
class="form-control"
type="text"
name="company"
data-bind="textInput: company"
/>

https://www.commcarehq.org/styleguide/b5/html/

</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label class="control-label">
{% trans "Job title" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<input type="text"
name="company"
data-bind="textInput: jobtitle"
class="form-control">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://www.commcarehq.org/styleguide/b5/html/

Suggested change
<input type="text"
name="company"
data-bind="textInput: jobtitle"
class="form-control">
<input
class="form-control"
type="text"
name="company"
data-bind="textInput: jobtitle"
/>

</div>
</div>
</div>
</div>
<div class="form-group"
data-bind="visible: showPhoneNumber">
<div class="form-group">
<label class="control-label">
{% trans "Preferred phone number" %}<span class="asteriskField">*</span>
{% trans "Preferred language" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<input type="text"
name="phone"
data-bind="textInput: phone"
class="form-control">
<select name="language"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data-bind="value: language"
class="form-control">
<option value="">{% trans "Please Select" %}</option>
<option value="English">{% trans "English" %}</option>
<option value="French">{% trans "French" %}</option>
<option value="Spanish">{% trans "Spanish" %}</option>
</select>
</div>
</div>
<div class="form-group"
data-bind="visible: showSkype">
<div class="form-group">
<label class="control-label">
{% trans "Skype username" %}<span class="asteriskField">*</span>
{% trans "How did you hear about us?" %}
</label>
<div class="controls">
<input type="text"
name="skype__c"
data-bind="textInput: skype__c"
class="form-control">
</div>
<select name="discoverySource"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data-bind="value: discoverySource"
class="form-control">
<option value="">{% trans "Please Select" %}</option>
<option value="Newsletter">{% trans "Newsletter" %}</option>
<option value="Podcast">{% trans "Podcast" %}</option>
<option value="Social Media">{% trans "Social Media" %}</option>
<option value="Web Search">{% trans "Web Search (e.g. Google)" %}</option>
<option value="Referral">{% trans "Word of Mouth / Referral" %}</option>
<option value="Event / Conference">{% trans "Event / Conference" %}</option>
<option value="Other">{% trans "Other" %}</option>
</select>
</div>
<div class="form-group"
data-bind="visible: showWhatsApp">
<div class="form-group" data-bind="visible: discoverySource() === 'Other'">
<label class="control-label">
{% trans "Preferred WhatsApp number" %}<span class="asteriskField">*</span>
{% trans "We'd love to hear more! Please specify -" %}
</label>
<div class="controls">
<input type="text"
name="preferred_whatsapp_number"
data-bind="textInput: preferred_whatsapp_number"
name="otherSource"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data-bind="textInput: otherSource"
class="form-control">
</div>
</div>
<div class="form-group"
data-bind="visible: showPreferredLanguage">
<label class="control-label">
{% trans "Preferred Language" %}<span class="asteriskField">*</span>
</label>
<div class="controls">
<select name="language__c"
data-bind="value: language__c"
class="form-control">
<option value="">{% trans "Please Select" %}</option>
<option value="English">{% trans "English" %}</option>
<option value="French">{% trans "French" %}</option>
<option value="Spanish">{% trans "Spanish" %}</option>
</select>
</div>
</div>
{% blocktrans %}
By clicking this button, you agree to Dimagi's
<a href="http://www.dimagi.com/terms/latest/tos/" target="_blank">Terms of Service</a> and
Expand Down
Loading