จะรับค่าดิบในฟิลด์ <input type =“ number”> ได้อย่างไร


117

ฉันจะรับค่า"จริง"ของ<input type="number">ฟิลด์ได้อย่างไร


ฉันมีinputกล่องและฉันใช้ประเภทอินพุต HTML5 ที่ใหม่กว่าnumber:

<input id="edQuantity" type="number">

ส่วนใหญ่รองรับใน Chrome 29:

ใส่คำอธิบายภาพที่นี่

สิ่งที่ฉันต้องการตอนนี้คือความสามารถในการอ่านค่า"ดิบ"ที่ผู้ใช้ป้อนในช่องป้อนข้อมูล หากผู้ใช้ป้อนตัวเลข:

ใส่คำอธิบายภาพที่นี่

แล้วedQuantity.value = 4และทุกอย่างก็เรียบร้อยดี

แต่ถ้าผู้ใช้ป้อนข้อความที่ไม่ถูกต้องฉันต้องการให้ช่องป้อนข้อมูลเป็นสีแดง:

ใส่คำอธิบายภาพที่นี่

น่าเสียดายสำหรับtype="number"ช่องป้อนข้อมูลหากค่าในกล่องข้อความไม่ใช่ตัวเลขvalueจะส่งคืนสตริงว่าง:

edQuantity.value = "" (String);

(ใน Chrome 29 เป็นอย่างน้อย)

ฉันจะรับค่า"ดิบ"ของ<input type="number">คอนโทรลได้อย่างไร

ฉันพยายามค้นหารายการคุณสมบัติอื่น ๆ ของช่องป้อนข้อมูลของ Chrome:

ใส่คำอธิบายภาพที่นี่

ฉันไม่เห็นสิ่งใดที่คล้ายกับอินพุตจริง

ฉันไม่สามารถหาวิธีที่จะบอกได้ว่ากล่องนั้น "ว่าง"หรือไม่ บางทีฉันอาจจะสรุปได้:

value          isEmpty        Conclusion
=============  =============  ================
"4"            false          valid number
""             true           empty box; not a problem
""             false          invalid text; color it red

หมายเหตุ : คุณสามารถละเว้นทุกสิ่งหลังจากกฎแนวนอน เป็นเพียงฟิลเลอร์เพื่อปรับคำถาม นอกจากนี้: อย่าสับสนตัวอย่างกับคำถาม ผู้คนอาจต้องการคำตอบสำหรับคำถามนี้ด้วยเหตุผลอื่นนอกเหนือจากการระบายสีกล่องสีแดง (ตัวอย่างหนึ่ง: การแปลงข้อความ"four"เป็น"4"สัญลักษณ์ละตินระหว่างเหตุการณ์ onBlur)

ฉันจะรับค่า"ดิบ"ของ<input type="number">คอนโทรลได้อย่างไร

การอ่านโบนัส


2
ค่า 'จริง' ของช่องป้อนตัวเลขต้องเป็นตัวเลข หากคุณต้องการอนุญาตให้ป้อนข้อมูลอื่นที่ไม่ใช่ค่าตัวเลขแสดงว่าnumberไม่ใช่ประเภทอินพุตที่คุณต้องการ ใช้textอินพุตปกติ
robertc

7
@robertc Chrome เป็นตัวแทนที่อนุญาตให้ป้อนข้อมูลอื่นที่ไม่ใช่ตัวเลข ฉันแค่ต้องรู้ว่าพวกเขาป้อนสิ่งอื่นที่ไม่ใช่ตัวเลข
Ian Boyd

1
ตรวจสอบvalidityสถานะของฟิลด์- ฉันคาดหวังtypeMismatchแต่ฉันไม่ได้ตรวจสอบตัวเอง
robertc

2
@ int32_t อ่านบรรทัดที่หกด้านล่าง (เช่น"แต่ถ้าผู้ใช้ป้อน ... " )
เอียนบอยด์

