I am using this laravel package called yajra datables to create a data table for my app. But I am getting this error whenever I reload the page. After a few reloads the table gets loaded. However, page keeps throwing me ajax errors every time I use the search option.
I have searched the internet for every possible solution, but none of them seemed to work.
Below is my code:
Index.blade
<script>
$(document).ready(function(){
$('#jobsTable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('activity.index') }}",
dom: "B" + /* Buttons */
"<'row'<'col-sm-12 col-md-6'l>" + /* Length changing input control */
"<'col-sm-12 col-md-6'f>>" + /* Filtering Input */
"<'row'<'col-sm-12'tr>>" + /* The Table! + Processing Display Element*/
"<'row'<'col-sm-12 col-md-5'i>" + /* Table Information Summary */
"<'col-sm-12 col-md-7'p>>" , /* Pagination Control*/
columns:[
/* 1 */ {data: 'id' , name: 'id', visible: false },
/* 0 */ {data: 'action', name: 'action', orderable: false, searchable: false },
/* 1 */ {data: 'job_id' , name: 'job_id' },
/* 2 */ {data: 'type' , name: 'type' },
/* 3 */ {data: 'job_no' , name: 'job_no' },
/* 4 */ {data: 'deal_no' , name: 'deal_no' },
/* 5 */ {data: 'cyc_no' , name: 'cyc_no' },
/* 6 */ {data: 'deal_name' , name: 'deal_name' },
Controller
public function index()
{
if (request()->ajax()) {
$jobs = Job::all();
return DataTables::of($jobs)
->addColumn('action', function ($jobs) {
$button = '<div class="btn-group btn-group-xs">';
$button .= '<i class="fa fa-edit fa-fw"></i> Edit';
$button .= '<button type="button" name="deleteButton" id="' . $jobs->id . '" data-jobcycid="' . $jobs->job_no . ' | ' . $jobs->cyc_no . '" class="btn btn-danger btn-xs deleteButton"><i class="fas fa-trash-alt"></i> Delete</button>';
$button .= '</div>';
return $button;
})
->rawColumns(['action'])
->setRowID(function ($jobs) {
return $jobs->id;
})
->make(true);
}
return view('activity.index');
}
Routes
Route::group(['middleware' => ['auth.roles']], function () {
/*Side bar menu Routes*/
Route::get('/home', 'HomeController#index')->name('home');
Route::get('/dashboard', 'HomeController#dashb')->name('dashboard');
Route::get('/profile', 'HomeController#profile')->name('profile');
/*Activity Routes*/
Route::resource('/activity', 'JobController');
// Route::get('/activity', 'JobController#getIndex')->name('activity.index');
/*Activity Sub Routes*/
Route::get('/jobEditCancel', 'JobController#jobEditCancel')->name('jobEditCancel');
Route::get('/jobAddCancel', 'JobController#jobAddCancel')->name('jobAddCancel');
// Route::get('/activity', 'JobController#index')->name('activity.index');
// Route::delete('/activity/destroy/{id}', 'JobController#destroy')->name('activity.destroy');
/*FPBlog Routes*/
Route::resource('fpblog', 'PostController');
Route::get('/postEditCancel', 'PostController#postEditCancel')->name('postEditCancel');
Route::get('/blogManager', 'PostController#blogManager')->name('blogManager');
});
You are using url: "{{ route('activity.index') }}" yet in your route file you commented the alias.
You can put alias for resource routes like this
/*Activity Routes*/
Route::resource('activity', 'JobController', [
'names' => [
'index' => 'activity.index',
'create' => 'activity.create',
'store' => 'activity.store',
'show' => 'activity.show',
'edit' => 'activity.edit',
'update' => 'activity.update',
'destroy' => 'activity.destoy'
],
]);
and this should work for your case in using the alias activity.index in the blade.
For why you're better off without resource ? it's mostly a point of view.
When you declare each route yourself, you have more control on the routes:
middleware per route possible
clear which route is valid without having to check the controller
name the methods/routes as you want
...etc
Thank you each and every one of you who have tried your best to support me to solve this problem. However, after so many searches for the answer, I have figured it it out.
Apparently my URI is far too long. I was able to understand this after moving my development environment to laravel Homestead.
I have followed the steps on this blog to shorten the url. And it solved all the issues:
DataTables and Long URL
Once again thank you very much for anyone who has provided their opinion. I hope this post will be useful to someone who is trying to create data tables which have high column counts.
Related
I have a form in my application that allows users to create posts and while doing so upload multiple images to the post being created.
I am using Laravel Livewire and Filepond to achieve this.
The problem I am having is I need to allow the user to reorder the images (as it is a gallery and the order is important), and save the order in the database when the form in submitted.
Another issue I am running into is allowing a user to edit their post later. I need their pre-existing post images loaded in filepond, and also allow them to upload more, delete, and/or reorder.
When the user saves the post I need to be able to update my database and file system.
All info online is how to upload files, but no info on how to reorder, or pre-populate with pre-existing files.
Here is my current code for reference:
<div
x-data=""
x-init="
FilePond.setOptions({
allowMultiple: true,
allowReorder: true,
itemInsertLocation: 'after',
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
#this.upload('images', file, load, error, progress)
},
revert: (filename, load) => {
#this.removeUpload('images', filename, load)
},
load: (source, load, error, progress, abort, headers) => {
var myRequest = new Request(source);
fetch(myRequest).then(function(response) {
response.blob().then(function(myBlob) {
load(myBlob)
});
});
},
},
});
const pond = FilePond.create($refs.input, {
acceptedFileTypes: ['image/png', 'image/jpeg'],
maxFileSize: '7MB',
allowImageCrop: true,
allowReorder: true,
allowImageResize: true,
imageResizeTargetWidth: '1000px',
imageResizeTargetHeight: '1000px',
filePosterMaxHeight: '256px',
files: {{ $existingImages }} // used for when editing a post and it already has images. see php component on how I set this variable
});
"
>
<div wire:ignore wire:key="images">
<div class="form-group text-center">
<input
id="image-upload"
type="file"
x-ref="input"
multiple
data-allow-reorder="true"
data-max-file-size="3MB"
data-max-files="10"
>
</div>
</div>
</div>
My Livewire PHP component:
public $images = [];
public $existingImages;
public function mountMedia($post) {
if($post){
$this->existingImages = $post->images->map(function ($image) use ($post) {
return [
'source' => $image->id,
'options' => [
'type' => 'local',
'file' => [
'name' => $image->getUrl(),
'size' => $image->file_size,
'type' => $image->mime_type,
],
'metadata' => [
'poster' => $image->getUrl(),
'position' => $image->position
],
],
];
});
}
}
public function saveImage($file, $post, $position) {
// Create a unique random string
$randString = Str::random(3);
// Get time
$time = time();
// Set file name
$filename = $time. '-' . $randString.'-'.auth()->user()->id;
$extension = '.'.$file->getClientOriginalExtension();
// Save images for gallery
$regImage = $file->storeAs('/'. $post->id, $filename.$extension, 'post_images');
// Create a new image in db
Image::create([
'user_id' => auth()->user()->id,
'post_id' => $post->id,
'position' => $position,
'filename' => $filename,
'extension' => $extension,
'src' => 'post_images',
'mime_type' => $file->getMimeType(),
'file_size' => $file->getSize(),
]);
}
public function saveMedia($post) {
// Make sure user owns post
abort_unless($post->user_id == auth()->user()->id, 403);
// Set default position
$position = 1;
// Save each image
foreach ($this->images as $file) {
$this->saveImage($file, $post, $position);
// Increment position for next image
$position++;
}
}
}
For sorting items in Livewire I would use https://github.com/livewire/sortable.
Sortable is very easy to use.
For filepond if the original image should be used again later I would save that image as well with a relation to the edited version.
I am working on Yii 1 application. In my application, there is a CGridView where there is a link, which also fires an ajax request on onclick event. I am sending id as parameter. But the ajax return 400 Bad Request error. Please help me in this matter.
Here is the Gridview:
<h3>Civil Cases</h3>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'notifications-grid',
'dataProvider'=>$dataProvider_civil,
'summaryText' => false,
'columns'=>array(
array(
'name' => 'case_id',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->case_id),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
array(
'name' => 'caseno',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->caseno),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
'date_filing',
'next_date',
'panel_lawyer_id',
),
));
?>
here is the script:
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id}
});
};
</script>
here is the controller:
public function actionReadNotification(){
echo $_POST['id'];
}
added readNotification function to the accessRules. When clicking on the link new page is loading but ajax request shows error.
Try adding the csrf token inside your data with your ajax request.
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id,<?=
Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>,}
});
};
</script>
You can also disable the csrftoken by adding the below in the beforeAction()
public function beforeAction($action) {
if($action->id=='readnotification'){
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
but this is not recommended way of doing the work.
EDIT
i mistakenly added Yii::$app->request instead of Yii::app()->request as the first one is for Yii2 and not for Yii1 please change it to
<?=Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>
and make sure you have the request component with the following configurations
'components'=>array(
.
.
.
'request'=>array(
'enableCookieValidation'=>true,
'enableCsrfValidation'=>true,
'csrfTokenName'=>'_my-token',
),
Note : you can change the _my-token to any other name you like
I'm creating a module that has a custom admin 2-col page that uses ajax to populate a div, showing content based on a dropdown selection before form submission.
It all works fine, and I can see the container updated by ajax.
But when I try use a custom template for 2-col layout, I get the following inserted into the container:
An unrecoverable error occurred. The uploaded file likely exceeded the
maximum file size (50 MB) that this server supports.
There are no watchdog messages or log details, so this might suggest an apache configuration issue (https://www.drupal.org/forum/support/post-installation/2013-02-27/an-unrecoverable-error-occurred-the-uploaded-file-likely), but mod_security does not appear to be enabled, and the form does not contain any files and it's no way near 50MB! So I don't know where this is coming from. This is currently in my dev environment on my laptop and I've not faced this before, so I don't think apache config is an issue.
It strikes me that there may be a core bug in the form API for ajax with custom templates, because it works fine without a custom template... unless I'm implementing the custom template incorrectly.
A possible workaround would be to use CSS for force the container onto the RHS, but this should ideally be in the template so that admin themes can work with it.
I've put the code in pastebin: https://pastebin.com/F1zkd5rg.
or listed below:
my_module.links.menu.yml
my_module.main:
route_name: my_module.main
title: My Module
parent: system.admin
weight: -6
my_module.form_page:
route_name: my_module.form_page
title: My Module Form
parent: my_module.main
weight: -6
my_module.routing.yml
my_module.main:
path: '/admin/my_module'
defaults:
_controller: 'Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
_title: 'My Module'
requirements:
_permission: 'administrator'
my_module.form_page:
path: '/admin/my_module/form'
defaults:
_form: 'Drupal\my_module\Form\MyModuleForm'
_title: 'My Module Form'
requirements:
_permission: 'administrator'
my_module.module
<?php
/**
* Implements hook_theme_registry_alter
*/
function my_module_theme($existing, $type, $theme, $path) {
return [
'my_module_form' => [
'render element' => 'form',
],
];
}
templates/my-module-form.html.twig
<form {{ attributes }}>
<div class="layout-column layout-column--half">
{{ form.user_view }}
{{ form.submit }}
</div>
<div class="layout-column layout-column--half">
{{ form.user_list_wrapper }}
</div>
</form>
src/Form/MyModuleForm.php
<?php
/**
* #file
* Contains \Drupal\my_module\Form\MyModuleForm.
*/
namespace Drupal\my_module\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Views;
/**
* Configure custom_rest settings for this site.
*/
class MyModuleForm extends FormBase {
/**
* {#inheritdoc}
*/
public function getFormId() {
return 'my_module_form';
}
/**
* {#inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
...
$form['#theme'] = 'my_module_form';
$form['user_view'] = [
'#type' => 'select',
'#title' => $this->t('Select element'),
'#options' => $userViews,
'#ajax' => [
'callback' => '::findUsers',
'event' => 'change',
'wrapper' => 'edit-user-list',
'progress' => array(
'type' => 'throbber',
'message' => t('Searching Users...'),
),
],
];
$form['user_list_wrapper'] = [
'#type' => 'container',
'#attributes' => array(
'class' => array(
'user-list-wrapper',
),
),
];
$form['user_list_wrapper']['user_list'] = [
'#type' => 'item',
'#attributes' => [
'id' => ['user_list'],
],
'#markup' => '<ul><li>None</li></ul>'
];
$form['submit'] = [
'#type' => 'submit',
'#value' => t('Submit'),
];
return $form;
}
/**
* Ajax callback to list users.
*/
public function findUsers(array &$form, FormStateInterface $form_state) {
// Create the user list HTML
$selected = $form_state->getValue('user_view');
...
$user_list = '';
...
if (strlen($user_list) == 0) {
$user_list = 'None';
} else {
$user_list = "<ul>$user_list</ul>";
}
// Generate the AJAX response
$ajax_response = new AjaxResponse();
$ajax_response->addCommand(new HtmlCommand('#edit-user-list', $user_list));
return $ajax_response;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
drupal_set_message('Nothing Submitted. Just an Example.');
}
}
Thanks in advance
Example for send and received data between ajax function and action of controller in Zend framework 3
Here is a simple example of an ajax request using ZF3. You may give a try with this one. In this example we would use ZF3's default Application module.
Lets assume we would retrieve data via a ajax call from the following url.
http://yoursite.com/title
Lets create an action method for the title route in the IndexController.
public function titleAction()
{
// Initialize view
$view = new ViewModel();
// Checks if this is a Javascript request
$xmlHttpRequst = $this->getRequest()->isXmlHttpRequest();
if (! $xmlHttpRequst) {
die('Bad request');
}
/**
* Here we may pull data from database but for tests
* here we make an array of titles for the view
*/
$titles = [];
for ($i = 0; $i < 10; $i++) {
$titles[] = "Lorem ipsum dolor {$i}";
}
// Set data to be used in the view
$view->setVariable('titles', $titles);
/**
* Tell the renderer not to show the layout
* by setting setTerminal to true
*/
$view->setTerminal(true);
return $view;
}
We created a method, we need creating a view template for it.
view/application/index/title.phtml
<?php
foreach ($titles as $title) {
echo '<h2>' . $title . '</h2>';
}
Now we would create another action method in the IndexController from where we would make the ajax call.
http://yoursite.com/text
So lets make that action method too...
public function textAction()
{
return new ViewModel();
}
and view template would be like so
view/application/index/text.phtml
<h1>Handling ajax request</h1>
<button onclick="showTitle()">Show Title</button>
<div id="box"></div>
<?php
// Set url
$url = $this->serverUrl('/title'); // http://yoursite.com/title
// This is for the "url" catch
echo "<script>" . PHP_EOL;
echo "\tvar url = '{$url}';" . PHP_EOL;
echo "</script>" . PHP_EOL;
?>
<script>
function showTitle() {
$.get(url, function(data){
$('#box').html(data);
})
.done(function(){
console.log('Done!');
})
.fail(function(){
console.log('Failed!');
});
}
</script>
This script needs jQuery Javascript library to make the ajax call. So make sure that script is added in your view/layout/layout.phtml.
The last thing we need is to set up routes for the /title and /text. Lets add those two routes to the route section of module/Application/config/module.config.php
'title' => [
'type' => Literal::class,
'options' => [
'route' => '/title',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'title',
],
],
],
'text' => [
'type' => Literal::class,
'options' => [
'route' => '/text',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'text',
],
],
],
Let us know if it makes you happy!
I'm using Symfony 2.7 and I'm trying to use EWZRecaptchaBundle (dev-master) in my registration form. I have followed the steps of documentation but it's not work, never validate the recaptcha field.
I've configured the bundle:
ewz_recaptcha:
public_key: my_public_key
private_key: my_private_key
locale_key: %kernel.default_locale%
I've added recaptcha in my class Register:
// ...
use EWZ\Bundle\RecaptchaBundle\Validator\Constraints as Recaptcha;
class Register
{
// ...
/**
* #Recaptcha\IsTrue
*/
public $recaptcha;
// ...
}
and in my RegisterType:
// ...
class RegisterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
->add('recaptcha', 'ewz_recaptcha');
}
public function getName()
{
return 'register';
}
}
and in my form template:
{# ... #}
{{ form_widget(form.recaptcha) }}
{# ... #}
But when I submit the form, never validate recaptcha field and never show error message "This value is not a valid captcha." although I don't check it. Is it necessary to do something in the controller that get the form submit?
Thanks.
Found the solution. The key is not to use AJAX. Set the config.yml and the RegisterType as follows:
In app/config.yml you should set the following:
ewz_recaptcha:
public_key: public_key_here
private_key: private_key_here
locale_key: '%kernel.default_locale%'
enabled: true
ajax: false
Inside the RegisterType you should have:
->add('recaptcha', EWZRecaptchaType::class,
[
'label' => 'Captcha check:',
'mapped' => false,
'constraints' => [
new Recaptcha()
],
'attr' => [
'options' => [
'type' => 'image',
'defer' => false,
'async' => false,
'size' => 2
]
]
])
I suggest to use gregwar captcha bundle , it is a powerful bundle and easy to use
https://github.com/Gregwar/CaptchaBundle