button 要素の type 属性は「押したときに何をするか」を決める属性で、submit はフォームを送信、reset は入力内容を初期値に戻し、button は何もしません(JavaScript で動きを付ける用)。 そして type を書かなかったときの既定は submit です。フォームの中に type を省略したボタンを置くと、「行を追加」や「キャンセル」のつもりのボタンでもフォームが送信されます。

この記事では、ローカルに立てたサーバーに Chromium 141 から実際に送信し、届いたリクエストを記録して動きを確かめました。3種の type と input 要素のボタンの比較表、Enter キーで押されるボタンの決まり方、disabled にしたボタンの値が送られない点、form・formaction・formnovalidate 属性、二重送信を防ぐコード、そして popovertarget と command/commandfor までを、コピペで動くコードと実行結果つきでまとめます。

button type の早見表

書き方 押したときの動き フォーム送信 向いている用途
<button type="submit"> フォームを送信する する 登録・保存・検索など、送信するボタン
<button type="reset"> フォーム内の入力を初期値に戻す しない 入力のやり直し(置く場面は少なめ)
<button type="button"> 何もしない しない 行の追加、モーダルを開く、計算など JavaScript で動かすボタン
<button>(type 省略) submit と同じ する 省略せず、どれかを明記するのがおすすめ
<button type="foo">(想定外の値) submit と同じ(実測) する 書き間違いに注意

フォームの中に置くボタンは、送信用なら type="submit"、それ以外は type="button" と必ず書く。これだけで、この記事で扱うつまずきの大半を避けられます。

検証環境と記録の取り方

  • Playwright 1.56.0 + Chromium 141.0.7390.37(ヘッドレス)、Node.js 22.22
  • Node.js の http モジュールで 127.0.0.1 にサーバーを立て、届いたリクエストの「メソッド・URL・本文」を記録
  • Firefox・Safari では未実行です

以降の「実行結果」は、すべてこのサーバーに届いたリクエストの記録です。(送信なし) は、リクエストが1件も届かなかったことを表します。

type を省略すると submit になる例を再現する

注文フォームに「行を追加」ボタンを足した、という想定です。

<form action="/order" method="get">
  <input name="item" value="pen">
  <button id="add">行を追加</button>           <!-- type を省略 -->
  <button type="submit" id="go">注文する</button>
</form>

「行を追加」をクリックしたときの実行結果:

GET /order?item=pen

行を追加するつもりのボタンで、フォームが送信されました。JavaScript で click 時の処理を書いていても、その処理のあとに送信が走り、ページが切り替わります。type="button" を付けて同じ操作をした結果は次のとおりです。

<button type="button" id="add">行を追加</button>
(送信なし)

type 属性を1つ足すだけで、送信されなくなります。 event.preventDefault() で送信を止める方法もありますが、type を正しく書くほうが、JavaScript が読み込まれる前に押された場合にも同じ動きになります。

button と input のボタンの比較表(実測)

同じフォームの中に、ボタンを1種類ずつ置いて試しました。テキスト欄 q の初期値は abc で、changed と入力し直してからボタンを押しています。各ボタンには name="act" value="v" を付けています。

<form action="/c" method="get">
  <input name="q" value="abc">
  <!-- ここに1種類ずつ置く -->
  <button type="submit" name="act" value="v">b</button>
</form>
ボタン 送信する ボタンの値が送られる 入力欄 q 中に HTML を入れられる
<button>(省略) する 送られる(act=v) 入力後のまま送信 入れられる
<button type="submit"> する 送られる(act=v) 入力後のまま送信 入れられる
<button type="reset"> しない — 初期値 abc に戻る 入れられる
<button type="button"> しない — changed のまま 入れられる
<input type="submit"> する 送られる(act=v) 入力後のまま送信 入れられない(value の文字列が表示される)
<input type="reset"> しない — 初期値 abc に戻る 入れられない
<input type="button"> しない — changed のまま 入れられない
<input type="image"> する クリック座標が送られる(act.x・act.y) 入力後のまま送信 入れられない(画像を表示)

届いたリクエストの記録(抜粋):

