ปุ่มอัพโหลดองค์ประกอบไฟล์แบบฟอร์ม Twitter Bootstrap


573

เหตุใดจึงไม่มีปุ่มอัปโหลดองค์ประกอบไฟล์แฟนซีสำหรับ twitter bootstrap มันจะหวานถ้าปุ่มหลักสีฟ้าถูกนำมาใช้สำหรับปุ่มอัปโหลด เป็นไปได้ไหมที่จะใช้ปุ่มอัพโหลดในการใช้ CSS? (ดูเหมือนองค์ประกอบเบราว์เซอร์ดั้งเดิมที่ไม่สามารถจัดการได้)


13
คุณสามารถค้นหาได้ที่นี่ markusslima.github.io/bootstrap-filestyle
rh0dium

คำตอบ:


972

นี่คือทางออกสำหรับ Bootstrap 3 และ 4

ในการสร้างการควบคุมอินพุตไฟล์ที่ใช้งานได้ซึ่งดูเหมือนว่าปุ่มคุณจะต้องใช้ HTML เท่านั้น

HTML

<label class="btn btn-default">
    Browse <input type="file" hidden>
</label>

สิ่งนี้ใช้ได้กับเบราว์เซอร์ที่ทันสมัยทั้งหมดรวมถึง IE9 หากคุณต้องการการสนับสนุนสำหรับ IE เก่าเช่นกันโปรดใช้วิธีดั้งเดิมที่แสดงด้านล่าง

เทคนิคนี้อาศัยhiddenคุณลักษณะHTML5 Bootstrap 4 ใช้ CSS ต่อไปนี้เพื่อชิมคุณลักษณะนี้ในเบราว์เซอร์ที่ไม่รองรับ คุณอาจต้องเพิ่มถ้าคุณใช้ Bootstrap 3

[hidden] {
  display: none !important;
}

วิธีดั้งเดิมสำหรับ IE เก่า

หากคุณต้องการการสนับสนุนสำหรับ IE8 และด้านล่างให้ใช้ HTML / CSS ต่อไปนี้:

HTML

<span class="btn btn-default btn-file">
    Browse <input type="file">
</span>

CSS

.btn-file {
    position: relative;
    overflow: hidden;
}
.btn-file input[type=file] {
    position: absolute;
    top: 0;
    right: 0;
    min-width: 100%;
    min-height: 100%;
    font-size: 100px;
    text-align: right;
    filter: alpha(opacity=0);
    opacity: 0;
    outline: none;
    background: white;
    cursor: inherit;
    display: block;
}

โปรดทราบว่า IE เก่าไม่เรียกใช้ไฟล์เมื่อคุณคลิก a <label>ดังนั้น CSS "bloat" จะทำสองสามอย่างเพื่อแก้ไข:

  • ทำให้อินพุตไฟล์ขยายความกว้าง / ความสูงเต็มของรอบโดยรอบ <span>
  • ทำให้ไฟล์ที่มองไม่เห็น

ข้อเสนอแนะและการอ่านเพิ่มเติม

ฉันโพสต์รายละเอียดเพิ่มเติมเกี่ยวกับวิธีการนี้รวมถึงตัวอย่างวิธีแสดงผู้ใช้ที่เลือกไฟล์ / จำนวน:

http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/


52
+ 1 สำหรับฉันนี่คือคำตอบที่ดีที่สุด โซลูชั่นที่รัดกุมมากโดยใช้ bootstrap เวอร์ชันล่าสุด
Ulises

6
@Ulises @JaredEitnier @IvanWang ฉันไม่เห็นด้วยอย่างเคารพ และเสนอปลั๊กที่ไร้ยางอายกับคำตอบของฉันซึ่งใช้<label>องค์ประกอบ ในฐานะที่เป็นทางออกที่ดีที่สุด :)
คิริลล์ Fuchs

9
ฉันต้องเห็นด้วยกับ @KirillFuchs; ป้ายกำกับจะดีกว่า บวก - ผู้ใช้ไม่สามารถดูว่าพวกเขาเลือกไฟล์ที่ถูกต้องหรือไม่เพราะปุ่มไม่แสดงชื่อไฟล์ที่เลือก: jsfiddle.net/36o9pdf9/1
danwild

1
ป้ายกำกับจะดีกว่าความหมาย ตรวจสอบบทความเพื่อดูวิธีการแสดงไฟล์ที่เลือก (บางแอพพลิเคชั่นจะทำการอัปโหลดอัตโนมัติเมื่อไฟล์ถูกเลือกดังนั้นในกรณีเหล่านั้นคำติชมของชื่อไฟล์ก็ไม่สำคัญ)
claviska

1
ฉันไม่สามารถทำให้มันทำงานบน IE11 พร้อมกับวัตถุ FormData ได้ อย่างใด IE จะละเว้นช่องใส่เมื่อมันอยู่ในองค์ประกอบฉลากและเป็นผลให้ข้อมูลไฟล์ไม่สามารถใช้ได้จากวัตถุ FormData
René