6
กรณีการใช้งานของฉัน ... ฉันมีช่องตัวเลขสองช่อง: ละติจูดและลองจิจูด ฉันต้องการตรวจสอบว่ามีใครวาง "lat, lon" และจัดการอย่างเหมาะสมหรือไม่ ขณะนี้ใช้ type = "number" ไม่ได้ เนื่องจาก "lat, lon" ไม่ถูกต้อง .. จึงไม่มีทางที่จะรับค่า "raw" เพื่อดำเนินการ regex ได้ กรณีการใช้งานอื่น: การแสดงข้อผิดพลาดของลูกค้า: " blahเป็นหมายเลขที่ไม่ถูกต้อง"
Brad Kent

คำตอบ:


55

ตามWHATWGคุณไม่ควรรับค่านี้เว้นแต่ว่าจะป้อนข้อมูลเป็นตัวเลขที่ถูกต้อง อัลกอริธึมการฆ่าเชื้อของช่องหมายเลขอินพุตกล่าวว่าเบราว์เซอร์ควรกำหนดค่าเป็นสตริงว่างหากอินพุตไม่ใช่ตัวเลขทศนิยมที่ถูกต้อง

อัลกอริทึมค่ารักษาสุขอนามัยเป็นดังนี้: ถ้าค่าขององค์ประกอบไม่ได้เป็นเลขทศนิยมที่ถูกต้องแล้วตั้งค่าให้สตริงที่ว่างเปล่าแทน

โดยระบุประเภท (<input type="number"> ) คุณกำลังขอให้เบราว์เซอร์ทำงานให้คุณ ในทางกลับกันหากคุณต้องการจับอินพุตที่ไม่ใช่ตัวเลขและทำอะไรกับมันคุณจะต้องพึ่งพาฟิลด์ป้อนข้อความที่พยายามและจริงแบบเก่าและแยกวิเคราะห์เนื้อหาด้วยตัวคุณเอง

W3นอกจากนี้ยังมีรายละเอียดเดียวกันและเพิ่ม:

ตัวแทนผู้ใช้ต้องไม่อนุญาตให้ผู้ใช้กำหนดค่าเป็นสตริงที่ไม่ว่างเปล่าซึ่งไม่ใช่ตัวเลขทศนิยมที่ถูกต้อง


6
มันจะมีประโยชน์ถ้าตัวแทนผู้ใช้ไม่อนุญาตให้ผู้ใช้ตั้งค่าเป็นสตริงที่ไม่ว่างเปล่าซึ่งไม่ใช่ตัวเลขทศนิยมที่ถูกต้อง แต่ถ้า whatwg บอกว่าทำไม่ได้; นั่นคือคำตอบ วิธีแก้ปัญหาสำหรับความต้องการปัจจุบันของฉันที่เพิ่มไว้ด้านล่าง
Ian Boyd

57
การระบุประเภท ( <input type="number">) คุณกำลังขอให้เบราว์เซอร์ทำงานให้คุณ โดยส่วนตัวแล้วฉันแค่ขอให้เบราว์เซอร์บนอุปกรณ์เคลื่อนที่แสดงแป้นพิมพ์ตัวเลขและได้รับการตรวจสอบความถูกต้องว่าเป็นสิ่งที่ไม่พึงประสงค์ ปัญหาเหล่านี้ส่วนใหญ่เกิดจากข้อเท็จจริงที่ว่าtypeแอตทริบิวต์กำหนดทั้งกฎการตรวจสอบความถูกต้องและกฎเกี่ยวกับกลไกการป้อนข้อมูลที่จะแสดง แต่มีความเป็นไปได้ค่อนข้างมากที่จะต้องการแสดงแป้นพิมพ์ตัวเลขแก่ผู้ใช้อุปกรณ์เคลื่อนที่โดยไม่ต้องการให้มีการตรวจสอบหมายเลขกับผู้ใช้เดสก์ท็อป HTML 5.1 อย่างน้อยจะแก้ปัญหานี้ได้ในที่สุดด้วยไฟล์inputmodeแอตทริบิวต์
Mark Amery

