Boky Boky - 5 months ago 62
jQuery Question

Jquery change function doesn't work with React JS

I'm trying to create input file button in React and I want to show the file name if the file is selected using jQuery.

My component where I call input button component is as follows :

<FileInputButton pictureID="idCard" pictureIcon="credit-card" text={language.btnIdCard}
btnName="idCard" className="col-lg-4 col-md-4 col-sm-4 col-lg-offset-2 col-md-offset-2 col-sm-offset-2"/>

<FileInputButton pictureID="statuten" pictureIcon="file-text-o" text={language.btnStatut}
btnName="statuten" className="col-lg-4 col-md-4 col-sm-4 col-lg-offset-right-2 col-md-offset-right-2 col-sm-offset-right-2"/>

<div className="clearfix noMarginXs"></div>

<FileInputButton pictureID="blancoBriefhoofd" pictureIcon="file-o" text={language.btnBlanco}
btnName="blancoBriefhoofd" className="col-lg-4 col-md-4 col-sm-4 col-lg-offset-2 col-md-offset-2 col-sm-offset-2"/>

<FileInputButton pictureID="companyPhoto" pictureIcon="camera-retro" text={language.btnCompanyPhoto}
btnName="companyPhoto" className="col-lg-4 col-md-4 col-sm-4 col-lg-offset-right-2 col-md-offset-right-2 col-sm-offset-right-2"/>


The FileInput component is something like :

<div style={{width: '100%', textAlign: 'center', marginTop: 20}}>
<label className="advanced-button">
<FontAwesome name="upload" className="faIcon" style={{height: '39px !important'}}/>
<span className={`btnFileText ${btnName}`}>{text}</span>
<input id="btnFile" type="file" style={{display: 'none'}} name={btnName}/>
</label>
</div>


And my jquery code is as follows :

$(function () {
$("#btnFile").change(function () {
var id = this.name;
switch (id) {
case "idCard":
{
filename = $('#btnFile').val().split('\\').pop();
filenameWithoutExtension = filename.replace(/\.[^/.]+$/, "");
$('.' + id).text(filenameWithoutExtension);
console.log("Usao je u prvu");
break;

}
case "statuten":
{
filename = $('#btnFile').val().split('\\').pop();
filenameWithoutExtension = filename.replace(/\.[^/.]+$/, "");
$('.' + id).text(filenameWithoutExtension);
console.log("Usao je u drugu");
break;
}
case "blancoBriefhoofd":
{
filename = $('#btnFile').val().split('\\').pop();
filenameWithoutExtension = filename.replace(/\.[^/.]+$/, "");
$('.' + id).text(filenameWithoutExtension);
console.log("Usao je u trecu");
break;
}
default: {
filename = $('#btnFile').val().split('\\').pop();
filenameWithoutExtension = filename.replace(/\.[^/.]+$/, "");
$('.' + id).text(filenameWithoutExtension);
console.log("Usao je u default");
}
}
});
});


When I click on first button, everything works fine. The text in the span is changed with the selected file, but the other buttons will not work.

UPDATE

import React, {propTypes} from 'react';
import FontAwesome from 'react-fontawesome';

const FileInputButton = ({className, pictureID, pictureIcon, text, btnName}) => {
return (
<div className={className}>
<div className="picture-container" style={{marginLeft: 18}}>
<div className="picture" id={pictureID}>
<FontAwesome name={pictureIcon} size="3x" className="picture-src" style={{paddingTop: 14}}/>
</div>
</div>

<div style={{width: '100%', textAlign: 'center', marginTop: 20}}>
<label className="advanced-button">
<FontAwesome name="upload" className="faIcon" style={{height: '39px !important'}}/>
<span className={`btnFileText ${btnName}`}>{text}</span>
<input id="btnFile" type="file" style={{display: 'none'}} name={btnName}/>
</label>
</div>
</div>
);
};

FileInputButton.propTypes = {
className: React.PropTypes.string.isRequired,
pictureID: React.PropTypes.string.isRequired,
pictureIcon: React.PropTypes.string.isRequired,
text: React.PropTypes.string.isRequired,
btnName: React.PropTypes.string.isRequired
};

export default FileInputButton;

Answer

I don't know if this qualifies as an answer but as a sketch a React type approach might be something like:

//in parent component initialise state

function getInitialState: () { state = {'displayField' : '', 'displayFieldClass': ''} return state; }

//in parent component define handler

function inputChange(e) {
    this.state.displayField = e.target.value;
    this.state.displayFieldClass = 'activeFileName'; //CSS class defined somwhere
}

//in parent component display the filename and render the FileInputButton(s) passing in the handler

function render() {

    Filename: <span className={this.state.displayFieldClass}>{this.state.displayField}</span>

    <FileInputButton handler={this.inputChange} ...otherProps />

}

// in FileInputButton associate the onChange event with the passed in handler

function render() {

     <input className="btnFile" type="file" onchange={this.props.handler}>

}
Comments