385

ฉันประหลาดใจที่ไม่มีการกล่าวถึง<label>องค์ประกอบ

สารละลาย:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" class="d-none">
    Button Text Here
</label>

ไม่จำเป็นต้องใช้ JS หรือ CSS ...

โซลูชันสำหรับการรวมชื่อไฟล์:

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" style="display:none" 
    onchange="$('#upload-file-info').html(this.files[0].name)">
    Button Text Here
</label>
<span class='label label-info' id="upload-file-info"></span>

การแก้ปัญหาข้างต้นต้องใช้ jQuery


38
คำตอบนี้ควรเป็นคำตอบที่ยอมรับได้ ดียิ่งกว่าคำตอบของ @ claviska
Fernando Carvalhosa

4
ไม่เข้าใจเลยว่าทำไมคำตอบนี้ถึงไม่ยอมรับ สะอาดเรียบง่ายและเสถียร (เว้นแต่คุณจะกำหนดเป้าหมาย <IE9 นั่นคือ ... )
Jake Foster

3
ฉันไม่สามารถทำให้มันทำงานบน IE11 พร้อมกับวัตถุ FormData ได้ อย่างใด IE จะละเว้นช่องใส่เมื่อมันอยู่ในองค์ประกอบฉลากและเป็นผลให้ข้อมูลไฟล์ไม่สามารถใช้ได้จากวัตถุ FormData
René

25
มันไม่แสดงไฟล์ที่ถูกเลือก (
godblessstrawberry

3
คุณไม่จำเป็นต้องใช้forถ้าคุณกำลังห่อองค์ประกอบเป้าหมายด้วยป้ายกำกับ
0xcaff

132

ไม่ต้องใช้ปลั๊กอินเพิ่มเติมวิธีการแก้ปัญหา bootstrap นี้ทำงานได้ดีสำหรับฉัน:

<div style="position:relative;">
        <a class='btn btn-primary' href='javascript:;'>
            Choose File...
            <input type="file" style='position:absolute;z-index:2;top:0;left:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0;background-color:transparent;color:transparent;' name="file_source" size="40"  onchange='$("#upload-file-info").html($(this).val());'>
        </a>
        &nbsp;
        <span class='label label-info' id="upload-file-info"></span>
</div>

การสาธิต:

http://jsfiddle.net/haisumbhatti/cAXFA/1/ (bootstrap 2)

ป้อนคำอธิบายรูปภาพที่นี่

http://jsfiddle.net/haisumbhatti/y3xyU/ (bootstrap 3)

ป้อนคำอธิบายรูปภาพที่นี่


6
ฉันมีปัญหาบางอย่างกับส่วนล่างของปุ่มไม่สามารถคลิกได้ คำตอบนี้ช่วยฉันใน bootstrap 3: stackoverflow.com/a/18164555/44336
Paul Lemke

3
นี่เป็นทางออกที่ยอดเยี่ยมเพราะจะแสดงชื่อไฟล์ของไฟล์ที่แนบมา!
cb88

2
มีคนได้โปรดอธิบายความต้องการ href = 'javascript :;' ? ฉันไม่ต้องการ onchange = '$ ("# upload-file-info"). html ($ (this) .val ());' เพื่ออัปเดตองค์ประกอบอัปโหลดไฟล์ข้อมูล แต่กล่องโต้ตอบอัปโหลดไฟล์จะไม่เปิดขึ้นหากไม่มี href
user12121234

2
'C: \ fakepath' มาจากไหนและฉันจะกำจัดมันได้อย่างไร
ยะ

1
@Ya C: \ fakepath เป็นคุณลักษณะการรักษาความปลอดภัย html5 และนำหน้าไปยังเส้นทางไฟล์ถ้าเราจัดการกับ javascript ดูโพสต์บล็อกนี้davidwalsh.name/fakepathสำหรับรายละเอียด
codefreak

88

มันรวมอยู่ใน bootstrap ของส้อมของ Jasny

สามารถสร้างปุ่มอัพโหลดอย่างง่ายโดยใช้

<span class="btn btn-file">Upload<input type="file" /></span>

ด้วยปลั๊กอินการอัปโหลดไฟล์คุณสามารถสร้างวิดเจ็ตขั้นสูงเพิ่มเติมได้ ดูที่ http://jasny.github.io/bootstrap/javascript/#fileinput


ทำงานได้ดีใน IE9 หรือไม่ ฉันถามเพราะฉันคิดว่าโซลูชันใช้ประโยชน์จาก Javascript และในเวลาเดียวกัน "IE ไม่อนุญาตให้จัดการองค์ประกอบอินพุต" ไฟล์ "จาก javascript เนื่องจากเหตุผลด้านความปลอดภัย"
Marek Příhoda

ใช่มันทำงานได้ใน IE9 เช่นกัน มันตั้งค่าความทึบขององค์ประกอบอินพุทเป็น 0 ซึ่งโชคดีที่ทำงานได้ในทุกเบราว์เซอร์ :) มันอธิบายไว้ในบทความ quirksmode
อาร์โนลด์แดเนียลส์

