var cardTypeEl = document.getElementById(‘gdm-cardtype’); var dynamicFieldsEl = document.getElementById(‘gdm-dynamic-fields’); var gridEl = document.getElementById(‘gdm-qty-grid’); var notesEl = document.getElementById(‘gdm-notes’); var summaryEl = document.getElementById(‘gdm-price-summary’); var priceTotalEl = document.getElementById(‘gdm-price-total’);
var hidPrice = document.getElementById(‘gdm-hidden-price’); var hidQty = document.getElementById(‘gdm-hidden-qty’); var hidSku = document.getElementById(‘gdm-hidden-sku’); var hidSpec = document.getElementById(‘gdm-hidden-spec’); var hidNotes = document.getElementById(‘gdm-hidden-notes’);
var currentData = []; // rows for the selected card type var selections = {}; // { field: value } for fields resolved so far (incl. auto-picked) var fieldEls = {}; // { field: } for fields currently rendered var selectedRow = null; var selectedQty = null;
function uniq(arr) { return Array.from(new Set(arr)); }
function sortValues(field, values) { if (field === ‘size’) { return values.sort(function (a, b) { var pa = a.split(/[x×]/i).map(parseFloat), pb = b.split(/[x×]/i).map(parseFloat); if (!isNaN(pa[0]) && !isNaN(pb[0]) && pa[0] !== pb[0]) return pa[0], pb[0]; if (!isNaN(pa[1]) && !isNaN(pb[1]) && pa[1] !== pb[1]) return pa[1], pb[1]; return a.localeCompare(b); }); } return values.sort(); }
function rowMatches(row, uptoIdx) { for (var i = 0; i < uptoIdx; i++) { var f = FIELD_ORDER[i]; if (selections[f] && row[f] !== selections[f]) return false; } return true; }
// Removes any rendered dropdowns for fields at or after `idx`, then figures // out the next real decision point (skipping fields with 0 or 1 real // values for the current filtered data) and either renders a dropdown for // it or, once every field is resolved, renders the qty grid. function renderFrom(idx) { for (var i = idx; i = FIELD_ORDER.length) { renderGrid(); return; }
var field = FIELD_ORDER[idx]; var filtered = currentData.filter(function (r) { return rowMatches(r, idx); }); var values = uniq(filtered.map(function (r) { return r[field]; }).filter(function (v) { return v; }));
if (values.length === 0) { // This field isn’t a real dimension for this card type, skip it. renderFrom(idx + 1); return; } if (values.length === 1) { selections[field] = values[0]; renderFrom(idx + 1); return; }
renderGrid(); // nothing resolvable yet at/after this level }
function findRow() { if (Object.keys(selections).length === 0) return null; for (var i = 0; i < FIELD_ORDER.length; i++) { var f = FIELD_ORDER[i]; // every field that has a rendered dropdown must have a real (non-empty) selection if (fieldEls[f] && !selections[f]) return null; } var match = currentData.filter(function (r) { return rowMatches(r, FIELD_ORDER.length); }); return match.length ? match[0] : null; }
function renderGrid() { gridEl.innerHTML = ''; selectedRow = findRow(); if (!selectedRow) { gridEl.innerHTML = '
var specParts = [cardTypeEl.value]; FIELD_ORDER.forEach(function (f) { var v = selectedRow[f]; if (v) specParts.push(v); }); hidSpec.value = specParts.join(‘ / ‘);
var wcPriceEl = document.querySelector(‘.summary .price .woocommerce-Price-amount, .summary .price ins .woocommerce-Price-amount’); if (wcPriceEl) wcPriceEl.innerHTML = ‘$’ + total.toFixed(2); }
// Populate the Card Type dropdown (Standard first, then alphabetical) var types = Object.keys(MASTER); types.sort(function (a, b) { if (a === ‘Standard’) return -1; if (b === ‘Standard’) return 1; return a.localeCompare(b); }); types.forEach(function (t) { var o = document.createElement(‘option’); o.value = t; o.textContent = t + ‘ Business Cards’; cardTypeEl.appendChild(o); });
//, Locked single-line mode: this page is dedicated to one card type, // so the Card Type field is hidden and auto-selected on load instead of // requiring the shopper to pick it. Same tested cascade code underneath. if (types.length === 1) { cardTypeEl.value = types[0]; var ctRow = document.getElementById(‘gdm-cardtype-row’); if (ctRow) ctRow.style.display = ‘none’; cardTypeEl.dispatchEvent(new Event(‘change’)); } })();
Looking for painted edge business cards? Graphics Design Media, a Las Vegas print and design studio, makes ordering easy. Make bold first impressions with edge-painted luxury business cards. Printed on ultra-thick 32pt stock and hand-finished with vivid edge colors, these cards add a powerful finishing detail that’s impossible to ignore.
Whether you’re a designer, real estate agent, or creative professional, these cards are crafted to leave a lasting impact.
Specs:
Stock: 32pt ultra-thick cardstock
Edge colors: 16 options available, including metallic and neon (red, black, gold, silver, neon pink, and more)
Essential cookies enable basic functions and are necessary for the proper function of the website.
Name
Description
Duration
Cookie Preferences
This cookie is used to store the user's cookie consent preferences.
30 days
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Jetpack's built-in visitor analytics. It records page views, referring sites, search terms, and outbound link clicks, and also carries the shared visitor-tracking library used by Jetpack Instant Search and WooCommerce Analytics.
Stores a randomly-generated anonymous visitor ID so Jetpack's Tracks analytics library can link tracking events to the same visitor.
Session in wp-admin; up to 5 years on the frontend
tk_qs
Queues analytics events for Jetpack's Tracks library so none are lost if the page closes before they can be sent.
30 minutes
tk_tc
Used once per page load to work out which cookie domain the Tracks library should use, then removed as soon as it's read back.
Session (deleted immediately after use)
tk_aip
Stores a list of anonymous visitor IDs so they can be merged into one identity once a visitor is recognized.
Up to 5 years
SourceBuster is used by WooCommerce for order attribution based on user source.
Name
Description
Duration
sbjs_session
The number of page views in this session and the current page path
30 minutes
sbjs_udata
Information about the visitor’s user agent, such as IP, the browser, and the device type
session
sbjs_first
Traffic origin information for the visitor’s first visit to your store (only applicable if the visitor returns before the session expires)
session
sbjs_current
Traffic origin information for the visitor’s current visit to your store
session
sbjs_first_add
Timestamp, referring URL, and entry page for your visitor’s first visit to your store (only applicable if the visitor returns before the session expires)
session
sbjs_current_add
Timestamp, referring URL, and entry page for your visitor’s current visit to your store
session
sbjs_migrations
Technical data to help with migrations between different versions of the tracking feature
session
You can find more information in our Cookie Policy and .