VBScriptベースのHTAで入力フォームを増やしたり減らしたりする


環境:windows10

 HTAは知名度が低いですが,windowsでHTML形式でアプリを作成できる機能です。
 メモ帳だけでGUIアプリが作成できるので,主にVBScriptでメッセージボックス以上のGUIが必要になったら選択肢の一つになります(実際はExcelでVBEに記述して,VBScriptに書き下して,HTAに挿入というのがよいと思います。開発環境が使えない人のための最大限効率のよい開発手法について別記事にしようと思ってます)。
 PowerShellとどっちがいいか,という点については,開発環境や機能ではPowerShellの方が優れていますが,PowerShellは配布時に起動用のバッチファイルが必要になったり,
https://qiita.com/harryyuni/items/c7095d0e472d50fdc35e
オブジェクト渡しの関係で遅く,MicrosoftOfficeやIEへのアクセスはVBScriptの方が優れているので,配布を考えたときにはHTAでの開発がよいケースも依然としてあります。

 HTAはだいぶ古い技術ですが,マイクロソフト公式にヘッダーの指定やフォームの追加について書かれていて,検索窓で「HTA」と検索すると参考になります。
 https://docs.microsoft.com/en-us/previous-versions/ms536495(v=vs.85)
(マイクロソフト公式)
 VBScriptベースの開発用の本ならこちらが参考になります。VBScript Hackers Technique Webクライアント・アプリケーションの制作―
(アマゾン)

概要

追加ボタンで増えて,削除ボタンで減る,よくある実装です。

スクリプト

 以下の内容でメモ帳の拡張子を.htaにして保存すればすぐに使用できます。
 保存時の「文字コード」は「ANSI」にしないと文字化けします。このあたりはVBScriptと一緒です。

hta
<html><head>
<title>フォームの増減</title></head>
<body>
<p id="product" name="productParent">
物品<input type="text" name="product"/></p>
<input type="button" name="add" value="追加" onClick=clone_tag("product") />
<input type="button" name="remove" value="削除" onClick=remove_tag("product") />
<br>

<script language="VBScript">
Sub clone_tag(parentId)
    Dim parentTagsNum
    parentTagsNum=document.getElementsByName(parentId).Length
    Dim lastParentId
        If parentTagsNum = 2 Then
            lastParentId = parentId
        Else
            lastParentId = parentId & parentTagsNum - 1
        End if
    Dim parentTag
    Set parentTag=document.getElementById(lastParentId)
    Dim cloneTag
    Set cloneTag=parentTag.cloneNode(true)
    cloneTag.Id=parentId & parentTagsNum
    parentTag.appendchild(cloneTag)
End Sub
Sub remove_tag(parentId)
    Dim parentTagsNum
    parentTagsNum=document.getElementsByName(parentId).Length
    Dim lastParentId,deleteChildId
        If parentTagsNum = 2 Then
            Exit Sub
        Elseif parentTagsNum = 3 Then
            lastParentId = parentId
            deleteChildId = parentId & parentTagsNum - 1
        Else
            lastParentId = parentId & parentTagsNum - 2
            deleteChildId = parentId & parentTagsNum - 1
        End if
    Dim lastParentTag
    Set lastParentTag=document.getElementById(lastParentId)
    Dim deleteChildTag
    Set deleteChildTag=document.getElementById(deleteChildId)
    lastParentTag.removeChild(deleteChildTag)
End Sub
</script>
</body>
</html>

補足

追加ボタン

hta
Sub clone_tag(parentId)
    Dim parentTagsNum
    parentTagsNum=document.getElementsByName(parentId).Length
    Dim lastParentId
        If parentTagsNum = 2 Then
            lastParentId = parentId
        Else
            lastParentId = parentId & parentTagsNum - 1
        End if
    Dim parentTag
    Set parentTag=document.getElementById(lastParentId)
    Dim cloneTag
    Set cloneTag=parentTag.cloneNode(true)
    cloneTag.Id=parentId & parentTagsNum
    parentTag.appendchild(cloneTag)
End Sub

 親タグの要素数で直近の親のIdを特定して,子要素を加える実装です。
 親タグの要素数は,pタグとinputタグで最初が2です。
 なので,タグが2のときはそのままのId,3以降は生成時に指定したIdで特定しています。
 どうも,HTAでは使えるメソッドなどに制限があるようです。
 .appendchildは使えますが,.Afterはエラーになったのでどんどん子要素を増やす実装になっています。
 僕の技術不足で動かせなかった可能性はあります。

削除ボタン

hta
Sub remove_tag(parentId)
    Dim parentTagsNum
    parentTagsNum=document.getElementsByName(parentId).Length
    Dim lastParentId,deleteChildId
        If parentTagsNum = 2 Then
            Exit Sub
        Elseif parentTagsNum = 3 Then
            lastParentId = parentId
            deleteChildId = parentId & parentTagsNum - 1
        Else
            lastParentId = parentId & parentTagsNum - 2
            deleteChildId = parentId & parentTagsNum - 1
        End if
    Dim lastParentTag
    Set lastParentTag=document.getElementById(lastParentId)
    Dim deleteChildTag
    Set deleteChildTag=document.getElementById(deleteChildId)
    lastParentTag.removeChild(deleteChildTag)
End Sub

 こちらは,親タグ,子タグを特定して削除するので,3のときに元々のIdを,4以上のときに指定したIdで.removeChildを実行します。
 全く追加していない2のときは削除すると項目がなくなってしまうので,条件分岐しておきます。