iT邦幫忙

0

請問各位大神我在做的html表單遇到一些問題該如何解決(不懂程式的菜鳥)-2

  • 分享至 

  • xImage

寫了一份表單透過Apps Script傳送資料到雲端試算表,當中遇到問題是,當我將表單送出之後required屬性卻失效了,就算空白表單都能傳送,資料式接收的到沒錯,但是怕有刻意胡亂填寫的人去填寫,會導致試算表亂套需要花時間整理,再麻煩各位大神解惑了,感謝(此程式是看yt影片臨摹的本人並不懂程式編碼)請各位手下留情/images/emoticon/emoticon06.gif。
▼** HTML表單程式碼**

<!DOCTYPE html>

<html lang="en">

<head>
<title>連結試算表 - 表單Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 連結Bootstrap -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css"
rel="stylesheet" integrity="sha384-
KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We"
crossorigin="anonymous">
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-
U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj"
crossorigin="anonymous">
</script>
<style>
.container-contact {
padding: 20px;
text-align: center;
color: white;
background-color: rgb(42, 165, 159);
width: 100%;
}

.container-contact h3 {
font-size: 30px;
text-align: center;
padding: 20px;
}

.btn {
width: 100%;
font-size: 20px;

margin: 20px 0px 20px 0px;
background-color: rgb(6, 117, 119);
color: rgb(255, 255, 255);
border-radius: 20px;
transition: 1s;
}

.btn:hover {
background-color: rgb(178, 224, 84);
color: black;
}

input {
margin-top: 10px;
}
</style>
</head>

<body>
<div class="container-contact">
<h3>保固登錄</h3>

<div class="row">
    <!--第一欄-->
<div class="col-sm-2">

</div>
<!--第二欄-->
<div class="col-sm-8">
<form id="myForm">
<div class="row">
    
<!--名稱-->
<div class="col-sm-6 form-group">
    <br>
<label> 姓名 </label>
<input class="form-control" id="name" name="name"

placeholder="姓名" type="text" required="required" />

</div>

<!-- 電話 格式 -->
<div class="col-sm-6 form-group">
    <br>
<label> 聯絡電話 </label>
<input class="form-control" type="tel" id="userhphone" name="userhphone" pattern="[0-9]{10}"
placeholder="請輸入09xxxxxxxx格式" required="required" />
</div>
<!--生日-->
<div class="col-sm-6 form-group">
    <br>
<label> 出生日期 </label>
<input class="form-control" type="date" id="happy" name="happy"
placeholder="請輸入生日" required="required" />
</div>

<!--e-mail-->
<div class="col-sm-6 form-group">
    <br>
<label> Email </label>

<input class="form-control" id="email" name="email"

placeholder="請輸入Email" type="email" required="required" />

</div>

<!-- 產品 格式 -->
<div class="col-sm-6 form-group"> 
    <p></p>
<label> 產品 </label>
<p></p>

<select  class="form-control" id="catordog" name="catordog" required >
    <option value=""selected disabled style="background-color: #E0E0E0;">請選擇您購買的產品</option>
    <option value="太空寶寶點讀筆">太空寶寶點讀筆</option>
    
    
</select>
</div>

<!-- 地址 格式 -->
<div class="col-sm-6 form-group">
    <br>
<label> 聯絡地址 </label>
<input class="form-control" type="text" id="address" name="address" 
placeholder="例:台中市龍井區*段***巷**弄**號" required="required">
</div>

   <!-- isbn 格式 -->
   <div class="col-sm-6 form-group">
    <br>
    <label> 產品序號 </label>
<input class="form-control" type="tel" id="isbn" name="isbn" pattern="[0-9]{10}"
placeholder="詳見電池蓋上的編號共10碼" required="required" />
</div>


<!-- 日期 格式 -->
<div class="col-sm-6 form-group">
    <br>
<label> 購買日期 </label>

<input class="form-control" type="date" id="userbirthday" name="userbirthday"
placeholder="購買日期" required="required" />
</div>

<!-- 店家 格式 -->
<div class="col-sm-6 form-group">
    <br>
<label> 購買通路 </label>

<input class="form-control" type="text" id="shop" name="shop" 
placeholder="例:博客來..." required="required">

</div>

<!-- 發票 格式 -->
<br> 

<div class="col-sm-6 form-group">
    <br>
<label> 發票號碼 </label>
<input class="form-control" type="text" id="bill" name="bill" pattern="[a-zA-Z]{2}-[0-9]{8}"
placeholder="請輸入xx-xxxxxxxx格式" required="required" />
</div>

<p></p>
<div class="col-md-12 form-group">
<input type="radio" name="sex" id="female" required="required" />
<label><a style="color:rgb(255, 251, 0);">歡迎加入</a>
<a href="https://zh-tw.facebook.com/weesing123/"  target="_blank" style="color:rgb(255, 251, 0);">華碩文化粉絲團</a>
<a style="color:rgb(255, 251, 0);">與</a>
<a href="https://www.youtube.com/channel/UCcd0sGMrNzj5FpHdEsz63EA/featured"  target="_blank" style="color:rgb(255, 251, 0);">Youtube頻道</a>
<a style="color:rgb(255, 251, 0);">,好書資訊不漏接!</a>
</label>
</div>
</div>

