# ivyforms/1.1.1/frontend/src/utils/nameFieldKeyUtils.ts

The Innovative Form Builder – IvyForms, version 1.1.1. 156 lines.

- Page: https://pluginprobe.com/plugins/ivyforms/1.1.1/code/frontend/src/utils/nameFieldKeyUtils.ts
- Raw: https://pluginprobe.com/plugins/ivyforms/1.1.1/raw/frontend/src/utils/nameFieldKeyUtils.ts
- Modified: 2026-06-17T12:13:02+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/ivyforms/1.1.1/code/frontend/src/utils/nameFieldKeyUtils.ts#L10-L20`.

```typescript
import type { Field } from '@/types/field'

const NAME_FIELD_KEY_PATTERN = /^nameField(\d+)$/i

export function isNameFieldKey(value: unknown): value is string {
  return typeof value === 'string' && NAME_FIELD_KEY_PATTERN.test(value)
}

function parseNameFieldKeyIndex(value: string): number | null {
  const match = NAME_FIELD_KEY_PATTERN.exec(value)
  return match ? parseInt(match[1], 10) : null
}

export function getChildFieldSettings(field: Field): Record<string, unknown> {
  let settings: Record<string, unknown> = {}

  if (typeof field.settings === 'string') {
    try {
      settings = JSON.parse(field.settings) as Record<string, unknown>
    } catch {
      settings = {}
    }
  } else if (typeof field.settings === 'object' && field.settings !== null) {
    settings = { ...(field.settings as Record<string, unknown>) }
  }

  if (field.nameFieldType) {
    settings.nameFieldType = field.nameFieldType
  }
  if (field.subFieldIndex !== undefined) {
    settings.subFieldIndex = field.subFieldIndex
  }

  return settings
}

function inferNameFieldKeyFromLabel(label: unknown): string | null {
  if (typeof label !== 'string' || label.trim() === '') {
    return null
  }

  const nameFieldMatch = /^nameField(\d+)$/i.exec(label.trim())
  if (nameFieldMatch) {
    return `nameField${nameFieldMatch[1]}`
  }

  const labelMatch = /name\s*field\s*(\d+)/i.exec(label.trim())
  if (labelMatch) {
    return `nameField${labelMatch[1]}`
  }

  return null
}

export function resolveNameFieldKey(
  subfield: { type?: string; label?: string },
  settings?: Record<string, unknown>,
  fallbackIndex?: number,
): string {
  if (isNameFieldKey(subfield.type)) {
    return subfield.type
  }

  const fromSettings = settings?.nameFieldType
  if (isNameFieldKey(fromSettings)) {
    return fromSettings
  }

  const fromLabel = inferNameFieldKeyFromLabel(subfield.label)
  if (fromLabel) {
    return fromLabel
  }

  if (fallbackIndex !== undefined) {
    return `nameField${fallbackIndex + 1}`
  }

  return 'nameField1'
}

function canonicalizeNameFieldKey(key: string): string {
  const index = parseNameFieldKeyIndex(key)
  return index !== null ? `nameField${index}` : key
}

function ensureUniqueNameFieldKey(key: string, usedKeys: readonly string[]): string {
  const normalizedKey = isNameFieldKey(key) ? canonicalizeNameFieldKey(key) : key
  const normalizedUsed = usedKeys.map((usedKey) =>
    isNameFieldKey(usedKey) ? canonicalizeNameFieldKey(usedKey) : usedKey,
  )

  if (!normalizedUsed.includes(normalizedKey)) {
    return normalizedKey
  }

  let candidate = 1
  while (normalizedUsed.includes(`nameField${candidate}`)) {
    candidate++
  }

  return `nameField${candidate}`
}

export function resolveUniqueNameFieldKey(
  subfield: { type?: string; label?: string },
  settings: Record<string, unknown> | undefined,
  fallbackIndex: number,
  usedKeys: readonly string[],
): string {
  const key = resolveNameFieldKey(subfield, settings, fallbackIndex)
  return ensureUniqueNameFieldKey(key, usedKeys)
}

function getSubFieldDisplayIndex(settings?: Record<string, unknown>): number | null {
  const value = settings?.subFieldIndex
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value
  }
  if (typeof value === 'string' && value.trim() !== '') {
    const parsed = Number(value)
    return Number.isFinite(parsed) ? parsed : null
  }
  return null
}

export function sortChildrenByDisplayOrder<T extends Field>(
  children: T[],
  apiOrder: Map<T, number>,
): T[] {
  return [...children].sort((a, b) => {
    const aSettings = getChildFieldSettings(a)
    const bSettings = getChildFieldSettings(b)
    const aIndex = getSubFieldDisplayIndex(aSettings)
    const bIndex = getSubFieldDisplayIndex(bSettings)
    const aHas = aIndex !== null
    const bHas = bIndex !== null
    if (aHas && bHas) return aIndex - bIndex
    if (aHas) return -1
    if (bHas) return 1
    return (apiOrder.get(a) || 0) - (apiOrder.get(b) || 0)
  })
}

export function assignLegacyNameFieldKeysIfMissing<T extends { type?: string; label?: string }>(
  subfields: T[],
  settingsList: Array<Record<string, unknown>> = [],
): Array<T & { type: string }> {
  const usedKeys: string[] = []

  return subfields.map((subfield, idx) => {
    const type = resolveUniqueNameFieldKey(subfield, settingsList[idx], idx, usedKeys)
    usedKeys.push(type)
    return { ...subfield, type }
  })
}

```