1
มันไม่ทำงานกับ jQuery 1.9.0 เพราะพวกเขาลดการสนับสนุน $ .browser
Giedrius

14
ดูน่ากลัวกับบูตปกติ - img688.imageshack.us/img688/948/pictureui.png
CWD

66

ปุ่มอัปโหลดมีความเจ็บปวดอย่างมีสไตล์เนื่องจากเป็นรูปแบบอินพุตและไม่ใช่ปุ่ม

แต่คุณสามารถใช้เคล็ดลับนี้:

http://www.quirksmode.org/dom/inputfile.html

สรุป:

  1. ใช้เวลาปกติและวางไว้ในองค์ประกอบที่มี<input type="file">position: relative

  2. ในองค์ประกอบหลักเดียวกันนี้ให้เพิ่มปกติ<input>และรูปภาพซึ่งมีสไตล์ที่ถูกต้อง <input type="file">ตำแหน่งองค์ประกอบเหล่านี้อย่างแน่นอนเพื่อให้พวกเขาครอบครองสถานที่เดียวกันเป็น

  3. ตั้งค่าดัชนี z ของค่า<input type="file">เป็น 2 เพื่อให้อยู่ด้านบนของอินพุต / รูปภาพสไตล์

  4. ในที่สุดตั้งค่าความทึบของ<input type="file">ถึง 0 <input type="file">ตอนนี้กลายเป็นมองไม่เห็นได้อย่างมีประสิทธิภาพและรูปแบบการป้อน / ภาพที่ส่องผ่าน แต่คุณยังสามารถคลิกที่ปุ่ม "เรียกดู" หากปุ่มอยู่ในตำแหน่งด้านบนของภาพผู้ใช้จะปรากฏขึ้นเพื่อคลิกที่ภาพและได้รับหน้าต่างการเลือกไฟล์ปกติ (โปรดทราบว่าคุณไม่สามารถใช้การเปิดเผยได้: ซ่อนไว้เนื่องจากองค์ประกอบที่มองไม่เห็นอย่างแท้จริงไม่สามารถคลิกได้เช่นกันและเราต้องการให้ยังคงคลิกได้)


6
นี่เป็นวิธีการทำงานมากเกินไปสำหรับวันนี้ การใช้บางอย่างที่พร้อมเช่นโซลูชันของ Jasny ในคำตอบต่อไปจะสมเหตุสมผลมากกว่า
mgPePe

2
หากตัวอย่างของคุณมีการรองรับการรองรับ netscape อาจเป็นข้อมูลล่าสุด
Typhomism

22

ใช้งานได้สำหรับฉัน:

ปรับปรุง

สไตล์ปลั๊กอิน jQuery :

// Based in: http://duckranger.com/2012/06/pretty-file-input-field-in-bootstrap/
// Version: 0.0.3
// Compatibility with: Bootstrap 3.2.0 and jQuery 2.1.1
// Use:
//     <input class="nice_file_field" type="file" data-label="Choose Document">
//     <script> $(".nice_file_field").niceFileField(); </script>
//
(function( $ ) {
  $.fn.niceFileField = function() {
    this.each(function(index, file_field) {
      file_field = $(file_field);
      var label = file_field.attr("data-label") || "Choose File";

      file_field.css({"display": "none"});

      nice_file_block_text  = '<div class="input-group nice_file_block">';
      nice_file_block_text += '  <input type="text" class="form-control">';
      nice_file_block_text += '  <span class="input-group-btn">';
      nice_file_block_text += '   <button class="btn btn-default nice_file_field_button" type="button">' + label + '</button>';
      nice_file_block_text += '  </span>';
      nice_file_block_text += '</div>';

      file_field.after(nice_file_block_text);

      var nice_file_field_button = file_field.parent().find(".nice_file_field_button");
      var nice_file_block_element = file_field.parent().find(".nice_file_block");

      nice_file_field_button.on("click", function(){ console.log("click"); file_field.click() } );
      file_field.change( function(){
        nice_file_block_element.find("input").val(file_field.val());
      });
    });
  };
})( jQuery );

17

คำตอบที่ง่ายขึ้นโดยใช้ชิ้นส่วนจากคำตอบอื่น ๆ ส่วนใหญ่เป็นผู้ใช้ 2309766 และ dotcomsuperstar

คุณสมบัติ:

  • ใช้ปุ่ม Bootstrap เพื่อเป็นปุ่มและฟิลด์
  • อินพุตเดียวเท่านั้น หลายอินพุตจะรับแบบฟอร์ม
  • ไม่มี CSS พิเศษยกเว้น "display: none;" เพื่อซ่อนอินพุตไฟล์
  • ปุ่มที่มองเห็นจะยิงเหตุการณ์คลิกเพื่อป้อนไฟล์ที่ซ่อน
  • split เพื่อลบเส้นทางไฟล์ใช้ regex และ delimiters '\' และ '/'

