This is my uploadifive setup:
Inside body:
<div id="file_rows_wrapper">
<div class="file_row">
<input class="file_upload" name="file_upload" type="file" multiple="false">
</div>
</div>
Add Another File
While this is the javascript part:
$(function() {
uploadify();
});
function uploadify() {
<?php $timestamp = time();?>
$('.file_upload').uploadifive({
'auto' : true,
'checkScript' : '/files/check_exists',
'formData' : {
'timestamp' : '<?php echo $timestamp;?>',
'token' : '<?php echo md5('hiall' . $timestamp);?>'
},
'queueID' : 'queue',
'uploadScript' : '/files/upload_file',
'multi' : false,
'buttonText' : 'Upload File',
});
};
function add_file()
{
var file = $('.file_row:first').clone();
file.css('margin-top', '20px');
file.fadeIn().appendTo($('#file_rows_wrapper'));
uploadify();
}
All works as expected. The "file_row" div is being cloned but when clicking on the "Add Another File" and choosing the local file, nothing happens. There is no upload. If I maually copy the "file_row" div more times then the upload works fine, even more uploads at once. What am I doing wrong?
I think you need a unique id in your file input to have multiple instances on one page.
Related
I'm building a simple app with node.js and reactjs but the problem arises when I want to add book especially while selecting dropdown value.
In the select tag when I select the first element it crashes the backend but when I select the second or below it they work just fine. What could be the reason behind it ? Dropdown menu has been filled correctly. My code is :
import React, { Component } from 'react'
import axios from 'axios'
export default class AddBook extends Component {
state = {
name : '',
author : '',
publishers : '',
pages :'',
genres : [],
genre : '',
addedMessage : null
}
async componentDidMount() {
const genres = await axios.get('http://localhost:5000/api/genres')
this.setState({ genres : genres.data})
}
onInputChange = (e) => {
this.setState({[e.target.name] : e.target.value }) //looks for name
}
onFormSubmit = (e) => {
e.preventDefault();
const book = {
name : this.state.name,
author : this.state.author,
publishers : this.state.publishers,
pages : this.state.pages,
genres : this.state.genre
}
axios.post('http://localhost:5000/api/books', book)
.then(res => console.log(res))
.catch(err => console.log("error occured while posting data ", err))
console.log(book)
//alert("book added successfully !!!")
this.setState({addedMessage : 'Book added successfully'})
window.location = "/books"
}
render() {
const { name, author, publishers, pages, genres, addedMessage } = this.state;
return (
<div className="container">
<h2>ADD BOOK </h2>
{ addedMessage && <h2 style={{textAlign : 'center'}} className="alert alert-info">{addedMessage}</h2> }
<form onSubmit = { this.onFormSubmit }>
<div className="form-group">
<label htmlFor="name">BookName:</label>
<input type="text" required className="form-control" id="name"
placeholder="Enter Book name" name="name"
onChange={this.onInputChange}
value={name}
/>
</div>
<div className="form-group">
<label htmlFor="author">Author:</label>
<input type="text" required={ true } className="form-control"
id="author" placeholder="Enter Author" name="author"
onChange={this.onInputChange}
value={author}
/>
</div>
<div className="form-group">
<label htmlFor="publishers">Publishers:</label>
<input type="text" required className="form-control"
id="publishers" placeholder="Enter Publishers Name"
name="publishers"
onChange={this.onInputChange}
value={publishers}
/>
</div>
<div className="form-group">
<label htmlFor="pages">Pages:</label>
<input type="number" required className="form-control"
id="pages" placeholder="Enter No of Page" name="pages"
onChange={this.onInputChange}
value={pages}
/>
</div>
<div className="form-group">
<label htmlFor="genre">Category:</label>
<select type="select" className="form-control"
id="genre"
name="genre"
onChange={this.onInputChange}
>
{/* <option value="selectCategory" onChange={this.onInputChange}>Select</option> */}
{
genres.map( genre => (
<option key={genre._id} onChange={this.onInputChange} value={genre.name}>
{genre.name }</option>
))
}
</select>
</div>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
)
}
}
My backend is up and running and has successfully fetched the genres[ categories ] , but I am not able
to figure out why selecting the first doesn't work but others just work fine. How should I solve it ?
It shows the following error for this case.
Error: Book validation failed: genres: Path `genres` is required.
at ValidationError.inspect
(E:\nodejs\nodejs\MERN_STACK_Book\node_modules\mongoose\lib\error\validation.js:48:26)
at formatValue (internal/util/inspect.js:718:31)
at inspect (internal/util/inspect.js:287:10)
at afterInspector (internal/errors.js:682:14) {
errors: {
genres: ValidatorError: Path `genres` is required.
at validate (E:\nodejs\nodejs\MERN_STACK_Book\node_modules\mongoose\lib\schematype.js:1178:13)
at E:\nodejs\nodejs\MERN_STACK_Book\node_modules\mongoose\lib\schematype.js:1161:7
at Array.forEach (<anonymous>)
at SchemaString.SchemaType.doValidate
(E:\nodejs\nodejs\MERN_STACK_Book\node_modules\mongoose\lib\schematype.js:1106:14)
at E:\nodejs\nodejs\MERN_STACK_Book\node_modules\mongoose\lib\document.js:2387:18
at processTicksAndRejections (internal/process/task_queues.js:79:11) {
properties: [Object],
kind: 'required',
path: 'genres',
value: '',
reason: undefined,
[Symbol(mongoose:validatorError)]: true
}
},
_message: 'Book validation failed'
}
[nodemon] app crashed - waiting for file changes before starting...
And code for my book schema is as follows
const mongoose = require('mongoose')
//schema for genres
const bookSchema = mongoose.Schema({
name : {
type : String,
required : true,
trim : true,
unique : true //title is made unique.
},
author : {
type : String,
required : true,
trim : true
},
publishers : {
type : String,
trim : true,
},
pages : {
type : Number,
required : true,
trim : true
},
genres : {
type : String,
required : true,
trim : true
},
create_date : {
type : Date,
default : Date.now
}
})
//It will create books collection in your database and documents
//inside that collection will have fields from bookSchema when you save first document.
const Book = module.exports = mongoose.model('Book', bookSchema)
//get the books
module.exports.getBooks = (callback, limit) => {
// Book.find(callback)
Book.find(callback).limit(limit)
}
//get single book
module.exports.getBookById = (id,callback) => {
// Book.find(callback)
Book.findById(id,callback);
}
module.exports.addBook = (book,callback) => {
Book.create(book, callback);
}
module.exports.updateBook = (id,book,options, callback) => {
const query = {
_id : id
}
const updatedBook = {
name : book.name,
author : book.author,
publishers : book.publishers,
pages : book.pages,
genres : book.genres
}
Book.findByIdAndUpdate(query, updatedBook, {} , callback);
}
module.exports.deleteBook = (id,callback) => {
const query = {
_id : id
}
Book.findByIdAndDelete(query, callback);
}
I checked some of the similar answers in the stackoverflow but couldn't figure out why I'm getting that
error.
Here's the problem with your code :
The first option of the dropdown is chosen by default, and thus "selecting" the first option doesn't trigger the Category dropdown's onChange function (because the selected value doesn't really change).
Since the default value of this.state.genre is an empty string, the genres property of the book you send to the backend also has genres as an empty string.
Finally, Mongoose does not accept an empty string for a required string field, which gives you the Path 'genres' is required error.
Try switching to another option and back to the first. It will work then because the onChange function will then get called and this.state.genre will be set properly.
There are a few ways to fix this:
Add a placeholder option to the dropdown - something like "Select an option...". Then the user will be forced to select a genre from the dropdown and onChange would be called.
Or, in componentDidMount, set this.state.genre to the first genre of the list of genres you fetch.
I would like to create a web app with Express and Node.js. I'm currently trying to let user uploads a profile picture and I use Dropzone.js. Here, what I did for now :
<script type="text/javascript">
Dropzone.options.ppDrop = {
paramName: username,
maxFilesize: 10, // MB
maxFiles : 1,
uploadMultiple = false,
acceptedFiles : "image/*",
dictDefaultMessage : "Drop files here or click to upload"
};
</script>
<form action="/PPupload" method="post" class="dropzone" id="ppDrop" enctype="multipart/form-data">
<div class="fallback">
<input name="pic" type="file" />
</div>
</form>
But it doesn't work. What I did wrong ?
I also need help to define a route that could store the image in an internal folder and display it after the user confirms his choice. How I could do that ? Many thanks in advance !
You're trying to set an object property with an = instead of a :. The fixed code would look like this:
Dropzone.options.ppDrop = {
paramName: username,
maxFilesize: 10, // MB
maxFiles : 1,
uploadMultiple : false,
acceptedFiles : "image/*",
dictDefaultMessage : "Drop files here or click to upload"
};
Still trying to work with Dgrid (0.4) and dojo (1.10), I have now another issue with the selection.
My web page contain a Dialog opened when you click on a button.
Inside this dialog, we have the following code which display a grid with data coming from a database through a Json HTTP page. This is working fine, even sorting and query filtering.
What I want to do know is to allow the user to double click on a row, get the selected row Id contains in the first column to update the form in the main page. I use the dgrid/selection for this. However, it always return the last row of the grid instead of the one the user selected.
The selection code is based on this :
http://dgrid.io/tutorials/0.4/hello_dgrid/
Any idea?
Thanks
<script language="javascript">
require
(
[
"dojo/_base/declare",
"dojo/_base/array",
"dgrid/OnDemandList",
"dgrid/OnDemandGrid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/Editor",
"dgrid/extensions/ColumnHider",
"dstore/Memory",
"dstore/RequestMemory",
"dojo/_base/lang",
"dojo/dom-construct",
"dojo/dom",
"dojo/on",
"dojo/when",
"dojo/query",
"dojo/store/Observable",
"dstore/Rest",
"dojo/_base/Deferred",
"dojo/store/Cache",
"dojo/domReady!",
],
function(
declare, arrayUtil, OnDemandList, OnDemandGrid, Keyboard, Selection, Editor, ColumnHider, Memory, RequestMemory, lang, ObjectStore, dom, on, when, query, Observable, Rest, Deferred
){
var fform = dom.byId("filterForm");
var ContactColumns = [
{ label: "", field: "contact_id", hidden: true, unhidable: true},
{ label: "Company Name", field: "company_name", unhidable: true },
{ label: "Contact Name", field: "contact_name", unhidable: true },
{ label: "Email", field: "contact_email", unhidable: true }
];
var ContactGrid=declare([OnDemandGrid, Keyboard, Selection,ColumnHider]);
var contactlist = new Observable(new Rest({ target: './ajax.contactsLoader.php' }));
var selection = [];
window.contactgrid = new ContactGrid(
{
className: "dgrid-selectors",
collection: contactlist,
maxRowsPerPage:10,
selectionMode: 'single',
cellNavigation: false,
columns: ContactColumns
}, "contacttable"
);
on(fform, "submit", function (event) {
var cpy_filter = fform.elements.fcompany_name.value;
var ct_filter = fform.elements.fcontact_name.value;
var email_filter = fform.elements.fcontact_email.value;
contactgrid.set('collection',contactlist.filter({contact_name: ct_filter, company_name: cpy_filter, contact_email: email_filter }));
contactgrid.refresh();
event.preventDefault();
});
contactgrid.on('dgrid-select', function (event) {
// Report the item from the selected row to the console.
console.log('Row selected: ', event.rows[0].data);
});
contactgrid.on('dgrid-deselect', function (event) {
console.log('Row de-selected: ', event.rows[0].data);
});
contactgrid.on('.dgrid-row:click', function (event) {
var row = contactgrid.row(event);
console.log('Row clicked:', row.data);
});
}
);
</script>
<div class="dijitDialogPaneContentArea" style="width:96%;margin-left:5px">
<form id="filterForm">
<div class="dijitDialogPaneActionBar" >
<button data-dojo-type="dijit.form.Button" type="submit">Filter</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="submitButton"
type="submit"
>
Select
</button>
<button
data-dojo-type="dijit.form.Button"
data-dojo-attach-point="cancelButton"
>
Close
</button>
</div>
<div data-dojo-attach-point="contentNode" >
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcompany_name" id="fcompany_name" style="width:33%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_name" id="fcontact_name" style="width:32%">
<input type="text" data-dojo-type="dijit.form.TextBox" name="fcontact_email" id="fcontact_email" style="width:33%">
<div id="contacttable">
</div>
</div>
</form>
</div>
Just found the reason.
the columns need to have a 'id' column called ID. I just change the 'contact_id' column to 'id' and it works fine.
thanks
I bought 'uploadifive' today. I managed to get it to work with firefox and opera. However, I can only upload small files. The filesizelimit or sizeLimit or uploadlimit option does not seem to work for me? Do I have to format it in a certain way, or maybe I have to change something in the uploadifive.php file too?
here is the index file below. Any help would be great. thanks : )
<script type="text/javascript">
<?php $timestamp = time();?>
$(function() {
$('#file_upload').uploadifive({
'auto' : false,
'checkScript' : 'check-exists.php',
'formData' : {
'timestamp' : '<?php echo $timestamp;?>',
'token' : '<?php echo md5('unique_salt' . $timestamp);?>'
},
'queueID' : 'queue',
'uploadLimit' : 0,
'uploadScript' : 'uploadifive.php',
'onUploadComplete' : function(file, data) { console.log(data); }
});
});
</script>
I'm new at Angularjs and I'm trying to create an AngularJS project with jQuery File Upload but I could not distinguish between directives file controllers file and the view.
Can anyone help me by providing me a clear structure of how files should be placed? (controllers, directives, and view)
I wrote something for my very first Angular.js project. It's from before there was an Angular.js example, but if you want to see the hard way, you can have it. It's not the best, but it may be a good place for you to start. This is my directives.js file.
(function(angular){
'use strict';
var directives = angular.module('appName.directives', []);
directives.directive('imageUploader', [
function imageUploader() {
return {
restrict: 'A',
link : function(scope, elem, attr, ctrl) {
var $imgDiv = $('.uploaded-image')
, $elem
, $status = elem.next('.progress')
, $progressBar = $status.find('.bar')
, config = {
dataType : 'json',
start : function(e) {
$elem = $(e.target);
$elem.hide();
$status.removeClass('hide');
$progressBar.text('Uploading...');
},
done : function(e, data) {
var url = data.result.url;
$('<img />').attr('src', url).appendTo($imgDiv.removeClass('hide'));
scope.$apply(function() {
scope.pick.photo = url;
})
console.log(scope);
console.log($status);
$status.removeClass('progress-striped progress-warning active').addClass('progress-success');
$progressBar.text('Done');
},
progress : function(e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$progressBar.css('width', progress + '%');
if (progress === 100) {
$status.addClass('progress-warning');
$progressBar.text('Processing...');
}
},
error : function(resp, er, msg) {
$elem.show();
$status.removeClass('active progress-warning progress-striped').addClass('progress-danger');
$progressBar.css('width', '100%');
if (resp.status === 415) {
$progressBar.text(msg);
} else {
$progressBar.text('There was an error. Please try again.');
}
}
};
elem.fileupload(config);
}
}
}
]);
})(window.angular)
I didn't do anything special for the controller. The only part of the view that matters is this:
<div class="control-group" data-ng-class="{ 'error' : errors.image }">
<label class="control-label">Upload Picture</label>
<div class="controls">
<input type="file" name="files[]" data-url="/uploader" image-uploader>
<div class="progress progress-striped active hide">
<div class="bar"></div>
</div>
<div class="uploaded-image hide"></div>
</div>
</div>