Load Table But another response is undefined - php

I am using Codeigniter 4 with csrf active.
I have tried to make Search form with the table will load without loading on page.
It is success on first attempt, but another response--which is token_value get undefined. And if I tried to search for the second time it get error 403 Forbidden.
Here is my jquery looks like:
$("#btnSearch").click(function(){
$.post("vendor/search",
{
"searchByCode":$("input[name='searchByCode']").val(),
"<?= csrf_token() ?>" : "<?= csrf_hash() ?>"
},
function(data, status){
alert(data.token_value);
$("#table_vendors").html(data);
});
});
and this is my related Controller looks like
public function search()
{
$result = $this->vendors;
if ($this->request->getPost('searchByCode')) {
$result->like('code', $this->request->getPost('searchByCode'));
};
$data = [
'vendors' => $result->paginate(10, 'vendors'),
'page' => $result->pager,
'token_value' => csrf_hash()
];
return view('vendors/_vendors', $data);
}
This is what happen when I click search for a second time.
I wish I could do re-search with my code above without refreshing page.

Try this in your JS:
// Courtesy of W3Schools :o)
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length,c.length);
}
}
return "";
}
function resetCSRF(){
$('input[name="csrf_cookie_name"]').val(getCookie('csrf_cookie_name'));
}
Assuming your cookie name is csrf_cookie_name then call resetCSRF() after each form submit. This code will get the latest Cookie value and set it in the form and should allow you to resubmit without refreshing.

Related

CakePHP 4 Return data from controller to AJAX render issue

I am submitting data to a controller function via AJAX, doing what I need to do with the data, and trying to echo it back out to the ajax function.
The issue I am having, is the controller is dumping out the error message and trying to redirect me to the actual function. Obviously the function doesn't have a view, which results in a blank white screen with the response echoed out in the top left corner.
Here is the ajax:
$('#submit_new_split_promo').on('click',function(e){
e.preventDefault();
var id = $(this).data('id');
$('#d_overlay').show();
form = {};
$.each($('#promo-mail-split-add-'+id).serializeArray(),function(k,v){
form[this.name] = this.value;
});
$.ajax({
url:$('#promo-mail-split-add-'+id).attr('action'),
type:"POST",
dataType: "json",
data: form
}).done(function(result){
var res = JSON.parse(result);
if (res == 'Duplicate') {
$('#ms-promo').css('border','3px solid red');
$('#ms-promo').effect('shake');
$('#dynamodal-unique-title').text('That code has been used. Please enter a new Promo Code.');
$('#dynamodal-unique-title').text('That code has been used. Please enter a new Promo Code.').css('color','red').delay(2000).queue(function(next){
$('#dynamodal-unique-title').text('Create Mail Split Promo');
next();
});
return false;
}
$('#mail_split_promo_'+id).modal('toggle');
if (res == false) {
alert('Mail Split Promo did not save. Please try again.');
} else {
$('#add-promo-to-split-'+id).prop('disabled',true);
$('#promo-view-abled-'+id).hide();
$('#promo-view-disabled-'+id).show();
$('#promo-view-disabled-'+id).prop('disabled',false);
}
}).fail(function(){
}).always(function(){
$('#d_overlay').hide();
});
});
Here is the Controllers code
public function addpromo() {
$this->Authorization->skipAuthorization();
$this->request->allowMethod(['get','post']);
$this->autoRender = false;
$data = $this->request->getData();
$mail_split_id = $data['mail_split_id'];
$code = $data['code'];
$result = false;
$doesExist = $this->Promos->findByCode($code)->toArray();
if ($doesExist) {
$result = 'Duplicate';
}
if ($result !== 'Duplicate') {
$MailSplits = $this->getTableLocator()->get('MailSplits');
$mailSplit = $MailSplits->get($mail_split_id);
$entity = $this->Promos->newEmptyEntity();
foreach ($data as $key => $val) {
$entity->$key = $val;
}
$entity->record_count = $mailSplit->record_count;
$result = $this->Promos->save($entity);
if ($this->get_property($result,'id')) {
$promo_id = $result->id;
$MailSplits = $this->loadModel('MailSplits');
$mentity = $MailSplits->get($mail_split_id);
$mentity->promo_id = $promo_id;
$updated = $MailSplits->save($mentity);
if ($this->get_property($updated,'id')) {
$result = true;
} else {
$result = false;
}
$output = [];
exec(EXEC_PATH.'AddPromoToRecordSplits '.$promo_id,$output);
} else {
$result = false;
}
}
ob_flush();
echo json_encode($result);
exit(0);
}
The URL it is trying to redirect me to is: /promos/addpromo when I really just need to stay on the same page, which would be /mail-jobs/view
Response dumped to browser
A couple of things to note:
I have tried adding the function to the controllers policy, and actually authorizing an initialized entity. This has no effect and does not change the issue I am facing.
Something that is more frustrating, I have essentially the same code (ajax structure and controller structure) for other forms on the page, and they work just fine. The only difference seems to be any form that utilizes ajax that is on the page on render, works just fine. The ajax functions I am having an issue with, all seem to be from the forms rendered in Modals, which are different elements. Every form in a modal / element, gives me this issue and that's really the only pattern I have noticed.
Any help is greatly appreciated, I know it's an odd and vague issue.
Thank you!

