I'm trying to set a default value in an input. The value is sent from the Controller to the Twig as shown below
ClienteController.php
$loc_default = $em->getRepository('AppBundle:Localidad')->findOneBy(
array('nombre' => 'aaaa'));
$localidad_default = $loc_default;
return $this->render('cliente/new.html.twig', array(
'localidad_default' => $localidad_default,
'form' => $form->createView(),
'form2' => $form2->createView(),
));
and this is my Twig View with the javascript line
$("#appbundle_cliente_localidad").val({{localidad_default['localidad_default']}});
but it shows the following error
Impossible to access a key "localidad_default" on an object of class "AppBundle\Entity\Localidad" that does not implement ArrayAccess interface.
Thanks for the answer
Try this:
$loc_default = $em->getRepository('AppBundle:Localidad')->findOneBy(array(
'nombre' => 'aaaa')
);
$localidad_default = $loc_default->getSomething();
return $this->render('cliente/new.html.twig', array(
'localidad_default' => $localidad_default,
'form' => $form->createView(),
'form2' => $form2->createView(),
));
And in the template:
$("#appbundle_cliente_localidad").val({{ localidad_default }});
Change getSomething() to a valid public method of your Localidad entity!
Or if you need the whole entity in your twig template:
$loc_default = $em->getRepository('AppBundle:Localidad')->findOneBy(array(
'nombre' => 'aaaa')
);
return $this->render('cliente/new.html.twig', array(
'localidad_default' => $loc_default,
'form' => $form->createView(),
'form2' => $form2->createView(),
));
And in the template:
$("#appbundle_cliente_localidad").val({{ localidad_default.something }});
In my opinion is too much code, if the controller sends the default data from the same action the form is sended just set the value at form or controller like this:
Inside the form
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name',TextType::class,[
'attr'=>[
'value' => 'some_default_value'
]
]);
}
Inside the controller
...
$form = $this->createForm('AppBundle\Form\SomeFormType', $data);
$form->get('somefield')->setData('default_data');
...
This way is better for you, less code and test. Also if you need to access database or something it is easier.
Hope it helps!
Related
I send data with this code to JS:
$user = User::where('id' , $this->selectedItem)->first();
$this->dispatchBrowserEvent('userModal', [
'name' => $user->name,
'signup' => jdate($user->created_at),
]);
jDate() Is a function to convert to Persian date
but in frontend for signup I will receive a empty value
and this is JS code to receive data :
window.addEventListener('userModal', event => {
console.log(event.detail);
});
I would suggest to simply use Carbon instead of jDate().
'signup' => \Carbon\Carbon::parse($user->created_at)->setTimezone('Asia/Tehran'),
I've managed to get x-editable (https://vitalets.github.io/x-editable/) to work with a page, in so far as when I click on a field, it displays inline and I can edit it, and I'm able to successfully submit to a POST URI.
The idea here is that I'm sending three key-value pairs:
array:3 [▼
"name" => "name"
"value" => "mathematics"
"pk" => "1"
]
and my update() method catches the array, and it successfully updates the record in the database. But I'm failing to validate the data.
This is how my controller looks:
public function update(Request $request)
{
//
$id = $request->pk;
$subject = Subject::findOrFail($id);
$rules = array (
'name' => 'bail|required|max:20|unique:subjects,name,'.$id
);
This validation pass easily even if I try to fail it
$validator = Validator::make ( $request->all(), $rules );
if ($validator->fails ()) {
return response()->json ( array (
'errors' => $validator->getMessageBag ()->toArray ()
) );
} else {
$subject->update([$request->name => $request->value]);
}
return response ()->json ( $subject );
}
So it's as if I'm somehow not passing the "correct" Request object to validate()? There is no form submission, but the documentation clearly states that:
Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.1
Route:
Route::post('/subjects/update/', 'SubjectsController#update');
script:
$('#subjects').editable({
container:'body',
selector:'td.name',
type:'post',
dataType:'JSON',
validate:function(value){
if ($.trim(value) === '') {
return "Field is required";
}
}
});
1https://laravel.com/docs/5.4/validation#quick-ajax-requests-and-validation
If I'm not mistaken, name is the field to be edited (the DB column), and value is, well, the value. It looks like you are updating the name column, so you have to validate the uniqueness of the value in the request, not the "name".
Also, I'd suggest you use the validate method of your controller (provided by the ValidatesRequests trait):
public function update(Request $request)
{
$id = $request->pk;
$subject = Subject::findOrFail($id);
$this->validate($request, [
'name' => 'required', // this should be the column to update
'value' => 'bail|required|max:20|unique:subjects,name,'.$id
];
$subject->update([$request->name => $request->value]);
return $subject;
}
Here validate will automatically reject with a 422 code and the validation errors in the JSON response. If it passes, it will continue with the update. (return $subject also returns a JSON representation of the object in the response.)
i am using laravel with pusher to send an event message to pusher. the code is in my controller which is a post controller, triggered when an input form is submitted. below is my code. what am i doing wrong? there is no event received.
this is an ajax call route based controller.
$pusher = new Pusher( env('PUSHER_KEY'), env('PUSHER_SECRET'), env('PUSHER_APP_ID'), array( 'encrypted' => true ) );
$pusher->trigger( 'test_channel', 'my_event', 'hello world' );
I am also assuming you have set up your Pusher account correctly and that your environment variables are correct.
If so, you may need to ensure you are using the correct Cluster (the default is fine for the US, but outside the East coast of the US for example, the cluster must be explicitly defined).
Update:
Controller code:
<?php
namespace App\Http\Controllers;
use Vinkla\Pusher\Facades\Pusher;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class TestPusherController extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function test(){
$arr = array('test' => 'hello world 2') ;
$pusher = new Pusher( env('PUSHER_KEY'), env('PUSHER_SECRET'), env('PUSHER_APP_ID'), array( 'encrypted' => true, 'cluster' => 'ap1' ) );
$pusher::trigger( 'test_channel', 'my_event', $arr);
return $arr;
}
public function shortenedTest(){
$message = 'Hello world';
Pusher::trigger('my-channel', 'my-event', ['message' => $message]);
}
}
In web routes:
Route::get('testPusherController', 'TestPusherController#test');
Route::get('shortenedTestPusherController', 'TestPusherController#shortenedTest');
I have got this working on a fresh install of vinkla/pusher following the setup steps in https://github.com/vinkla/laravel-pusher, on Laravel 5.3, using the built in PHP server and Connecting to the EU server (I do not have any Pusher apps using ap1 at this time).
You will notice a small number of changes to the coding in the controller to get the correct format. You must 'use' the Pusher facade above the controller.
For completeness, I have added a neater way of working with this where you can set the Pusher credentials in the Config/pusher.php file without the need to setup the connection for each use. This can be seen in the shortenedTest() method on the controller.
<?php
return [
'connections' => [
'main' => [
'auth_key' => env('PUSHER_KEY'),
'secret' => env('PUSHER_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_CLUSTER')
],
'host' => null,
'port' => null,
'timeout' => null,
],
'alternative' => [
'auth_key' => 'your-auth-key',
'secret' => 'your-secret',
'app_id' => 'your-app-id',
'options' => [],
'host' => null,
'port' => null,
'timeout' => null,
],
],
];
I am trying to make ZF2 respond in REST way to different request type.
In my module.config.php I have this router config.
'router' => array(
'routes' => array(
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\Student',
'action' => 'index',
),
),
),
),
),
On frontend I am using Backbone to send GET, POST, DELETE requests to server based on user interactions.
When user trigger action to delete student with id of n, backbone will send /somePath/student/n using DELETE request.
When user trigger action to get student with id of n, backbone will send /somePath/student/n using GET request.
If I want current setup to work I have to change Backbone request and change URL from student/n to student/delete/n if I want to delete student with that id and similarly for GET.
This is what I did on client side which I would like to avoid.
define(['backbone'], function(Backbone){
return Backbone.Model.extend({
defaults:{
//set default model values
},
initialize: function(){
//initialize
},
methodToURL: {
'delete': '/student/delete'
},
sync: function(method, model, options) {
options = options || {};
var id = arguments[1]['id']
options.url = model.methodToURL[method.toLowerCase()] + '/' + id;
return Backbone.sync.apply(this, arguments);
}
});
});
In controller on server side I have different action methods I would like to run for different request types.
public function deleteAction()
{
//some code
}
public function getAction()
{
//some code
}
I don't want to change default backbone behaviour (intercepting and altering requests).
Is there a way to configure ZF2 router to use same route but trigger different actions based on request method type?
You can use Method route as child route of segment route. http://framework.zend.com/manual/2.3/en/modules/zend.mvc.routing.html
There is a example named A complex example with child routes where author for blog literal route create child routes each of which is different type.
Simply You can create child routes in your student route which will be type Method for each method You want to use and then change only action for this method types.
'router' => array(
'routes' => array(
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\Student',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'delete' => array(
'type' => 'method',
'options' => array(
'verb' => 'delete',
'defaults' => array(
'action' => 'delete'
),
),
),
'put' => array(
'type' => 'method',
'options' => array(
'verb' => 'put',
'defaults' => array(
'action' => 'put'
),
),
),//and so on...
),
),
),
),
You can use the Zend\Mvc\Controller\AbstractRestfulController
It will call Certain function depending on the HTTP request method
class StudentRest extends AbstractRestfulController {
/**
* will be called with a GET request when it detects that route
* matches paramater id has been set
*/
public function get($id) {
/*load studentdata*/
return new JsonModel($data);
}
/**
* Will be called on a POST request, and data should be sent with a $_POST
* This should create a new object/row in db and return 201
*/
public function Create($data) {
/*create student*/
$this->response->setStatusCode(201); // if new student was created.
return JsonModel();
}
/**
* Will be called on a PUT request. Data should be sent via $_POST
* It also requires that the $id parameter is set in the route match
*/
public function Update($id, $data) {}
/**
* Will be called on a DELETE request, It requires that the $id parameter is set in the route match
*/
public function Delete($id) {}
}
with that u can just link to the controller via the route as so
'student' => array(
'type' => 'segment',
'options' => array(
'route' => '/student[/:id]',
'constraints' => array(
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Student\Controller\StudentRest ',
),
),
),
there are also some function for getList which will be called when not suppling $id in route parameters.
Also might be worth saying that the default implementation of all the functions returns a 405 with a ['content' => 'Method Not Allowed']
Documentation how to use it
As per the documentation :
http://framework.zend.com/manual/1.12/en/zend.controller.request.html
Determining the Request Method
getMethod() allows you to determine the HTTP request method used to request the current resource. Additionally, a variety of methods exist that allow you to get boolean responses when asking if a specific type of request has been made:
isGet()
isPost()
isPut()
isDelete()
isHead()
isOptions()
The primary use case for these is for creating RESTful MVC architectures.
Well, I have a CakePHP 2.2.5 app which is basically management of users, and a user has a photo, and I create a PhotosController (as suggestion of this tutorial). I tested it and it works perfectly on Photos/View, including the ajax elements to be possible send a photo in a form without redirecting. And now I'm trying to connect all of this, but it ins't as easy as I think it should be.
My Photo add method:
public function add()
{
if ( $this->request->is( 'post' ) ) {
$this->Photo->create();
$json = array( 'result' => array( 'files' => array() ) );
if ( $this->Photo->save( $this->request->data ) ) {
$photo = $this->Photo->findById( $this->Photo->id );
$json['files'][0]['name'] = $photo['Photo']['basename'];
$json['files'][0]['size'] = $this->request->data['Photo']['file']['size'];
$json['files'][0]['url'] = $this->webroot . 'media/transfer/img/' . $photo['Photo']['basename'];
$json['files'][0]['thumbnail_url'] = $this->webroot . 'media/filter/thumbnail/img/' . $photo['Photo']['basename'];
}
else {
$json = 'Error';
$this->Session->setFlash( __( 'The photo could not be saved. Please, try again.' ) );
}
$this->RequestHandler->renderAs( $this , 'ajax' );
Configure::write( 'debug' , 0 );
$this->set( 'json' , json_encode( $json ) );
$this->render( '/Elements/ajax' );
}
My test View (on users controller):
<?php echo $this->Form->create(
'Photo' ,
array( 'url' => array( 'controller' => 'photos' ,
'action' => 'add'
) ,
'id' => 'fileupload' ,
'enctype' => 'multipart/form-data'
)
); ?>
<-- Some HTML HERE-->
<?php
echo $this->TB->input(
'Photo.file' ,
array(
'prepend' => 'Upload' ,
'type' => 'file' ,
'class' => 'fileUpload' ,
//'multiple' => 'multiple',
'div' => FALSE ,
'between' => FALSE ,
'after' => FALSE ,
'label' => FALSE ,
'help' => NULL ,
)
);
?>
</form>
<-- Some (already tested) Javascript to make this work HERE-->
The view renders without php errors, but when I upload a file I get an Javascript error, and the debug says:
GET http://<server>/<app>/users/add 404 (Not Found) jquery.min.js:1960
send jquery.min.js:1960
b.extend.ajax jquery.min.js:1840
(anonymous function) main.js:59
c jquery.min.js:215
p.fireWith jquery.min.js:249
b.extend.ready jquery.min.js:69
H jquery.min.js:10
Actually, I get this error on both, GET and POST methods (with some different line of jQuery of course).
Even the action is set to the PhotosController it is trying to access the Users. I think because of the view, as I din't specify users anywhere. I am trying to solve this problem for a week and I don't have more ideas.
Any help would be greatly appreciated.
Thanks in advance.