Add Code 39 barcode format to barcode generator tool

Feature: Support Code 39 symbology alongside existing QR and CODE128
- Added CODE39 option to code type dropdown (front and back sides)
- Updated renderOne() to handle code39 type with format parameter
- Code 39 shares CSS styling with CODE128 (linear barcode layout)
- Updated error message to be format-agnostic

Use case: Legacy systems and equipment that require Code 39 format
for compatibility (common in manufacturing and inventory systems)

Technical notes:
- JsBarcode library already supports CODE39 format
- Passed format parameter to barcodeSvgDataUri() function
- Both CODE128 and CODE39 use .type-barcode CSS class

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Proudlock
2026-09-12 10:29:13 -04:00
parent 2ac2e6d33d
commit 64ab1c5299
2 changed files with 19 additions and 4 deletions

View File

@@ -41,6 +41,7 @@ export const LABEL_PRESETS = [
// CODE128 is what the scanners on the floor are configured for, and a label
// carries its text separately, so the barcode never renders its own.
// Code 39 available as an alternative for compatibility with legacy systems.
export const BARCODE_DEFAULTS = {
format: 'CODE128',
displayValue: false,
@@ -130,7 +131,12 @@ export function barcodeInto(element, text, options = {}) {
return element
}
/** A barcode as an SVG data URI, for pages that print an <img>. */
/**
* A barcode as an SVG data URI, for pages that print an <img>.
*
* @param {string} text - Content to encode
* @param {object} options - JsBarcode options (format, width, height, etc.)
*/
export function barcodeSvgDataUri(text, options = {}) {
const element = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
barcodeInto(element, text, options)

View File

@@ -40,6 +40,7 @@
<select v-model="codetype">
<option value="qr">QR</option>
<option value="barcode">CODE128</option>
<option value="code39">CODE39</option>
</select>
</label>
<label v-if="codetype === 'qr'">
@@ -242,6 +243,7 @@
<option value="same">Same as the front</option>
<option value="qr">QR</option>
<option value="barcode">CODE128</option>
<option value="code39">CODE39</option>
</select>
</label>
<label>
@@ -301,7 +303,7 @@
- split the CSV and print it in batches.
</p>
<p v-if="overlong.length" class="control-note">
{{ overlong.length }} row(s) could not be encoded as CODE128 or were empty:
{{ overlong.length }} row(s) could not be encoded or were empty:
{{ overlong.slice(0, 3).join(', ') }}{{ overlong.length > 3 ? ' ...' : '' }}
</p>
</div>
@@ -475,9 +477,12 @@ function showPicture(page) {
}
function labelClasses(page) {
const type = codeTypeFor(page)
// code39 and barcode (CODE128) share the same CSS class for linear barcode layout
const typeClass = type === 'code39' ? 'barcode' : type
return [
'layout-' + layoutFor(page),
'type-' + codeTypeFor(page),
'type-' + typeClass,
'side-' + page.side,
showPicture(page) && pictureposition.value !== 'behind' ? 'pic-' + pictureposition.value : '',
]
@@ -588,9 +593,13 @@ const fitAdvice = computed(() => {
async function renderOne(page) {
const text = page.content
if (!text) return ''
if (codeTypeFor(page) === 'qr') {
const type = codeTypeFor(page)
if (type === 'qr') {
return qrSvgDataUri(text, { errorCorrection: errorcorrection.value })
}
if (type === 'code39') {
return barcodeSvgDataUri(text, { format: 'CODE39' })
}
return barcodeSvgDataUri(text)
}