4
แต่เมื่อเบราว์เซอร์ทำงานไม่เพียงพอฉันก็อยากจะดำเนินการให้เสร็จสิ้น เช่นการลบช่องว่างในอินพุตการอนุมานจุดทศนิยม ...
njzk2

1
นอกจากนี้ในภาษาต่างๆเช่นฝรั่งเศสมี 2 คำสำหรับตัวเลข หนึ่งสำหรับตัวเลขเป็นตัวระบุเช่นหมายเลขบัตรเครดิตและอีกอันสำหรับการนับตัวเลขเช่นตัวเลขทศนิยม
njzk2

1
@MotiKorets ใช้ไม่ได้กับการป้อนตัวเลขทศนิยมเนื่องจาก iPhone ไม่ใส่จุดทศนิยมบนแป้นพิมพ์ น่าเสียดายที่นักพัฒนามักจะเมาในขณะนี้เท่าที่การให้ UX เข้าจุดลอยตัวที่ดี ...
Andy

50

ไม่ได้ตอบคำถาม แต่วิธีแก้ปัญหาที่เป็นประโยชน์คือการตรวจสอบ

edQuantity.validity.valid

ValidityStateของวัตถุให้เบาะแสเกี่ยวกับสิ่งที่ผู้ใช้ป้อน พิจารณาtype="number"อินพุตด้วย a minและmaxset

<input type="number" min="1" max="10">

เราต้องการใช้เสมอ.validity.validต้องการที่จะใช้

คุณสมบัติอื่น ๆ ให้ข้อมูลโบนัสเท่านั้น:

User's Input  .value  .valid | .badInput  .rangeUnderflow  .rangeOverflow
============  ======  ====== | =========  ===============  ==============
""            ""      true   | false      false            false  ;valid because field not marked required
"1"           "1"     true   | false      false            false  
"10"          "10"    true   | false      false            false
"0"           "0"     false  | false      true             false  ;invalid because below min
"11"          "11"    false  | false      false            true   ;invalid because above max
"q"           ""      false  | true       false            false  ;invalid because not number
"³"           ""      false  | true       false            false  ;superscript digit 3
"٣"           ""      false  | true       false            false  ;arabic digit 3
"₃"           ""      false  | true       false            false  ;subscript digit 3

คุณจะต้องตรวจสอบให้แน่ใจว่าเบราว์เซอร์รองรับการตรวจสอบความถูกต้องของ HTML5 ก่อนใช้งาน:

function ValidateElementAsNumber(element)
{
   //Public Domain: no attribution required.
   if ((element.validity) && (!element.validity.valid))
   {
      //if html5 validation says it's bad: it's bad
      return false;
   }

   //Fallback to browsers that don't yet support html5 input validation
   //Or we maybe want to perform additional validations
   var value = StrToInt(element.value);
   if (value != null)
      return true;
   else
      return false;
}

โบนัส

Spudly มีคำตอบที่เป็นประโยชน์ที่เขาลบ:

เพียงแค่ใช้ CSS :invalidตัวเลือกสำหรับสิ่งนี้

input[type=number]:invalid {
    background-color: #FFCCCC;
}

สิ่งนี้จะทำให้องค์ประกอบของคุณเปลี่ยนเป็นสีแดงทุกครั้งที่ป้อนตัวเลขที่ไม่ใช่ตัวเลขที่ถูกต้อง

รองรับเบราว์เซอร์สำหรับ <input type='number'>นั้นใกล้เคียงกัน :invalidดังนั้นจึงไม่มีปัญหา

อ่านเพิ่มเติมเกี่ยวกับ:invalidที่นี่


ไม่ทำงานใน Opera มันบอกว่าใช้ได้แม้ว่าคุณจะป้อนสตริงก็ตาม
Bergi

Opera สนับสนุน.validityทรัพย์สิน แต่จัดการไม่ถูกต้อง.valid?!
Ian Boyd

