I'm trying to persist grid updates to database, so I write in my controller:
//...
editUser: function(button, eventObj) {
var view = Ext.widget('useredit');
view.down('form').loadRecord(this.getSelected());
},
getSelected: function() {
var grid = this.getUserList();
var selectedRecord = grid.getSelectionModel().getSelection()[0];
return selectedRecord;
},
updateUser: function(button) {
var win = button.up('window'),
form = win.down('form'),
record = form.getRecord(),
values = form.getValues();
record.set(values);
form.updateRecord();
win.close();
this.getUsersStore().sync();
}
});
And this is my store code:
Ext.define('MyApp.store.Users', {
extend: 'Ext.data.Store',
model: 'MyApp.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
actionMethods:
{create: 'POST', read: 'GET', update: 'POST', destroy: 'POST'},
api: {
create: 'data/createUser.php',
read: 'data/getUsers.php',
update: 'data/updateUser.php',
destroy: 'data/deleteUser.php'
},
reader: {
type: 'json',
root: 'users',
successProperty: 'success'
}
}
});
When I hit "save" button firebug tells me that POST request has been sent to my php file, but when I
print_r($_POST) in php it shows me an empty array. How can this be?
By default, the proxy's writer will send the JSON string as raw POST data to the server. PHP's $_POST superglobal takes variables/parameters from the raw POST data, if possible, e.g. if it contains url-encoded data:
var1=a&var2=b&var3=c
However, since your POST data is just a JSON string, there are no key=value pairs to extract from, which is why your $_POST array is empty.
To read the raw post data, you can use PHP's input stream php://input:
$json = file_get_contents('php://input');
$data = json_decode($json);
var_dump($data);
Alternatively, in ExtJS you can also tell the writer to pass the JSON string as a HTTP parameter to the request using the encode and root configurations:
proxy: {
// ...
writer: {
type: 'json',
encode: true,
root: 'users'
}
}
Which will result in the writer generating the POST data like this:
users={"var1":"a","var2":"b","var3":"c"}
and therefore allows you to use the $_POST variable in PHP:
$data = json_decode($_POST['users']);
var_dump($data);
Related
So I have a input with "multiple" files and I'm passing this to a form Data but in my Controller I only can access to $_POST['Files']
So in my index.file I'm sending files through ajax request with form data,
var fileList=tr.children[29].children[0].files;
var fd2 = new FormData();
fd2.append('Files',filesArray);
fd2.append('_token',"{{ csrf_token() }}");
$.ajax({
method: "POST",
type: "POST",
url:"{{ route('SaveFileInfo') }}",
data:fd2,
dataType:'multipart/form-data',
processData: false,
contentType: false,
success: function(data){
alert('sucess');
},
error:function(err){
console.log("error---> ", err);
}
});
In my controller,
public function saveFileInfo(Request $request) {
$fileList=$_POST['Files'];
var_dump($fileList);
foreach($fileList as $file){
print_r($file);
}
I'm trying to access to my [object File List] and iterate it like a array and save all info of the files in a table (file name, size, mime-type)...
The problem is I don't know hot to manage this kind of object.. can i covnert it to array? I've tried do convert to array in javascript side like,
var filesArray = JSON.stringify(Object.keys(fileList).map(i => fileList[i]));
but this returns
[{},{}]
Any idea of how to handle this in server side (laravel) ?
I'm trying to grasp more than I should at once.
Let's say I have 2 inputs and a button, and on button click I want to create a json containing the data from those inputs and send it to the server.
I think this should do it, but I might be wrong as I've seen a lot of different (poorly explained) methods of doing something similar.
var Item = function(First, Second) {
return {
FirstPart : First.val(),
SecondPart : Second.val(),
};
};
$(document).ready(function(){
$("#send_item").click(function() {
var form = $("#add_item");
if (form) {
item = Item($("#first"), $("#second"));
$.ajax ({
type: "POST",
url: "post.php",
data: { 'test' : item },
success: function(result) {
console.log(result);
}
});
}
});
});
In PHP I have
class ClientData
{
public $First;
public $Second;
public function __construct($F, $S)
{
$this->First = F;
$this->Second = S;
}
}
if (isset($_POST['test']))
{
// do stuff, get an object of type ClientData
}
The problem is that $_POST['test'] appears to be an array (if I pass it to json_decode I get an error that says it is an array and if I iterate it using foreach I get the values that I expect to see).
Is that ajax call correct? Is there something else I should do in the PHP bit?
You should specify a content type of json and use JSON.stringify() to format the data payload.
$.ajax ({
type: "POST",
url: "post.php",
data: JSON.stringify({ test: item }),
contentType: "application/json; charset=utf-8",
success: function(result) {
console.log(result);
}
});
When sending an AJAX request you need to send valid JSON. You can send an array, but you need form valid JSON before you send your data to the server. So in your JavaScript code form valid JSON and send that data to your endpoint.
In your case the test key holds a value containing a JavaScript object with two attributes. JSON is key value coding in string format, your PHP script does not not how to handle JavaScript (jQuery) objects.
https://jsfiddle.net/s1hkkws1/15/
This should help out.
For sending raw form data:
js part:
$.ajax ({
type: "POST",
url: "post.php",
data: item ,
success: function(result) {
console.log(result);
}
});
php part:
..
if (isset($_POST['FirstPart']) && isset($_POST['SecondPart']))
{
$fpart = $_POST['FirstPart'];
$spart = $_POST['SecondPart'];
$obj = new ClientData($fpart, $spart);
}
...
For sending json string:
js part:
$.ajax ({
type: "POST",
url: "post.php",
data: {'test': JSON.stringify(item)},
success: function(result) {
console.log(result);
}
});
php part:
..
if (isset($_POST['test']))
{
$json_data = $_POST['test'];
$json_arr = json_decode($json_data, true);
$fpart = $json_arr['FirstPart'];
$spart = $json_arr['SecondPart'];
$obj = new ClientData($fpart, $spart);
}
...
Try send in ajax:
data: { 'test': JSON.stringify(item) },
instead:
data: { 'test' : item },
I am working with Extjs4.1 MVC. What I am trying to do is save some data to the server but I do not know the proper format or how I should go about submitting the data to the server.
Here is what I am thinking but I do not believe the Ajax call should be in the controller, it should be in the model or in the store file?
method in my controller:
submit: function(value) {
data = {"id": 100, "tdt": "rTk", "val": "445"} // test data
Ext.Ajax.request({
url: 'http://test.myloc.com/providerSvc/dbproxy.php',
params: {
'do':'insert',
'object': 'stk',
'values': data
},
success: function(response){
alert('response.responseText);
}
})
}
My store:
Ext.define('STK.store.Stack', {
extend: 'Ext.data.Store',
model: 'STK.model.Stack',
autoLoad: true,
proxy: {
type: 'ajax',
api: {
read: 'http://test.myLoc.com/providerSvc/dbproxy.php?do=get&object=stack'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json'
}
}
});
my model:
Ext.define('STK.model.Stack', {
extend: 'Ext.data.Model',
fields: ['id', 'tdt', 'val']
});
store.sync() works only when the endpoints for GET and POST are same.
What you can do is, for GET,
set the extraParams by concatenating to the URL or by creating an object like
extraParams[urlKeys] = paramObject[urlKeys];
store.getProxy().setExtraParams(extraParams);
then,
Store.getProxy().setUrl(StoreUrlForGET);
Store.load({
callback : function(rec, operation, success) {
if (success) {}
else {}
});
and for POST write an AJAX request as,
Ext.Ajax.request({
url : StoreURLForPOST,
method : 'POST',
jsonData : Ext.JSON.encode(YourPostData),
success : function(response, request) {},
failure : function(response, request) {}
});
for this AJAX request you can,
Ext.Ajax.setDefaultHeaders({
"TokenId" : TokenValue
});
All of this code goes into your controller.
I think the store is the proper place to make the ajax call.
You can "save" one record by adding it to the store, and then calling the "sync()" function.
Something like this (beware: code not tested):
var store = Ext.create("STK.store.Stack");
var record = Ext.create("STK.model.Stack");
record.set(xvalues);
record.isDirty = true;
record.setDirty(true); // I don't know if this line is required
store.add(record);
store.sync({
success: function(batch, options){
alert("OK!")
},
failure: function(batch, options){
alert("failure!")
}
});
I'm trying to send JSON data from a web page using JQuery, like this:
$.ajax({
type: "post", // Request method: post, get
url: "http://localhost/ajax/login",
data: '{username: "wiiNinja", password: "isAnub"}',
dataType: "json", // Expected response type
contentType: "application/json",
cache: false,
success: function(response, status) {
alert ("Success");
},
error: function(response, status) {
alert('Error! response=' + response + " status=" + status);
}
});
In cake2.2, I have a controller named Ajax that has a method named "login", like this:
public function login($id = null)
{
if ($this->RequestHandler->isAjax())
{
$this->layout = 'ajax'; // Or $this->RequestHandler->ajaxLayout, Only use for HTML
$this->autoLayout = false;
$this->autoRender = false;
$response = array('success' => false);
$data = $this->request->input(); // MY QUESTION IS WITH THIS LINE
debug($data, $showHTML = false, $showFrom = true);
}
return;
}
I just want to see if I'm passing in the correct data to the controller. If I use this line:
$data = $this->request->input();
I can see the debug printout:
{username: "wiiNinja", password: "isCool"}
I read in the CakePHP manual 2.x, under "Accessing XML or JSON data", it suggests this call to decode the data:
$data = $this->request->input('json_decode');
When I debug print $data, I get "null". What am I doing wrong? Is my data passed in from the Javascript incorrect? Or am I not calling the decode correctly?
Thanks for any suggestion.
============= My own Edit ========
Found my own mistake through experiments:
When posting through Javascript, instead of this line:
data: '{username: "wiiNinja", password: "isAnub"}',
Change it to:
data: '{"username": "wiiNinja", "password": "isAnub"}',
AND
In the controller code, change this line:
$data = $this->request->input('json_decode');
To:
$data = $this->request->input('json_decode', 'true');
It works.
Dunhamzzz,
When I followed your suggestions, and examine the "$this->request->params" array in my controller code, it contains the following:
array(
'plugin' => null,
'controller' => 'ajax',
'action' => 'login',
'named' => array(),
'pass' => array(),
'isAjax' => true
)
As you can see, the data that I'm looking for is not there. I've already got the the proper routes code. This is consistent with what the documentation for 2.x says here:
http://book.cakephp.org/2.0/en/controllers/request-response.html
So far, the only way that I found to make it work, is as stated above in "My own Edit". But if sending a JSon string to the server is not the right thing to do, I would like to fix this, because eventually, I will have to handle third party code that will send JSon objects.
The reason you are struggling wit the data is because you are sending a string with jQuery, not a proper javascript object (JSON).
$.ajax({
type: "post", // Request method: post, get
url: "http://localhost/ajax/login",
data: {username: "wiiNinja", password: "isAnub"}, // outer quotes removed
dataType: "json", // Expected response type
contentType: "application/json",
cache: false,
success: function(response, status) {
alert ("Success");
},
error: function(response, status) {
alert('Error! response=' + response + " status=" + status);
}
});
Now the data will be available as a PHP array in $this->request->params.
Also for sending a JSON response, please see this manual page. Most of your code there can be reduced to just 2 lines...
//routes.php
Router::parseExtensions('json');
//Controller that sends JSON
$this->set('_serialize', array('data'));
I've a ScriptTagProxy and I'm able to receive the data, but now I wanted to update a record. I've specified an url but only one url. Do I have to handle all the actions (read, update, create, delete) with this url?
If yes: how does the action is applied to the url?
If not: how I can specify more urls?
Here is the code I have so far:
app.stores.entries = new Ext.data.Store({
model: "app.models.Entry",
storeId: 'app.stores.entries',
proxy: {
type: 'scripttag',
url: 'http://myurl.de/getEntries.php',
extraParams: {
username: Ext.util.JSON.decode(window.localStorage.getItem('settings')).username,
password: Ext.util.JSON.decode(window.localStorage.getItem('settings')).password
},
reader: {
type: 'json'
},
writer: {
type: 'json'
}
}
});
I've read in the docs that you can pass an config object to the save function of a model to configurate the proxy.
So I tried following:
entry.save({
url: 'http://mysite.com/updateEntry.php',
extraParams: {
username: Ext.util.JSON.decode(window.localStorage.getItem('settings')).username,
password: Ext.util.JSON.decode(window.localStorage.getItem('settings')).password,
entry: entry
},}
As you see there is a url specified.
But I still get the error:
Uncaught Error: You are using a ServerProxy but have not supplied it with a url.
);
Same behaviour when using AjaxProxy or RestProxy for example :(
Hering,
With your first block of code you ask:
Question 1) "Do I have to handle all the actions (read, update, create, delete) with this url?"
The answer is yes.
Question 2) "If yes: how does the action is applied to the url?"
According to the Sencha source code you need to define the actionMethods like so:
myApp.stores.Things = new Ext.data.Store({
model: "Things", proxy: {
type: 'ajax',
actionMethods: {
create: 'POST',
read: 'GET',
update: 'PUT',
destroy: 'DELETE'
},
url: 'jsontest.json',
reader: {
type: 'json',
root: 'things'
}
},
autoLoad: true
});
If you delete, create or edit a record you must call:
store.sync();
There is also a "autoSave" property but it only syncs on edits, not removes.
This will send over the things that have changed or been deleted as part of the request payload, it is your responsibility to parse the json and handle it.
Hering,
I was reading the documentation here, I found this example in the Model class:
Ext.regModel('User', {
fields: ['id', 'name', 'email'],
proxy: {
type: 'rest',
url : '/users'
}
});
But above you don't show your Model for app.models.Entry, have you tried that?