[button-none]   GET /c?q=changed&act=v
[button-submit] GET /c?q=changed&act=v
[button-reset]  (送信なし) | q=abc
[button-button] (送信なし) | q=changed
[input-submit]  GET /c?q=changed&act=v
[input-reset]   (送信なし) | q=abc
[input-button]  (送信なし) | q=changed
[input-image]   GET /c?q=changed&act.x=3&act.y=4
[button-bogus]  GET /c?q=changed&act=v     ← type="foo" と書いた場合

button と input のどちらを使うか

送信・リセット・何もしない、という動きは button 要素と input 要素で同じでした。違いは中身の書き方です。

<!-- button 要素:開始タグと終了タグの間に HTML を書ける -->
<button type="submit" name="act" value="save">
  <svg width="16" height="16" aria-hidden="true"><circle cx="8" cy="8" r="6"/></svg>
  <strong>保存</strong>する
</button>

<!-- input 要素:value の文字列がそのままラベルになる -->
<input type="submit" name="act" value="保存する">

input 要素の value に <b>x</b> と書いて確かめたところ、タグとして解釈されず、文字列のまま表示用の値になりました。

比べる点 button 要素 input 要素(submit/reset/button)
ラベルの書き方 要素の中身(アイコン・太字・改行も可) value 属性の文字列のみ
送信される値と表示の関係 value と表示を別々にできる value が表示と送信値を兼ねる
擬似要素(::before/::after)での装飾 使える 使えない場面がある(未実行)
type の既定 submit text(type を省くとテキスト欄になる)

新しく書くなら button 要素を選び、type を明記するのが扱いやすい形です。表示と送信値を分けられるので、「表示は『保存する』、送る値は save」のように設計できます。

Enter キーで押されるボタンの決まり方

テキスト欄で Enter キーを押すとフォームが送信されます。このとき、どのボタンが押された扱いになるかを確かめました。

最初にある submit ボタンが使われる

<form action="/e" method="get">
  <input name="q">
  <button name="act" value="cancel">キャンセル</button>   <!-- type 省略 -->
  <button name="act" value="save">保存</button>
</form>

テキスト欄で Enter を押した結果:

GET /e?q=&act=cancel

フォームの中で、文書の順で最初にある submit ボタン(既定のボタン)が押された扱いになり、その値が送られました。「キャンセル」に type を書いていないため、Enter で act=cancel が送信されています。キャンセルを type="button" にすると、次のように「保存」が既定のボタンになります。

<button type="button" name="act" value="cancel">キャンセル</button>
<button name="act" value="save">保存</button>
GET /e?q=&act=save

Enter キーの挙動の一覧

フォームの状態 テキスト欄で Enter を押した結果(実測)
submit ボタンが複数ある 最初の submit ボタンの値つきで送信
最初の submit ボタンが disabled 送信されない(2番目のボタンには移らない)
submit ボタンがなく、テキスト欄が1つ 送信される(GET /e?q=)
submit ボタンがなく、テキスト欄が2つ 送信されない
textarea の中で Enter 送信されない(改行が入る)
type="button" のボタンにフォーカスして Enter/Space そのボタンの click が起き、送信はされない

Enter による送信では、既定のボタンの click イベントも1回発生しました(submit イベントの event.submitter はそのボタンを指していました)。ボタンの click に処理を書いている場合、Enter でもその処理が動きます。

[enter-clickevent] submitter=save clicks=1

送信時の処理はボタンの click ではなく、フォームの submit イベントに書くと、クリックでも Enter でも同じ処理を通せます。

disabled にしたボタンと入力欄は値が送られない

disabled を付けた部品は、押せなくなるだけでなく、フォーム送信のデータにも含まれません。

<form action="/d" method="get">
  <input name="a" value="1">
  <input name="b" value="2" disabled>
  <input name="c" value="3" readonly>
  <fieldset disabled>
    <input name="d" value="4">
  </fieldset>
  <button name="act" value="draft" disabled>下書き</button>
  <button name="act" value="send">送信</button>
</form>

「下書き」(disabled)をクリックし、続けて「送信」をクリックした結果:

