901 lines
23 KiB
JavaScript
901 lines
23 KiB
JavaScript
// Service search data with keyword matching and "alternative to" support
|
|
const searchServices = [
|
|
{
|
|
name: "Web Hosting",
|
|
price: "$29/mo.",
|
|
description:
|
|
"Build and launch impressive WordPress websites with dedicated features, tools, and guidance.",
|
|
link: "/web-hosting.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/web-hosting",
|
|
keywords: [
|
|
"website",
|
|
"blog",
|
|
"wordpress",
|
|
"cms",
|
|
"site",
|
|
"landing page",
|
|
"portfolio",
|
|
"web hosting",
|
|
"web",
|
|
"hosting",
|
|
"publish",
|
|
"domain",
|
|
"webpage",
|
|
"church website",
|
|
"business website",
|
|
"personal site",
|
|
],
|
|
alternativeTo: [
|
|
"squarespace",
|
|
"wix",
|
|
"godaddy",
|
|
"bluehost",
|
|
"siteground",
|
|
"hostgator",
|
|
"wordpress.com",
|
|
"weebly",
|
|
"dreamhost",
|
|
"a2 hosting",
|
|
"ionos",
|
|
"namecheap",
|
|
"hostinger",
|
|
],
|
|
},
|
|
{
|
|
name: "E-Commerce",
|
|
price: "$29/mo.",
|
|
description:
|
|
"Get a stunning online store with PrestaShop — built to sell, whether from scratch or pre-built themes.",
|
|
link: "/e-commerce.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/e-commerce-hosting",
|
|
keywords: [
|
|
"store",
|
|
"shop",
|
|
"sell",
|
|
"online store",
|
|
"products",
|
|
"ecommerce",
|
|
"e-commerce",
|
|
"shopping cart",
|
|
"payments",
|
|
"retail",
|
|
"inventory",
|
|
"checkout",
|
|
"merchandise",
|
|
"order",
|
|
"catalog",
|
|
"prestashop",
|
|
],
|
|
alternativeTo: [
|
|
"shopify",
|
|
"bigcommerce",
|
|
"magento",
|
|
"woocommerce",
|
|
"etsy",
|
|
"squarespace commerce",
|
|
"wix stores",
|
|
"ecwid",
|
|
"volusion",
|
|
"3dcart",
|
|
"gumroad",
|
|
"square online",
|
|
],
|
|
},
|
|
{
|
|
name: "Workspace Tools",
|
|
price: "$49/mo.",
|
|
description:
|
|
"A secure, private Nextcloud workspace for up to 100 users — files, calendars, contacts, and full data ownership.",
|
|
link: "/workspace-tools.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/workspace",
|
|
keywords: [
|
|
"files",
|
|
"storage",
|
|
"cloud storage",
|
|
"collaboration",
|
|
"calendar",
|
|
"contacts",
|
|
"documents",
|
|
"drive",
|
|
"office",
|
|
"workspace",
|
|
"nextcloud",
|
|
"share",
|
|
"sync",
|
|
"team",
|
|
"productivity",
|
|
"document",
|
|
],
|
|
alternativeTo: [
|
|
"google workspace",
|
|
"google drive",
|
|
"microsoft 365",
|
|
"office 365",
|
|
"dropbox",
|
|
"onedrive",
|
|
"box",
|
|
"icloud",
|
|
"notion",
|
|
"sharepoint",
|
|
"zoho",
|
|
"confluence",
|
|
],
|
|
},
|
|
{
|
|
name: "Private Email",
|
|
price: "$29/mo.",
|
|
description:
|
|
"Secure, dedicated, ad-free email with Mailu — full control over your inbox and data.",
|
|
link: "/private-email.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/private-email",
|
|
keywords: [
|
|
"email",
|
|
"inbox",
|
|
"mail",
|
|
"messaging",
|
|
"communication",
|
|
"smtp",
|
|
"imap",
|
|
"mailu",
|
|
"ad-free",
|
|
"private email",
|
|
"custom email",
|
|
"business email",
|
|
],
|
|
alternativeTo: [
|
|
"gmail",
|
|
"outlook",
|
|
"yahoo mail",
|
|
"protonmail",
|
|
"proton mail",
|
|
"tutanota",
|
|
"hey",
|
|
"fastmail",
|
|
"zoho mail",
|
|
"aol",
|
|
"icloud mail",
|
|
"mailchimp",
|
|
"addy.io",
|
|
],
|
|
},
|
|
{
|
|
name: "VPS Hosting",
|
|
price: "Custom",
|
|
description:
|
|
"Powerful Linux VPS with SSH access, IPv4 + IPv6, full KVM hypervisor, and no lock-in.",
|
|
link: "/vps-hosting.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/vps",
|
|
keywords: [
|
|
"server",
|
|
"vps",
|
|
"linux",
|
|
"ssh",
|
|
"virtual server",
|
|
"dedicated",
|
|
"deploy",
|
|
"app",
|
|
"application",
|
|
"database",
|
|
"docker",
|
|
"container",
|
|
"root access",
|
|
"kvm",
|
|
"virtual machine",
|
|
"vm",
|
|
"cloud server",
|
|
"node",
|
|
"backend",
|
|
"api",
|
|
],
|
|
alternativeTo: [
|
|
"aws",
|
|
"amazon web services",
|
|
"azure",
|
|
"digitalocean",
|
|
"digital ocean",
|
|
"linode",
|
|
"vultr",
|
|
"hetzner",
|
|
"ovh",
|
|
"google cloud",
|
|
"gcp",
|
|
"lightsail",
|
|
"render",
|
|
"railway",
|
|
"fly.io",
|
|
"heroku",
|
|
"vercel",
|
|
"netlify",
|
|
],
|
|
},
|
|
{
|
|
name: "Complete Wordpress Migration",
|
|
price: "$100",
|
|
description:
|
|
"Transfer your WordPress Website or Store seamlessly to Last Hour Hosting!",
|
|
link: "/data-migration.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/migration",
|
|
keywords: [
|
|
"migrate wordpress",
|
|
"wordpress",
|
|
"transfer wordpress",
|
|
"move wordpress",
|
|
"switch wordpress",
|
|
"import wordpress",
|
|
"export wordpress",
|
|
"migration wordpress",
|
|
"move over wordpress",
|
|
"switching wordpress",
|
|
"transition wordpress",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "Email Migration",
|
|
price: "$100",
|
|
description:
|
|
"We will migrate up to 5 mailboxes to your Last Hour Hosting email service.",
|
|
link: "/data-migration.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/migration",
|
|
keywords: [
|
|
"migrate email",
|
|
"email",
|
|
"transfer email",
|
|
"move email",
|
|
"switch email",
|
|
"import email",
|
|
"export email",
|
|
"migration email",
|
|
"move over email",
|
|
"switching email",
|
|
"transition email",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "Google Workspace to Nextcloud Migration",
|
|
price: "$100",
|
|
description:
|
|
"We'll migrate your Google Workspace account to your Last Hour Hosting Nextcloud service.",
|
|
link: "/data-migration.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/migration",
|
|
keywords: [
|
|
"migrate Google Workspace",
|
|
"Google Workspace",
|
|
"transfer Google Workspace",
|
|
"move Google Workspace",
|
|
"switch Google Workspace",
|
|
"import Google Workspace",
|
|
"export Google Workspace",
|
|
"migration Google Workspace",
|
|
"move over Google Workspace",
|
|
"switching Google Workspace",
|
|
"transition Google Workspace",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "Microsoft Office 365 to Nextcloud Migration",
|
|
price: "$100",
|
|
description:
|
|
"We'll migrate your Microsoft Office 365 account to your Last Hour Hosting Nextcloud service.",
|
|
link: "/data-migration.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/migration",
|
|
keywords: [
|
|
"migrate Microsoft Office 365",
|
|
"Microsoft Office 365",
|
|
"transfer Microsoft Office 365",
|
|
"move Microsoft Office 365",
|
|
"switch Microsoft Office 365",
|
|
"import Microsoft Office 365",
|
|
"export Microsoft Office 365",
|
|
"migration Microsoft Office 365",
|
|
"move over Microsoft Office 365",
|
|
"switching Microsoft Office 365",
|
|
"transition Microsoft Office 365",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "1 Hour of Tech Support for 1 Issue",
|
|
price: "$125",
|
|
description:
|
|
"Access flexible, on-demand hourly support, allowing you to choose when and how much work you want from our tech experts, with a simple and secure payment process.",
|
|
link: "/managed-it.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/managed-it",
|
|
keywords: [
|
|
"managed IT",
|
|
"tech support",
|
|
"support",
|
|
"hourly",
|
|
"technology",
|
|
"tech help",
|
|
"issue",
|
|
"problem",
|
|
"IT",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "Starter Wordpress Website",
|
|
price: "$500",
|
|
description:
|
|
"Done for you homepage or landing page custom built by our team.",
|
|
link: "/website-design.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/website-design",
|
|
keywords: [
|
|
"new website",
|
|
"redesign",
|
|
"replace website",
|
|
"improve website",
|
|
"design",
|
|
"UI",
|
|
"UX",
|
|
"landing",
|
|
"page",
|
|
"custom",
|
|
"Build website",
|
|
],
|
|
alternativeTo: ["webflow", "wix", "squarespace", "shopify", "hostinger"],
|
|
},
|
|
{
|
|
name: "Software Discovery Call",
|
|
price: "$100",
|
|
description:
|
|
"30-minute call to provide clarity on your idea potential, feasibility, and resource-intensity!",
|
|
link: "/software-development.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/software-development",
|
|
keywords: [
|
|
"consulting",
|
|
"software",
|
|
"idea",
|
|
"concept",
|
|
"design",
|
|
"UI",
|
|
"UX",
|
|
"mvp",
|
|
"app",
|
|
"mobile app",
|
|
"software design",
|
|
"software development",
|
|
],
|
|
alternativeTo: [],
|
|
},
|
|
{
|
|
name: "ERPnext",
|
|
price: "$29/mo.",
|
|
description:
|
|
"ERPNext is the world's best open source ERP and we're managing it for you at Last Hour Hosting!",
|
|
link: "/erp.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/erp",
|
|
keywords: [
|
|
"erp",
|
|
"enterprise resource planning",
|
|
"hr",
|
|
"order management",
|
|
"payroll",
|
|
"manufacturing",
|
|
"crm",
|
|
"projects",
|
|
"helpdesk",
|
|
"asset management",
|
|
"warehouse",
|
|
"distribution",
|
|
"supply chain management",
|
|
"financial management",
|
|
"accounting",
|
|
"inventory management",
|
|
"production planning",
|
|
"quality control",
|
|
"compliance management",
|
|
"business intelligence",
|
|
"reporting",
|
|
"analytics",
|
|
"integration",
|
|
"automation",
|
|
"business process management",
|
|
"erp software",
|
|
"erp system",
|
|
"erp solutions",
|
|
"cloud erp",
|
|
"open-source erp",
|
|
"erp implementation",
|
|
"erp consulting",
|
|
],
|
|
alternativeTo: [
|
|
"SAP ERP",
|
|
"Oracle ERP Cloud",
|
|
"Microsoft Dynamics 365",
|
|
"Infor ERP",
|
|
"Epicor ERP",
|
|
"Sage ERP",
|
|
"NetSuite ERP",
|
|
"QAD ERP",
|
|
"Workday ERP",
|
|
"Zoho Inventory",
|
|
"Acumatica ERP",
|
|
"SAP ECC",
|
|
"SAP S/4HANA",
|
|
"Oracle E-Business Suite",
|
|
"Microsoft Dynamics NAV",
|
|
"Microsoft Dynamics GP",
|
|
"Infor M3",
|
|
"Epicor Prophet21",
|
|
"Sage X3",
|
|
],
|
|
},
|
|
{
|
|
name: "Twenty CRM",
|
|
price: "$29/mo.",
|
|
description:
|
|
"The open alternative to Salesforce, designed for all your data integration needs. Twenty CRM gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves.",
|
|
link: "/crm.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/crm",
|
|
keywords: [
|
|
"crm",
|
|
"customer relationship management",
|
|
"salesforce",
|
|
"hubspot",
|
|
"zoho crm",
|
|
"microsoft dynamics 365 crm",
|
|
"crm software",
|
|
"crm system",
|
|
"crm solutions",
|
|
"cloud crm",
|
|
"open-source crm",
|
|
"crm implementation",
|
|
"crm consulting",
|
|
"lead management",
|
|
"contact management",
|
|
"account management",
|
|
"sales automation",
|
|
"marketing automation",
|
|
"customer service",
|
|
"support ticketing",
|
|
"analytics",
|
|
"reporting",
|
|
"integration",
|
|
"automation",
|
|
],
|
|
alternativeTo: [
|
|
"Salesforce",
|
|
"HubSpot",
|
|
"Zoho",
|
|
"Microsoft Dynamics 365",
|
|
"Oracle",
|
|
"SAP",
|
|
"SugarCRM",
|
|
"Pipedrive",
|
|
"Freshsales",
|
|
"Copper",
|
|
"Insightly",
|
|
],
|
|
},
|
|
{
|
|
name: "TradeNote",
|
|
price: "$4.99/mo.",
|
|
description:
|
|
"Helps traders store, discover and recollect all their trades so they can become and remain consistent and profitable.",
|
|
link: "/trade-journal.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/trade-journal",
|
|
keywords: [
|
|
"trade journal",
|
|
"trading journal",
|
|
"stock trading journal",
|
|
"forex trading journal",
|
|
"trader journal",
|
|
"trade log",
|
|
"trading log",
|
|
"trade tracking",
|
|
"trading tracking",
|
|
"performance tracking",
|
|
"trading analytics",
|
|
"trade management",
|
|
"trading software",
|
|
"trader tools",
|
|
],
|
|
alternativeTo: [
|
|
"Edgewonk",
|
|
"Tradervue",
|
|
"Trade-Ideas",
|
|
"Tradecopier",
|
|
"Journalyt",
|
|
"Trade Journal Pro",
|
|
"Trader's Journal",
|
|
"StockSharp",
|
|
"TradeLogger",
|
|
"TradeMeta",
|
|
"Daily Trade Journal",
|
|
"Trade Analysis",
|
|
"Trader Performance",
|
|
"Trade Keeper",
|
|
"Profit Journal",
|
|
],
|
|
},
|
|
{
|
|
name: "Basic Website SEO",
|
|
price: "$175",
|
|
description:
|
|
"Improve your website's search engine ranking and drive more traffic with our basic website SEO services.",
|
|
link: "/seo.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/seo",
|
|
keywords: [
|
|
"seo",
|
|
"search engine optimization",
|
|
"website seo",
|
|
"seo services",
|
|
"seo optimization",
|
|
"search engine ranking",
|
|
"keyword research",
|
|
"on-page seo",
|
|
"off-page seo",
|
|
"link building",
|
|
"content optimization",
|
|
],
|
|
alternativeTo: [
|
|
"Ahrefs",
|
|
"SEMrush",
|
|
"Moz",
|
|
"Google Analytics",
|
|
"Google Search Console",
|
|
"Yoast SEO",
|
|
"All in One SEO Pack",
|
|
"SEOPress",
|
|
"Rank Math",
|
|
],
|
|
},
|
|
{
|
|
name: "Virtual Phone System",
|
|
price: "$29/mo.",
|
|
description:
|
|
"Get an open-standard virtual phone system that works with Signal Wire, Twilio, and more!",
|
|
link: "/virtual-phone.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/virtual-phone",
|
|
keywords: [
|
|
"virtual phone system",
|
|
"cloud phone system",
|
|
"voip phone system",
|
|
"sip trunking",
|
|
"virtual pbx",
|
|
"business phone system",
|
|
"phone service",
|
|
"voice over ip",
|
|
"cloud communications",
|
|
"unified communications",
|
|
],
|
|
alternativeTo: [
|
|
"RingCentral",
|
|
"Grasshopper",
|
|
"8x8",
|
|
"Vonage",
|
|
"Nextiva",
|
|
"RingCentral Office",
|
|
"Microsoft Teams",
|
|
"Google Voice",
|
|
"Skype for Business",
|
|
],
|
|
},
|
|
{
|
|
name: "Small Wordpress Website Fix",
|
|
price: "$100",
|
|
description:
|
|
"Small fixes (Up to 1 Hour). Fixing minor WordPress issues or bugs on your website.",
|
|
link: "/website-maintenance.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/website-maintenance",
|
|
keywords: [
|
|
"wordpress website fix",
|
|
"wordpress maintenance",
|
|
"wordpress troubleshooting",
|
|
"wordpress bug fix",
|
|
"wordpress issue resolution",
|
|
"wordpress support",
|
|
"website repair",
|
|
"wordpress errors",
|
|
"wordpress problems",
|
|
],
|
|
alternativeTo: [
|
|
"WP Filler",
|
|
"WP Support",
|
|
"WordPress Care",
|
|
"FixMySite",
|
|
"WP Rescue",
|
|
"WordPress Fix",
|
|
"SiteGround Support",
|
|
"Bluehost Support",
|
|
"HostGator Support",
|
|
],
|
|
},
|
|
{
|
|
name: "Basic Wordpress Speed Optimization",
|
|
price: "$270",
|
|
description:
|
|
"Page caching, removing unused JS & CSS, image optimization (WEBP), smart lazy load, critical CSS",
|
|
link: "/website-maintenance.html",
|
|
orderLink: "https://my.lasthourhosting.org/products/website-maintenance",
|
|
keywords: [
|
|
"wordpress speed optimization",
|
|
"wordpress performance optimization",
|
|
"wordpress page speed",
|
|
"wordpress website speed",
|
|
"wordpress caching",
|
|
"wordpress image optimization",
|
|
"wordpress lazy loading",
|
|
"wordpress critical css",
|
|
"wordpress speed improvement",
|
|
],
|
|
alternativeTo: [
|
|
"WP Rocket",
|
|
"W3 Total Cache",
|
|
"WP Super Cache",
|
|
"WP Fastest Cache",
|
|
"Autoptimize",
|
|
"WP Optimize",
|
|
"ShortPixel",
|
|
"ImageOptim",
|
|
"WP Speed Optimizer",
|
|
],
|
|
},
|
|
];
|
|
|
|
function initSearch() {
|
|
const input = document.getElementById("service-search-input");
|
|
const results = document.getElementById("search-results");
|
|
if (!input || !results) return;
|
|
|
|
input.addEventListener("input", function () {
|
|
const query = this.value.trim().toLowerCase();
|
|
if (query.length < 2) {
|
|
results.classList.remove("active");
|
|
results.innerHTML = "";
|
|
return;
|
|
}
|
|
|
|
const matches = findMatches(query);
|
|
renderResults(matches, query, results);
|
|
results.classList.add("active");
|
|
});
|
|
|
|
// Close results on click outside
|
|
document.addEventListener("click", function (e) {
|
|
if (!e.target.closest(".search-hero")) {
|
|
results.classList.remove("active");
|
|
}
|
|
});
|
|
|
|
// Re-open on focus if there's input
|
|
input.addEventListener("focus", function () {
|
|
if (this.value.trim().length >= 2) {
|
|
const matches = findMatches(this.value.trim().toLowerCase());
|
|
renderResults(matches, this.value.trim().toLowerCase(), results);
|
|
results.classList.add("active");
|
|
}
|
|
});
|
|
}
|
|
|
|
function findMatches(query) {
|
|
// Check for "alternative to" pattern
|
|
const altMatch = query.match(
|
|
/(?:alternative\s+to|replace|replacing|switch\s+from|instead\s+of|competitor\s+to|like)\s+(.+)/i
|
|
);
|
|
const altQuery = altMatch ? altMatch[1].trim() : null;
|
|
|
|
const scored = searchServices.map(function (service) {
|
|
let score = 0;
|
|
|
|
if (altQuery) {
|
|
// Match against alternativeTo list
|
|
for (var i = 0; i < service.alternativeTo.length; i++) {
|
|
if (service.alternativeTo[i].indexOf(altQuery) !== -1) {
|
|
score += 100;
|
|
break;
|
|
}
|
|
if (altQuery.indexOf(service.alternativeTo[i]) !== -1) {
|
|
score += 80;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Match against keywords
|
|
for (var j = 0; j < service.keywords.length; j++) {
|
|
if (service.keywords[j].indexOf(query) !== -1) {
|
|
score += 50;
|
|
}
|
|
if (
|
|
query.indexOf(service.keywords[j]) !== -1 &&
|
|
service.keywords[j].length > 2
|
|
) {
|
|
score += 30;
|
|
}
|
|
}
|
|
|
|
// Match against service name
|
|
if (service.name.toLowerCase().indexOf(query) !== -1) {
|
|
score += 60;
|
|
}
|
|
|
|
// Match against description
|
|
if (service.description.toLowerCase().indexOf(query) !== -1) {
|
|
score += 20;
|
|
}
|
|
|
|
// Match against alternativeTo even without "alternative to" prefix
|
|
for (var k = 0; k < service.alternativeTo.length; k++) {
|
|
if (service.alternativeTo[k].indexOf(query) !== -1 && query.length > 2) {
|
|
score += 40;
|
|
}
|
|
}
|
|
|
|
return { service: service, score: score };
|
|
});
|
|
|
|
scored.sort(function (a, b) {
|
|
return b.score - a.score;
|
|
});
|
|
|
|
return scored.filter(function (item) {
|
|
return item.score > 0;
|
|
});
|
|
}
|
|
|
|
function renderResults(matches, query, container) {
|
|
if (matches.length === 0) {
|
|
container.innerHTML =
|
|
'<div class="search-result-item search-no-results">' +
|
|
"<h4>Not sure what you need?</h4>" +
|
|
"<p>Let's figure it out together — our team is here to help.</p>" +
|
|
'<a class="button-3" href="/contact.html">Talk to Our Team</a>' +
|
|
"</div>";
|
|
return;
|
|
}
|
|
|
|
// Check if this is an "alternative to" query
|
|
var altMatch = query.match(
|
|
/(?:alternative\s+to|replace|replacing|switch\s+from|instead\s+of|competitor\s+to|like)\s+(.+)/i
|
|
);
|
|
var altProduct = altMatch ? altMatch[1].trim() : null;
|
|
|
|
var html = "";
|
|
var shown = matches.slice(0, 3);
|
|
|
|
for (var i = 0; i < shown.length; i++) {
|
|
var s = shown[i].service;
|
|
var altLabel = "";
|
|
if (altProduct) {
|
|
// Find which specific product it's an alternative to
|
|
for (var j = 0; j < s.alternativeTo.length; j++) {
|
|
if (
|
|
s.alternativeTo[j].indexOf(altProduct) !== -1 ||
|
|
altProduct.indexOf(s.alternativeTo[j]) !== -1
|
|
) {
|
|
altLabel =
|
|
'<span class="search-alt-badge">Alternative to ' +
|
|
s.alternativeTo[j].charAt(0).toUpperCase() +
|
|
s.alternativeTo[j].slice(1) +
|
|
"</span>";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
html +=
|
|
'<div class="search-result-item">' +
|
|
'<div class="search-result-header">' +
|
|
"<h4>" +
|
|
s.name +
|
|
"</h4>" +
|
|
'<span class="search-result-price">' +
|
|
s.price +
|
|
"</span>" +
|
|
"</div>" +
|
|
altLabel +
|
|
"<p>" +
|
|
s.description +
|
|
"</p>" +
|
|
'<div class="search-result-actions">' +
|
|
'<a class="button-3" href="' +
|
|
s.orderLink +
|
|
'">Get Started</a>' +
|
|
'<a class="search-learn-more" href="' +
|
|
s.link +
|
|
'">Learn More →</a>' +
|
|
"</div>" +
|
|
"</div>";
|
|
}
|
|
|
|
// Always show a "Talk to us" option at the bottom
|
|
html +=
|
|
'<div class="search-result-item search-cta">' +
|
|
"<p>Need something custom or want to discuss your options?</p>" +
|
|
'<a class="search-learn-more" href="/contact.html">Talk to Our Team →</a>' +
|
|
"</div>";
|
|
|
|
container.innerHTML = html;
|
|
}
|
|
|
|
// Cycling placeholder suggestions — drawn from full service catalog
|
|
var placeholderSuggestions = [
|
|
// Alternative-to queries (the signature feature)
|
|
{ full: 'Try "alternative to Shopify"', short: '"alternative to Shopify"' },
|
|
{ full: 'Search for "alternative to Gmail"', short: '"replace Gmail"' },
|
|
{ full: 'Try "switch from Google Drive"', short: '"replace Google Drive"' },
|
|
{ full: 'Search for "alternative to AWS"', short: '"alternative to AWS"' },
|
|
{ full: 'Try "instead of Squarespace"', short: '"instead of Squarespace"' },
|
|
{ full: 'Try "alternative to Dropbox"', short: '"replace Dropbox"' },
|
|
{ full: 'Search for "replace Heroku"', short: '"replace Heroku"' },
|
|
{
|
|
full: 'Try "alternative to Microsoft 365"',
|
|
short: '"replace Microsoft 365"',
|
|
},
|
|
{ full: 'Try "alternative to Salesforce"', short: '"replace Salesforce"' },
|
|
// Service keyword queries
|
|
{
|
|
full: 'What do you need? Try "website hosting"',
|
|
short: '"website hosting"',
|
|
},
|
|
{ full: 'Try searching "online store"', short: '"online store"' },
|
|
{ full: 'What do you need? Try "private email"', short: '"private email"' },
|
|
{ full: 'Try searching "cloud storage for teams"', short: '"cloud storage"' },
|
|
{ full: 'What do you need? Try "VPS hosting"', short: '"VPS hosting"' },
|
|
{ full: 'Try searching "migrate my data"', short: '"data migration"' },
|
|
{ full: 'What do you need? Try "WordPress site"', short: '"WordPress site"' },
|
|
{ full: 'Try searching "docker container"', short: '"docker container"' },
|
|
{ full: 'What do you need? Try "business email"', short: '"business email"' },
|
|
{ full: 'Try searching "shopping cart"', short: '"shopping cart"' },
|
|
{
|
|
full: 'What do you need? Try "file collaboration"',
|
|
short: '"file collaboration"',
|
|
},
|
|
{ full: 'Try searching "Linux server"', short: '"Linux server"' },
|
|
];
|
|
|
|
function initPlaceholderCycle() {
|
|
var input = document.getElementById("service-search-input");
|
|
if (!input) return;
|
|
|
|
// Shuffle suggestions so the order feels fresh each visit
|
|
for (var i = placeholderSuggestions.length - 1; i > 0; i--) {
|
|
var j = Math.floor(Math.random() * (i + 1));
|
|
var temp = placeholderSuggestions[i];
|
|
placeholderSuggestions[i] = placeholderSuggestions[j];
|
|
placeholderSuggestions[j] = temp;
|
|
}
|
|
|
|
var index = 0;
|
|
var isMobile = function () {
|
|
return window.innerWidth <= 960;
|
|
};
|
|
|
|
function setPlaceholder() {
|
|
var suggestion = placeholderSuggestions[index];
|
|
input.setAttribute(
|
|
"placeholder",
|
|
isMobile() ? suggestion.short : suggestion.full
|
|
);
|
|
}
|
|
|
|
setPlaceholder();
|
|
|
|
setInterval(function () {
|
|
// Don't cycle if user is typing or input is focused with text
|
|
if (document.activeElement === input && input.value.length > 0) return;
|
|
|
|
input.classList.add("placeholder-fade-out");
|
|
|
|
setTimeout(function () {
|
|
index = (index + 1) % placeholderSuggestions.length;
|
|
setPlaceholder();
|
|
input.classList.remove("placeholder-fade-out");
|
|
}, 300);
|
|
}, 3000);
|
|
|
|
// Update on resize
|
|
window.addEventListener("resize", setPlaceholder);
|
|
}
|
|
|
|
// Initialize when DOM is ready
|
|
$(function () {
|
|
initSearch();
|
|
initPlaceholderCycle();
|
|
});
|