-
今回は checkbox がチェックされている状態のものを全てカウントする方法について説明します。
以下のソースは以下の記事を少し変更したものです。
⇒JavaScript jQueryを使った checkbox の操作方法■チェック件数取得
<html> <head> <meta charset="utf-8"> <title>test checkbox</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // 初期処理 $(function(){ // 全てのチェックボックスをOFF $('input[type="checkbox"]').prop('checked', false); }); // チェック件数取得関数 function getCountChk() { var intCnt = 0; // 選択済チェックボックス $('input[type="checkbox"]:checked').each(function() { intCnt += 1; }); alert("チェック件数:" + intCnt); return false; } </script> </head> <body> <h2>test checkbox</h2> <label><input id="chk1" type="checkbox" value="1" />チェック1</label><br /> <label><input id="chk2" type="checkbox" value="2" />チェック2</label><br /> <label><input id="chk3" type="checkbox" value="3" />チェック3</label><br /> <br /> <button onclick="getCountChk();">チェック件数取得</button> </body> </html>
16行目の $('input[type="checkbox"]:checked').each の部分でチェックされている全てのチェックボックスを列挙して カウントしています。 これは非常にベタな方法で、個別に処理する必要が無ければ、以下の様にした方がより簡単にできます。
■チェック件数取得その2
<html> <head> <meta charset="utf-8"> <title>test checkbox</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // 初期処理 $(function(){ // 全てのチェックボックスをOFF $('input[type="checkbox"]').prop('checked', false); }); // チェック件数取得関数 function getCountChk() { // 選択済チェックボックス var intCnt = $('input[type="checkbox"]:checked').length; alert("チェック件数:" + intCnt); return false; } </script> </head> <body> <h2>test checkbox</h2> <label><input id="chk1" type="checkbox" value="1" />チェック1</label><br /> <label><input id="chk2" type="checkbox" value="2" />チェック2</label><br /> <label><input id="chk3" type="checkbox" value="3" />チェック3</label><br /> <br /> <button onclick="getCountChk();">チェック件数取得</button> </body> </html>
入力画面でグループが異なるチェックボックスを設置することがありますので、その方法について例を示します。 以下の例では、上のソース15行目の $('input[type="checkbox"]:checked').length の部分で name 属性でアクセスする様に変更しています。
■チェック件数取得その3
<html> <head> <meta charset="utf-8"> <title>test checkbox</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> // 初期処理 $(function(){ // 全てのチェックボックスをOFF $('input[type="checkbox"]').prop('checked', false); }); // チェック件数取得関数 function getCountChk(strName) { // 選択済チェックボックス var intCnt = $('input[name="' + strName + '[]"]:checked').length; alert("チェック件数:" + intCnt); return false; } </script> </head> <body> <h2>test checkbox 1</h2> <label><input name="chk1[]" type="checkbox" value="1" />チェック1-1</label><br /> <label><input name="chk1[]" type="checkbox" value="2" />チェック1-2</label><br /> <label><input name="chk1[]" type="checkbox" value="3" />チェック1-3</label><br /> <br /> <button onclick="getCountChk('chk1');">チェック件数取得</button> <br /> <br /> <h2>test checkbox 2</h2> <label><input name="chk2[]" type="checkbox" value="10" />チェック2-1</label><br /> <label><input name="chk2[]" type="checkbox" value="20" />チェック2-2</label><br /> <label><input name="chk2[]" type="checkbox" value="30" />チェック2-3</label><br /> <br /> <button onclick="getCountChk('chk2');">チェック件数取得</button> </body> </html>
PR -
最近はまったことですが IE(Internet Explorer) では関数のデフォルト引数が動作しないことです。
比較的規模の大きい PHP がらみのプログラムで IE では全く JavaScript の部分が動かなくなったのです。 非常にあせってしまって、何が原因かがよくわからなったのですが、どうもデフォルト引数の宣言の関数があると全ての JavaScript の関数が 動かなくなる様です。
IE 以外のブラウザでは JavaScript の関数の引数で =(イコール) を後ろに付けてデフォルト値を設定できます。 この関数を呼出す時に指定なしを記述できます。
例として以下のソースを見て下さい。 IE 以外のブラウザでは、それぞれのボタンをクリックした時にメッセージが表示されます。 しかし IE では、うんともすんとも何も実行されません。
■関数にデフォルト引数がある例
<html> <head> <meta charset="utf-8"> <title>test func</title> <script type="text/javascript"> function doTest(msg = 'test message') { alert('Test:' + msg); } </script> </head> <body> <h2>test func</h2> <br /> <button onclick="doTest();">Test</button><br /> <button onclick="doTest('aaaa');">Test</button> </body> </html>
そこで、以下の様にデフォルト引数を止めてみました。
当然のことながら、IE でも関数が動作することが分かります。
■関数にデフォルト引数を止める
<html> <head> <meta charset="utf-8"> <title>test func</title> <script type="text/javascript"> function doTest(msg) { alert('Test:' + msg); } </script> </head> <body> <h2>test func</h2> <br /> <button onclick="doTest('test message');">Test</button><br /> <button onclick="doTest('aaaa');">Test</button> </body> </html>
MDN docs ではちゃんと IE はデフォルト引数は実装されていないと載っていました。
⇒https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters
どうしてもデフォルト引数が必要な場合は以下の様にすれば動きます。
■無理やり関数にデフォルト引数
<html> <head> <meta charset="utf-8"> <title>test func</title> <script type="text/javascript"> function doTest(msg) { if(typeof msg === 'undefined') { msg = 'test message'; } alert('Test:' + msg); } </script> </head> <body> <h2>test func</h2> <br /> <button onclick="doTest();">Test</button><br /> <button onclick="doTest('aaaa');">Test</button> </body> </html>
-
前回の TCP の記事では、クライアント側で1回の通信毎に TCP の接続を切断していたので、 複数回の文字列送信ができませんでした。
それで今回は、クライアント側で TCP の接続のタイミングと、文字列送信のタイミングを別々で行う様にすることで 複数回の文字列送信を可能にしています。
これを行う為に、以下のクライアント側の処理手順の中で、(1)(2)を1個の処理として、また(5)の処理も別のタイミングに追い出します。 具体的にはそれぞれフォームにボタンを設置(「Start」「Stop」の名前で)し、それぞれのクリック処理内でそれらを行います。- (1)IP アドレスとポート番号で TcpClient クラスの生成によりTCPソケット作成・接続
- (2)TcpClient クラスの GetStream メソッドで NetworkStream を取得
- (3)NetworkStream の Write メソッドでテキストボックスの内容をバイト配列化して送信
- (4)NetworkStream の Read メソッドでサーバからの応答を受信しテキストボックスに表示
- (5)最後にネットワークストリーム、ソケットをクローズ
それでは以下にクライアント側のソースを示します。 TcpClient と NetworkStream クラスのオブジェクトを関数の外に出し、静的変数としています。
■TCP クライアント側のプログラム
Imports System.Net Imports System.Text Public Class frmTcpClient 'サーバーのIPアドレス(または、ホスト名)とポート番号 Dim strIpAddr As String = "localhost" Dim intPort As Integer = 60000 'ソケット Dim mTcpClient As Sockets.TcpClient 'ソケットストリーム Dim mNetStream As Sockets.NetworkStream '[Start]リック時イベント Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ソケット生成 mTcpClient = New Sockets.TcpClient 'ソケット接続 mTcpClient.Connect(strIpAddr, intPort) 'ソケットストリーム取得 mNetStream = mTcpClient.GetStream() End Sub '[Stop]リック時イベント Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click 'ソケットクローズ mNetStream.Close() mTcpClient.Close() End Sub '[Send]リック時イベント Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click Try '送信文字列をバイト配列変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") '最後尾にCR Dim data As Byte() = enc.GetBytes(Me.TextBox1.Text.Trim & ControlChars.Cr) Me.TextBox1.Text = "" 'ソケット送信 mNetStream.Write(data, 0, data.Count) 'サーバからの応答を受信 Dim bytRead As Byte() = New Byte(255) {} Dim intBytes As Integer = mNetStream.Read(bytRead, 0, bytRead.Length) '受信したデータを文字列に変換 Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除し表示 Me.TextBox2.Text = resMsg.TrimEnd(ControlChars.Cr) Catch ex As Exception MsgBox(ex.Message) End Try End Sub End Class
サーバ側のプログラムに変更は無いのですが、一応ソースを載せておきます。
■TCP サーバ側のプログラム
Imports System.Net Imports System.Threading Imports System.Text Public Class frmTcpServer 'リッチテキストボックスにメッセージを表示する Public Sub DispMsg(ByVal message As String) RichTextBox1.AppendText(message & vbNewLine) RichTextBox1.SelectionStart = RichTextBox1.TextLength RichTextBox1.Refresh() End Sub '[Start]ボタンクリック Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ボタン制御 Me.btnStart.Enabled = False 'ポート番号 Dim pintPort As Integer = 60000 'IPアドレス&ポート番号設定 Dim pEndPoint As New IPEndPoint(IPAddress.Any, pintPort) 'ソケット・リスナー作成 Dim pListener As New Sockets.TcpListener(pEndPoint) 'リスナー開始 pListener.Start() Call DispMsg("リスナー開始...") 'クライアントから接続有りでこの処理を抜ける Dim pTcpClient As Sockets.TcpClient = pListener.AcceptTcpClient() Call DispMsg("クライアントから接続有り...") '送受信用ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() 'バイト配列(取敢えず受信バッファとして256バイト) Dim bytRead As Byte() = New Byte(255) {} 'ソケット受送信ループ While True 'TCP受信(バッファ領域まで) Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Count) If intBytes = 0 Then Exit While End If '受信したデータを文字列に変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除 resMsg = resMsg.TrimEnd(ControlChars.Cr) '表示 Call DispMsg(resMsg) '正常受信の場合、送信データ作成 Dim bytSend() As Byte = enc.GetBytes(resMsg & "...ACK" & ControlChars.Cr) 'ソケット送信 pNetStream.Write(bytSend, 0, bytSend.Length) End While 'ソケットストリームクローズ pNetStream.Close() 'クライアントクローズ pTcpClient.Close() 'リスナー停止 pListener.Stop() Call DispMsg("リスナー停止...") 'ボタン制御 Me.btnStart.Enabled = True End Sub End Class
実際の実行は以下の様になります。
サーバ側の「Start」押下後、クライアント側の「Start」を押下し”abcdef”,”123456”,”ABCDEFGHI”の順に文字列を「Send」し、 更に「Stop」を押下したところまでを表しています。
ここまでのPGはサーバとクライアントが1対1のみでしか動作しません。 しかし、これでは面白くありませんので、次回は複数のクライアントからの接続を受け付けるものを紹介したいと思います。関連する記事
⇒TCP (TcpListener, TcpClient)を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信についてその2(HTTPチャネル)
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)
-
このページでは TCP を使ったプロセス(EXE)間で通信について説明します。 (いわゆる TCP クライアント・サーバプログラム を作ることになります。)
TCP クライアントは TcpClient クラスを、 TCP サーバは TcpListener クラスを使います。
そこで先ずは TCP サーバのプログラムの例を示します。 今回の処理は TCP での受信待ち状態にし、クライアントからの1回のメッセージを受信し、 そのメッセージをクライアント側に返し、処理が終わるという簡単なものです。 以下にその手順を示します。- IP アドレスとポート番号でネットワークエンドポイントを作成し TcpListener クラスの生成
- TcpListener クラスの Start メソッドで受信接続要求の待機を開始
- TcpListener クラスの AcceptTcpClient メソッドでクライアントからの接続要求を待機
- 接続要求待機を抜けた後で送受信用ソケットストリーム取得
- ソケットストリームからデータ受信し、さらにデータを送信
- 最後にソケットストリーム等をクローズし、リスナーを停止
以下にそのソースを示します。 フォーム上にはサーバ開始用の「start」ボタンと、送受信文字列等を表示する為に RichTextBox を設置しています。
■TCP サーバープログラム
Imports System.Net Imports System.Threading Imports System.Text Public Class frmTcpServer 'リッチテキストボックスにメッセージを表示する Public Sub DispMsg(ByVal message As String) RichTextBox1.AppendText(message & vbNewLine) RichTextBox1.SelectionStart = RichTextBox1.TextLength RichTextBox1.Refresh() End Sub '[Start]ボタンクリック Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click 'ボタン制御 Me.btnStart.Enabled = False 'ポート番号 Dim pintPort As Integer = 60000 'IPアドレス&ポート番号設定 Dim pEndPoint As New IPEndPoint(IPAddress.Any, pintPort) 'ソケット・リスナー作成 Dim pListener As New Sockets.TcpListener(pEndPoint) 'リスナー開始 pListener.Start() Call DispMsg("リスナー開始...") 'クライアントから接続有りでこの処理を抜ける Dim pTcpClient As Sockets.TcpClient = pListener.AcceptTcpClient() Call DispMsg("クライアントから接続有り...") '送受信用ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() 'バイト配列(取敢えず受信バッファとして256バイト) Dim bytRead As Byte() = New Byte(255) {} 'ソケット受送信ループ While True 'TCP受信(バッファ領域まで) Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Count) If intBytes = 0 Then Exit While End If '受信したデータを文字列に変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除 resMsg = resMsg.TrimEnd(ControlChars.Cr) '表示 Call DispMsg(resMsg) '正常受信の場合、送信データ作成 Dim bytSend() As Byte = enc.GetBytes(resMsg & "...ACK" & ControlChars.Cr) 'ソケット送信 pNetStream.Write(bytSend, 0, bytSend.Length) End While 'ソケットストリームクローズ pNetStream.Close() 'クライアントクローズ pTcpClient.Close() 'リスナー停止 pListener.Stop() Call DispMsg("リスナー停止...") 'ボタン制御 Me.btnStart.Enabled = True End Sub End Class
以下に TCP クライアントのプログラムの例を示します。 この処理は、TCPソケットを作成・接続した後で、NetworkStream によりサーバへデータを送信し、 その後サーバからの応答を受信します。
- IP アドレスとポート番号で TcpClient クラスの生成によりTCPソケット作成・接続
- TcpClient クラスの GetStream メソッドで NetworkStream を取得
- NetworkStream の Write メソッドでテキストボックスの内容をバイト配列化して送信
- NetworkStream の Read メソッドでサーバからの応答を受信しテキストボックスに表示
- 最後にネットワークストリーム、ソケットをクローズ
以下にそのソースを示します。 フォーム上には送信文字列用と受信文字列用のテキストボックス、送信開始用の「Send」ボタンを設置しています。
■TCP クライアントプログラム
Imports System.Net Imports System.Text Public Class frmTcpClient '[Send]リック時イベント Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click Me.btnSend.Enabled = False Try 'サーバーのIPアドレス(または、ホスト名)とポート番号 Dim strIpAddr As String = "localhost" Dim intPort As Integer = 60000 'ソケット生成・指定したホストの指定したポートに接続 Dim pTcpClient = New Sockets.TcpClient(strIpAddr, intPort) 'ソケットストリーム取得 Dim pNetStream As Sockets.NetworkStream = pTcpClient.GetStream() '送信文字列をバイト配列変換 Dim enc As Encoding = Encoding.GetEncoding("SHIFT-JIS") '最後尾にCR Dim data As Byte() = enc.GetBytes(Me.TextBox1.Text.Trim & ControlChars.Cr) Me.TextBox1.Text = "" 'ソケット送信 pNetStream.Write(data, 0, data.Count) 'サーバからの応答を受信 Dim bytRead As Byte() = New Byte(255) {} Dim intBytes As Integer = pNetStream.Read(bytRead, 0, bytRead.Length) '受信したデータを文字列に変換 Dim resMsg As String = enc.GetString(bytRead, 0, intBytes) '末尾の\rを削除し表示 Me.TextBox2.Text = resMsg.TrimEnd(ControlChars.Cr) 'ソケットクローズ pNetStream.Close() pTcpClient.Close() Catch ex As Exception MsgBox(ex.Message) End Try Me.btnSend.Enabled = True End Sub End Class
実際の実行は以下の様になります。
今回のPGはクライアント側で文字列送信後すぐに接続を切っていますので、 1回の送受信毎にサーバ側で「start」をクリックしないといけないので実用には供しないですが、ご参考になればと思います。
次回はこれを踏まえて、サーバ側で開始したらそのまま連続でクライアントからの受信と送信を出来る様にしたいと思います。関連する記事
⇒TCP (TcpListener, TcpClient)を使ったプロセス間通信について・その2
⇒Remoting の IPC を使ったプロセス間通信について
⇒Remoting の IPC を使ったプロセス間通信についてその2(HTTPチャネル)
⇒名前付きパイプを使ったプロセス間通信について
⇒名前付きパイプを使ったプロセス間通信についてその2(複数クライアントとの通信)
⇒名前付きパイプを使ったプロセス間通信についてその3(クライアントとの双方向通信)
-
HTML で用意されているパスワード入力に input type="password" があるのですが、 この入力では通常入力内容が ●●●●… と表示されます。
これを見える様にしたいと思います。
よくあるのはパスワード入力の下にチェックボックスを設置し、チェックされていない時は通常で、 チェックされた場合に内容を表示させるやり方です。
方法はパスワード入力の type 属性を password から text に変更します。 これで input がパスワード入力から普通のテキスト入力に変わり、入力内容が見えることになります。
■チェックボックスの変化時にパスワード入力を可視化
<html> <head> <meta charset="utf-8"> <title>test canvas</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script type="text/javascript"> $(function() { //チェックボックスの変化時関数 $("#password-check").change(function() { if ($(this).prop("checked")) { //チェックONの場合 $("#password-test").attr("type","text"); } else { //チェックOFFの場合 $("#password-test").attr("type","password"); } }); }); </script> </head> <body> <h2>test password</h2> <input type="password" id="password-test" name="Password" value="" placeholder="パスワード入力" /><br /> <label>パスワードを表示する<input type="checkbox" id="password-check" /></label> </body> </html>
以下のパスワード入力に文字を入れてみて下さい。 その後で、チェックボックスをON/OFFすることでパスワードの中身が見えると思います。