I'm working on this project base on tutorials around web and YOUTUBE .
My problem is that base on tutorial I've got a from like this:
<form class="form-horizontal">
<div class="form-group">
<label for="mellicode_front_url" class="col-sm-2 control-label">scan</label>
<div class="col-sm-12">
<input type="file" #change="updateMelliCodeFrontScan" name="mellicode_front_url" class="form-input" >
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-12">
<button #click.prevent="saveMelliCodeFrontScan" type="submit" class="btn btn-success">submit scan</button>
</div>
</div>
</form>
as u can see in this code when i opened a IMAGE file i use #change method, then I'll use click.prevent in submit button to upload image into host.
problem is I'm using component from this site :
https://lusaxweb.github.io/vuesax/components/upload.html
which it's using this type of code for uploading :
<vs-upload action="https://jsonplaceholder.typicode.com/posts/" #on-success="successUpload" />
I've changed and removed action with onChange and other things but just because i'm beginner i'm sure i didn't properly. so what i'm trying to do is implement those #change="updateShenasnameScan" & #click.prevent="saveShenasnameScan" into this vs-upload component.
I think that component not supporting the binding or form object to assign the files to it.
But in the backend in Laravel you can get files by $_FILES, this will gives you an object of files that you can use it and store the files simply on the server.
Here is my work on this upload system
Laravel Function
public function store(Request $request)
{
$stored = [];
$files = $_FILES;
foreach ($files['archive']['tmp_name'] as $key => $value) {
$file = file_get_contents($value);
if(Storage::disk('local')->put('archive/'. $files['archive']['name'][$key], $file)){
$stored[$key] = 'archive/'. $files['archive']['name'][$key];
}else{
$stored[$key] = $files['archive']['error'][$key];
}
}
return $stored;
}
And the VUE code, that you can find more about it here https://lusaxweb.github.io/vuesax/components/upload.html#automatic
<vs-upload multiple fileName='archive[]' automatic action="/api/archive" #on-success="successUpload" />
And the $_FILES data as bellow
Related
I'm trying to upload multiple files with it's respective data from vue to laravel. I'm getting the files in vue (on vue console) but when submitting the form and doing dd($request['new_members']); on the laravel controller, it returns the result below:
The other data is available but the file value is gone.
Vue
<div class="row mt-2" v-for="(new_member,index) in new_members" :key="index">
<div class="col-md-4">
<label>NAME</label>
<input class="form-control" type="text" v-model="new_member.name" required/>
</div>
<div class="col-md-4">
<label>POSITION</label>
<input class="form-control" type="text" v-model="new_member.position" required/>
</div>
<div class="col-md-4">
<label>IMAGE</label>
<input type="file" #change="onFileChange(index,$event)" name="file" ref="fileInput" required/>
</div>
</div>
<button class="btn btn-primary col-md-2 col-12 rounded-0 float-right" #click.prevent="addMoreMember()">ADD MORE</button>
<script>
data(){
return{
new_members:[{
name:'',
position:'',
file:''
}]
}
},
methods:{
addMoreMember(){
this.new_members.push({name:'',position:'',file:''})
},
onFileChange(index,$event) {
this.new_members[index].file = $event.target.files[0]
},
submit(){
let form = new FormData()
form.append('new_members',JSON.stringify(this.new_members));
form.append('content_team', this.content_team);
axios.post('/api/mainpage/addNewMember',form).then(res=>{
})
},
}
</script>
For multiple file uploading concepts,
You need to create an API service for upload files only and returning that response return string for accessing uploaded file path,
For every file uploading, You need to call this API services that you created.
And the final page submission you just send the file path string where you got from the file uploading API services
I hope you are getting my points ❤
The code is working just fine on my local machine, but when I upload it to the server it doesn't work.
This is my back end code:
public function changeCodePost(Request $request)
{
$s = Setting::all()->first();
$s->update([
'code' => $request->scriptCode
]);
alert()->success('تم الحفظ');
return redirect()->back();
}
And here is the form:
<form method="post" action="{{route('code.post')}}">
#csrf
<div class="form-group">
<input type="text" name="scriptCode" class="form-control" value="{{$code}}">
</div>
#error('scriptCode')
{{$message}}
#enderror
<button class="btn btn-primary">حفظ</button>
</form>
Please help, could it be the server I'm uploading on?
I want to save a value such as:
but only when I enter a value like <script></script> it doesn't work.
I have a form with multiple fields but also a file upload. I am able to upload multiple files.
I also know that it is possible to upload files with AJAX.
So I would like to upload my files using ajax while i'm filling in every other field. But how would I link the already uploaded images then? And also prevent the images to be uploaded again?
This is the form:
<form id="form_validation" method="POST" action="{{route('storeexpense')}}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group form-float">
<div class="form-line">
<input type="text" class="form-control" name="description" required>
<label class="form-label">Omschrijving</label>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="number" class="form-control" name="amount" required>
<label class="form-label">Bedrag</label>
</div>
</div>
<div class="form-group form-float">
#foreach ($types as $type)
#if ($type->id === 1)
<input name="transactiontype" type="radio" id="rdio{{$type->id}}" value="{{$type->id}}" checked />
<label for="rdio{{$type->id}}">{{$type->description}}</label>
#else
<input name="transactiontype" type="radio" id="rdio{{$type->id}}" value="{{$type->id}}" />
<label for="rdio{{$type->id}}">{{$type->description}}</label>
#endif
#endforeach
</div>
<div class="form-group form-float">
<div class="form-line">
<input type="text" class="datepicker form-control" name="date" placeholder="Please choose a date..." required>
<!-- <label class="form-label">Datum</label> -->
</div>
</div>
<div class="form-group demo-tagsinput-area">
<div class="form-line">
<input type="text" class="form-control" id="tagsinput" data-role="tagsinput" placeholder="Labels" name="tags" required>
</div>
</div>
<div class="form-group form-float">
<div class="form-line">
#if (count($errors) > 0)
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
<input type="file" name="attachments[]" multiple class="custom-file-control"/>
</div>
</div>
<button class="btn btn-primary waves-effect" type="submit">SAVE</button>
</form>
This is the PHP code that saves the information from the form:
public function store(UploadRequest $request)
{
// Save new transaction in database
$transaction = new Transaction;
$transaction->description = $request->description;
$transaction->amount = $request->amount;
$input = $request->date;
$format = 'd/m/Y';
$date = Carbon::createFromFormat($format, $input);
$transaction->date = $date;
$transaction->transactiontype_id = $request->transactiontype;
$transaction->user_id = Auth::id();
$transaction->save();
// Put tags in array
$inputtags = explode(",", $request->tags);
// Loop through every tag exists
// EXISTS: get ID
// NOT EXISTS: Create and get ID
foreach ($inputtags as $inputtag)
{
$tag = Tag::firstOrCreate(['description' => $inputtag]);
$transaction->tags()->attach($tag->id); //Put the 2 ID's in intermediate table ('tag_transaction')
}
//Check if there are files
if (!is_null($request->attachments))
{
//Loop through every file and upload it
foreach ($request->attachments as $attachment) {
$filename = $attachment->store('attachments');
// Store the filename in the database with link to the transaction
Attachment::create([
'transaction_id' => $transaction->id,
'path' => $filename
]);
}
}
Thanks,
Bart
It sounds like you want to make a fancy form that starts uploading the file as soon as you choose it and meanwhile the user can continue filling the rest of the form. If so, I'd do it like this:
Implement your main text/data form, eg.
<form method="POST" action="/save-data-endpoint.php">
<input name="email" type="text" />
<button type="submit>Submit</button>
</form>
Next to it, a form for the images. eg.
<form method="POST" class="file-upload-form" action="/save-file.php">
<input name="my-file" type="file" />
<!-- note that we wont show a submit button -->
</form>
For the user, it all looks like the same form but clicking the submit button will send only the data to the save-data-endpoint.php. Now we need some js to control this madness (I'll use jQuery for brevity). But you can use FileReader api in js, ajax progress tracking to make it even fancier. See https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications for more.
$(function(){ // run when document is ready
// listen when the input changes (when a file is selected)
$('.file-upload-form').on('change', function(e){
// file has been selected, submit it via ajax
// show some kind of uploading indication, eg. a spinner
$.ajax({
type:'POST',
url: $(this).attr('action'),
data: new FormData(this),
cache:false,
contentType: false,
processData: false,
success:function(data){
// the save-file.php endpoint returns an id and/or a url to the saved/resized/sanitized image
console.log(data.id, data.url);
// we then inject this id/url, into the main data form
var $hiddenInput = $('<input type="hidden" name="uploads[]" value="'+data.id+'">');
$('.main-form').append($hiddenInput);
// show a thumbnail maybe?
var $thumbnail = $('<img src="'+data.url+'" width="20" height="20" />');
$('.main-form').append($thumbnail);
// hide spinner
// reactivate file upload form to choose another file
$('.file-upload-form').find('input').val('');
},
error: function(){
console.log("error");
}
});
});
});
Your backend will get the images as they are selected, one by one. You then save them and return an id and/or a url to the image to be used in the success handler in js. After adding some images your main form should look something like this:
<form method="POST" action="/save-data-endpoint.php">
<input name="email" type="text" />
<button type="submit>Submit</button>
<input type="hidden" name="uploads[]" value="x">
<img src="...x.jpg" width="20" height="20" />
<input type="hidden" name="uploads[]" value="y">
<img src="...y.jpg" width="20" height="20" />
</form>
Now when the user fills the remaining fields and clicks submit, your server will get all the data along with an array called uploads which contains all the image ids/paths you have already saved. You can now store this data and relate it to the files.
I wont go deeper on the backend side as it can be implemented on any language. In summary the basic flow would be:
send files one at a time to a save file endpoint that returns a file identifier (can be an id, hash, full path to image, etc)
js injects those ids into the main form
the main form is submitted to a save data endpoint that returns a success or error message and stores + relates all the data in your preferred method of storage.
Hope it helps!
I'm still new to how Web API 2.0 works but I'm starting to get the hang of things. The one issue I've been having though is how to post a form along with multiple files that the user uploaded to my controller.
I guess I mainly need help with how to use JavaScript or jquery with ajax to post all of the correct values.
Here is a snippit of my HTML:
<form id="CreateAnnouncementForm" class="form-horizontal">
<input type="hidden" name="announcementTypeID"/>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="col-sm-2 control-label">Headline</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="headline" />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">More Info</label>
<div class="col-sm-10">
<textarea class="form-control" name="moreInfo"></textarea>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Attachments</label>
<div class="col-sm-10">
<input type="file" name="Attachments" multiple/>
</div>
</div>
</div>
</div>
</div>
</form>
Here is the JavaScript/jQuery/Ajax that I normally use to post my form to the controller:
onAnnouncementCreate: function () {
var form = $("#CreateAnnouncementForm");
var validator = $(form).kendoValidator().data("kendoValidator");
if (validator.validate()) {
var options = {
url: getApiUrl() + "/Announcement",
dataType: "json",
type: "POST",
headers: {
"Authorization": "Bearer " + getJwtToken(),
"LocationId": getCurrentLocation()
},
data: $(form).serialize(),
statusCode: {
200: function () {
$("#AnnouncementCreateModal").modal("hide");
announcementViewModel.reloadGrids();
},
400: function (response) {
toastr.options = { "positionClass": "toast-bottom-full-width";
toastr.error(response.responseText);
}
}
};
$.ajax(options);
}
}
Now I believe it would be best if I just created a ViewModel that contained both the ViewModel for all of the values in my form and have it contain an IEnumerable for the attachments that the users can upload within the form.
The trouble I'm having though is correctly adding the attachments to the form so that they map correctly.
My ViewModel will look like this:
public class AnnouncementCreateViewModel
{
public AnnouncementViewModel Announcement { get; set; }
public IEnumerable<HttpPostedFileBase> Attachments { get; set; }
}
Of course I would then need to change the names in my form to reflect the new model.
If anyone can help me on how to post them to my controller that would be much appreciated as that's the only thing I'm still struggling with.
Since this turned out to be more difficult than I thought it would be. I decided to go an alternative route.
Since I'm already using the Kendo UI framework, I am now using the Kendo Upload widget to handle the uploading of my files. I have it asynchronously upload the files to my Web API controller and then I have a separate action to handle the form when it's submitted.
Of course I'm welcome to other answers as well that might be able to solve this issue by posting all of the data in one call but for now, this will do.
I am creating an application based on Yii framework, now I'm trying to setup the login for it, as I have shown in the picture below. The Yii folder is within my web application directory. In the login of web application when I call
Login_yii/index.php?r=site/login
as the action of my login form (one of the scripts I have circled) it redirects to the index.php of the yii folder instead of redirecting to my index.php(which i have circled in the picture). Can anybody help me on this? I even tried modifying the site controller
if($model->validate() && $model->login())
$this->redirect(array("/<controller>/<action>"));
but it didn't work but not sure whether I gave the correct path to it, and not sure what shall I put for the controller to get my own index
File structure:
login.php:
<div class="col-xs-12 col-sm-12 col-md-5 col-lg-4">
<div class="well no-padding">
<form action="Login_yii/index.php?r=site/login" id="login-form" class="smart-form client-form">
<header>
Sign In
</header>
<fieldset>
<section>
<label class="label">Username</label>
<label class="input"> <i class="icon-append fa fa-user"></i>
<input type="text" name="LoginForm[username]" id="username">
<b class="tooltip tooltip-top-right"><i class="fa fa-user txt-color-teal"></i> Please enter the username</b></label>
</section>
<section>
<label class="label">Password</label>
<label class="input"> <i class="icon-append fa fa-lock"></i>
<input type="password" name="LoginForm[password]" id="password">
<b class="tooltip tooltip-top-right"><i class="fa fa-lock txt-color-teal"></i> Enter your password</b> </label>
<div class="note">
Forgot password?
</div>
</section>
<section>
<label class="checkbox">
<input type="checkbox" name="remember" checked="">
<i></i>Stay signed in</label>
</section>
</fieldset>
<footer>
<button type="submit" class="btn btn-primary" su>
Sign in
</button>
</footer>
</form>
Controller:
<?php
class SiteController extends Controller
{
public function actions()
{
return array(
// captcha action renders the CAPTCHA image displayed on the contact page
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
// page action renders "static" pages stored under 'protected/views/site/pages'
// They can be accessed via: index.php?r=site/page&view=FileName
'page'=>array(
'class'=>'CViewAction',
),
);
}
public function actionIndex()
{
// renders the view file 'protected/views/site/index.php'
// using the default layout 'protected/views/layouts/main.php'
$this->render('index');
}
public function actionError()
{
if($error=Yii::app()->errorHandler->error)
{
if(Yii::app()->request->isAjaxRequest)
echo $error['message'];
else
$this->render('error', $error);
}
}
public function actionContact()
{
$model=new ContactForm;
if(isset($_POST['ContactForm']))
{
$model->attributes=$_POST['ContactForm'];
if($model->validate())
{
$name='=?UTF-8?B?'.base64_encode($model->name).'?=';
$subject='=?UTF-8?B?'.base64_encode($model->subject).'?=';
$headers="From: $name <{$model->email}>\r\n".
"Reply-To: {$model->email}\r\n".
"MIME-Version: 1.0\r\n".
"Content-Type: text/plain; charset=UTF-8";
mail(Yii::app()->params['adminEmail'],$subject,$model->body,$headers);
Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
$this->refresh();
}
}
$this->render('contact',array('model'=>$model));
}
public function actionLogin()
{
$form=new LoginForm;
// collect user input data
if(isset($_POST['LoginForm']))
{
$form->attributes=$_POST['LoginForm'];
// validate user input and redirect to previous page if valid
if($form->validate() && $form->login()) $this->redirect(Yii::app()->user->returnUrl);
}
// display the login form
$this->render('login',array('form'=>$form));
/*$model=new LoginForm;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
//$this->redirect(Yii::app()->user->returnUrl);
$this->redirect(array("/<controller>/<action>"));
}
// display the login form
$this->render('login',array('model'=>$model));*/
}
public function actionLogout()
{
Yii::app()->user->logout();
$this->redirect(Yii::app()->homeUrl);
}
}
Try using the base url:
$this->redirect( Yii::app()->getBaseUrl(true) . '/site/index' );
getBaseUrl returns the relative/absolute URL for the application. From there, you have to specify which path you want to run.
If you want to call files in a parent directory, you will have to use '..':
$this->redirect( Yii::app()->getBaseUrl(true) . '/../site/index' );
Try like this -
if (isset($_POST['LoginForm'])){
$model->attributes = $_POST['LoginForm'];
if ($model->validate(array('username', 'password')) && $model->login()) //if authentication successfull
$this->redirect(array('site/dashboard'));
}