iT邦幫忙

0

AJAX 在PHP迴圈中 如何正確找到對應的ID欄位顯示呢

  • 分享至 

  • xImage

小弟剛接觸ajax不久 只懂出淺概念想請教各位
我如果有三個input欄位id分別是 tn1 tn2 tn3 ,在鍵入的時候要計算這三個欄位的值相乘得出總數顯示在id=result中 以下是我的程式碼,但如果我今天要要計算的欄位數量如果不固定(因PHP跑出的數量不一定)如何把鍵入的值都丟到同一個PHP頁面運算後再回傳到正確的result欄位呢?
EX:
第一列:tn1tn2tn3=result1
第二列atn1atn2atn3=result2
第三列btn1btn2btn3=result3
第N列.....
......
但不可能每次多跑一列欄位就多寫一個PHP頁面去接收運算回傳值吧?
以下是原本的程式碼
html input:

<input name="itprice"  type="text"  id="tn1" value="">
<input name="itnum"    type="text" class="normalinput" id="tn2"  value="">
<input name="percent"  type="text" id="tn3" value="">
<p  id="result"></p>

jquery ajax:

	   $(document).ready(function() {
			
			var result =false ; //預設值
			
			
            $('input').keyup(function() { //input被鍵入時
			   $.ajax({
                    type: "POST", //傳送方式 
                    url: "service.php", //傳送目的地
                    dataType: "json", //資料格式
                    data: { //傳送資料
                        tn1: $("#tn1").val(), //表單欄位 ID tn1
                        tn2: $("#tn2").val(), //表單欄位 ID tn2
						tn3: $("#tn3").val()  //表單欄位 ID tn3
                    },
                    success: function(data) {
                        if (data.total) { //如果後端回傳 json 資料有 tn1
                            //$("#demo")[0].reset(); //重設 ID 為 demo 的 form (表單)=清空欄位
                            $("#result").html(data.total);
                        } else { //否則讀取後端回傳 json 資料 errorMsg 顯示錯誤訊息
                            <!--$("#demo")[0].reset(); //重設 ID 為 demo 的 form (表單)-->
                            <!--$("#result").html('<font color="#ff0000">' + data.errorMsg + '</font>');-->
                        }
                    },
                    error: function(jqXHR) {
                        $("#demo")[0].reset(); //重設 ID 為 demo 的 form (表單)
                        $("#result").html('<font color="#ff0000">發生錯誤:' + jqXHR.status + '</font>');
                    }
                })
            })
        });

php:

header('Content-Type: application/json; charset=UTF-8'); //設定資料類型為 json,編碼 utf-8

if ($_SERVER['REQUEST_METHOD'] == "POST") { //如果是 POST 請求
    @$tn1 = $_POST["tn1"]; //取得 tn1 POST 值
    @$tn2 = $_POST["tn2"]; //取得 tn2 值
	@$tn3 = $_POST["tn3"]; //取得 tn3 值
    
	if ($tn1 != null && $tn2 != null&& $tn3 != null ) { //如果 tn1 和 tn2和 tn3 都有填寫
	
        //回傳 tn1 和 tn2 和 tn3  json 資料
        echo json_encode(array(
            'total' => round($tn1*$tn2*$tn3/100)
        ));
    } else {
        //回傳 errorMsg json 資料
        echo json_encode(array(
            'errorMsg' => '資料未輸入完全!'
        ));
    }
} else {
    //回傳 errorMsg json 資料
    echo json_encode(array(
        'errorMsg' => '請求無效,只允許 POST 方式訪問!'
    ));
}

這是可以正常讀取跟顯示的 但是如果遇到很多列的話不知道怎麼寫
希望有人可以解答 謝謝

看更多先前的討論...收起先前的討論...
柯柯 iT邦新手 2 級 ‧ 2021-01-18 13:39:31 檢舉
我在想你怎不用JS去算數值出來就好?
為甚麼要用AJAX回傳給伺服器去計算
也許你有甚麼特別目的要回傳給伺服器?
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 14:02:04 檢舉
要非同步更新 ,
在鍵入數值的時候 result就會顯示算好的數值出來 不是就要用到伺服器端嗎?
柯柯 iT邦新手 2 級 ‧ 2021-01-18 14:28:19 檢舉
如果你在非同步更新的當下 也有需要寫入資料庫的話
才會推薦用JS先驗證資料正確性
再用AJAX傳給PHP計算 做第二次認證 寫入資料庫