passing javascript variable to php in cakephp 2 view

I am trying to pass a javascript variable into a php code in the view file of the cakephp 2.
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
<?php
$file11 = WWW_ROOT . 'img' . DS . 'book_images';
define('DIRECTORY', $file11);
$content = file_get_contents($abc);
file_put_contents(DIRECTORY . '/'.$isbn.'.jpg', $content);
?>
}
}
i am trying to pass the value of x in the file_get_contents function in place of $abc so that it could save the image coming from the javascript's URL accordingly.
EDIT::
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
$.ajax({
type: "POST",
url: '/BookSearchs/test',
data: {'yourX':x}
}).done(function(result) {
alert("yes");
}).fail(function() {
alert("no");
});
}
}
This is what i wrote after implementing the answers i got . But Everytime it pops up "no". Here BookSearchs is my controller and test is my function inside it.
EDIT 2:
function handleResponse(response) {
var target = '';
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x = book.thumbnail_url;
$.ajax({
type: 'POST',
url: "BookSearchs/test",
data: {
myVal: x
},
success: function() {
alert('AjaX Success')
},
error: function() {
alert('AjaX Failed')
}
})
.done(function() {
alert('AjaX Done!');
});
}
}
return true;
}
Currently this is what i've have done so far , the form method did not work out . It was redirecting me to another page . Anyways this is my current code . And 'test' is the my function inside the controller where i want to access the myVal value using POST . Also i have this question do i need to create a physical file for test in order to make the ajax function work, because if i delete the test.ctp file then the ajax starts giving the fail message . So for now i have created a physical test.file in the BookSearchs folder in the view , although it's empty in order to make the ajax function work . I am having a doubt whether my Url in Ajax is wrong or i am not accessing the values properly in the controller.
I don't think that this is a proper way to do that in theory. But, sometime we might need this.
Before we proceed to this way, you might need to think other technologies such as NodeJs (e.g fs.readFileSync)
Basically, you can't directly do that. Because, JavaScript run on client side and PHP is run on sever side.
Anyway, there might be a few tweak to do that. But, this approach might be slow and it depends on how many loop you making.
for (id in response) {
var book = response[id];
if (typeof(book.thumbnail_url) != "undefined") {
var x= book.thumbnail_url;
$.ajax({
type: "POST",
url: '/yourcontroller/route',
data: {'yourX':x}
}).done(function(result) {
//if success, execute other code
}).fail(function() {
//DO other if fail
});
}
}
Then, read this value in your controller
$xValue = $_POST['yourX'];
$file11 = WWW_ROOT . 'img' . DS . 'book_images';
define('DIRECTORY', $file11);
$content = file_get_contents($xValue);
file_put_contents(DIRECTORY . '/'.$isbn.'.jpg', $content);
//do some checking success or fail
//I will assume success
$status = 'success';
echo json_encode(['status'=>$status]);
Usally I use a Trick to pass JS variable to a CakePhp Controller(php variable). Actionly I create a form that contain a hidden input, I'll also put the link of the page that will receive the php variable.
.ctp
<?=
$this->Html->link('<i class="fa fa-file-pdf-o"></i>' .__('Export'),
'javascript:myFunction();',
array('escape' => false, 'class' => 'btn btn-app dispatch', 'id' => 'dispatch_packages',
'style'=>'margin-right:0px;background: #f39c12;color:white;',
'disabled' => 'false'));
?>
<form id="sampleForm" name="sampleForm" style="display: none" method="post" action="<?= $this->Url->build([
'controller' => 'YourController',
'action' => 'youraction']) ?>">
<input type="hidden" name="variable" id="variable" value="">
</form>
JS
var jsVar=0;
function myFunction()
{
document.sampleForm.variable.value = jsVar;
document.forms["sampleForm"].submit();
}
I used it with the CakePhp 3.x framework & it's working very fine. You have just to write the url with the CakePhp 2.x Syntax.
Don't hesitate to comment my answer if you'll have any difficulties to apply it.
Good Luck !

