i want to remove image src,
here is my template
<div class="file-upload-section">
<label id="preview" for="file-upload">
<img v-if="url" :src="url" />
</label>
<div class="file-upload">
<label class="file-upload-button" for="file-upload">Upload Image</label>
<input type="file" id="file-upload" #change="onFileChange"/>
</div>
<div v-if="url">
<button #click="removeImage()">Remove image</button>
</div>
</div>
this is my script
data: function () {
return {
url: null,
file: null
}
},
methods: {
onFileChange (e) {
this.file = e.target.files[0]
this.url = URL.createObjectURL(this.file)
},
removeImage: function () {
this.url = null
}
}
}
this is all i did, am i doing anything wrong or there is another way to delete a picture from a img
Your code is working; I tried it in my environment. It works perfectly. The issue could be re-rendering. I removed the "file" variable, as this seems no use based on your code, and I created scoped variable inside onFileChange function.
For a re-rendering issue to fix, add the key in your "img" tag and give it a unique value which will change on the "add" and "remove" image. In the below case, I use "URL" as a key.
<img :key="url" v-if="url" :src="url" />
Here is the code, give it a try:
<template>
<div class="file-upload-section">
<label id="preview" for="file-upload">
<img :key="url" v-if="url" :src="url" />
</label>
<div class="file-upload">
<label class="file-upload-button" for="file-upload">Upload Image</label>
<input type="file" id="file-upload" #change="onFileChange"/>
</div>
<div v-if="url">
<button #click="removeImage()">Remove image</button>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
url: null
}
},
methods: {
onFileChange (e) {
let file = e.target.files[0]
this.url = URL.createObjectURL(file)
},
removeImage: function () {
this.url = null
}
}
}
</script>
Edit:
On testing your code, I noticed the file preview does reset (the url variable), however the value of the input, did not. I assume that's what you mean, thus:
You can use a ref on the file input, and reset it as well.
Add a ref to your input:
<input type="file" id="file-upload" ref="file" #change="onFileChange"/>
Also, update your removeImage method accordingly:
removeImage: function () {
this.url = ""
this.$refs.file.value = ""
}
Pen here
In Vuejs in order to bind an event you should use v-on:click or in short way :click:
<button :click="removeImage">Remove image</button>
https://v2.vuejs.org/v2/guide/events.html
Related
Ok so I have a form that has file inputs on it for images (and it previews the image before submission) but only the first input updates (no matter which input I use to put my image up).
Here are the repro steps:
Click "Add Question" button 2 or more times
Click (because drop doesn't work yet) on the second dropzone and upload a file.
See that the first dropzone updates and not the second
Here's a CodeSandbox for it.
And here is my code for the drop zone component:
class DropZone extends Component {
constructor(props){
super(props)
this.state = {
file: "",
fileId: uuid()
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
file: URL.createObjectURL(event.target.files[0])
})
//document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
}
render() {
return (
<div >
<input type="file" id="file" name="file" class="inputFile" onChange={this.handleChange}/>
<label key={uuid()} for="file" value={this.state.file} onchange={this.handleChange}>
<div class="dropZone" key={uuid()}>
Drop or Choose File
<img src={this.state.file} id="pic" name="file" accept="image/*"/>
</div>
</label>
<div>
</div>
</div>
);
}
}
I am new to React and JS so any explanation would help loads. Thanks!
It is not an issue with React but with HTML bindings. You need to provide a unique id to the input box and the label htmlFor attribute. I have updated the code below. and your code sandbox here -> https://codesandbox.io/s/kkj7j61noo
class DropZone extends Component {
constructor(props){
super(props)
this.state = {
file: "",
fileId: uuid()
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
file: URL.createObjectURL(event.target.files[0])
})
//document.getElementsByClassName("dropZone").style.backgroundImage = 'url(' + this.state.file + ')';
}
render() {
const uniqueId = this.state.fileId;
return (
<div >
<input type="file" id={uniqueId} name={uniqueId} class="inputFile" onChange={this.handleChange}/>
<label key={uuid()} htmlFor={uniqueId} value={this.state.file}>
<div class="dropZone" key={uuid()}>
Drop or Choose File
<img src={this.state.file} id="pic" name="file" accept="image/*"/>
</div>
</label>
<div>
</div>
</div>
);
}
}
My vue component like this :
<template>
<div>
...
<form class="form-horizontal" id="form-profile">
...
<input type="number" class="form-control" required>
...
<button type="submit" class="btn btn-primary" #click="submit">Submit</button>
...
</form>
...
</div>
</template>
<script>
export default {
...
methods: {
submit(e) {
e.preventDefault()
if (this.checkForm()) {
// do ajax here
}
},
checkForm() {
let field = true
$('#form-profile :required').each(function(i) {
if(this.checkValidity() == false)
field = false
})
return field
},
}
}
</script>
I using required html5 to validation
I using e.preventDefault() to prevent page redirects. Because I want to using ajax
My problem here is the required validation html5 not show if not filled. Maybe it because I using e.preventDefault()
How can I display the required html5?
In order to work as expected you have to set the v-on:submit method on the form tag, and have a button/input type "submit".
Also, notice the event modifier prevent on the #submit, it's a shorcut to not have to write e.preventDefault() on the method
new Vue({
el: '#app',
data() {
return {
myText: ''
}
},
methods: {
submitForm() {
alert('submited: ' + this.myText)
}
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.15/vue.js"></script>
<div id="app">
<form #submit.prevent="submitForm">
<input type="text" v-model="myText" required />
<button type="submit">Submit</button>
</form>
</div>
I'm still relatively new to Vue.js and am having an issue binding one of my inputs to my viewmodel.
Here is my JavaScript:
var viewModel = new Vue({
el: "#InventoryContainer",
data: {
upcCode: "",
component: {
Name: ""
}
},
methods: {
upcEntered: function (e) {
if (this.upcCode.length > 0){
$.ajax({
url: "/Component/GetByUpc",
type: "GET",
data: {
upc: this.upcCode
}
}).done(function (response) {
if (response.exists) {
$("#ComponentInformation").toggleClass("hidden");
this.component = response.component;
} else {
alert("No component found.");
}
});
}
}
}
});
Here is my HTML:
<div class="form-horizontal row">
<div class="col-sm-12">
<div class="form-group">
<label class="control-label col-md-4">UPC Code</label>
<div class="col-md-8">
<input id="ComponentUPC" class="form-control" placeholder="Scan or enter UPC Code" v-on:blur="upcEntered" v-model="upcCode" />
</div>
</div>
<div id="ComponentInformation" class="hidden">
<input type="text" class="form-control" readonly v-model="component.Name" />
</div>
</div>
</div>
Now the issue is that even when I enter a valid UPC code and I assign the component to my ViewModel, the input that is bound to component.Name does not update with the component name. And when I enter into the console viewModel.component.Name I can see that it returns "".
But if I put an alert in my ajax.done function after I've assigned the component and it looks like this alert(this.component.Name) it alerts the name of the component.
Any ideas of where I'm going wrong here?
You cannot use that line
this.component = response.component;
because of the this-variable.
You should put the line
var self = this
before your ajax call and use self.component instead of this.component
in order for vue to work you need to define the parent container with id InventoryContainer
<div id="InventoryContainer" class="form-horizontal row">
<div class="col-sm-12">
<div class="form-group">
....
here is the updated code: https://jsfiddle.net/hdqdmscv/
here is the updated fiddle based on your comment
https://jsfiddle.net/hdqdmscv/2/
(replace this with name of vue variable in ajax)
I am having a button from which I open the file explorer. I am doing it like this
{
this.props.fileUploadIsOpen
&& <div className='assign-dialog'>
<div className='assign-dialog-inner'>
<div className='dia-title'> File Upload</div>
<div className='dia-body'>
<div className='control-container'>
<div className='control-label'> Video File</div>
<div className='control'>
<input type="text" className="form-control" id="usr"/>
<button type="button" className="btn btn-primary" onClick={(e) => this.upload.click()}>Browse</button>
<input id="myInput" type="file" ref={(ref) => this.upload = ref} style={{visibility: 'hidden', width:0}} onChange={this.handleFileSelect}/>
</div>
</div>
But onChange method is not getting called. When I select a file, nothing happens. onChange method is supposed to called handleFileSelect function, which prints the file name in console. But nothing happens in console. Is onChange not getting triggered? How can I solve it?
I do not know why you are passing a function to the ref attr, but
I have recreated your case and it nails what you want
class Uploader extends React.Component {
constructor () {
super();
}
onClick (e) {
const {fileUpload} = this.refs;
fileUpload.click();
}
// prints the file name
handleFileSelect (e) {
const {fileUpload} = this.refs;
console.log(fileUpload.files[0].name)
}
render () {
return (
<div>
<div className='control-label'> Video File</div>
<div className='control'>
<input type="text" className="form-control" id="usr"/>
<button
type="button"
className="btn btn-primary"
onClick={this.onClick.bind(this)}>Browse</button>
<input id="myInput" type="file" ref="fileUpload" style={{visibility: 'hidden', width:0}} onChange={this.handleFileSelect.bind(this)}/>
</div>
</div>
);
}
}
Because you didn't call handleFileSelect function here and it call by your eventListener, you need to bind it, like this code:
this.handleFileSelect.bind(this)
I want to require an input of type file using angularjs without using the attribute required in the HTML code.
My interface is : enter image description here
I want to get an alert after hitting the button submit.
This is what I have done : enter image description here
function DatabaseCtrl($scope, $http, predefineds, locationSearch, queries, database, $window) {
var credentials = {
fileName: ""
};
$scope.credentials = credentials;
$scope.uploadToFolder = function() {
if( $scope.credentials.fileName.length<1 ) {
$window.alert("Please select a file!");
return false;
}
database.uploadToFolder($scope.credentials.fileName, true);
};
The HTML code :
<form role="form" name="frmUploadFolder" ng-submit="uploadToFolder()">
<div class="box">
<h2>
<span ng-show="isUserFile">File directory browser :</span>
<button type="button" ng-show="isUserFile" class="btn btn-default">See file(s)</button>
<button type="button" ng-show="!isUserFile" class="btn btn-default">Upload file(s)</button>
</h2>
<div class="content">
<p>
<label ng-show="isUserFile" >Please specify a file, or a set of files:</label><br>
<input type="file" ng-show="isUserFile" name="datafile" id="fileName" ng-model="credentials.fileName" size="20" required multiple>
<button type="submit" ng-show="isUserFile" class="btn btn-default" >Upload</button><br>
</p>
<div ui-if="!tree.length" class="message">
<p ui-if="!tree.loading">
<span ng-show="!isUserFile">Empty directory</span>
</p>
</div>
</div>
</div>
</form>
The service js :
angular.module('referl.services').factory('database', function($http, channel, $rootScope) {
var database = {
uploadToFolder: function(fileName, navigateOnSuccess) {
var parameters = {
fileName: fileName
};
$http.get("api/database/uploadToFolder", {params: parameters})
.success(function(response) {
if(response.error) {
alert(response.error);
} else {
if (navigateOnSuccess) {
alert("Navigation On Success !");
}
}
});
}
};
Any help please?
For some reason angular does not fully support binding a model element to a file input. The directive approach is generally the accepted work around, but within your controller you can also use document.getElementById("filename") to get a reference to the filename input and grab its value.