如果只是為了在使用者打完數量後馬上計算出結果查看
而且不需寫入資料庫或其他伺服器運算用
用JS計算即可 也節省伺服器的負擔
不然照你的寫法 每次keyup一次就丟給伺服器算一次 一列三欄 我打 111 222 333 伺服器就要跑9次計算了
player iT邦大師 1 級 ‧ 2021-01-18 14:55:45 檢舉
多筆資料表達,建議請找Grid或MVVM的相關套件來用
如果要傳給Server端也可以一次打包成一筆JSON一次傳出
通靈亡 iT邦高手 1 級 ‧ 2021-01-18 15:34:22 檢舉
先釐清一下輸入輸出的部分
tn1 tn2 tn3 跟 result 哪些是在伺服器端(PHP)已知?
還是你只知道「列數」但不知道 tn1 tn2 tn3 跟 result ?

因為你有寫到這句:
「因PHP跑出的數量不一定」

如果是已知列數,每一筆資料可以定義一個data_id
例如:「你有20筆資料,每一筆資料都要設定3個參數到後端設定」
AJAX 只需要負責送出目前資料的「data_id」與「三個數字」給PHP處理後吐回前端,顯示在指定的 data_id 列即可

不過就像柯柯說的,除非你有什麼需求是需要讓後端做相乘
例如:「後端出好20題三個數字相乘的題目,帶到前端讓使用者依序輸入每個題目的答案,送到後端做相乘比對答案後,傳回作答結果給前端」

不然如果只需要取得相乘結果,後端無需做其他處理,可以在前端直接計算即可。
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 16:42:29 檢舉
了解感謝 我只是要做前端顯示用途而已 我以為都要丟到後端運算才能非同步更新,那如果我只用前端運算 但是起初後端丟出來的欄位可能是3列也可能是60列 ,每列都是讓使用者先輸入三個數字然後最後顯示相乘總數 但不確定後端丟出幾列出來 因為我是做讓不同使用者登入後看到需要填入的列數不相同 請問這樣須要如何寫入呢 謝謝
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 16:49:06 檢舉
tn1 tn2 tn3 跟 result 哪些是在伺服器端(PHP)已知?
還是你只知道「列數」但不知道 tn1 tn2 tn3 跟 result ?
tn1 tn2 tn3 是讓使用者鍵入的數字 result是其相乘的結果
後端只知道要丟出幾列讓使用者去填寫
我是做類似計價單的東西
所以可能不同專案有不同工項的數量要去報價
每期要估驗的工項數量不同
感謝耐心回復~
通靈亡 iT邦高手 1 級 ‧ 2021-01-18 17:23:47 檢舉
所以你這個需求,資料是來自後端的資料表吧

那你只需要從PHP後端得到那個使用者有幾筆工項,顯示在前端上
然後用AJAX更新指定工項ID的資料到後端,成功後傳回前端更新畫面即可。

例如:
1. PHP 得到 A使用者有60列
第一次進入網頁時,PHP echo 印出60列資料給使用者輸入,並在每一列資料列上定義是第幾筆工項資料 (data-id)

2.1 假設使用者修改第39筆工項資料(<tr data-id="39">),將 <tr data-id="39"> 裡面的<input class="value01">、<input class="value02">、<input class="value03"> 的value 值,以及工項的id編號(39),帶到 PHP 計算並儲存該工項的三筆數字與乘積,將成功處理後的資料回傳給前端更新畫面上的資料。

2.2 若你要批量更新,在<form>裡面的每一列可用<tr>包住<input type="text" class="id" name="id[]">、<input type="text" class="value01" name="value01[]">、<input type="text" class="value02" name="value02[]">、<input type="text" class="value03" name="value03[]">,用 FormData 送出,PHP全部處理後將處理的結果傳回前端更新。類似柯柯的做法。

不確定你實際期望的需求和做法細節,你可以自己嘗試看看,或等其他好心的大大回答吧。
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 20:04:20 檢舉
請問如果我現在縮減只需要兩個值相乘得出結果就好
tn1*ctn1 = result1
.......
假設需要60列 這樣就有60個result ,但是只有被鍵入的才會計算
例如第42列的 tn42*ctn42=result42
result只要能顯示運算後的數值就好 不用把值存到資料庫 單純顯示而已 但是要再鍵入ctn42的時候 result42就會同步顯示運算後的數值
請問這樣要如何寫呢 謝謝
簡單來說就是我可以土法煉鋼用迴圈預設建60列需要的欄位 但是運算都跑到同一個PHP頁面做運算後回傳嗎 然後回傳的值剛好都在正確的欄位上 如上面result42那樣 不然60列就要60個PHP頁面好蠢哈哈
抱歉我資質太差 可能需要一點點註解才比較好理解CODE 感激不盡
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
㊣浩瀚星空㊣
iT邦大神 1 級 ‧ 2021-01-18 13:20:01
最佳解答

