$ajax->submit Does Not Go To Controller - ajax

I am using cakephp and pippoacl plugin and I simply cannot add a new role. What I modify in the plugin is to make the submit using ajax, something like this in my view (add.ctp):
<?php echo $ajax->submit(
'submit',
array(
'url' => array('controller' => 'roles', 'action' => 'add'),
'before' => 'beforeSubmitAdd();',
'complete' => 'completeSubmitAdd(request);'
)
);
?>
When the add.ctp gets loaded for the first time, I can print_r something from the controller. But the ajax submit above only executes the javascript on 'before' and 'complete'. I check on the firebug, the response is blank.
On my controller:
function add() {
print_r("start");
if (!empty($this->data)) {
print_r("add new role");
// save new role
}
}
I use ajax submit for user and I don't have any problem adding new user. Is there any idea where I should check? I have been comparing the user and role code for a week and I have asked a friend to look at my code, too, but we still cannot find what causes this.
Thanks in advance! :D

I am not so familiar with the Ajax helper, but I haven't using it from so long that I can't remember what is it doing :).
Back to the problem.
Did you check if the requested URL in the Ajax address is correct? This should work straightforward, but it's possible that the url to be invalid.
Are you using Security component (even just adding it on the var $components variable)?. This could lead to blank screen especially if you modifying the fields in the form somehow. Try to remove it and see if it's working without.
Finally I would say how I would do it with jQuery.
Following code should do the job:
$(document).ready(function(){
$('form').live('submit', function(){ //handles also dynamically loaded forms
var form = $(this).addClass('loading'); //indicate somehow that the form has been submitted
$('#content').load($(this).attr('action'), $(this).serialize(), function(){
form.removeClass('loading');
});
})
});
This will handle all submits in the forms of the system, but you can modify of course.

Related

Inertia.JS reload props after post request

I am currently pretty confused why Inertia.js is not reloading or rerendering my page.
I have a form that could be filled, once submitting this will execute:
Inertia.post("/ban", ban);
This will redirect to a POST in the web.php of my Laravel.
That looks like this:
Route::post("/ban", [Speler::class, "ban"]);
This redirects to a class called "Speler", in there is a function called "ban".
Once done some SQL statements it will execute this return:
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
This will go back to the web.php, and go to the route speler with the session data "success".
That redirect goes into the web.php:
Route::get("/speler/{steam}", [PageLoader::class, "speler"])->name("speler");
This one goes to the PageLoader controller, and execute the "speler" function.
But here it gets weird, this will return a Inertia::render of the same page the person was on, but would need to add another prop, or change the prop. (so i can show a popup with te text that it succeeded)
return Inertia::render("Panel/Speler",
["steamNaam" => $steamNaam, "discord" => $discord, "karakterAantal" => $karakterAantal, "karakters" => $karakters, "sancties" => $sanctiesReturn, "punten" => $aantalPunten, "steamid" => $steamid, "success" => $melding]
);
The "success" prop contains $melding that simply contains a string.
But for some reason it doesn't seem to re-render the page, the form stays filled, and the props are the same.
Does someone have a solution?
If you setup your form with the form helper, you can reset the form on a successful post like this:
form.post('/ban', {
preserveScroll: true,
onSuccess: () => form.reset(), // reset form if everything went OK
})
The success message, which you set with
return Redirect::route("speler", [$steam])->with("success", "Ban doorgevoerd!");
is usually taken care of by the Inertia middleware and made available as 'Shared data'. See this docs page on how to configure that. Shared data is rendered in $page.props variable. That is where you can find the Ban doorgevoerd! message. You can show these to the user as follows:
<div v-if="$page.props.flash.message" class="alert">
{{ $page.props.flash.message }}
</div>
Depending on your implementation, you would need to watch this property. See the FlashMessages component on the pingCRM demo app for an example implementation.

Laravel: controller not teletransporting me (redirect-ing me) to the page

