Laravel and dropzone using div and another form inputs - laravel-5

I want to use dropzone to upload multiple images with another form inputs
so i want a div that show the images when the user click,
also i have a button that trigger the form.
i have this but its not working
html:
<div class="col-md-12">
<h1>Upload Multiple Images using dropzone.js and Laravel</h1>
{!! Form::open([ 'route' => [ 'dropzone.store' ], 'files' => true, 'enctype' => 'multipart/form-data', 'class' => '', 'id' => '' ]) !!}
{!! Form::text('name'); !!}
<div class="dropzone" id="image-upload">
<h3>Upload Multiple Image By Click On Box</h3>
<button type="submit" class="btn btn-success" id="submit-all">
Enviar files
</button>
</div>
{!! Form::close() !!}
</div>
dropzone:
Dropzone.autoDiscover = false;
var imageUpload = new Dropzone("div#image-upload", {
url: "dropzone/store",
autoProcessQueue:false,
uploadMultiple: true,
maxFilesize:5,
maxFiles:3,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
init: function() {
var submitButton = document.querySelector("#submit-all")
//imageUpload = this; // closure
submitButton.addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
imageUpload.processQueue(); // Tell Dropzone to process all queued files.
});
// You might want to show the submit button only when
// files are dropped here:
this.on("addedfile", function() {
// Show submit button here and/or inform user to click it.
});
}
}
this gave me this error:
http://127.0.0.1/project/public/dropzone/store 419 (unknown status)
myController:
public function dropzone()
{
return view('dropzone-view');
}
/**
* Image Upload Code
*
* #return void
*/
public function dropzoneStore(Request $request)
{
$dir = public_path().'/upload/';
$files = $request->file('file');
foreach($files as $file){
$fileName = $file->getClientOriginalName();
$file->move($dir, $fileName);
}
}
routes: web.php
Route::get('dropzone', 'HomeController#dropzone');
Route::post('dropzone/store', ['as'=>'dropzone.store','uses'=>'HomeController#dropzoneStore']);

Laravel returns a 419 response when there is a token mismatch problem. The code you've shown POSTs files to your server, but does not pass a _token with the request. The web middleware, which is applied by default, will do token verification, and since there is no token, that will fail and throw a 419.
You can probably see this yourself if you look in your browser's devtools, click the network tab, click the POST request where the file is uploaded, and click the Preview or Response tabs.
So you need to pass a _token along with the request. There are many ways to do that, but the simplest is probably what is described in the docs:
Add the token to your <head>
<meta name="csrf-token" content="{{ csrf_token() }}">
Automatically pass it with every AJAX request:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

Related

How to automatically update data in laravel view?

I have a view which will show the list important tasks from database. I have a function in controller which returns the collection of data to the view.
My controller function is
public function list()
{
$tasks= Task::where('category','1')->get();
//category is 1 when the task is important
return view('important', compact('tasks'));
}
My view is like
<ul>
#foreach ($tasks as $task)
<li> {{$task->body}}</li>
#endforeach
</ul>
What I want to essentially do is to call the list function whenever a new important task is added into the database. How can I do that?
in your web.php
Route::get('/tasks','TasksController#list')->name('get_tasks');
inside your controller :
use Illuminate\Http\Request;
public function list(Request $request)
{
$tasks= Task::where('category','1')->get();
if($request->ajax()){
return response()->json(array('tasks'=>$tasks));
}
return view('important', compact('tasks'));
}
inside your blade view :
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
$(document).ready(function(){
setInterval(function(){
$.ajax({
url:'/tasks',
type:'GET',
dataType:'json',
success:function(response){
if(response.tasks.length>0){
var tasks ='';
for(var i=0;i<response.tasks.length;i++){
tasks=tasks+'<li>'+response.tasks[i]['body']+'</li>';
}
$('#tasklist').empty();
$('#tasklist').append(tasks);
}
},error:function(err){
}
})
}, 5000);
});
</script>
<ul id="tasklist">
#foreach ($tasks as $task)
<li> {{$task->body}}</li>
#endforeach
</ul>
To achieve this kind of setup you may use Pusher or any other similar provider, once you signup on pusher you can send 200k notifications per day for free, you can check the limits after login to pusher. Before we proceed please install pusher's official php package
composer require pusher/pusher-php-server
From your pusher dashboard obtain app_id, key, secret and cluster now in your controller/model where you are inserting the data in database add the following code
//You will get cluster name from pusher.com replace it below
$options = ['cluster' => 'mt1', 'encrypted' => true];
//Replace your key, app_id and secret in the following lines
$pusher = new Pusher(
'key',
'secret',
'app_id',
$options
);
//this could be a single line of message or a json encoded array, in your case you want to pass some data to display in table I assume you have an array
$message= json_encode(['name' => 'John doe', 'age' => 42, 'etc' => 'etc']);
//Send a message to users channel with an event name of users-list. Please mind this channel name and event name could be anything but it should match that with your view
$pusher->trigger('users', 'users-list', $message);
Now in your view before the </body> tag paste the following code
<!-- Incldue Pusher Js -->
<script src="https://js.pusher.com/4.2/pusher.min.js"></script>
<script>
//Remember to replace key and cluster with the credentials that you have got from pusher.
var pusher = new Pusher('key', {
cluster: 'mt1',
encrypted: true
});
//In case you have decided to use a different channel and event name in your controller then change it here to match with the one that you have used
var channel = pusher.subscribe('users');
channel.bind('users-list', function(message) {
//if you will console.log(message) at this point you will see the data
//that was sent from your controller is available here please consume as you may like
alert(message);
});
</script>