我只給你思維。
幸好你只是要將所有的值相乘。
那倒還好處理。

你的問題是卡在固定數的情況。
也就是你是用 tn1 tn2 ...... tn(n)。
所以需要幾個值全都要再定義處理。也就會發生你說的,只要增加一個值就得要再改程式。

那~~~如果這些值都是要相乘的。
其實你可以不需要用指定式的方式。
而將其全換成陣列送進去就好。

在其對應的input,給與自定義屬性
如 data-mult = "Multiply"

則在jquery的用法下

var multiply = [];
$("input[data-mult='Multiply']").each(function(){
    multiply[] = $(this).val();
});

這樣可獲得陣列。
再將其當成變數給ajax發送。

$.ajax({
                    type: "POST", //傳送方式 
                    url: "service.php", //傳送目的地
                    dataType: "json", //資料格式
                    data: {multiply:multiply},
                    .
                    .
                    .

其php則用迴圈相乘處理

$setV = 1;//要先給1的初始值
foreach($_POST AS $m){
    setV = setV*$m;
}

約是這樣的東西。我不給全部的程式碼。
你試著去思考如何用上面的應用處理就好了。
有問題再問。直接你答案你會不了解何謂邏輯。
就先點到為止就好。

看更多先前的回應...收起先前的回應...
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 13:37:11 檢舉

我的意思應該是
第一列:tn1tn2tn3=result1
第二列:atn1atn2atn3=result2
第三列:btn1btn2btn3=result3
第N列.....
每一列都要有一個RESULT
在不知道有幾列的情況下 如何寫入呢 謝謝

先去了解我第一個echo的用意。
並捨棄你指定式的用法。

簡單來說,你要捨棄id用法。
要不然你的問題永遠都無法解決的。

要學會群集式的處理方式。

如以下的規劃

<input name="itprice"  type="text" data-mult="Multiply1"  value="">
<input name="itnum"    type="text"  data-mult="Multiply1" class="normalinput"  value="">
<input name="percent"  data-mult="Multiply1" type="text" value="">
<p data-sub="Multiply1"></p>

<input name="itprice1"  type="text" data-mult="Multiply2"  value="">
<input name="itprice2"  type="text" data-mult="Multiply2"  value="">
<input name="itprice3"  type="text" data-mult="Multiply2"  value="">
<input name="itnum"    type="text"  data-mult="Multiply2" class="normalinput"  value="">
<input name="percent"  data-mult="Multiply2" type="text" value="">
<p data-sub="Multiply2"></p>
$("input[data-mult='Multiply1']").each(function(i,v){
    if(i==0){
        multiply1=$(this).val();
    }else{
        multiply1 = multiply1*$(this).val();
    }    
});
$("input[data-sub='Multiply1']").html(multiply1)

$("input[data-mult='Multiply2']").each(function(i,v){
    if(i==0){
        multiply2=$(this).val();
    }else{
        multiply2 = multiply2*$(this).val();
    }    
});
$("input[data-sub='Multiply2']").html(multiply1)

可以依此類推。
但這樣子寫又太過落落長。每增加一組就得寫一次
這時就可以寫成function的方式來處理

$("input[data-sub]").each(function(i,v){
    var sumKey = $(this).attr('data-sub');
    var mu = multiply(sumKey);
    $(this).html(mu);
}


function multiply(key){
    var multiply=0;
    $("input[data-mult='"+key+"']").each(function(i,v){
        if(i==0){
            multiply=parseFloat($(this).val());
        }else{
            multiply = multiply * parseFloat($(this).val());
        }    
    });
    return multiply;
}

這樣如上的寫法,你就可以隨你高興怎麼去加html了。
都一定能幫你計算。

對了,上面的寫法,還有一些要注意的,像是數值化處理的。
空值判斷處理的。這些就交給你自已來。
我並沒寫的很全。只是大約告訴你怎麼去萬用處理。

yhn2880 iT邦新手 5 級 ‧ 2021-01-18 23:18:35 檢舉

剛剛試出來了 我因為只要顯示所以發現不用AJAX到PHP 直接前端JQUERY 取值相乘得到結果就好 感謝提供想法!

1
japhenchen
iT邦超人 1 級 ‧ 2021-01-18 13:39:56

你可以把checkbox的名字設成一樣,用value來區分

HTML

<label><input type="checkbox" name="sports[]" value="cycling" /> cycling</label>
<label><input type="checkbox" name="sports[]" value="running" /> running</label>
<label><input type="checkbox" name="sports[]" value="visit gym" /> visit gym</label>
<label><input type="checkbox" name="sports[]" value="swimming" /> swimming</label>
<label><input type="checkbox" name="sports[]" value="team sports" /> team sport(s)</label>
<label><input type="checkbox" name="sports[]" value="other" /> other</label>   

js(jQ)

$.ajax({
    // 其他省略3000字
    data: { 
        sports:document.forms['demoForm'].elements[ 'sports[]' ] 
        //有勾的有傳,沒勾的不傳
        }        
}) //以下再省略1001字

PHP

$sport = $_POST["sports"];
foreach($sport as $s)
{
    echo $s;
}
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 14:10:25 檢舉

我是希望input 在keyup的時候就可以計算了然後顯示在result中
同時我的列數可能會超過50列 不是固定的 所以ID要先設好50列的ID嗎? 謝謝

0
柯柯
iT邦新手 2 級 ‧ 2021-01-18 13:55:16

只是直接用JS計算應該會比較方便吧

HTML

<form id="Form1">
    <input name="tn[]"  type="text"  id="tn1" value="">
    <input name="tn[]"  type="text" class="normalinput" id="tn2"  value="">
    <input name="tn[]"  type="text" id="tn3" value="">
    
    <input name="atn[]"  type="text"  id="atn1" value="">
    <input name="atn[]"  type="text" class="normalinput" id="atn2"  value="">
    <input name="atn[]"  type="text" id="atn3" value="">
    
    <button id="submit" type="button">送出</button>
</form>

JS

$('#submit').on('click', function(){
    var form = $('form')[0];
    var formData = new FormData(form);
    $.ajax({
        ...
        data : formData,
        ...
    })
});

php

    $tempArr = array();
    foreach ($_POST as $key => $value) {
    	foreach ($value as $k => $v) {
    		if(empty($tempArr[$key])) $tempArr[$key] = 1;
            $tempArr[$key] *= $v;
    	}
        $tempArr[$key] /= 100;
    }
    echo json_encode($tempArr);
看更多先前的回應...收起先前的回應...
yhn2880 iT邦新手 5 級 ‧ 2021-01-18 14:07:52 檢舉

可是我不確定有幾列要去做運算
如果有一百列怎麼做呢
tn1tn2tn3=result1
tn4tn5tn6=result2
.....
tn301tn302tn303=result100
例如這樣 麻煩了感恩

yhn2880 iT邦新手 5 級 ‧ 2021-01-18 14:08:48 檢舉

希望在鍵入完成的時候後面就可以顯示運算結果了

柯柯 iT邦新手 2 級 ‧ 2021-01-18 14:23:23 檢舉

如果是打算輸入完成後就可以顯示的話
JS計算的 如果是AJAX 這個想法去改就可以

$('input').on('change',function() {
	    var thisName = $(this).attr('name');
	    var sum = 0;
	    $('[name="'+thisName+'"]').each(function(){ sum += parseInt($(this).val()); });
	   	console.log(sum);
});

如果只是為了 在輸入後馬上計算結果出來 input
預設給他0 否則空值會被轉成NaN

一個按鍵一個動作實在有點..因為還不確定有沒有輸入完,要是輸入的是除法,就會出現除零錯誤,諸如此類
所以最好是用onchange或onblur在輸入完跳出欄位才檢查內容→ajax→得到運算結果→匯整畫面

柯柯 iT邦新手 2 級 ‧ 2021-01-18 14:54:41 檢舉

對齁 可以用onchange 去讓他一個input只觸發一次 用樓主的突然忘記有這個 XDD 感謝提醒

yhn2880 iT邦新手 5 級 ‧ 2021-01-18 23:18:54 檢舉

剛剛試出來了 我因為只要顯示所以發現不用AJAX到PHP 直接前端JQUERY 取值相乘得到結果就好 感謝提供想法!

1
海綿寶寶
iT邦大神 1 級 ‧ 2021-01-18 17:03:24

請參考
StackOverflow 此篇的第一個回答

可以先 Run code snippet 看看跟你要的結果是否差不多
再去細看別人的寫法

我要發表回答

立即登入回答