มันไม่ แต่เมื่อเป็นใส่หมายเลขที่ไม่ถูกต้อง ? มันทำราวกับว่าอินพุตว่างเปล่า typeMismatchอาจทำให้รู้สึก แต่นั่นเป็นเพียงสำหรับอีเมลหรือ URL ประเภท ...
Bergi

@Bergi ตารางด้านบนแสดงตัวอย่างที่อินพุตตัวเลขอาจไม่ถูกต้อง: "q", "11" (จากนั้นสูงสุดคือ 10), "0" (เมื่อนาทีคือ 1), "" (จากนั้นองค์ประกอบคือrequired)
เอียน Boyd

1
@Bergi .badInputถูกเพิ่ม 2012/11/20 แต่ไม่มีใครควรbadInputดูว่าอินพุตถูกต้องหรือไม่ .validพวกเขาควรจะมองหาที่ เป็นไปได้ (และถูกต้อง) เนื่องจาก.badInputเป็นเท็จและยังคงมีข้อมูลที่ไม่ถูกต้อง .validหมายถึงการไม่มีข้อผิดพลาดในการตรวจสอบความถูกต้องใด ๆ (เช่นไม่ตรงกัน, โอเวอร์โฟลว์, อันเดอร์โฟลว์) ซึ่ง.badInputเป็นข้อผิดพลาดเพียงประเภทเดียว สังเกตแผนภูมิด้านบนซึ่ง.badInputเป็นเท็จ แต่อินพุตยังคงไม่ถูกต้อง
Ian Boyd

11
input.focus();
document.execCommand("SelectAll");
var displayValue = window.getSelection().toString();


ไม่ทำงานใน firefox: bugzilla.mozilla.org/show_bug.cgi?id=85686 (โปรดทราบว่าข้อผิดพลาดนี้ถูกยื่นในปี 2544 !!)
Brad Kent

เช่นเคย Firefox ถูกต้อง สิ่งนี้ไม่ควรทำงานและเป็นข้อผิดพลาด
vsync

4

ติดตามคีย์ที่กดทั้งหมดตามรหัสคีย์

ฉันคิดว่าคน ๆ หนึ่งสามารถฟังเหตุการณ์คีย์อัพและเก็บอาร์เรย์ของอักขระทั้งหมดที่ป้อนตามรหัสของพวกเขา แต่มันเป็นงานที่ค่อนข้างน่าเบื่อและอาจเกิดข้อบกพร่องได้ง่าย

http://unixpapa.com/js/key.html

เลือกอินพุตและรับการเลือกเป็นสตริง

document.querySelector('input').addEventListener('input', onInput);

function onInput(){
  this.select(); 
  console.log( window.getSelection().toString() )
}
<input type='number'>

เครดิตทั้งหมดถึง: int32_t


การแก้ปัญหาที่กำลังพยายามที่อื่นและไม่ทำงาน โดยเฉพาะอย่างยิ่งเมื่อมีการกดผู้ใช้Delete, Backspace, Ctrl+X, Ctrl+V, ,Right-click-cut Right-click-paste
Ian Boyd

ฉันเห็นด้วยกับคุณโดยพื้นฐานแล้วสิ่งที่ OP ถามเป็นไปไม่ได้ อย่างไรก็ตามแฮ็กทั้งสองที่ฉันพูดถึง (และเป็นแฮ็กฉันไม่ปฏิเสธว่า) ได้ผลในระดับหนึ่ง บางทีอาจเป็นประโยชน์กับใครบางคนในบางกรณี?
sandstrom

น่าประหลาดใจที่สิ่งที่เลือกดูเหมือนจะใช้งานได้ อะไรคือข้อ จำกัด ของวิธีการนั้น?
njzk2

ข้อ จำกัด : ข้อความถูกเลือกด้วยสายตา หากผู้ใช้พิมพ์บางสิ่งเนื้อหาจะหายไป
อิสระ

แก้ไขด้วยการสาธิตสดซึ่งแสดงให้เห็นว่าวิธีนี้แย่แค่ไหน
vsync
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.