close

前情提要

  如果有印象的話,之前在某篇介紹Button時,曾經簡單的講解過form submit的概念。但人參總是那麼複雜(User總是那麼難搞),如果是唯讀欄位卻又想送回後台呢…?

 

問題情境

  某天被隔壁的小姐姐呼喊了,某個select欄位的值在後台不知道為什麼都接不到。看了之後發現,那是一個唯讀的select(下拉選項)

  在解決這個問題前,我們先來聊聊資安這件事。

只是想唯讀,有需要講資安那麼嚴重嗎?

  大家都知道(?)網頁的前端並不是安全的。即使設定為唯讀,都還是有被修改的可能,據我淺薄的前端觀念,使用label會比較安全。

  但有時人在屋簷下,不得不低頭,如果美編就是弄了個唯讀的select,甚至更多的唯讀文字方塊給你,主管覺得你神經敏感、大驚小怪那說不得也是得照著做。(我不知道小姐姐有沒有那麼悲慘,總之看到的時候她已經在做了。可能真的有些情境會用到select唯讀吧,有人要分享嗎?XD

 


 

那先講講文字方塊(textbox)的唯讀吧

  如果在Google上搜尋「HTML 文字方塊 唯讀」,會先看到的結果應該都是 readonly ,從字面上解讀確實如此,也的確可以解決文字方塊Textbox唯讀的需求。

  只是如果再繼續深入看下去,應該會發現有一個類似的關鍵字 : disabled

  以我自己而言,readonly disables 可區分成三個層面的差異。

  1. 1.視覺呈現

  image
  在沒有額外css的狀況下,readonly和一般的文字方塊幾乎一樣。只是readonly的文字方塊即使點到滑鼠爆掉裡面的文字也不會改變XD
  
disabled
略為反灰,比較直覺性的讓User知道無法更改。(但這是個有css的時代,蛋糕上面不但要有鮮奶油還要畫花畫朵)
 

  1. 2.操作差異

  如果網頁上的資訊需要另外擷取處理,熟練的User在操作時會習慣點按Tab做切換的動作,避免在鍵盤與滑鼠間交替而耗費時間。
  
readonly
的欄位會提供Tab停留,而如果是disabled的欄位,則會被直接跳過。(User拿起滑鼠嗎? 真不友善XD)
 

  1. 3.前端事件

  系統越大越複雜,有時難免又要體貼使用者( 各種防呆)
  端事件多如繁星,沒有前端一起分擔的全端工程師只能哭哭。如果剛好
textbox
有作事件處理,不管是click或是blur,那麼readonly也會一起被影響,但事實上或許不需要(例如說跳出欄位的檢查,但readonly的值不會變動,根本不需要檢查)
  相對來說
disabled
根本在頁面上完全裝死,就不需要擔心~
 

  1. 4.後台處理

  理論上來說,既然欄位唯讀了,那麼這項資料後台一定取得到,不需要傳回後台處理。
  但不幸的是,有些狀況下,你還是會希望在後台接收到唯讀欄位的資訊,而如果更不幸的,你是個全端工程師,那麼這有時可能會讓你好一陣打架並且困惑不已
- 使用
disabled的欄位,其數值不會被傳回後台。

所以在文字方塊的狀況下,唯讀要使用readonly或是disabled,還是取決於後台是否需要接收其值 (UI & UX 可能又有另外的考量,改天找友人問問看再分享~)

 

來說說readonly~

  Readonly屬性是一個布林屬性,可以防止使用者對值進行修改,規定輸入欄位是唯讀的。
  欄位被設置唯讀時無法修改,但使用者仍可以
tab切換到該欄位選取或拷貝文字,亦可被提交

 

那麼disabled?

       Disabled屬性是一個布林屬性,規定應該禁用的input元素。被禁用的元素無法使用或點選(tab也進不去),且不會被提交。
  除了文字方塊外,
disabled還可以設置在許多其他不同的元素上,包含 : buttonfieldsetinputoptgroupoptionselecttextarea

  另外有看到「disabled屬性不適用於<input type=hidden>」。但實際測試後,hidden可設置disabled,其結果一樣該值不會送回後台。(只是這樣的作法有點匪夷所思,又藏在前端又不送回後端XD)

 

回到正題

        如果大家還記得,最一開始的問題是「唯讀的select,且需要傳值回後台」。

        對兩個屬性有點基本認知後,從上面的資訊其實可以看出答案了 : select沒有readonly,可設置disabled但就無法送回後台欸嘿嘿,沒有概念的話真的會好陣子打架,誰知道加了個disabled就此前台與後台海闊天空呢?(小姐姐檢查了好久的ajax)

        此情境可以採用的作法有四種,如果有其他作法也歡迎大家分享~

  1. 1.設置disabled開關。在每次頁面提交(submit)前,移除disabled屬性。(看起來是大家比較偏好的作法)image
    $('input[name="s3"]').prop('disabled',false);

     
  2. 2.隱形的文字方塊。每次select change時,將其值置入隱藏的文字方塊。(也不少人使用!但稍微麻煩點,還要考慮到name)
     
  3. 3.關閉其他選項。這個是從Stack Overflow看到的方法,以前沒有用過,但真的滿神的。透過把其他未選擇的選項disabled,同時達成唯讀與傳值的效果。
    但部分瀏覽器早期似乎不支援此做法(option無法為disabled),經測試目前win 10IEEdgeChrome(版本 88.0.4324.150)皆可使用。image
            $('#s1 option').not(':selected').prop('disabled',true)
  4. 4.設定class。其實這沒有跳脫第12點,只是非處理單一頁面,強調統一處理。之前處理的系統有遇過類似狀況,所以將「在前台因為特定原因,無法將資料送至後台的欄位」設定共同的class,不管是產生隱藏的文字方塊塞值,或是在提交前取消disabled。好處是不用在各個頁面處理,寫好後只要記得設定class即可。那為什麼要額外設定class,不能直接移除所有disabled就好嗎?畢竟有些欄位會真的是 forever disabled,為了避免需求異動造成其他問題,且較好管理,就另外用class設定了~
     

 

disabled disabled=”disabled”?

        數個經手的網站,這兩種寫法都有看過。前者簡潔、後者清楚,且都可運作。

        那實際上應該要採用哪種比較好?

        HTMLdisabled,但XHTML要寫disabled = “disabled”

        就看專案的類型了

readonlydisabledreset

        User輸入完資料後,不論將該欄位readonlydisabled,看起來似乎就保全了資料,萬無一失了。

        如果在表單中有reset的狀況下,雖然可保有欄位唯讀的效果,但User輸入的資料,還是會被還原到原始的狀態(空值或預設文字),需要注意。

 

結語

本篇大多是概念性的東西,所以貼Code部分不多,就不逐行說明示範。

如果有問題,歡迎留言告知,到時再詳細補上~

其實對我自己來說,用 readonly 或 disalbed 並沒有很明顯的差異。因為就是得照頁面設計走,select如果真的傳不回去等等的問題,因應辦法有很多,只是"很麻煩"還是"有點麻煩"的差別

不過概念還是推薦要弄懂,才不會發生卡了很久,但只是為了一個屬性的差異~

( 這次嘗試改了編排的方式,有看起來比較好嗎? )

 

參考資料

HTML <input> readonly 屬性

HTML <input> disabled 屬性

HTML <input> readonly Attribute

HTML disabled Attribute

[JavaScript]設定SelectInput標籤,只可讀不可修改且可傳值

how to set select element as readonly ('disabled' doesnt pass select value on server)

將網頁輸入欄位設為唯讀的做法

HTML form readonly SELECT tag/input

What's the difference between disabled=“disabled” and readonly=“readonly” for HTML form input fields?

Disabled vs Readonly Form Fields

arrow
arrow

    律晴音 發表在 痞客邦 留言(0) 人氣()