Prestashop: How to submit data from adminpanel template to Admin Controller? - ajax

I'm trying to make a custom page in the adminpanel of Prestashop where the shopowner can fill in his upcoming events that will appear in a column in the header.tpl page. The templates and controller are working so far, with a structure based on an answer here at Stack Overflow:
How to create a new page in prestashop admin panel?
Now I have made in the content.tpl (with the added custom JavaScript and CSS files) the form with the input fields. The next step is to send it to the controller to save it in the database. But I'm stuck this part. I can't find how I can nicely submit the form to the controller. First I tried it with an Ajax function but I couldn't find the right way. Also without Ajax no success.
$.ajax({
type: 'POST',
headers: { "cache-control": "no-cache" },
url: baseUri + '?rand=' + new Date().getTime(),
async: true,
cache: false,
dataType : "json",
data:{
processEvents: true,
ajax: 'true',
controller: 'AdminEvents',
token: static_token
},
//success: function(jsonData){
//}
});
This is an example of an Ajax function that I tried. My questions:
How does other tpl or js files receive the baseUri, where is that
variable set?
What is the function of the ?rand date and time in that line? A kind
of security token?
What is the url of the controller? Also the url when I use
I guess the processEvents : true and Ajax : true is for security
reasons and to check if the form is submitted by Ajax or not?
Why is it necessary to send the controller name?
Where does the token come from?
Questions about the controller:
Which (Prestashop default functions) can or do need to use? For
example:
if (Tools::isSubmit('name')){
etc.
if (Tools::getValue('create_account')){
etc.
Can I use that functions anywhere or maybe only in an Init function?
A lot of questions, feel free to answer only a part of it, I just need a good push in the right direction, searching and reading in the online documentation and on the internet doesn't brought me the solution and brainwashed me a little.
EDIT:
I made a little progress by myself:
Where does the token come from?
What is the url of the controller? Also the url when I use
With the tools getAdminTokenLite and the controller name I generated the controller url:
$token = '?controller=AdminEvents&token='.Tools::getAdminTokenLite('AdminEvents');
The url to post to is the token plus the domain, admin directory and index.php.
With the tool getValue I get the POST data like in PHP with $_POST["name"].
Tools::getValue('event_name')
So its working but I guess it can be better with other Presta default tools.

I know that it's very late to answer you, but for sure it will help other mates with same problem.
Here is an example about how to implement ajax calls in Prestashop 1.6 on Admin panel using ANY Controller from BackOffice (if you want also, you can use ajax.php controller, but I'm using for this AdminImportController() )
tpl part:
$('#mybtn').click(function(e) {
var data = $('#datalist').val();
// Ajax call with secure token
$.post( "{$current|escape:'html':'UTF-8'}&token= {$token|escape:'html':'UTF-8'}",
{ ajax: true, action: "MyFunction", mydata: data } );
  });
And in admin controller side:
public function ajaxProcessMyFunction()
{
// Get param
$mydata = (int)Tools::getValue('mydata');
$answer = 0;
if( $mydata > 0 ) {
$this->importProfList = Db::getInstance()->executeS(
"SELECT * FROM .... LIMIT 1"
);
...
$answer = $someOperationResult;
}
// Response
die(Tools::jsonEncode(array(
'answer' => htmlspecialchars($answer)
)));
}
Tested and working like a charm.
Regards

Related

Insert Data Using Ajax

I am using Laravel 5.3. I want to insert the data using blade template.But my when i press submit button it gets refreshed every time. what to do? and please anyone tell me how to use ajax url,type,data
If you try to submit via Javascript make sure prevent form default action with e.preventDefault(). This code prevent the form submitted in a regular way. Just add this code to wrap your AJAX call:
$('#form-id').submit(function(e){
e.preventDefault();
$.ajax({...});
});
I just assume you are using jquery if you are talking about ajax. It's really simple. Your laravel routes listen to "post", "get", "patch", "delete" methods.
Everything of these can be created with a ajax request - example:
$.ajax({
method: "POST",
url: "/posts",
data: { title: "Hello World", text: "..." }
})
.done(function( post ) {
// assuming you return the post
alert(post.title + " created");
});
Now that you use ajax you will not want to return a view to the ajax call. You have different options here (create a new route, helper functions etc.) I will give the most easy example
Controller function:
public function store(Request $request) {
$post = App\Post::create($request->all());
if($request->ajax()) {
return $post;
} else {
return redirect('/posts');
}
}
now you controller will return data on ajax calls and will redirect you on default calls without ajax.
Finally you have a last thing to keep in mind. If you have web middleware applied ( done by default ) you need to handle the csrf token. The most easy way to handle this is by adding a meta tag to your html head
and then (before doing all your calls etc.) add this to configure your ajax
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
this will add the valid csrf token which is in your head to every ajax call and will ensure you not run into token missmatch exceptions.
Things to keep in mind:
- if you stay very long on one page tokens might expire ( laravel-caffeine will help here )
- you need to handle validation for ajax calls

AJAX response returns current page

I was searching for a similar issue for a while now, but none of the solutions worked for me (and I couldn't find exactly the same issue).
First of all, the website I'm working on is running on Zend Framework. I suspect that it has something to do with the issue.
I want to make a pretty basic AJAX functionality, but for some reason my response always equals the html of the current page. I don't need any of Zend's functionality, the functions I need to implement could (and I'd prefer them to) work separately from the framework.
For testing purposes I made it as simple as I could and yet I fail to find the error. I have a page "test.php" which only has a link that triggers the ajax call. Here's how this call looks:
$('.quiz-link').click(function(e){
e.preventDefault();
$.ajax({
URL: "/quiz_api.php",
type: "POST",
cache: false,
data: {
'test': 'test'
},
success: function(resp){
console.log(resp);
},
error: function(resp){
console.log("Error: " + reps);
}
});
});
And this quiz_api.php is just:
<?php
echo "This is a test";
?>
When I click on the link I get the entire HTML of the current page. "This is a test" can't be found there. I'm also getting an error: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/."
I reckon it has to do with the JS files that are included into this HTML response, but I've also tried setting "async: true" and it didn't help.
I would like to avoid using Zend Framework functions for this task, because I'm not well familiar with it and even making a simple controller sounds rather painful. Instead I want to find out what's causing such behavior and see if it can be changed.
PS: I've also tried moving quiz_api.php to another domain, but it didn't change anything.
I know that it might be an older code but it works, simple and very adaptable. Here's what I came up with. Hope it works for you.
//Here is the html
Link Test
<div id="test_div"></div>
function test(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// This is the php file link
var url = "quiz_api.php";
// Attaches the variables to the url ie:var1=1&var2=2 etc...
var vars = '';
hr.open("POST", url, true);
//Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange =
function(){
if(hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
console.log(return_data);
document.getElementById('test_div').innerHTML = return_data;
}else{
document.getElementById('test_div').innerHTML = "XMLHttpRequest failed";
}
}
//Send the data to PHP now... and wait for response to update the login_error div
hr.send(vars); // Actually execute the request
}
you can change the whole page with a document.write instead of changing individual "div"s

Ajax username and date Instagram API

Currently, I'm trying to create a page using instagram's api, showing recent pictures with a specific tag, as well as the user who posted it and the date posted. I'm also trying to have the infinite loading functionality, with ajax loading in more instagram posts as the page reaches the bottom.
Heres a link to the live site http://www.laithazzam.com/work/nukes/indexnew.php
Clicking the red yes will skip the video, and go straight to the instagram feed.
I'm currently using Christian Metz's solution found here, https://gist.github.com/cosenary/2961185
I am also having an issue with posting the date, in the first initial load, as well in the ajax loads. I was previously able to use this following code, before trying to implement Christian's php/ajax solution.
var date = new Date(parseInt(data.data[i].created_time) * 1000);
<p class='date'>"+(date.getMonth()+1)+"/"+date.getDate()+"/"+date.getFullYear()+"</p>
I guess what I don't understand, is how the ajax loading function, is actually functioning. How would I also pull the name, and date through the ajax loading success function as well?
$.ajax({
type: 'GET',
url: 'ajax.php',
data: {
tag: tag,
max_id: maxid
},
dataType: 'json',
cache: false,
success: function(data) {
// Output data
$.each(data.images, function(i, src) {
$("#instafeed").append('<img src="' + src + '">');
});
// Store new maxid
$('#more').data('maxid', data.next_id);
}
});
});
The data parameter of the success handler function is populated from whatever JSON ajax.php returns and the structure will match accordingly. It looks like the images attribute of that object only has an array of URLs for the images and no other data.
You'll need to update this section of the PHP script to return more than just the array of URLs for the images and also include the additional data retrieved from the Instagram API.
Try updating the last part to this:
echo json_encode(array(
'next_id' => $media->pagination->next_max_id,
'images' => $media->data
));
Then you'll have full access to all the media data, not just the URL.

Codeigniter not detecting form on jQuery send

I'm going a little crazy here as I'm at a real loss for words what is happening. After a lot of digging around, I believe I am doing everything as should be.
Situation
I'm trying to send a user creation form to the server via AJAX and codeIgniter fails to even get past this part
if($this->input->post('blnAjax')) { // do something }
I have successfully incorporated the AJAX side of things in to the client as it fetches content from the server with very little problem. Here are some of the details involved in the call:
Ajax code
The ajax code is part of a much larger framework beyond the scope of this question but in terms of the actual call function, the event has event.preventDefault(); event.stopImmediatePropagation(); to stop it running off. The URL is reachable and the post values have been serialized with request type set to POST
requestpage: function(){
var strURL = params.strBaseURL + params.strRequestURL;
$.ajax({
type: params.strRequestMethod,
url: strURL,
data: params.strRequestParameters,
dataType: 'json',
success: function(json) {
methods.postrequestprocedure(json);
}
});
},
Ajax request
Everything runs smoothly on the client making the XMLHttpRequest with json as expected return. I don't even get to this point when the form has been submitted however. Codeigniter will never think the form has been set if using AJAX
Parameters application/x-www-form-urlencoded
blnAjax 1
user_login_name[] fred
user_login_name[] ted
user_name[] Fred Flintstone
user_name[] Ted bear
usergroup_id[] 16
usergroup_id[] 16
Controller
On the controller, with regard to the action, I have included alall code up to the point of fail. Please note that I have tested the other aspects of the code and they run fine
public function user_add() {
/* Include extra script files needed for form handling */
$this->view['aryScript'][] = 'jquery.validate.min';
$this->view['aryScript'][] = 'jquery.validate.additional-methods';
/* Include extra CSS files */
$this->view['aryCSS'][] = 'form';
/* First check if the user has correct access rights */
if($this->view['intAccessLevel'] < INT_SUPER_USER_ACCESS_LEVEL) {
$aryResponse['notifications'][] = array('strType' => 'permanent',
'strMessage' => 'Denied!');
}
/* Import extra libraries and helpers */
$this->load->library(array('PasswordHash'));
$this->load->model('UserAdminModel');
$this->view['strTitle'] = 'Add User';
$this->view['aryButtons']['user_add_another'] = array(
'strDisplay' => $this->lang->line('user_add_another')
'strURL' => '#',
'strID' => 'user_add_another',
'aryData' => array('action' => 'form-clone')
);
if($this->input->post('blnAjax')) {
echo 'Big sigh of relief';
Thank you kindly for taking the time to read my problem
The answer is never as simple as it seems! My client is using a CodeIgniter mod that rewrites the URI and thus dumping the data passed from the ajax query. It hadn't been a problem when performing gets and "real" POST queries.
So if you are ever using Wiredesignz - Language Identifier beware that it can affect your queries
How I fixed it, I use a custom page controller but the theory is the same:
Be sure that you have $this->config->item('language_abbr'); available to your javascript functions maybe through a constant or echo it directly in to the javascript if on the same page
Modify the URL before sending it with something similar to params.strBaseURL + params.strLanguage + '/' + params.strRequestURL;
You should now find things work just fine. I hope this helps and noone else has to spend a mini eternity to find this out

codeigniter get URL after ajax

I am trying to get the URL i see on my browser after i do an ajax request but the problem is that it changes the URL with the Ajax URL.
ex.
i am on domain.com/user/username
and the ajax URL that i call is in domain.com/posts/submit
when i echo $_SERVER['REQUEST_URI'] on the posts controller in submit function it will display the second URL and not the first... how can i assure and get the first inside the ajax function that its 100% valid and not changed by the user to prevent any bad action?
Thanks
There is HTTP_REFERER but I don't know if that works for javascript requests. Another problem of this: It won't work for all browsers.
You could try the following:
1.) As the user visits domain.com/user/username the current URL is saved with a token - let's say 5299sQA332 - into the database and the token is provided through PHP to Javascript
2.) The ajax request will send this token along with the other variables needed to the controller through POST
3.) In your ajax controller you search the database for the given token 5299sQA332 and there you have your first URL and you can be damn sure, that it hasn't been manupulated
:)
If I understand you correctly, you want to make sure the ajax call is coming from the page it is supposed to be on? In that case just pass a token with the call.
In the controller function set a token variable in session;
public function username() {
$this->session->set_userdata('ajax_token', time());
}
Then in the view with the js;
$.ajax({
url: '/user/username',
type: 'post',
data: 'whatever=bob&token='+<?php echo $this->session->userdata('ajax_token'),
success: function( data ) {
},
error: function( data ) {
}
});
Then in you form validation, do a custome callback to check they are the same.
Have you looked at CodeIgniter's Input Class ?
$this->input->get('something', TRUE);
i used javascript for it and it seems to work... hope not to have any problems in the future with it...
ps: i dont get why my other answer was deleted.. thats the answer anyway.

Resources