<!--  -->

<div class="row">
    <div class="col-sm-12 form-group">
        <button class="btn" type="submit" id="submitButton">送出</button>
    </div>


</form>
</div>
<!--第三蘭-->
<div class="col-sm-2">

</div>

<!-- JavaScript程式 -->
<script>
    //抓輸入的值

    function getValues(){
        var name=document.getElementById("name");
        var email=document.getElementById("email");
        var userbirthday=document.getElementById("userbirthday");
        var happy=document.getElementById("happy");
        var shop=document.getElementById("shop");
        var catordog=document.getElementById("catordog");
        var address=document.getElementById("address");
        var bill=document.getElementById("bill");
        var isbn=document.getElementById("isbn");
        var userhphone=document.getElementById("userhphone")

        var rowData={
            name:name.value,
            email:email.value,
            userbirthday:userbirthday.value,
            userhphone:userhphone.value,
            happy:happy.value,
            shop:shop.value,
            catordog:catordog.value,
            address:address.value,
            bill:bill.value,
            isbn:isbn.value
        

        };

         //上傳資料
         google.script.run.addData(rowData);
         //清除表單上資料
         document.getElementById("myForm").reset();
         //完成後訊息
         alert("已註冊成功!");

    }

    document.getElementById("submitButton").addEventListener("click", getValues);
    
    </script>
</body>

</html>

▼** Apps Script 中間部屬程式碼.gs**


            // 連結HTML檔案
            
            function doGet(){
              var html=HtmlService.createTemplateFromFile("form");
              var check=html.evaluate();
              var show =check.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
              return show;
            }
            
            
            // 新增資料到試算表
            
            function addData(rowData){
                //抓時間 
              var currentDate=new Date();
                // 取得目前的試算表檔案
              var ss=SpreadsheetApp.getActiveSpreadsheet();
                // 抓試算表名稱
                // 請輸入您的試算表名稱在這裡
              var ws=ss.getSheetByName("12");
                //插入資料
              ws.appendRow([currentDate, rowData.name, rowData.email, rowData.userbirthday, rowData.userhphone, rowData.happy, rowData.shop, rowData.catordog, rowData.address, rowData.bill, rowData.isbn,]);
            
            }
      

在visual的html測試required屬性雖然會鎖空值跟有固定格式輸入欄位(像是電話號碼、發票號碼)但是卻沒辦法彈出 alert("已註冊成功!")

2.移到Apps Script做布署動作後required屬性會失效,但會跳出 alert("已註冊成功!")的通知字樣,資料也能接收的到(就算是空值)。

3.若強行打上驗證代碼,雖然能成功驗證空值但是填完後傳送卻跳轉白屏,而且資料也沒接收到。

目前遇到這些問題
★(簡單的required屬性)必填屬性失效,送出不會白屏,會跳註冊成功的通知,但是有資料。 目前使用

★(其他驗證代碼)有必填屬性功能,送出就會白屏,不會跳註冊成功的通知,而且資料接收不到。

為小弟我解個惑!麻煩了(敬禮180度)

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

0
iT邦新手 4 級 ‧ 2022-10-12 23:25:45
最佳解答

問題的根源出在input元素的required屬性是給 html 的form進行post之前檢查用的,如果檢查不過,就不會觸發submit事件

以前的網頁很常用formsubmit,但由於submit之後需要讓頁面重繪,使用者體驗不好,所以新的網頁大都改用 javascript 把資料透過post傳給伺服器端

你若想讓required屬性生效,就必須改用formpost的方式來傳資料給伺服器,要修改的檔案有.html.gs

.gs

.gs加入doPost函式跟getScriptUrl函式,前者用來接收表格資料以及把資料寫入試算表,還有回傳網頁內容讓瀏覽器顯示,也就是原本doGet在做的事情,所以這部分就直接呼叫doGet()了,後者用來讓 html 的表格可以得到部署後的連結,以下是整個.gs內容

// 連結HTML檔案
function doGet(){
  var html=HtmlService.createTemplateFromFile("test");
  var check=html.evaluate();
  var show =check.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  return show;
}

function getScriptUrl() {
  var url = ScriptApp.getService().getUrl();
  Logger.log(url);
  return url;
}         
            
// 新增資料到試算表            
function doPost(e){
  // 抓時間 
  var currentDate=new Date();
  // 取得目前的試算表檔案
  var ss=SpreadsheetApp.getActiveSpreadsheet();
  // 抓試算表名稱
  // 請輸入您的試算表名稱在這裡
  var ws=ss.getSheetByName("12");
  //插入資料
  ws.appendRow([currentDate, e.parameter.name, e.parameter.email, e.parameter.userbirthday, e.parameter.userhphone, e.parameter.happy, e.parameter.shop, e.parameter.catordog, e.parameter.address, e.parameter.bill, e.parameter.isbn,]);
  var html=HtmlService.createTemplateFromFile("test");
  var check=html.evaluate();
  var show =check.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  return show;
}