รหัส:

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="input-group">
  <span class="input-group-btn">
    <span class="btn btn-primary" onclick="$(this).parent().find('input[type=file]').click();">Browse</span>
    <input name="uploaded_file" onchange="$(this).parent().parent().find('.form-control').html($(this).val().split(/[\\|/]/).pop());" style="display: none;" type="file">
  </span>
  <span class="form-control"></span>
</div>


12

ด้วยแรงบันดาลใจบางส่วนจากการโพสต์อื่น ๆ ข้างต้นนี่คือวิธีการแก้ปัญหาแบบเต็มซึ่งรวมสิ่งที่ดูเหมือนว่าเขตข้อมูลควบคุมแบบฟอร์มกับกลุ่มอินพุต - addon สำหรับเครื่องมือป้อนข้อมูลไฟล์ที่สะอาดที่มีการเชื่อมโยงไปยังไฟล์ปัจจุบัน

.input-file { position: relative; margin: 60px 60px 0 } /* Remove margin, it is just for stackoverflow viewing */
.input-file .input-group-addon { border: 0px; padding: 0px; }
.input-file .input-group-addon .btn { border-radius: 0 4px 4px 0 }
.input-file .input-group-addon input { cursor: pointer; position:absolute; width: 72px; z-index:2;top:0;right:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0; background-color:transparent; color:transparent; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div class="input-group input-file">
  <div class="form-control">
    <a href="/path/to/your/current_file_name.pdf" target="_blank">current_file_name.pdf</a>
  </div>
  <span class="input-group-addon">
    <a class='btn btn-primary' href='javascript:;'>
      Browse
      <input type="file" name="field_name" onchange="$(this).parent().parent().parent().find('.form-control').html($(this).val());">
    </a>
  </span>
</div>


9

มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน

<span>
    <input  type="file" 
            style="visibility:hidden; width: 1px;" 
            id='${multipartFilePath}' name='${multipartFilePath}'  
            onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))"  /> <!-- Chrome security returns 'C:\fakepath\'  -->
    <input class="btn btn-primary" type="button" value="Upload File.." onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
    &nbsp;
    <span  class="badge badge-important" ></span>
</span>

9

กรุณาตรวจสอบเงินทุน Twitter แฟ้มใส่ มันใช้โซลูชันที่ง่ายมากเพียงแค่เพิ่มไฟล์ javascript หนึ่งไฟล์และวางรหัสต่อไปนี้:

$('input[type=file]').bootstrapFileInput();

ลิงก์ใช้งานไม่ได้ (กรกฎาคม 2019)
Yetti99

@ Yetti99 ใช่มันพังแล้ว
monsur.hoq

@ Yetti99 ฉันเปลี่ยนลิงค์ กรุณาตรวจสอบตอนนี้
monsur.hoq

6

ทางออกที่ง่ายพร้อมผลลัพธ์ที่ยอมรับได้:

<input type="file" class="form-control">

และสไตล์:

input[type=file].form-control {
    height: auto;
}

5

โซลูชันสำหรับการอัปโหลดหลายรายการ

ฉัน tweaked สองคำตอบก่อนหน้านี้เพื่อรวมการอัปโหลดหลายรายการ ด้วยวิธีนี้เลเบลจะแสดงชื่อไฟล์หากเลือกเพียงหนึ่งไฟล์หรือx filesในกรณีตรงกันข้าม

<label class="btn btn-primary" for="my-file-selector">
    <input id="my-file-selector" type="file" multiple="multiple" style="display:none"
        onchange="$('#upload-file-info').html(
            (this.files.length > 1) ? this.files.length + ' files' : this.files[0].name)">                     
    Files&hellip;
</label>
<span class='label label-info' id="upload-file-info"></span>

ป้อนคำอธิบายรูปภาพที่นี่

นอกจากนี้ยังอาจนำไปใช้กับการเปลี่ยนข้อความปุ่มและชั้นเรียน

<label class="btn btn-primary" for="multfile">
    <input id="multfile" type="file" multiple="multiple" style="display:none"
        onchange="$('#multfile-label').html(
            (this.files.length == 1) ? this.files[0].name : this.files.length + ' files');
            $(this).parent().addClass('btn-success')">
    <span id="multfile-label">Files&hellip;</span>
</label>

ป้อนคำอธิบายรูปภาพที่นี่


4

ฉันได้สร้างปุ่มอัพโหลดที่กำหนดเองเพื่อยอมรับภาพเท่านั้นซึ่งสามารถแก้ไขได้ตามความต้องการของคุณ

หวังว่านี่จะช่วยได้ !! :)

(เฟรมเวิร์ก Bootstrap ที่ใช้)

