I have a Wordpress website that users can submit posts from the front-end. Im trying to integrate dropzone.js so users can submit images via drag and drop and sort images from featured image and gallery images kinda like what craigslist has.
My question is how do I get the featured image to get added to a file input
<input id="fileUpload" type="file" name="feat-img" accept="image/*" value="">
and the gallery image get added to
<input id="gallery-photo-add" type="file" name="muti_files[]" accept="image/*" multiple>
Heres my code
Html
<div class="dropzone" drop-zone="" id="file-dropzone"></div>
<ul class="visualizacao sortable dropzone-previews" style="border:1px solid #000"></ul>
<div class="preview" style="display:none;">
<li>
<div class="dz-preview dz-file-preview">
<img data-dz-thumbnail />
<input id="fileUpload" type="file" name="feat-img" accept="image/*" value="">
<input id="gallery-photo-add" type="file" name="muti_files[]" accept="image/*" multiple>
</div>
</li>
</div>
Javascript
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.js"></script>
<script type="text/javascript">
var $ = jQuery
$(document).ready(function(){
$('.sortable').sortable();
});
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/dropzone/4.0.1/min/dropzone.min.js',function(){
$('#file-dropzone').dropzone({
url: "/",
maxFilesize: 100,
paramName: "uploadfile",
maxThumbnailFilesize: 99999,
previewsContainer: '.visualizacao',
previewTemplate : $('.preview').html(),
init: function() {
this.on('completemultiple', function(file, json) {
$('.sortable').sortable('enable');
});
this.on('success', function(file, json) {
alert('aa');
});
this.on('addedfile', function(file) {
console.log('File1',file);
});
this.on('drop', function(file) {
console.log('File2',file);
});
}
});
});
$(document).ready(function() {});
</script>
PHP
if( ! empty( $_FILES ) ){
$featured_image = $_FILES['feat-img'];
$attachment_id = upload_user_file( $featured_image, $post_id);
$files = $_FILES['upload_attachment'];
foreach ($files['name'] as $key => $value) {
if ($files['name'][$key]) {
$filee = array(
'name' => $files['name'][$key],
'type' => $files['type'][$key],
'tmp_name' => $files['tmp_name'][$key],
'error' => $files['error'][$key],
'size' => $files['size'][$key]
);
$_FILES = array("upload_attachment" => $filee);
foreach ($_FILES as $filee => $array) {
$newupload = my_handle_attachment($filee, $post_id);
}
}
}
}
if ( ! empty( $_FILES['muti_files'] ) ) {
$files = $_FILES['muti_files'];
foreach ($files['name'] as $key => $value){
if ($files['name'][$key]){
$file = array(
'name' => $files['name'][$key],
'type' => $files['type'][$key],
'tmp_name' => $files['tmp_name'][$key],
'error' => $files['error'][$key],
'size' => $files['size'][$key]
);
}
$_FILES = array("muti_files" => $file);
$i=1;
foreach ($_FILES as $file => $array) {
if ($_FILES[$file]['error'] !== UPLOAD_ERR_OK) __return_false();
require_once(ABSPATH . "wp-admin" . '/includes/image.php');
require_once(ABSPATH . "wp-admin" . '/includes/file.php');
require_once(ABSPATH . "wp-admin" . '/includes/media.php');
$attachment_id = media_handle_upload($file, $post_id);
$vv .= $attachment_id . ",";
$i++;
}
update_post_meta($post_id, '_product_image_gallery', $vv);
}
}
All this works fine if i dont use dropzone.js and just the <input type="file"> here is a codepen so you can see what im trying to do https://codepen.io/T-SEA/pen/OdqQOw
Related
So I want my users to be able to create a post in the frontend and upload an image with a form I've created.
When the image is uploaded I want to update an ACF-field with the uploaded image.
I've seen some posts on this but none of them are explained any good.
I want to use Ajax and I want to use axios, so please no jQuery. I also use Qs.
The image itself is never uploaded but the file name is inserted in the media library.
Thank you!
HTML
<form enctype="multipart/form-data" method="post" id="register-store-form">
<fieldset class="store-images mb-3">
<label for="store-images">Add images</label>
<input type="file" id="store_images" name="store_images" accept="image/png, image/jpeg">
</fieldset>
<button class="btn btn-primary" id="update-store">Save store</button>
</form>
JS
const Qs = require('qs');
const axios = require('axios');
const saveStoreBtn = document.querySelector('#update-store');
const addStore = document.querySelector('#add-one-more-store');
function saveStore(e) {
const storeName = document.querySelector('#store-name');
const storeImages = document.querySelector('#store_images');
const storeImageFile = storeImages.files[0];
const ajaxData = {
action : 'create_store',
security : shkGlobal.addStore,
name : storeName.value,
image_name : storeImageFile.name,
image_type : storeImageFile.type,
description : storeDescription.value
};
axios.post(shkGlobal.adminUrl, Qs.stringify(ajaxData))
.then(function(response) {
saveStoreBtn.innerHTML = "Thank you";
})
.catch(err => console.log('Not working', err));
};
updateStoreBtn.addEventListener('click', saveStore);
PHP
function create_store() {
check_ajax_referer('add_store', 'security');
$name_value = $_POST['name'];
$image_name = $_POST['image_name'];
$image_type = $_POST['image_type'];
$post_data = array(
'post_type' => 'store',
'post_title' => htmlentities($name_value),
'post_content' => $_POST['description'],
'post_status' => 'draft'
);
$post_id = wp_insert_post( $post_data );
if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
$uploadedfile = $_FILES[$image_name];
$upload_overrides = array( 'test_form' => false );
$movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
if ($movefile) {
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'].'/'.$image_name,
'post_mime_type' => $image_type,
'post_title' => $image_name,
'post_content' => 'File '.$image_name,
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $movefile['file']);
update_field('field_602019eba7767', $attach_id, $post_id);
}
echo json_decode($response);
exit;
}
add_action('wp_ajax_create_store', 'create_store');
add_action('wp_ajax_nopriv_create_store', 'create_store');
There are two problems in your case, first one that you are uploading multiple files, so structure of $_FILES will be different. Second one is that you specified store_images instead store_images[] for multiple file upload.
So in html change <input type="file" name="store_images" multiple> to <input type="file" name="store_images[]" multiple>
And in php, change your code accordingly to example below.
$files = $_FILES['store_images];
foreach ($files as $key => $value) {
if ($files['name']) {
$file = array(
'name' => $files['name'][$key],
'type' => $files['type'][$key],
'tmp_name' => $files['tmp_name'][$key],
'error' => $files['error'][$key],
'size' => $files['size'][$key]
);
wp_handle_upload($file);
}
}
}
This implementation of dropzone.js works on my local host, but when I move it to live the files don't end up on the server:
Here's the form:
<form action="submit.php" enctype="multipart/form-data" method="POST">
<label for="fname">First name: </label>
<input type="text" name="fname" id="fname" required />
<label for="lname">Surname:</label>
<input type="text" name="lname" id="lname" required />
<div class="dropzone" id="file-upload"></div>
<button type="submit" id="submit-all">Submit</button>
</form>
I am using AJAX to submit the form:
$(document).ready(function() {
Dropzone.options.fileUpload = {
url: '/submit.php',
autoProcessQueue: false,
paramName: 'file',
uploadMultiple: true,
parallelUploads: 1,
maxFiles: 1,
maxFilesize: 10,
acceptedFiles: 'image/*,.mp4,.mkv,.avi',
addRemoveLinks: true,
init: function() {
dzClosure = this;
document.getElementById("submit-all").addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
dzClosure.processQueue();
});
this.on("sendingmultiple", function(data, xhr, formData) {
formData.append("fname", jQuery("#fname").val());
formData.append("lname", jQuery("#lname").val());
});
}
}
});
});
submit.php
<?php
require_once "db.php";
$target_dir = "uploads/";
echo '<pre>';
if (move_uploaded_file($_FILES["file"]["tmp_name"][0], $target_dir.$_FILES['file']['name'][0])) {
$status = 1;
echo 'uploaded, ';
}
else {
echo 'not uploaded, ';
}
echo 'Here is some more debugging info:';
print_r($_FILES);
print "</pre>";
$fname = mysqli_real_escape_string($conn, $_POST['fname']);
$lname = mysqli_real_escape_string($conn, $_POST['lname']);
if(mysqli_query($conn, "INSERT INTO CF_form(fname, lname
) VALUES('" . $fname . "', '" . $lname . "')")) {
echo 'sent';
} else {
echo "Error: " . $sql . "" . mysqli_error($conn);
}
mysqli_close($conn);
As I said, this all works on my local host but on the live site the file doesn't appear. I get the 'sent' message and the debugging info is like this:
uploaded, Here is some more debugging info:
Array
(
[file] => Array
(
[name] => Array
(
[0] => IMG_1129.JPG
)
[type] => Array
(
[0] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpriOyPQ
)
[error] => Array
(
[0] => 0
)
[size] => Array
(
[0] => 2181000
)
)
)
sent
The uploads directory is set to 777. Just can't figure out why I'm not getting the files.
I read about this on some posts on the stack, but I still do not see the same case as mine. I can not upload the image on phone device. I do not see why I do not have a console to see error. I'll show you the code, so someone who is experienced can see the error.
Laravel code to upload image:
public function uploadImage($car, $images)
{
$fileName = Carbon::now()->timestamp . $images->getClientOriginalName();
$path = $images->move(public_path('public/images'), $fileName);
if (!$path) {
return response()->json(['message' => 'An error has accured'], 500);
}
$carImage = new CarImages ([
'path' => 'public/images/' . $fileName
]);
$car->images()->save($carImage);
return $carImage;
}
Laravel code for store form with image:
public function store(CarRequest $request)
{
$file = null;
if ($request->has('picture')) {
$file = $request->file('picture');
}
$user = auth()->user();
if ($user) {
$car = Car::create([
'car_type' => $request->input('car_type'),
'mark' => $request->input('mark'),
'model' => $request->input('model'),
'user_id' => $user->id
]);
}
if (!$car) {
return response()->json(['message' => 'Oooops, something went wrong'], 500);
}
if ($file) {
$carImage = $this->uploadImage($car, $file);
}
Mail::to($user->email)->send(new NotifyNewCarUpload($user, $car));
return response()->json([
'message' => 'Your car has been successfully added',
'car' => $car,
'user' => $user
], 201);
}
In CarRequest for upload for car i have:
'car_type' => 'required',
'mark' => 'required',
'model' => 'required',
'picture' => 'required|image'
In Vue.js insert car I have:
<form enctype="multipart/form-data" accept-charset="utf-8"
#submit.prevent="submit">
...
...
<div class="col-3 insert-vehicle-right">
<div :class="{ 'error': errors.has('file') }" v-if="!imgSrc" class="image-upload-holder"></div>
<img :class="{ 'error': errors.has('file') }" v-if="imgSrc" class="uploaded-image" :src="imgSrc" alt="uploaded image"/>
<div class="upload-btn-wrapper">
<button class="btn action-btn">Upload Photo</button>
<input name="file"
v-validate="'required'"
type="file"
#change="onFileChange"/>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<button type="submit" class="btn action-btn save-btn">Save</button>
</div>
</form>
Vue.js javascript code for upload and preview image code:
onFileChange(event) {
this.picture = event.target.files[0];
const file = event.target.files[0];
this.imgSrc = URL.createObjectURL(this.picture);
},
And i have formData code for post that code:
...
...
formdata.append('picture', this.picture);
It's not working on mobile phones. Does anyone recognize the reason?
All my pictures are stored in the laravela folder public/public/images and work good on web browser (destop and laptop device). Also i have table for storing path images.. Only for phone device not work. Help?
Okey problem was be in php.ini configuraction and max_size_upload file. I only set more than 2mb images file and work perfecty.
#thanks Rasa
I have a problem with my form because it cant serialize the image file. So how can I submit a form that contains an image file input in Yii2 using ajax?
(Below you can see the active form and the js code.)
<div class="cars-form">
<?php $form = ActiveForm::begin(['options'=>['id'=>$model->formName(),'enableAjaxValidation'=>true,'enctype'=>'multipart/form-data']]); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?=$form->field($model, 'colour')->widget(ColorInput::classname(), ['options' => ['placeholder' => 'Select Color...'],]); ?>
<?=$form->field($model, 'imageFile')->widget(FileInput::classname(), [
'options' => ['accept' => 'image/*'],'pluginOptions' => [
'previewFileType' => 'image',
'showUpload' => false],]);?>
<?= $form->field($model, 'price')->textInput() ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<< JS
$('form#{$model->formName()}').on('beforeSubmit',function(e)
{var \$form =$(this);
$.post(
\$form.attr("action"),
\$form.serializefiles()
)
.done(function(result)
{
if (result == 1)
{
$(\$form).trigger("reset");
$.pjax.reload({container:'#cars'});
}
else
{
$("#message").html(result);
}
}).fail(function(data)
{console.log("server error: " + data);});
return false;
});
JS;
$this->registerJs($script);?>
(Controller)
public function actionCreate()
{
$model = new Cars();
if ($model->load(Yii::$app->request->post())) {
$imageName= $model->name;
$model->imageFile= UploadedFile::getInstance($model,'imageFile');
$model->imageFile->saveAs('carsimages/'.$imageName.'.'.$model->imageFile->extension);
$model->image='carsImages/'.$imageName.'.'.$model->imageFile->extension;
if($model->save())
//{
//return $this->redirect(['view', 'id' => $model->id]);
//}
{
echo 1;
}
else
{
echo 0;
}
}
else {
return $this->renderAjax('create', [
'model' => $model,
]);
}}
i currently have a wordpress with a custom post type and a custom taxonomy attached to this. ( jobs_category ).
I have the build listing out the categories from this taxonomy like so:
<?php
$taxonomy = 'jobs_category';
$tax_terms = get_terms($taxonomy);
?>
<ul>
<?php
foreach ($tax_terms as $tax_term) {?>
<li id="cat-<?php echo $tax_term->term_id; ?>">
<?php echo $tax_term->name; ?>
</li>
<? } ?>
</ul>
I have then used the following in my functions file:
add_action( 'wp_ajax_nopriv_load-filter', 'prefix_load_cat_posts' );
add_action( 'wp_ajax_load-filter', 'prefix_load_cat_posts' );
function prefix_load_cat_posts () {
$cat_id = $_POST[ 'cat' ];
$args = array (
'cat' => $cat_id,
'posts_per_page' => 10,
'order' => 'DESC'
);
$posts = get_posts( $args );
ob_start ();
foreach ( $posts as $p ) { ?>
<div id="post-<?php echo $post->ID; ?>">
<h1 class="posttitle"><?php the_title(); ?></h1>
<div id="post-content">
<?php the_excerpt(); ?>
</div>
</div>
<?php } wp_reset_postdata();
$response = ob_get_contents();
ob_end_clean();
echo $response;
die(1);
}
To do the AJAX with the following JS:
<script>
function cat_ajax_get(catID) {
jQuery("a.ajax").removeClass("current");
jQuery("a.ajax").addClass("current"); //adds class current to the category menu item being displayed so you can style it with css
jQuery("#loading-animation-2").show();
var ajaxurl = '/wp-admin/admin-ajax.php';
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {"action": "load-filter", cat: catID },
success: function(response) {
jQuery("#category-post-content").html(response);
jQuery("#loading-animation").hide();
return false;
}
});
}
</script>
My question is how do i get it to use the custom taxonomy categories? Im not 100% sure because i've never done it before.
Any help would be great.
Thanks
You have to use tax_query instead of cat. While category is used for native Wordpress taxonomy, so it won't work for custom taxonomies.
Replace your array $args to this:
$args = array (
'tax_query' => array(
array(
'taxonomy' => 'jobs_category',
'field' => 'term_id',
'terms' => array( $cat_id )
)
),
'post_type' => 'jobs', // <== this was missing
'posts_per_page' => 10,
'order' => 'DESC'
);