GET /d?a=1&c=3&act=send
部品 送信データ 補足
通常の入力欄(a) 含まれる
disabled の入力欄(b) 含まれない 編集もフォーカスもできない
readonly の入力欄(c) 含まれる 編集はできないが値は送られる
fieldset disabled の中の入力欄(d) 含まれない 中の部品がまとめて無効になる
disabled のボタン クリックしても何も起きない click イベントも発生しなかった
押された submit ボタン 含まれる(act=send) 押されなかったボタンの値は送られない

値は送りたいが編集はさせたくない場合は readonly、値も送らなくてよい場合は disabled、と使い分けます。

disabled と aria-disabled の違い

<button disabled onclick="document.title='clicked'">x</button>
<button aria-disabled="true" onclick="document.title='aria clicked'">y</button>

1つ目をクリック → Tab キー → 2つ目をクリック、の順に操作した結果:

disabled:      title=""  Tab の行き先 = 2つ目のボタン
aria-disabled: title="aria clicked"
属性 クリック Tab キーでのフォーカス 送信データ
disabled 反応しない 飛ばされる 含まれない
aria-disabled="true" 反応する(自分で止める必要あり) 当たる 含まれる

aria-disabled は「無効である」ことを支援技術に伝えるだけで、動きは止めません。フォーカスを残したまま無効に見せたいときに使い、click 処理の中で aria-disabled を見て処理を止める形にします。

form・formaction・formnovalidate 属性の使い方

submit ボタンには、フォーム側の設定をボタンごとに上書きする属性があります。

属性 役割 上書きする form 側の属性
form 関連付けるフォームを id で指定(フォームの外にも置ける) —
formaction 送信先 URL action
formmethod 送信メソッド(get/post/dialog) method
formenctype 本文のエンコード方式 enctype
formtarget 結果を表示する場所(_blank など) target
formnovalidate 入力チェックを行わずに送信 novalidate
name/value 押されたボタンを判別する値 —

属性の一覧は MDN の button 要素のページで確認しました。以下、form・formaction・formmethod・formnovalidate を実際に動かした結果です(formenctype と formtarget の _blank は未実行です)。

form 属性:フォームの外に置いたボタンで送信する

<form id="f1" action="/f" method="get">
  <input name="q" value="1">
</form>

<p>…ページの別の場所…</p>
<button type="submit" form="f1" name="act" value="out">フォームの外</button>
GET /f?q=1&act=out

form 属性にフォームの id を書くと、フォームの外にあるボタンでも送信でき、ボタンの値も送られました。画面下に固定した「保存」ボタンなど、レイアウトの都合で form 要素の中に入れにくいときに使えます。

formaction・formmethod:ボタンごとに送信先を変える

<form action="/save" method="post">
  <input name="title" value="memo">
  <button type="submit">保存</button>
  <button type="submit" formaction="/preview" formmethod="get">プレビュー</button>
  <button type="submit" formaction="/draft">下書き</button>
</form>

「プレビュー」→「下書き」→「保存」の順にクリックした結果:

GET /preview?title=memo
POST /draft body=title=memo
POST /save body=title=memo

1つのフォームで、押したボタンによって送信先とメソッドが切り替わりました。なお MDN には、「formaction を付けた submit ボタンは、関連付けられたフォームがないと何もしない」という注記があります。form 要素の中に置くか、form 属性でフォームを指定して使います。

送信先を変えずにサーバー側で分岐したい場合は、name と value を使います。

<button type="submit" name="act" value="save">保存</button>
<button type="submit" name="act" value="delete">削除</button>

押されたボタンの act=save/act=delete だけが送られるので、サーバー側はこの値で処理を分けられます。

formnovalidate:下書き保存では入力チェックを飛ばす

<form action="/v" method="get">
  <input name="mail" type="email" required>
  <button type="submit" name="act" value="send">送信</button>
  <button type="submit" name="act" value="draft" formnovalidate>下書き保存</button>
</form>

メール欄を空のまま、「送信」→「下書き保存」の順にクリックした結果:

「送信」クリック後の送信数 = 0   validationMessage = "Please fill out this field."
「下書き保存」クリック後      = GET /v?mail=&act=draft

「送信」は必須チェックで止まり、リクエストは届きませんでした。formnovalidate を付けた「下書き保存」は、空のままでも送信されています。メッセージが英語なのは検証環境のブラウザの言語設定によるもので、日本語環境では日本語の文言になります。