posting array using ajax to the controller in cakePHP

I am relatively new to cake and I am struggling with a custom filter that im making in order to display products based on which checkboxes have been ticked. The checkboxes get populated based on which attributes the user creates in the backend, i then collect all the values of the selected boxes into an array with javascript and post it to the controller, but for some reason I cannot access the controller variable named '$find_tags' in my view, it throughs undefined variable.
Here is my javascript and ajax which collects and posts correctly (when i firebug it 'data' in my controller has array values which im posting) so thats fine
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'data[ID]='+searchIDs;
$.post("",data,function(data){
console.log(data);
});
});
Here is my controller code which im assuming is where the fault lies
if ($this->request->is('post') ) {
$data = $this->request->data['ID'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
$this->set('find_tags', _($find_tags));
}
}
And here is my view code where i get Undefined variable: find_tags
foreach($find_tags as $all_tag)
{
echo $all_tag['Product']['name'];
echo '</br>';
}
Any help or suggestions would really be appreciated been struggling with this for a while now
If searchIDs is array of ids you just need to make the json of array and then send to your controller
$("#clickme").click(function(event){
event.preventDefault();
var searchIDs = $("#checkboxes input:checkbox:checked").map(function(){
return $(this).val();
}).get();
var contentType = "application/x-www-form-urlencoded";
var data = 'ids='+JSON.stringify(searchIDs);
$.post("controller url",data,function(data){
console.log(data);
});
});
On php side you are getting wrong variable
if ($this->request->is('post') ) {
$data = $this->request->data['ids'];
$find_tags = array();
$selected_tags = $data;
foreach($selected_tags as $tag)
{
array_push($find_tags,$this->Product->findByTag($tag));
}
$this->set('find_tags', _($find_tags));
}

Jquery and ajax, my function for username checking?