Codepen เชื่อมโยง

HTML

<center>
 <br />
 <br />
 <span class="head">Upload Button Re-Imagined</span>
 <br />
 <br />
 <div class="fileUpload blue-btn btn width100">
   <span>Upload your Organizations logo</span>
   <input type="file" class="uploadlogo" />
 </div>
</center>

CSS

 .head {
   font-size: 25px;
   font-weight: 200;
 }

 .blue-btn:hover,
 .blue-btn:active,
 .blue-btn:focus,
 .blue-btn {
   background: transparent;
   border: solid 1px #27a9e0;
   border-radius: 3px;
   color: #27a9e0;
   font-size: 16px;
   margin-bottom: 20px;
   outline: none !important;
   padding: 10px 20px;
 }

 .fileUpload {
   position: relative;
   overflow: hidden;
   height: 43px;
   margin-top: 0;
 }

 .fileUpload input.uploadlogo {
   position: absolute;
   top: 0;
   right: 0;
   margin: 0;
   padding: 0;
   font-size: 20px;
   cursor: pointer;
   opacity: 0;
   filter: alpha(opacity=0);
   width: 100%;
   height: 42px;
 }


 /*Chrome fix*/

 input::-webkit-file-upload-button {
   cursor: pointer !important;
 }

JS

// You can modify the upload files to pdf's, docs etc
//Currently it will upload only images
$(document).ready(function($) {

  // Upload btn
  $(".uploadlogo").change(function() {
    readURL(this);
  });

  function readURL(input) {
    var url = input.value;
    var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
    if (input.files && input.files[0] && (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "gif" || ext == "svg")) {
      var path = $('.uploadlogo').val();
      var filename = path.replace(/^.*\\/, "");
      $('.fileUpload span').html('Uploaded logo : ' + filename);
      // console.log(filename);
    } else {
      $(".uploadlogo").val("");
      $('.fileUpload span').html('Only Images Are Allowed!');
    }
  }
});

4

นี่เป็นรูปแบบการอัปโหลดไฟล์ที่ดีที่สุดที่ฉันชอบ:

<div class="fileupload fileupload-new" data-provides="fileupload">
  <div class="input-append">
    <div class="uneditable-input span3"><i class="icon-file fileupload-exists"></i> <span class="fileupload-preview"></span></div><span class="btn btn-file"><span class="fileupload-new">Select file</span><span class="fileupload-exists">Change</span><input type="file" /></span><a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>

คุณสามารถรับตัวอย่างและสไตล์เพิ่มเติมได้ที่:

http://www.jasny.net/bootstrap/javascript/#fileinput

แต่การใช้สิ่งนี้คุณควรแทนที่ twitter bootstrap ด้วยไฟล์ jasny bootstrap ..

ความนับถือ.


4

ขึ้นอยู่กับโซลูชัน @claviska ที่ยอดเยี่ยมอย่างแน่นอนซึ่งเป็นหนี้เครดิตทั้งหมด

อินพุตไฟล์ Bootstrap 4 เต็มรูปแบบพร้อมการตรวจสอบและข้อความช่วยเหลือ

จากตัวอย่างกลุ่มอินพุตเรามีฟิลด์ข้อความดัมมี่ที่ใช้สำหรับการแสดงชื่อไฟล์ให้กับผู้ใช้ซึ่งได้รับการเติมข้อมูลจากonchangeเหตุการณ์ในฟิลด์ไฟล์อินพุตจริงที่ซ่อนอยู่หลังปุ่มฉลาก นอกเหนือจากการรวมการตรวจสอบ bootstrap 4สนับสนุนการเรายังทำให้สามารถคลิกที่ใดก็ได้ในอินพุตเพื่อเปิดกล่องโต้ตอบไฟล์

สามสถานะของอินพุตไฟล์

สถานะที่เป็นไปได้ทั้งสามสถานะนั้นไม่ผ่านการตรวจสอบความถูกต้องและไม่ถูกต้องกับrequiredชุดแอตทริบิวต์แท็กอินพุต hummy ของ dummy

ป้อนคำอธิบายรูปภาพที่นี่

มาร์กอัป Html สำหรับอินพุต

เราแนะนำคลาสแบบกำหนดเองเพียง 2 คลาสเท่านั้นinput-file-dummyและinput-file-btnเพื่อจัดสไตล์และเชื่อมโยงพฤติกรรมที่ต้องการอย่างเหมาะสม ทุกอย่างอื่นคือมาร์กอัป Bootstrap 4 มาตรฐาน

<div class="input-group">
  <input type="text" class="form-control input-file-dummy" placeholder="Choose file" aria-describedby="fileHelp" required>
  <div class="valid-feedback order-last">File is valid</div>
  <div class="invalid-feedback order-last">File is required</div>
  <label class="input-group-append mb-0">
    <span class="btn btn-primary input-file-btn">
      Browse… <input type="file" hidden>
    </span>
  </label>