from Ajax the controller does get the keyword I want, as it confirms it (because I echo it), and my idea was that on getting that keyword, it should redirect to the page I want. Yet, it does not, and also, while it does change the locale, I have to reload the page, otherwise, it won't show any translation and locale changes on the page. In Firebug when I hover over the POST, I get the correct URL to where I would want to go: sort of http://myweb.com/es but the controller does not change the http URL box of my browser on my web to go there.
I am simplifying the Controller code here, but actually I will want it to go to different URLs depending on the keyword it gets, something that I would do with a switch statement or IF else if etc.
So the controller is as simple as this:
public function changelanguage()
{
$lang = \Input::get('locale');
echo "I got $lang";
Session::put('locale', $lang);
return redirect('/es');
}
If instead of using ajax I use a Form, then I dont need to reload, the Action of the form makes the controller change the locale and translate the page without reloading. But I need to use ajax and in any case, the controller does get correctly the keyword ('en', 'es', 'de' etc ) for languages, so it should take it from there and redirect me to the URL page, but it just doesnt move.
if you are curious about the Ajax, here it is, but it does send the keyword as I said.
$(document).ready(function(){
$('.choose-language').on('click', function(e){
e.preventDefault();
var selectedlanguage = $(this).data('value');
$.ajax({ // so I want to send it to the controller
type:"POST", // via post
url: 'language',
data:{'locale': selectedlanguage},
}); // HERE FINISHES THE $.POST STUFF
}); //HERE FINISHES THE CLICK FUNCTION
}); // HERE FINISHES THE CODE
ROUTES
Route::post('language', array(
'as' =>'language',
'uses' => 'LanguageController#changelanguage'
));
If you’re trying to perform the redirect in the AJAX-requested script, then it won’t work. You can’t redirect from a script request via AJAX otherwise people would be doing all kinds of nefarious redirects.
Instead, set up a “success” handler on your AJAX request that refreshes your page if the request was successful. It can be as simple as:
var url = '/language';
var data = {
locale: $(this).data('value');
};
var request = $.post(url, data)
.success(function (response) {
// Script was successful; reload page
location.reload();
});
I’m not sure how you’re allowing users to select locales, but since you need a reload any way I think AJAX is pointless here. Just have a traditional form that submits the new locale to an action, set the locale in a session/cookie/whatever, and then redirect back to the referring page.

Laravel 4.0 Filter and Ajax to load a bootstrap modal pop up

I'm doing a website based laravel 4.2 and Bootstrap. I want a bootstrap modal pop up dialog to load on certain routes provided that the user is not already logged in.
So far i have accomplsihed it to load for the entire application upon loading which is not i want but am in the right direction.
This is my ajax call
script type="text/javascript"> $(document).ready(function() {
$.get("status", function(data, status){
data.status == false ? $('#modal-form').modal({backdrop: 'static'}) : $('#modal-form').modal('hide');
});
});
Status refers to a URL defined in this route
Route::get('/status', 'LoginController#getLoginStatus');
and the method is defined here
public function getLoginStatus()
{
return Response::json(array( 'status' => Sentry::check()));
}
From that, the modal dialog loads on each route across the entire application. I would want to limit the dialog to load on certain routes provided the user is not logged in.
Thing Laravel filter would do the trick for me but i have failed to do so.
Something like
Route::filter('status', function()
{
});
and then the route be like:
Route::get('profile', array('as' => 'submit-profile','before' => 'status','uses' => 'ProfileController#getProfile'));
Thanks guys hope you can give me some advice.
You could use the
Route::currentRouteName()
to check what route your on and then do your preferred action,
like calling the ajax get request for the modal.

cakephp updating elements

I have an index view which has some elements on it .
index controller code;
$userID = $this->Authsome->get('id');
$qnotes = $this->Qnote->getnotes($userID);
$this->set('qnotes', $qnotes)
$this->render();
elements have been added to the page using
index view code
<?php echo $this->element('lsidebar'); ?>
now the Issue is I also Have an add controller.
add controller code
function add() {
if(!empty($this->data)) {
unset($this->Qnote->Step->validate['qnote_id']);
$this->Qnote->saveAll($this->data);
$this->Session->setFlash('New Note Template has been added.','flash_normal');
}
}
now what I am trying to achieve is once I add a Qnote i want the element('lsidebar') updated
for the new Qnote.
I am Using the Ajax helper. found at http://www.cakephp.bee.pl/
also Here the add qnote View Code :
<?php echo $ajax->submit(
'Submit', array(
'url' => array(
'controller'=>'qnotes',
'action'=>'add')
));
I know its sound like a noob question . can Somebody point me in the right direction atleast.
I have tried everything i could think off. I bet the solution something easy which i didnt think off
help :)
If you want to dynamically update a sidebar with information that is submitted via ajax, there should be a "success" option in your ajax post that would allow you to fire a specific javascript action when the post is finished (or succeeds). You should write a small javascript ajax function to reload the contents of your sidebar when the post succeeds.
See this other stackoverflow answer: CakePHP ajax form submit before and complete will not work for displaying animated gif

Yii, ajax, Button. How to prevent multiple JS onclick bindings