Call AJAX with Vue.js and Vue resource in Laravel

I'm making AJAX request in Laravel with Vue.js and Vue resource.
I have view:
{{Form::open(['method' => 'post', 'class' => 'form-inline', 'id' => 'main-form'])}}
{{Form::text('param1', null, ['id' => 'param1', 'class' => 'form-control'])}}
{{Form::text('param2', null, ['id' => 'param2', 'class' => 'form-control'])}}
<input #click="sendIt($event)" type="submit" value="Check prices" class="btn btn-success btn-theme" />
{{Form::close()}}
I have js:
var Vue = require('vue');
var VueResource = require('vue-resource');
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
const app = new Vue({
el: '#app',
methods: {
sendIt: function (e)
{
e.preventDefault();
var token = $('[name="_token"]').val();
this.$http.post('/data').then((response) => {
console.log(response);
}, (response) => {
console.log(response);
});
}
}
Route:
Route::post('/data', 'MainController#data');
And controller:
public function data()
{
$msg = $this->test(); //method that retrieves data from db
return response()->json(['msg'=> $msg], 200);
}
It gives me post 500 internal server error
In response I have this headers:
Cache-Control
Content-Type
Date
Phpdebugbar-Id
Server
Status
Transfer-Encoding
X-Powered-By
In network in my data site I have response headers without token, request headers with token and I have token in Request Payload.
If I change method to get I have same error but if I change method to get and if I remove from my controller part of code where I retrieve data from db and just pass string to json (example:
$msg = 'test';
return response()->json(['msg'=> $msg], 200);
I have success and I can output test on page.
So I'm not sure if it's some problem with token or something else.
I tried and this:
var token = $('[name="_token"]').val();
this.$http.post('/prices', {_token:token})
but nothing. Same error again.
If I add this:
http: {
headers: {
X-CSRF-TOKEN: document.querySelector('#token').getAttribute('content')
}
},
I have syntax error on page load.
If I change to this:
http: {
headers: {
Authorization: document.querySelector('#token').getAttribute('content')
}
}
I got internal server error again.
And this is my token in main view:
<meta name="csrf-token" id="token" content="{{ csrf_token() }}">
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
EDIT:
This part works if I add quotes around x-csrf-token but still I have token mismatch error.
http: {
headers: {
'X-CSRF-TOKEN': document.querySelector('#token').getAttribute('content')
}
},
I could be mistaken but in your example at the top you have:
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
However, in your main view file you have:
<meta name="csrf-token" id="token" content="{{ csrf_token() }}">
You should be able to simply change $('meta[name=_token]') to $('meta[name=csrf-token]') (so they match).
Furthermore, the reason you had a syntax error with X-CSRF-TOKEN: ... is because you can't use hyphens in key names unless you wrap them in quotes i.e. 'X-CSRF-TOKEN': ....
Hope this helps!

Silverstripe 3.4 load content via ajax / Shortcode issue

Shortcodes dont render correctly.
I am loading content via ajax into bootstrap-tabs.
calling ajax works.
routes are ok.
I've tried renderWith(), customise() ....
No matter what i try, the shortcodes don't render. Please help.
class EventPage_Controller extends Page_Controller {
public function EventDetail(SS_HTTPRequest $request){
if($request){
$group = DataObject::get_one('Group', "\"Code\" = 'eventgroup'");
$member = Member::currentUser();
if($member && $member->inGroup($group->ID)){
if($event = DataObject::get_by_id('Event', intval($request->param('eventID')))){
$eventDetail = array(
'EventTitle' => $event->Name,
'EventContent' => $event->Content
);
/* if( Director::is_ajax() ) {
return $this->renderWith('EventDetail', json_encode(array('EventContent' => $event->Content)));
}*/
//return $this->customise($eventDetail)->renderWith(array('EventDetail', 'Page'));
//echo $event->Content;
echo json_encode(array('error' => '0', 'EventContent' => $event->Content));
}
}
}
}
javascript:
$('#event-detail').hide();
$('.event-detail-btn').on('click', function(e){
//alert('click');
e.stopPropagation();
e.preventDefault();
if($(this).parent().is('tr')){
//alert('TR');
var eventID = $(this).parent().attr('id').split('_')[1];
var dateID = $(this).parent().attr('id').split('_')[2];
//alert(eventID + '_' + dateID);
getEventDetail(eventID, dateID);
}
$('#event-detail, #member-enrolment').toggle();
});
function getEventDetail(eventID, dateID){
//$('#eventDetail').load('Enrolment/EventDetail/'+ eventID + '/' +dateID);
$.ajax({
type: "POST",
url: 'Enrolment/EventDetail/'+ eventID + '/' +dateID,
dataType: "json"
}).success(function(msg){
$('#eventDetail').html(msg.EventContent);
});
}
Page.ss
<div id="enrolments" class="tab-pane fade">
<% include EventDetail %>
<% include MemberEnrolments %>
</div> <!--end enrolments-->
EventDetail.ss
<div id="event-detail">
<br><br>
<button type="button" class="event-detail-btn btn btn-default btn-sm">zurück</button>
<br><br>
<div id="eventDetail"></div>
<button type="button" class="event-detail-btn btn btn-default btn-sm">zurück</button>
</div>
Shortcodes are not automatically rendered when you're not calling them from a template, try:
$eventDetail = array(
'EventTitle' => $event->Name,
'EventContent' => $event->Content->forTemplate() //this is a HTMLText
);
or on SS3.4:
$eventDetail = array(
'EventTitle' => $event->Name,
'EventContent' => $event->Content->RAW() //this is a HTMLText
);
If this still doesn't work you might do it the hard way and call ShortcodeParser manually:
ShortcodeParser::get_active()->parse($event->Content);
Also, you might use Director::is_ajax() to check if it's really an ajax call and output the ajax response or - as a fallback - the whole page including ajax content. See lessons or docs

Getting Ajax to display your search result from a class

I'm working with a recipe API and at the moment you get an error because I'm calling for something that doesn't exist ($contentSearch for example) and I think I can solve this with using Ajax, and no matter what I want to use it to learn how it works.
I'm using fork2fork API and working in Laravel 5.
So far I've looked around but haven't found anything that works. Maybe because I'm calling for a function and from there getting the result?
Feel free to mess up my entire code, I want to learn how to make it right instead of making it just work!
And to make my question clear: How do I show my result from the search by using Ajax?
Here is the html:
#extends('app')
#section('content')
{!! Form::open(['url' => 'searchRecipe']) !!}
{!! Form::text('search') !!}
{!! Form::submit('Search recipe') !!}
{!! Form::close() !!}
<p>if you lucky and have more than one thing in your fridge, separate them with a ',' and nothing else. As in no space.</p>
<div class="text-info">
<ul class="list-unstyled">
#foreach($contentSearch->recipes as $recipe)
<li>{{$recipe->title}}</li>
#endforeach
</ul>
</div>
#stop
And here is the function that is getting called if you push the submit button:
public function getSearch() {
$apiKey = "thats a secret i never tell";
$search = Request::get('search');
// insert search and API key in URL
$apiUrl = "http://food2fork.com/api/search?key=" . $apiKey
. "&q=". $search ;
// get the content of the file
//header('Content-Type: application/json');
$contentSearch = json_decode(file_get_contents($apiUrl));
return view('index', compact('contentSearch'));
}
I'm not sure I've fully understood the question but I hope this helps.
View
{!! Form::open(['url' => 'recipes']) !!}
{!! Form::text('search', null, ['id' => 'search']) !!}
{!! Form::submit('Search recipe') !!}
{!! Form::close() !!}
<ul id="result"></ul>
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<script>
$(document).ready(function(){
// get the form submit event
$('form').submit(function(event){
// stop the form from submitting
event.preventDefault();
// the form object
var form = $(this);
// perform ajax post request
$.post(
form.attr('action'), // this will go to form url
form.serialize(), // grab the form data
function(data) { // do something with the response
console.log(data); // see response in the console
// add title of recipes in a list
$.each(data.recipes, function(key, value) {
$('#result').append($('<li></li>').text(value.title));
});
}
);
});
});
</script>
routes.php just for demo you can move this to your controller
Route::post('recipes', function() {
$apiKey = "yourAPIkey";
$search = \Request::get('search');
// insert search and API key in URL
$apiUrl = "http://food2fork.com/api/search?key=" . $apiKey . "&q=". $search ;
// get the content of the file
//header('Content-Type: application/json');
$contentSearch = json_decode(file_get_contents($apiUrl));
return response()->json($contentSearch);
});
I'm guessing as an alternative you could use JSONP, but I'm new to JSONP and struggled to get it working with food2fork's api. Perhaps research JSONP and see if it's what you want. Example of JSONP with JQuery: https://learn.jquery.com/ajax/working-with-jsonp/

Is updating codeigniter db-session data clientside via ajax possible?

I'm using codeigniter with encrypted sessions in the database and I'm using a twitter bootstrap modal to update some user details in a form.
I use jquery validation on the form and in the submitHandler I post the data via ajax and close the modal.
submitHandler: function (form) {
document.getElementById("edit-profile-submit-button").disabled = true;
$('.modal-ajax-loader').show();
$.ajax({
type: $(form).attr('method'), // 'Post'
url: $(form).attr('action'), // 'profile/edit_basic_details'
data: $(form).serialize(),
success: function(data, status){
$(form).html(data);
$('.modal-ajax-loader').hide();
setTimeout(function() { $('#edit-profile-details').modal('hide'); }, 2000);
},
error: function(data, status) {
$(form).html(data);
}
});
return false;
}
and here is the model function called from the controller with the same name,
function edit_basic_profile() {
$screenname = $this->security->xss_clean($this->input->post('screenname'));
$firstname = $this->security->xss_clean($this->input->post('firstname'));
$lastname = $this->security->xss_clean($this->input->post('lastname'));
$email = $this->security->xss_clean($this->input->post('email'));
$bio = $this->security->xss_clean($this->input->post('bio'));
$data = array(
'screen_name' => $screenname,
'first_name' => $firstname,
'last_name' => $lastname,
'email' => $email,
'bio' => $bio,
);
try{
// Run the update query
$this->db->where('profile_id', $this->session->userdata('profile_id'));
$this->db->update('profiles', $data);
// Let's check if there are any results
if($this->db->affected_rows() == 1)
{
// Setup the session information for the user
$this->session->set_userdata($data);
return true;
}
// If the previous process did not update rows then return false.
error_log("profile_model, edit_basic_profile(): There were no affected rows");
return false;
} catch(PDOExceprion $e) {
error_log("profile_model, edit_basic_profile(): ".$e);
return false;
}
}
I can update the values that changed on the page in the submitHandler also and of course the session on the server is updated in the model.
$("#profile-screenname").html($(screenname).val());
$("#profile-bio").html($(bio).val());
The problem is when I open the modal again it grabs the user details from the session data in the browser cookie and grabs the original data unless the page has been refreshed after the first update.
(form data is loaded like this);
<input type="text" class="input-large" id="firstname" name="firstname" placeholder="First Name" value="<?php echo $this->session->userdata('first_name'); ?>">
"<?php echo $this->session->userdata('first_name'); ?>" on the second time i open the modal before any page refresh loads the old data.
Sure, you just need to call an ajax url which updates/sets new session data:
HTML+JS
---> Ajax call
----> $this->session->set_userdata('key','new-value');
----> session and db updated.
Done.
Also notice and change all these:
$screenname = $this->security->xss_clean($this->input->post('screenname'));
to this:
$screenname = $this->input->post('screenname',true);
which is exactly the same result

Resources