I have written this ajax request for username checking...
function check_username() {
var username = $("#username").val();
$('.loading').fadeIn().delay(100);
$.post("ajax.php", {
username: $('#username').val(),
}, function (response) {
$('.error, .success').hide();
setTimeout(function () {
$('.loading').hide();
finishAjax('username', response);
}, 1000);
});
return false;
}
function finishAjax(id, response) {
$('#' + id).after(response).fadeIn(1000);
}
It all works fine just a couple of questions,
Can this code be improved in any way, this is the first ever one I have wrote so I wouldn't know.
Is there a way to make this a function for all my ajax requests rather than just username checking, so it can be used for email checking and such too. I am not sure on how to make a function like that would I have to pass variables on my onblur event which is attached to my form, at the minute it looks like this.
Is there a way to stop the ajax from running if the same error is there as previous, ie, string length should be over 3, so someone inputs AJ, and the error message 'must be over 3 characters' comes up, it the user then triggers the onblur event again, with the value of AJ, or CG, then the same error comes up, triggering a script that is useless and using memory.
Is there a way to make the ajax request with every character the user enters?
My ajax php is as follows...
<?php
require('dbc.php');
if (isset($_REQUEST['username'])) {
$q = $dbc -> prepare("SELECT username FROM accounts WHERE username = ?");
$q -> execute(array($_REQUEST['username']));
if (strlen($_REQUEST['username']) < 3) {
echo '<div class="error">Has to be at least 3 characters</div>';
}
elseif ($q -> rowCount() > 0) {
echo '<div class="error">Username already taken</div>';
}
else {
echo '<div class="success">Username available</div>';
}
}
?>
To answer 1 & 2. I would turn it into a plugin and do something along these lines.
$.fn.checkValid = function(options)
{
var response = function(response) {
var setClass = '';
var $span = $(this).data('checkValidTip');
if ($span)
{
$span.remove();
}
if (response === undefined) return;
setClass = (response.valid ? 'valid' : 'invalid');
var $span = $('<span>' + response.msg + '</span>');
$(this)
.data('checkValidTip', $span)
.after($span);
$span.hide()
.fadeIn(1000)[0]
.className = setClass;
};
var ajaxOptions = {
type: 'GET',
url: 'ajax.php',
success: response,
dataType: 'json'
};
this.each(function() {
var that = this;
var ajaxRequest = ajaxOptions;
ajaxRequest.data = {};
ajaxRequest.data[options.key] = this.value;
ajaxRequest.context = that
$.ajax(ajaxRequest);
});
};
Usage
$('#username, #email').blur(function() {
$(this).checkValid({ key: this.id });
});
PHP changes
You should make your PHP function return a JSON, instead of HTML i.e.
<?php
// Do your sql statements here, decide if input is valid or not
$arr = array('valid' => $is_valid,
'msg' => $error_or_good_msg
);
echo json_encode($arr);
/* For example will output:
{
"valid": "false",
"msg": "<b>Error: Must be at least 2 characters</b>"
}
Which can be read directly as response.valid
or response.msg from within response() function
*/
To answer question 3: short answer is no. For this to work, you should have basic validation in JS. The best option would be to use a plugin that uses objects for validation parameters, that way you can output your validation requirements dynamically from your database, from within PHP using json_encode i.e. your output format would be:
var validations = {
username: {
min_chars: 4,
max_chars: 10,
valid_chars: 'qwertyuiopasdfghjklzxcvbnm_-'
},
email: {
regex: /./ //your magic regex here
}
};
jsFiddle
http://jsfiddle.net/sqZfp/2/
To answer 4, just change the event as above from .blur to .keyup should do the trick.

accessing requestParameters when using AJAX - Symfony

I have a form that is a drop down select list.
I also have an action, that looks for the request parameter:
indexAction:
if($this->getRequest()->isXmlHttpRequest())
{
$this->setLayout('layout');
}
$param = $this->getRequestParameter('type');
if($param == 'video')
{
isicsBreadcrumbs::getInstance()->addItem('All Videos', '#homepage');
$pager = new sfPropelPager('Item', 15);
$pager->setPage($request->getParameter('page', 1));
$pager->setPeerMethod('doSelectLatestVideo');
$pager->init();
$this->pager = $pager;
}
elseif($param == 'photo')
{
isicsBreadcrumbs::getInstance()->addItem('All Photos', '#homepage');
$pager = new sfPropelPager('Item', 15);
$pager->setPage($request->getParameter('page', 1));
$pager->setPeerMethod('doSelectLatestPhoto');
$pager->init();
$this->pager = $pager;
}
}
Now this works fine when the url is: example.com?type=video - it loads the video content
The problem is, I'm wanting to update the content using AJAX and because I'm doing it via AJAX, I'm struggling to get the requestParamater, since it is no longer in mu URL;
ajax function:
$("#filter-form-newsroom .submit").live('click', function(e){
$("#search-results").html(ajax_loading);
var content_type = $("#filter-form-newsroom #type").val();
$.ajax(
{
url: "",
type: "GET",
data: "?type=" + content_type,
success: function(data){
var $response=$(data);
var filtered_response = $response.find('.post');
$("#search-results").html(filtered_response).hide().fadeIn("fast");
}
});
e.preventDefault();
});
This function checks the parameter in my select list and is supposed to filter by the requestParamter, but it isn't working.
Any ideas?
Thanks
Rather than putting ?type=" into the data property, put it in the url. Wouldn't that result in the same request you get when you type the URL yourself?

Categories