CotomyElement Value and Form Behavior

A practical guide focused on input value handling and concrete POST payload behavior when using CotomyElement.

This is a continuation of CotomyElement in Practice . The previous article focused on lookup, layout control, size, and scroll behavior. This time the focus is value and text handling, plus what is actually sent when a form is submitted.

The main point is simple: not theory, but the exact payload the browser sends.

text vs value

element.text rewrites textContent, while input.value is the form value used for submission. In practice, span and div are display targets and input is a submit target.

const nameInput = CotomyElement.byId("name")!;
const label = CotomyElement.byId("name-label")!;

nameInput.value = "John";
label.text = "Display: John";

text is for display. value is for submission.

Value handling by input type

Each type below is shown as one set:

HTML example, TypeScript get/set, and POST body on submit.

1) type=“text”

HTML:

<input type="text" name="username" value="alice">

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const usernameInput = form.first('input[name="username"]')!;

const username = usernameInput.value;
usernameInput.value = "bob";

POST body:

username=alice

Notes:

The value is sent as is, and if it is empty an empty string is sent.

2) type=“number”

HTML:

<input type="number" name="age" value="30">

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const ageInput = form.first('input[name="age"]')!;

const ageText = ageInput.value;
ageInput.value = "31";

POST body:

age=30

Notes:

Even when it looks numeric, submission is still string data, and if it is empty an empty string is sent.

3) type=“checkbox”

HTML (checked):

<input type="checkbox" name="active" value="true" checked>

TypeScript:

const form = CotomyElement.byId("account-form")!;
const activeInput = form.first('input[name="active"]')!;

const isActive = activeInput.match(":checked");
const activePayload = activeInput.value;

activeInput.attribute("checked", "checked");
activeInput.attribute("checked", null);

POST body (checked):

active=true

POST body (unchecked):

(not sent)

Notes:

If unchecked, the key itself is missing. The submitted payload uses the value attribute, and if value is omitted the browser sends on. In Cotomy code, checked toggling is handled through checked attribute operations.

4) type=“radio”

HTML:

<input type="radio" name="role" value="admin" checked>
<input type="radio" name="role" value="user">

TypeScript:

const form = CotomyElement.byId("account-form")!;

const selectedRole = form.first('input[name="role"]:checked')!.value;

form.find('input[name="role"]').forEach(r => {
  r.attribute("checked", null);
});
form.first('input[name="role"][value="user"]')!.attribute("checked", "checked");

POST body:

role=admin

Notes:

Inputs with the same name form one group, and only the selected item is sent. In Cotomy code, radio selection is also toggled through checked attribute operations.

5) select (single)

HTML:

<select name="country">
  <option value="jp" selected>Japan</option>
  <option value="us">USA</option>
</select>

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const countrySelect = form.first('select[name="country"]')!;

const country = countrySelect.value;
countrySelect.value = "us";

POST body:

country=jp

6) select multiple

HTML:

<select name="tags" multiple>
  <option value="a" selected>A</option>
  <option value="b" selected>B</option>
</select>

TypeScript:

const form = CotomyElement.byId("search-form")!;
const tagsSelect = form.first('select[name="tags"]')!;

const selectedTags = form
  .find('select[name="tags"] option:checked')
  .map(option => option.value);

tagsSelect.find('option[value="a"]')!.attribute("selected", "selected");
tagsSelect.find('option[value="b"]')!.attribute("selected", "selected");

POST body:

tags=a
tags=b

Notes:

The same key is sent multiple times, and the server side usually treats this as an array.

Important:

Multiple select is intentionally excluded from automatic fill in CotomyEntityFillApiForm. This is not a missing feature but a boundary decision.

Reason:

Array binding patterns differ across projects, and real business UIs often replace native multiple select with token UI, checkbox groups, or custom selector components. Enforcing one automatic array synchronization model in core would reduce architectural flexibility.

Cotomy core keeps multiple select behavior strictly native.

If array-based synchronization is required, it should be implemented explicitly at application level.

In the upcoming project template distribution, standardized multi-select synchronization may be introduced through a separate class designed for consistent array binding patterns.

7) textarea

HTML:

<textarea name="note">hello</textarea>

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const noteArea = form.first('textarea[name="note"]')!;

const note = noteArea.value;
noteArea.value = "updated note";

POST body:

note=hello

Notes:

Submission behavior is the same as value input handling.

8) disabled field

HTML:

<input type="text" name="internalId" value="123" disabled>

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const internalIdInput = form.first('input[name="internalId"]')!;

const internalId = internalIdInput.value;
internalIdInput.disabled = true;

POST body:

(not sent)

Important:

disabled fields are not submitted.

9) readonly field

HTML:

<input type="text" name="code" value="ABC" readonly>

TypeScript:

const form = CotomyElement.byId("profile-form")!;
const codeInput = form.first('input[name="code"]')!;

const code = codeInput.value;
codeInput.readonly = true;
codeInput.value = "DEF";

POST body:

code=ABC

Important:

readonly fields are submitted, and this is the key difference from disabled.

Updating value with CotomyElement

const form = CotomyElement.byId("order-form")!;
form.find("input, select, textarea").forEach(el => {
  if (el.attribute("data-auto-fill") === "true") {
    el.value = "auto";
  }
});

CotomyElement updates the real DOM directly. There is no separate virtual state. The value written to the element becomes the submit target as is.

Confirm what will be sent with FormData

const formEl = document.querySelector("form")!;
const fd = new FormData(formEl);

for (const [key, value] of fd.entries()) {
  console.log(key, value);
}

This lets you verify the real payload before sending. CotomyElement does not add special conversion here. It follows native browser form behavior.

Summary

CotomyElement updates values directly, but submit rules stay browser-native. Disabled fields are not sent, unchecked checkboxes are not sent, multiple select sends repeated keys, and non-file form values are handled as string payloads.

Last time was DOM lookup and control. This time was DOM values and submission.

Usage Series

This article is part of the Cotomy Usage Series, which focuses on concrete runtime behavior and day-to-day API usage.

Series articles: CotomyElement in Practice , CotomyElement Value and Form Behavior, CotomyApi in Practice , and Debugging Features and Runtime Inspection in Cotomy .

Previous article: CotomyElement in Practice Next article: CotomyApi in Practice

Learn Cotomy

Cotomy is a DOM-first UI runtime for long-lived business applications.