</div>
<small id="fileHelp" class="form-text text-muted">Choose any file you like</small>

บทบัญญัติเกี่ยวกับพฤติกรรมของ JavaScript

ตัวอย่างดัมมี่จะต้องอ่านอย่างเดียวตามตัวอย่างดั้งเดิมเพื่อป้องกันผู้ใช้จากการเปลี่ยนอินพุตซึ่งอาจเปลี่ยนแปลงได้ผ่านไดอะล็อกเปิดไฟล์เท่านั้น น่าเสียดายที่การตรวจสอบไม่เกิดขึ้นในreadonlyฟิลด์ดังนั้นเราจึงสลับความสามารถในการป้อนข้อมูลของโฟกัสและเบลอ ( เหตุการณ์ jquery onfocusinและonfocusout) และตรวจสอบให้แน่ใจว่ามันสามารถใช้งานได้อีกครั้งเมื่อเลือกไฟล์

นอกเหนือจากการทำให้สามารถคลิกฟิลด์ข้อความได้ด้วยการทริกเกอร์เหตุการณ์การคลิกปุ่มส่วนที่เหลือของฟังก์ชั่นการเติมฟิลด์ดัมมี่นั้นถูกจินตนาการโดย @claviska

$(function () {
  $('.input-file-dummy').each(function () {
    $($(this).parent().find('.input-file-btn input')).on('change', {dummy: this}, function(ev) {
      $(ev.data.dummy)
        .val($(this).val().replace(/\\/g, '/').replace(/.*\//, ''))
        .trigger('focusout');
    });
    $(this).on('focusin', function () {
        $(this).attr('readonly', '');
      }).on('focusout', function () {
        $(this).removeAttr('readonly');
      }).on('click', function () {
        $(this).parent().find('.input-file-btn').click();
      });
  });
});

ปรับแต่งสไตล์ที่กำหนดเอง

สิ่งสำคัญที่สุดคือเราไม่ต้องการให้readonlyฟิลด์กระโดดข้ามพื้นหลังสีเทาและสีขาวดังนั้นเราจึงมั่นใจได้ว่ามันจะเป็นสีขาว ปุ่มขยายไม่มีเคอร์เซอร์ตัวชี้ แต่เราจำเป็นต้องเพิ่มหนึ่งปุ่มสำหรับอินพุต

.input-file-dummy, .input-file-btn {
  cursor: pointer;
}
.input-file-dummy[readonly] {
  background-color: white;
}

Njoy!



2

/ * * Bootstrap 3 filestyle * http://dev.tudosobreweb.com.br/bootstrap-filestyle/ * * ลิขสิทธิ์ (c) 2013 Markus Vinicius da Silva Lima * อัปเดต bootstrap 3 โดย Paulo Henrique Foxer * เวอร์ชั่น 2.0.0 * ได้รับสิทธิ์การใช้งาน ภายใต้ใบอนุญาต MIT * * /

(function ($) {
"use strict";

var Filestyle = function (element, options) {
    this.options = options;
    this.$elementFilestyle = [];
    this.$element = $(element);
};

Filestyle.prototype = {
    clear: function () {
        this.$element.val('');
        this.$elementFilestyle.find(':text').val('');
    },

    destroy: function () {
        this.$element
            .removeAttr('style')
            .removeData('filestyle')
            .val('');
        this.$elementFilestyle.remove();
    },

    icon: function (value) {
        if (value === true) {
            if (!this.options.icon) {
                this.options.icon = true;
                this.$elementFilestyle.find('label').prepend(this.htmlIcon());
            }
        } else if (value === false) {
            if (this.options.icon) {
                this.options.icon = false;
                this.$elementFilestyle.find('i').remove();
            }
        } else {
            return this.options.icon;
        }
    },

    input: function (value) {
        if (value === true) {
            if (!this.options.input) {
                this.options.input = true;
                this.$elementFilestyle.prepend(this.htmlInput());

                var content = '',
                    files = [];
                if (this.$element[0].files === undefined) {
                    files[0] = {'name': this.$element[0].value};
                } else {
                    files = this.$element[0].files;
                }

                for (var i = 0; i < files.length; i++) {
                    content += files[i].name.split("\\").pop() + ', ';
                }
                if (content !== '') {
                    this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
                }
            }
        } else if (value === false) {
            if (this.options.input) {
                this.options.input = false;
                this.$elementFilestyle.find(':text').remove();
            }
        } else {
            return this.options.input;
        }
    },

    buttonText: function (value) {
        if (value !== undefined) {
            this.options.buttonText = value;
            this.$elementFilestyle.find('label span').html(this.options.buttonText);
        } else {
            return this.options.buttonText;
        }
    },

    classButton: function (value) {
        if (value !== undefined) {
            this.options.classButton = value;
            this.$elementFilestyle.find('label').attr({'class': this.options.classButton});
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                this.$elementFilestyle.find('label i').addClass('icon-white');
            } else {
                this.$elementFilestyle.find('label i').removeClass('icon-white');
            }
        } else {
            return this.options.classButton;
        }
    },

    classIcon: function (value) {
        if (value !== undefined) {
            this.options.classIcon = value;
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                this.$elementFilestyle.find('label').find('i').attr({'class': 'icon-white '+this.options.classIcon});
            } else {
                this.$elementFilestyle.find('label').find('i').attr({'class': this.options.classIcon});
            }
        } else {
            return this.options.classIcon;
        }
    },

    classInput: function (value) {
        if (value !== undefined) {
            this.options.classInput = value;
            this.$elementFilestyle.find(':text').addClass(this.options.classInput);
        } else {
            return this.options.classInput;
        }
    },

    htmlIcon: function () {
        if (this.options.icon) {
            var colorIcon = '';
            if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
                colorIcon = ' icon-white ';
            }

            return '<i class="'+colorIcon+this.options.classIcon+'"></i> ';
        } else {
            return '';
        }
    },

    htmlInput: function () {
        if (this.options.input) {
            return '<input type="text" class="'+this.options.classInput+'" style="width: '+this.options.inputWidthPorcent+'% !important;display: inline !important;" disabled> ';
        } else {
            return '';
        }
    },

    constructor: function () {
        var _self = this,
            html = '',
            id = this.$element.attr('id'),
            files = [];

        if (id === '' || !id) {
            id = 'filestyle-'+$('.bootstrap-filestyle').length;
            this.$element.attr({'id': id});
        }

        html = this.htmlInput()+
             '<label for="'+id+'" class="'+this.options.classButton+'">'+
                this.htmlIcon()+
                '<span>'+this.options.buttonText+'</span>'+
             '</label>';

        this.$elementFilestyle = $('<div class="bootstrap-filestyle" style="display: inline;">'+html+'</div>');

        var $label = this.$elementFilestyle.find('label');
        var $labelFocusableContainer = $label.parent();

        $labelFocusableContainer
            .attr('tabindex', "0")
            .keypress(function(e) {
                if (e.keyCode === 13 || e.charCode === 32) {
                    $label.click();
                }
            });

        // hidding input file and add filestyle
        this.$element
            .css({'position':'absolute','left':'-9999px'})
            .attr('tabindex', "-1")
            .after(this.$elementFilestyle);

        // Getting input file value
        this.$element.change(function () {
            var content = '';
            if (this.files === undefined) {
                files[0] = {'name': this.value};
            } else {
                files = this.files;
            }

            for (var i = 0; i < files.length; i++) {
                content += files[i].name.split("\\").pop() + ', ';
            }

            if (content !== '') {
                _self.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
            }
        });

        // Check if browser is Firefox
        if (window.navigator.userAgent.search(/firefox/i) > -1) {
            // Simulating choose file for firefox
            this.$elementFilestyle.find('label').click(function () {
                _self.$element.click();
                return false;
            });
        }
    }
};

var old = $.fn.filestyle;

$.fn.filestyle = function (option, value) {
    var get = '',
        element = this.each(function () {
            if ($(this).attr('type') === 'file') {
                var $this = $(this),
                    data = $this.data('filestyle'),
                    options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option);

                if (!data) {
                    $this.data('filestyle', (data = new Filestyle(this, options)));
                    data.constructor();
                }

                if (typeof option === 'string') {
                    get = data[option](value);
                }
            }
        });

    if (typeof get !== undefined) {
        return get;
    } else {
        return element;
    }
};