.html

  1. 把原本最底下的<script></script>內的程式碼都刪掉,因為不再使用這邊的程式碼把資料寫入試算表了
  2. 把原本<form id="myForm">的部分修改成<form id="myForm" action="<?!= getScriptUrl(); ?>" method="POST">

如果有遇到403的錯誤訊息,再在.html<head></head>裡面加上這一行<base target="_top" />,我不確定你看的那個影片中的多包一層作法是否能避免這問題,若沒遇到就不用加了

另外發現你少了好幾個</div>,印象中至少兩個,你可以透過 VSCode 的程式碼摺疊功能去找出沒有成對的div,沒有成對的div是不會出現摺疊箭頭的

參考資料

html-form-to-google-sheet
How to make submission function work in a web form that is created using Google Apps Script and embedded in a Google Site?
HTML Service: Communicate with Server
Form submission algorithm
How to Handle GET and POST HTTP Requests in Google Apps Script
google apps script 無法接收到ajax的post
required demo
標籤 (tag)
Google App Script到底是什麼?
【Google Sheets變成資料庫- EP1】上傳「表單」資料到Google 試算表

看更多先前的回應...收起先前的回應...
sking1225 iT邦新手 5 級 ‧ 2022-10-13 17:28:40 檢舉

太感謝您了~我試驗過了,沒問題
資料接收的到,也不會白屏,必填驗證也能觸發
唯一一個小問題想問您,我現在只差在傳送後想跳出
▼ 通知說你成功註冊的通知
google.script.run.addData(rowData); //清除表單上資料 document.getElementById("myForm").reset(); //完成後訊息 alert("已註冊成功!");

麻煩了,感謝!

iT邦新手 4 級 ‧ 2022-10-22 23:26:10 檢舉

doPost 最底下return的部分改成綠色新增的部分,紅色的部分刪掉

//插入資料
  ws.appendRow([currentDate, e.parameter.name, e.parameter.email, e.parameter.userbirthday,e.parameter.userhphone, e.parameter.happy, e.parameter.shop, e.parameter.catordog, e.parameter.address, e.parameter.bill, e.parameter.isbn,]); 
-  var html=HtmlService.createTemplateFromFile("test");
-  var check=html.evaluate();
-  var show =check.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
-  return show;
+  return HtmlService.createHtmlOutput(`<script>alert('已註冊成功');</script>${doGet().getContent()}`);
}

就可以跳出註冊成功的訊息並跳轉回原本的網頁了,如果你不希望跳轉回原網頁而是停留在空白頁面,就把${doGet().getContent()}刪掉就好

sking1225 iT邦新手 5 級 ‧ 2022-10-24 14:16:16 檢舉

會卡在一個【script.google拒絕連線】的頁面,回不去,也沒跳通知出來,但是資料傳得出去,驗證也OK

sking1225 iT邦新手 5 級 ‧ 2022-10-24 14:41:50 檢舉

▼ 像這樣
https://ithelp.ithome.com.tw/upload/images/20221024/20153548M2VgbNADnA.jpg

iT邦新手 4 級 ‧ 2022-10-25 00:12:35 檢舉

你參考底下這個連結的做法看看能不能解決
script.google.com 拒絕連線。

sking1225 iT邦新手 5 級 ‧ 2022-10-26 12:21:53 檢舉

這個也沒辦法呦,我就是照這個影片產出表格跟GS的,只是驗證失效來這邊問,解決驗證又跳不出通知的。

iT邦新手 4 級 ‧ 2022-10-27 20:39:00 檢舉

可能是因為你看的那個影片多包了一層的關係,你直連新部署的連結試看看,我這邊即使用無痕瀏覽新部署的連結也不會有問題

0
walis
iT邦新手 5 級 ‧ 2022-10-12 06:48:16

1.在我的情境中 required 就可以了, 不需要 required="required", 您可以多方用不同的 browser 測試.

2."驗證"一事, 涉及複雜的情境, 可以單純地不相信任何源自 client 的輸入內容, 把所有欄位都拿來過濾與檢查(包括空值), 接著才進入驗證階段.

3.涉及前端"錯誤否/正確否"的事件回應, 這跟流程相關, 假設流程是錯的, 不管 alert 什麼東西回來, 都一定錯的, 這要一步一步測試.

4.前端 js 的檢查, 可以被視為"假性檢查/假性驗證",後端要再重新確認, 檢查, 驗證.

sking1225 iT邦新手 5 級 ‧ 2022-10-12 17:40:47 檢舉

1.我一開始也是只有打required因為出問題所以才改成 required="required",沒有改回去而已,其他的瀏覽器我也都試過了,問題都是一樣的。
2.我的程式都是網上教學拼出來的,所以很多術語我看不懂(抱歉~)
3.其實我自己也是甚麼都看不太出來,只知道簡單得規則,所以才上來問大神們~
4.我在Apps Script中也有驗證、確認,顯示的也都是OK的,東西也都在跑,出來的URL卻出了問題。/images/emoticon/emoticon02.gif

我要發表回答

立即登入回答