写真を複数枚アップロードするコンポーネントを開発していたのですが
これがかなり骨が折れました。なんといってもmultipileを使わずに一つのボタンで一つずつアップロード
する必要があったのがかなり堪えました。
input_type_fileの素性を知るまではfor文で回して取得したindexに合わせてアップロードしていけば
いいじゃんと考えていたのですが、甘い。甘かったです。
なんとinput_type_fileは、複数生成されずindexの要素が与えられない為どの番号
で押されたかどのコンポーネントに作用させるかという考えが一切通用しないことが分かって
しまったのです。これはセキュリティの都合上どうしようもない決め事でした。
確かに何度もファイルを操作されては情報が漏洩する危険性も高まるのでえーとは
言えない立場。
これ詰んだんじゃない?と思ったのですがどこからかinput_type_fileがダメなら
役割をボタンに持たせてinput_type_fileから作用させなければいいじゃないという声が。。。
要はただのボタンから要素を取得してその関数の内部からdocumentsbyIdでinput_type_fileの
操作を行うというもの。
reactで書くとこんな感じになります。
takePicture(index) { console.log(index); this.setState({ index: index }); this.setState({ isShowModal: false }); document.getElementById("file").click(); } handleChangeFile(e){ const that = this; let images = this.state.images; var file = e; images[this.state.index] = file; that.setState({ files: images }); that.setState({ images: images }); } for (let i = 0; i < this.state.count; i++) { if (typeof this.state.images[i] === 'undefined') { buttons.push(<Button modifier="large" className="pictures" onClick={() => this.takePicture(i)}>{(i+1) + '枚目を撮影'}<Icon icon={{default: 'fa-camera'}} /></Button>) } else { buttons.push(<Button modifier="large" className="pictures" onClick={() => this.toggleImageModal(i)}>写真を確認する</Button>); } } <input type="file" id="file" accept="image/*" value="" onChange={e =>this.handleChangeFile(e.target.files[0])} />
ボタンの要素取得時にdocument.getElementById(“file”).click();で被せているのが分かります。
後はhandleChangeFile(e)内にinput_type_fileの機能を書くだけ。
はい、思った通りに動きました。
input_type_fileはfor文で要素を持たせられないのでCSSで見えないようにしてボタンに役割を持たせることで疑似的に
アップロードボタンを作ることができました。
裏技のような感じがしますがちゃんとindexの値を保ったまま動くのでお試しください。