$.fn.filestyle.defaults = {
    'buttonText': 'Escolher arquivo',
    'input': true,
    'icon': true,
    'inputWidthPorcent': 65,
    'classButton': 'btn btn-primary',
    'classInput': 'form-control file-input-button',
    'classIcon': 'icon-folder-open'
};

$.fn.filestyle.noConflict = function () {
    $.fn.filestyle = old;
    return this;
};

// Data attributes register
$('.filestyle').each(function () {
    var $this = $(this),
        options = {
            'buttonText': $this.attr('data-buttonText'),
            'input': $this.attr('data-input') === 'false' ? false : true,
            'icon': $this.attr('data-icon') === 'false' ? false : true,
            'classButton': $this.attr('data-classButton'),
            'classInput': $this.attr('data-classInput'),
            'classIcon': $this.attr('data-classIcon')
        };

    $this.filestyle(options);
});
})(window.jQuery);

2

ฉันแก้ไข @claviska คำตอบและทำงานได้ตามที่ต้องการ (Bootstrap 3, 4 ไม่ได้ทดสอบ):

<label class="btn btn-default">
    <span>Browse</span>
    <input type="file" style="display: none;" onchange="$(this).prev('span').text($(this).val()!=''?$(this).val():'Browse')">
</label>

2

ป้อนคำอธิบายรูปภาพที่นี่