二重送信を防ぐコード

送信に時間がかかると、利用者が同じボタンをもう一度押すことがあります。応答に 0.6 秒かかるサーバーに対して、0.15 秒あけて2回クリックして確かめました。

何もしない場合:2件届く

<form id="f" action="/slow" method="post">
  <input name="item" value="pen">
  <button type="submit" id="s" name="act" value="buy">注文する</button>
</form>
POST /slow body=item=pen&act=buy
POST /slow body=item=pen&act=buy

同じ内容が2件届きました(ダブルクリックのようにごく短い間隔の2回では1件だけでしたが、少し間があくと2件になります)。

うまくいかない例:submit イベントの中ですぐ disabled にする

// ボタンの値が送られなくなる書き方
f.addEventListener('submit', (e) => {
  e.submitter.disabled = true;
});
POST /slow body=item=pen

2回目は防げましたが、act=buy が送信データから消えています。submit イベントの時点ではまだ送信データが作られておらず、そのあとで「disabled の部品は含めない」というルールが適用されるためです。サーバー側が act の値で処理を分けていると、想定と違う動きになります。

直し方 A:フラグで2回目を止める(ボタンの値も送られる)

<form id="f" action="/slow" method="post">
  <input name="item" value="pen">
  <button type="submit" name="act" value="buy">注文する</button>
</form>

<script>
  const f = document.getElementById('f');
  f.addEventListener('submit', (e) => {
    if (f.dataset.sending) {      // 2回目以降は送信を止める
      e.preventDefault();
      return;
    }
    f.dataset.sending = '1';
    const b = e.submitter;        // 押されたボタン
    if (b) {
      b.setAttribute('aria-disabled', 'true');
      b.textContent = '送信中…';
    }
  });
</script>
POST /slow body=item=pen&act=buy

1件だけ届き、ボタンの値も含まれています。

直し方 B:送信データが作られたあとで disabled にする

f.addEventListener('submit', (e) => {
  const b = e.submitter;
  setTimeout(() => { b.disabled = true; }, 0);   // 送信データの作成後に無効化
});
POST /slow body=item=pen&act=buy

setTimeout で1拍遅らせると、値が送られたうえでボタンが無効になります。

直し方 C:fetch で送る場合

f.addEventListener('submit', async (e) => {
  e.preventDefault();
  const b = e.submitter;
  if (b.disabled) return;
  // 第2引数に押されたボタンを渡すと、その name/value も含まれる
  const data = new URLSearchParams(new FormData(f, b));
  b.disabled = true;
  try {
    await fetch(f.action, { method: 'POST', body: data });
  } finally {
    b.disabled = false;           // 完了後に戻す
  }
});
POST /slow body=item=pen&act=buy

new FormData(form, submitter) のように押されたボタンを第2引数に渡すと、ボタンの値も送信データに入ります。データを作ってから disabled にしているので、値が欠けることもありません。

方法 2回目を止める ボタンの値 向いている場面
submit 内ですぐ disabled = true 止まる 送られない ボタンに name/value がないフォーム
フラグ+ preventDefault() 止まる 送られる 通常のページ遷移を伴うフォーム
setTimeout で遅らせて disabled 止まる 送られる 見た目も無効にしたいとき
fetch + FormData(form, submitter) 止まる 送られる ページ遷移なしで送るフォーム

画面側の対策は利用者の操作を助けるためのものです。ブラウザの「戻る」や再読み込みでも同じリクエストは届くので、重複して登録したくない処理では、サーバー側でも一度きりのトークンなどで確認する設計にします(サーバー側の実装はこの記事では未実行です)。

JavaScript から送信する:submit() と requestSubmit()

<form id="f" action="/r" method="get" onsubmit="window.n = (window.n || 0) + 1">
  <input name="mail" required>
</form>

必須欄を空にしたまま、f.requestSubmit() → f.submit() の順に呼んだ結果:

requestSubmit(): submit イベント = 0回、送信 = 0件(入力チェックで止まる)
submit():        GET /r?mail=          (入力チェックも submit イベントもなしで送信)
メソッド 入力チェック submit イベント 使いどころ
form.requestSubmit() 行う 発生する ボタンを押したのと同じ流れで送りたいとき
form.submit() 行わない 発生しない チェックや submit 処理を通さず送りたいとき

二重送信防止などを submit イベントに書いている場合は、requestSubmit() を使うとその処理を通せます。

popovertarget と command/commandfor

JavaScript を書かずに、ボタンでポップオーバーやダイアログを開閉する属性です。属性の値は MDN の button 要素のページで確認し、Chromium 141 で動かしました。

popovertarget:ポップオーバーを開閉する

<button type="button" popovertarget="tip">ヘルプ</button>
<div id="tip" popover>入力した内容は下書きとして保存されます。</div>

ボタンを2回クリックしたときの :popover-open の一致:

false -> true -> false
属性 値 動き
popovertarget 対象の id そのポップオーバーを操作する
popovertargetaction toggle(既定) 開閉を切り替える
popovertargetaction show 開く(開いていれば何もしない)
popovertargetaction hide 閉じる(閉じていれば何もしない)

フォームの中では type="button" を忘れずに

popovertarget を付けても、type の既定は submit のままでした(button.type は submit)。フォームの中で type を省略すると、次のようになります。

<form action="/p" method="get">
  <input name="q" value="1">
  <button popovertarget="tip">ヘルプ</button>      <!-- type 省略 -->
  <div id="tip" popover>説明</div>
</form>
GET /p?q=1          ← ヘルプを開くつもりが送信された

type="button" を付けると送信されず、ポップオーバーが開きました(open=true)。

command/commandfor:ダイアログやポップオーバーを操作する

commandfor は popovertarget をより汎用にした属性で、対象の id を commandfor に、行う操作を command に書きます。

<button type="button" commandfor="dlg" command="show-modal">開く</button>

<dialog id="dlg">
  <p>この内容で登録しますか?</p>
  <button type="button" commandfor="dlg" command="close" value="ok">閉じる</button>
</dialog>

「開く」→「閉じる」の順にクリックしたときの dialog.open の変化:

supported=true  open: false -> true (modal=true) -> false  returnValue=ok

showModal() や close() を呼ぶ JavaScript なしで、モーダルダイアログの開閉ができました。close のボタンに付けた value は、ダイアログの returnValue に入っています。

command の値 動き(MDN の記載) 今回の確認
show-modal dialog をモーダルで開く 実行して確認
close dialog を閉じる 実行して確認
request-close cancel イベントを起こし、閉じてよいか確認してから閉じる 未実行
show-popover ポップオーバーを開く 未実行
hide-popover ポップオーバーを閉じる 未実行
toggle-popover ポップオーバーを開閉する 実行して確認(true → false)
-- で始まる独自の値 対象の要素で command イベントが発生する 実行して確認

独自コマンドの例です。

<button type="button" commandfor="box" command="--rotate">回す</button>
<div id="box"></div>

<script>
  document.getElementById('box').addEventListener('command', (e) => {
    console.log('command=' + e.command + ' source=' + e.source.id);
  });
</script>
command=--rotate source=cu     (cu は押したボタンの id)

commandfor をフォームの中で type なしで使うと、何も起きない

popovertarget とは違う結果になったのがこの点です。

<form action="/cm" method="get">
  <input name="q" value="1">
  <button commandfor="dlg" command="show-modal">開く</button>   <!-- type 省略 -->
</form>
<dialog id="dlg">x</dialog>
(送信なし) | open=false
コンソール: Buttons associated with forms that include command or commandfor attributes
           are ambiguous, and require a type=button attribute. No action will be taken.

送信もされず、ダイアログも開きませんでした。コンソールには「フォームに関連付けられたボタンに command/commandfor がある場合はあいまいなので、type=button が必要」という趣旨のメッセージが出ています。type="button" を付けると開きました(open=true)。

フォーム内で type を省略したボタン Chromium 141 での結果
属性なし 送信される
popovertarget つき 送信される
commandfor/command つき 送信されず、コマンドも実行されない

どの場合も type="button" を書けば意図どおりに動きます。 command/commandfor は比較的新しい属性で、今回は Chromium 141 のみで確認しています。ほかのブラウザの対応状況は未確認なので、利用前に MDN の対応表などで確かめてください。