(First of all English is not my native language, I'm sorry if I'll probably be mistaken).
I've created Yii Web app where is input form on the main page which appears after button click through ajax request. There is a "Cancel" button on the form that makes div with form invisible. If I click "Show form" and "Cancel" N times and then submit a form with data the request is repeating N times. Obviously, browser binds onclick event to the submit button every time form appears. Can anybody explain how to prevent it?
Thank you!
I've had the exact same problem and there was a discussion about it in the Yii Forum.
This basically happens because you are probably returning ajax results with "render()" instead or renderPartial(). This adds the javascript code every time to activate all ajax buttons. If they were already active they will now be triggered twice. So the solution is to use renderPartial(). Either use render the first time only and then renderPartial(), or use renderPartial() from the start but make sure the "processOutput" parameter is only set to TRUE the first time.
Solved!
There was two steps:
First one. I decided to add JS code to my CHtml::ajaxSubmitButton instance that unbind 'onclick' event on this very button after click. No success!
Back to work. After two hours of digging I realized than when you click 'Submit' button it raises not only 'click' event. It raises 'submit' event too. So you need to unbind any event from whole form, not only button!
Here is my code:
echo CHtml::submitButton($diary->isNewRecord ? 'Создать' : 'Сохранить', array('id' => 'newRecSubmit'));
Yii::app()->clientScript->registerScript('btnNewRec', "
var clickNewRec = function()
{
jQuery.ajax({
'success': function(data) {
$('#ui-tabs-1').empty();
$('#ui-tabs-1').append(data);
},
'type': 'POST',
'url': '".$this->createUrl('/diary/newRecord')."',
'cache': false,
'data': jQuery(this).parents('form').serialize()
});
$('#new-rec-form').unbind();
return false;
}
$('#newRecSubmit').unbind('click').click(clickNewRec);
");
Hope it'll help somebody.
I just run into the same problem, the fix is in the line that starts with 'beforeSend'. jQuery undelegate() function removes a handler from the event for all elements which match the current selector.
<?php echo CHtml::ajaxSubmitButton(
$model->isNewRecord ? 'Add week(s)' : 'Save',
array('buckets/create/'.$other['id'].'/'.$other['type']),
array(
'update'=>'#addWeek',
'type'=>'POST',
'dataType'=>'json',
'beforeSend'=>'function(){$("body").undelegate("#addWeeksAjax","click");}',
'success'=>'js:function(data) {
var a=[];
}',
),
array('id'=>'addWeeksAjax')
); ?>
In my example I've added the tag id with value 'addWeeksAjax' to the button generated by Yii so I can target it with jQuery undelegate() function.
I solved this problem in my project this way, it may not be a good way, but works fine for me: i just added unique 'id' to ajax properties (in my case smth like
<?=CHtml::ajaxLink('<i class="icon-trash"></i>',
$this->createUrl('afisha/DeletePlaceAjax',
array('id'=>$value['id'])),
array('update'=>'.data',
'beforeSend' => 'function(){$(".table").addClass("loading");}',
'complete' => 'function(){$(".table").removeClass("loading");}'),
array('confirm'=>"Уверены?",'id'=>md5($value['id']).time()))
?>
).
Of course, you should call renderPartial with property 'processOutput'=true. After that, everything works well, because every new element has got only one binded js-action.
text below copied from here http://www.yiiframework.com/forum/index.php/topic/14562-ajaxsubmitbutton-submit-multiple-times-problem/
common issue...
yii ajax stuff not working properly if you have more than one, and if
you not set unique ID
you should make sure that everything have unique ID every time...
and you should know that if you load form via ajax - yii not working
well with it, cause it has some bugs in the javascript code, with die
and live
In my opinion you should use jQuery.on function. This will fire up event on dynamically changed content. For example: you're downloading some list of images, and populate them on site with new control buttons (view, edit, remove). Example structure could looks like that:
<div id="img_35" class='img-layer'>
<img src='path.jpg'>
<button class='view' ... />
<button class='edit' ... />
<button class='delete' ... />
</div>
Then, proper JS could look like this ( only for delete, others are similiar ):
<script type="text/javascript">
$(document).on('click', '.img-layer .delete', function() {
var imgId = String($(this).parent().attr('id)).split('_')[1]; //obtain img ID
$.ajax({
url: 'http://www.some.ajax/url',
type : 'POST',
data: {
id: imgId
}
}).done({
alert('Success!');
}).fail({
alert('fail :(');
});
}
</script>
After that you don't have to bind and unbind each element when it has to be appear on your page. Also, this solutiion os simple and it's code-clean. This is also easy to locate and modify in code.
I hope, this could be usefull for someone.
Regards
. Simon

Resources