รหัสต่อไปนี้ทำตามภาพด้านบน

html

<form>
<div class="row">
<div class="col-lg-6">
<label for="file">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Browse</button>
</span>
<input type="text" class="form-control" id="info" readonly="" style="background: #fff;" placeholder="Search for...">
</div><!-- /input-group -->
</label>
</div><!-- /.col-lg-6 -->
</div>

</div>
<input type="file" style="display: none;" onchange="$('#info').val($(this).val().split(/[\\|/]/).pop()); " name="file" id="file">
</form>

จาวาสคริ

<script type="text/javascript">

$(function() {
    $("label[for=file]").click(function(event) {
        event.preventDefault();
        $("#file").click();
    });
});

</script>

1

ฉันมีปัญหาเดียวกันและฉันลองแบบนี้

<div>
<button type='button' class='btn btn-info btn-file'>Browse</button>
<input type='file' name='image'/>
</div>

CSS

<style>
.btn-file {
    position:absolute;
}
</style>

JS

<script>
$(document).ready(function(){
    $('.btn-file').click(function(){
        $('input[name="image"]').click();
    });
});
</script>

หมายเหตุ: ปุ่ม. btn-file จะต้องอยู่ในแท็กเดียวกับไฟล์อินพุต

หวังว่าคุณจะพบทางออกที่ดีที่สุด ...


1

ลองทำตามใน Bootstrap v.3.3.4

<div>
    <input id="uplFile" type="file" style="display: none;">

    <div class="input-group" style="width: 300px;">
        <div  id="btnBrowse"  class="btn btn-default input-group-addon">Select a file...</div>
        <span id="photoCover" class="form-control">
    </div>
</div>

<script type="text/javascript">
    $('#uplFile').change(function() {
        $('#photoCover').text($(this).val());
    });

    $('#btnBrowse').click(function(){
        $('#uplFile').click();
    });
</script>

1

นี่คือเคล็ดลับสำรองไม่ใช่ทางออกที่ดีที่สุด แต่ให้ทางเลือกแก่คุณ

รหัส HTML:

<button clss="btn btn-primary" id="btn_upload">Choose File</button>
<input id="fileupload" class="hide" type="file" name="files[]">

javascript:

$("#btn_upload").click(function(e){
e.preventDefault();
$("#fileupload").trigger('click');
});

1

ในส่วนของคำตอบ claviska - หากคุณต้องการแสดงชื่อไฟล์ที่อัปโหลดในการอัปโหลดไฟล์พื้นฐานคุณสามารถทำได้ในonchangeเหตุการณ์อินพุต เพียงใช้รหัสนี้:

 <label class="btn btn-default">
                    Browse...
                    <span id="uploaded-file-name" style="font-style: italic"></span>
                    <input id="file-upload" type="file" name="file"
                           onchange="$('#uploaded-file-name').text($('#file-upload')[0].value);" hidden>
 </label>

รหัส jquery นี้รับผิดชอบในการเรียกชื่อไฟล์ที่อัพโหลด:

$('#file-upload')[0].value

หรือกับวานิลลา JS:

document.getElementById("file-upload").value

ตัวอย่าง


1

ฉันคิดว่าฉันจะเพิ่มสามเพนนีของฉันมูลค่าเพียงเพื่อบอกว่าเริ่มต้น.custom-file-labelและcustom-file-inputไฟล์ BS4 เป็นอย่างไรและสามารถใช้งานได้อย่างไร

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

<div class="custom-file">
<input type="file" class="custom-file-input" id="upload">
<label class="custom-file-label" for="upload">Choose file</label>
</div>

คุณไม่สามารถเพิ่มคลาสให้กับ psuedoelements แต่คุณสามารถจัดสไตล์ใน CSS (หรือ SASS)

.custom-file-label:after {
    color: #fff;
    background-color: #1e7e34;
    border-color: #1c7430;
    pointer: cursor;
}

0

ไม่ต้องใช้ชิซแฟนซี:

HTML:

<form method="post" action="/api/admin/image" enctype="multipart/form-data">
    <input type="hidden" name="url" value="<%= boxes[i].url %>" />
    <input class="image-file-chosen" type="text" />
    <br />
    <input class="btn image-file-button" value="Choose Image" />
    <input class="image-file hide" type="file" name="image"/> <!-- Hidden -->
    <br />
    <br />
    <input class="btn" type="submit" name="image" value="Upload" />
    <br />
</form>

JS:

$('.image-file-button').each(function() {
      $(this).off('click').on('click', function() {
           $(this).siblings('.image-file').trigger('click');
      });
});
$('.image-file').each(function() {
      $(this).change(function () {
           $(this).siblings('.image-file-chosen').val(this.files[0].name);
      });
});

ข้อควรระวัง: องค์ประกอบของฟอร์มทั้งสามในคำถามต้องเป็นพี่น้องกัน (.image-file-selected, .image-file-button, .image-file)


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