dialog の中のフォームで閉じる

ダイアログを閉じる方法としては、method="dialog" のフォームも使えます。

<dialog id="dlg" open>
  <form method="dialog">
    <button type="submit" value="yes">はい</button>
  </form>
</dialog>
(送信なし) | open=false returnValue=yes

サーバーには送信されず、ダイアログが閉じて、押したボタンの value が returnValue に入りました。

よくあるつまずきと直し方

症状 原因 直し方
ボタンを押すとページが再読み込みされる フォーム内のボタンの type を省略している type="button" を付ける
Enter を押すと「キャンセル」が実行される 最初の submit ボタンがキャンセルになっている キャンセルを type="button" にする
Enter で送信されない 既定のボタンが disabled、または submit ボタンがなく入力欄が複数ある submit ボタンを置く/有効にする
サーバーにボタンの値が届かない ボタンに name がない、または送信前に disabled にしている name/value を付け、disabled にするタイミングを遅らせる
disabled の入力欄の値が届かない disabled の部品は送信データに含まれない 値を送りたいなら readonly にする
同じデータが2件登録される 送信中にもう一度押されている フラグで2回目を止める。サーバー側でも確認する
formaction が効かない ボタンがフォームに関連付けられていない form 要素の中に置くか、form 属性を付ける
commandfor のボタンが反応しない フォーム内で type を省略している type="button" を付ける

ボタンを書くときのチェックリスト

  • [ ] すべての button 要素に type を書いた
  • [ ] フォーム内で最初にある submit ボタンが、Enter で実行されてよいものになっている
  • [ ] 送信時の処理はフォームの submit イベントに書いた
  • [ ] ボタンの値で処理を分けるなら、name と value を付けた
  • [ ] 送信中の2回目を止める処理を入れた
  • [ ] アイコンだけのボタンには、aria-label などで名前を付けた

よくある質問

Q. button の type を省略すると、どうなりますか? A. submit として扱われます。フォームの中にあるとクリックで送信されます。今回の検証でも、type を省略した「行を追加」ボタンで GET /order?item=pen が送信されました。フォームの外にあるボタンでは送信は起きませんが、あとからフォームの中に移動することもあるので、常に書いておくと安心です。

Q. button 要素と input type="button" の違いは何ですか? A. 押したときの動きは同じで、どちらも何もしません。違いはラベルの書き方で、button 要素は中にアイコンや太字などの HTML を入れられ、input 要素は value 属性の文字列だけが表示されます。

Q. reset ボタンは置いたほうがよいですか? A. 必須ではありません。reset は入力内容をすべて初期値に戻すので、送信ボタンの隣にあると押し間違えたときの影響が大きくなります。置く場合は、送信ボタンから離す、見た目を控えめにするなどの工夫が役立ちます。

Q. 送信ボタンを disabled にして二重送信を防いでもよいですか? A. 使えますが、submit イベントの中ですぐ disabled にすると、そのボタンの name/value が送られなくなります。フラグで2回目を止めるか、setTimeout で遅らせてから disabled にすると、値を保ったまま防げます。

まとめ

  • type の既定は submit。フォーム内のボタンは type="submit" か type="button" を必ず書く
  • submit・reset・button の動きは、button 要素でも input 要素でも同じ。button 要素は中に HTML を入れられる
  • テキスト欄の Enter では、最初にある submit ボタンが押された扱いになり、その値が送られる
  • disabled の部品は送信データに含まれない。値を送りたいときは readonly を使う
  • form・formaction・formmethod・formnovalidate で、ボタンごとに送信先やチェックの有無を切り替えられる
  • 二重送信防止は、submit 内ですぐ disabled にするとボタンの値が消える。フラグ方式か、遅らせて disabled にする
  • popovertarget・commandfor を付けたボタンも、フォーム内では type="button" が必要

参考

  • MDN Web Docs「button: The Button element」(type、form 系属性、popovertarget、command/commandfor の値を確認)
  • 検証環境:Playwright 1.56.0、Chromium 141.0.7390.37(ヘッドレス)、Node.js 22.22

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?