Kill jquery ajax form submit - ruby-on-rails-3

I am remotely submitting a form potentially several times in close succession. For this particular case, debouncing is not an option. I am looking for the jQuery equivalent of .abort() for remote forms submitted using .submit() so I can cancel all previous submissions when a new one is made.
Thanks in advance,
Garrett

What I did is attach to the beforeSend event of the form, store the xhr object as part of the form's data, and abort it if a new request is enqueued:
$('form').bind("ajax:beforeSend", function(evt, xhr) {
console.log('Enqueued new xhr request');
var prevXhr = $(this).data('current-xhr');
if (prevXhr) {
prevXhr.abort();
console.log('Aborting previous xhr request');
}
$(this).data('current-xhr', xhr);
});
And you can still use the :remote => true option in the form straightforward.

Maybe you could use jQuery .queue() to queue your submits and .clearQueue() to clear the queue when needed. Just an idea...

I don't understand your problem. If the form is submitted, a request is sent to the server... so, how can you abort that?
If by abort you mean, cancelling the processing of the response, just use a control variable that you increase/decrease to know if there are pending requests.
From the API: http://api.jquery.com/category/ajax/ you can't do that.

Related

Multi-web server ajax callback with refresh on Enter

Question about how to send a jQuery callback with an onSuccess: refresh from a textInput when the user presses [Enter]. We use the [Enter] press to trigger a search callback.
Our GS Seaside app uses HAProxy. This means the onSuccess: script is handled by a different gem than the one that handles the callback. Because of this, users will sometimes get the refresh because the callback, which to them looks like a lost input (a browser F5 refresh shows the right state). If running single gem or in a VW / Pharo image this problem does not come up.
I can work around the problem by using...
async: false;
...but that prevents me from show any kind of waiting feedback (I normally use a busy gif).
So, the question is: in a multi-web server configuration, how can you code a callback to...
1 - show a busy gif
2 - trigger the search callback
3 - refresh the display when done
...all in that order.
Using a form submission callback is a problem because multiple text inputs can trigger the search, since the callback is 'set value + do search', by virtual of the default [Enter] press.
For the JS callback, I'm using...
self onKeyPress: (
(JSStream
on: '(window.event ? window.event.keyCode : event.which) == 13')
then: (canvas jQuery ajax callback: aBlock value: canvas jQuery this value))
It all works fine, except for the missing busy gif, due to the 'async: false'.
Any suggestions?
You can define a beforeSend and a complete handler to show and hide the loading indicator while the request is being processed. The global parameter set to false is meant to ignore your existing handlers to process request start and end (the mentioned spinner), and only use these defined in the particular instance of the JQAjax object.
((html jQuery ajax)
async: false;
global: false; "https://api.jquery.com/category/ajax/global-ajax-event-handlers/"
callback: aBlock value: canvas jQuery this value;
onBeforeSend: (html jQuery id: 'indicator') show;
onSuccess: ((html jQuery id: 'fieldId') load html: [:h | ]);
onComplete: (html jQuery id: 'indicator') hide;
That said, keep in mind that doing a synchronous AJAX call is discouraged since it will block the whole UI thread until the request is resolved.
So it's not completely clear how you manage the state in different worker images (gems, in this case) returning different things (probably because of having different sessions), so it's also not clear to me why doing an async XHR request will be served differently to doing it synchronously, I never experienced that.
From the small sample you mention, it can't be deduced what is the "refresh" part of your code. So maybe, providing more context will help us give you more accurate answers.
Fix ended up being trivial: needed to include 'event.preventDefault();' in the [Enter] key script. Seems obvious in hindsight.
if ((window.event ? window.event.keyCode : event.which) == 13) {
event.preventDefault();
};'
This problem is confirmed to be a narrow configuration symptom: GemStone with multiple gems. On every other configuration Seaside / javascript behaves as expected. I will follow this up as a vendor problem. Thanks to everyone that looked at it (this was also posted on other forums).

Vue changing the component without URL changes

I'm in Registration.vue component. The component contains registration form with email, password, etc.. fields.
I would like to thanks user for successful registering (with instruction that he should go check email).
What is the best solution to do this?
I was thinking about:
redirecting to second component using this.$router.push or this.$router.replace but this will change URL and when somebody go this URL without registering he will see message that he should check email...
replacing current component with other when registering action successful but I dont know how to do this (without URL change, and with good code).
using <component v-bind:is="currentView"> but I am not sure if this is best solution. I need to make three files (for parent component with :is, for form and for thanks). Also i need to emit event from child that registration went well, but on the other hand i should fire vuex registration action and dont expect for response (see the next sequence)
The other thing is that we should not wait for the vuex action to be completed, but i need to know if registration went well - https://github.com/vuejs/vuex/issues/46#issuecomment-174539828
I am using vue.js 2, vue-router, vuex
Thanks
You could use something like Sweet Alert to display a success or error dialog. It supports Ajax requests so you can display a "your registration is processing, please check your email" message while it is being handled.
The first approach is suitable when user successfully registers and then redirected to login page.
Now issue how to check whether user has entered required field? So there comes form validations. You can use vee-validate plugin and it's perfect for all projects. I am using it and it has so many available validations.
With these UI validations, after they are passed successfully then only submit action will be fired or else user will be prompted for entering required field.
You can see basic example here - http://vee-validate.logaretm.com/index.html#basic-example
When action is performed,
///main.js
...
Vue.use(VeeValidate)
...
// register.vue
this.$validator.validateAll().then((result) => {
if (result) {
//done
this.$router.replace( '/login' );
}
else{
// throw error
}
Simple as that.
Try this approach if you want the UI validations on the form.

YII getFlashes() not deleting?

Before jumping in with an answer, please make sure you understand my scenario.
I have ajax calls that CREATE flashes.
I have other ajax calls that FETCH the flashes as JSON.
What is currently happening: I click a button which creates the flash. After which I run a ajax call that executes:
public function actionGetAllFlashesAsJSON() {
$flashMessages = Yii::app()->user->getFlashes(true);
$returnResult = array();
foreach ($flashMessages as $key => $value) {
$newItem = array();
$newItem['message'] = $value;
$newItem['kind'] = $key;
$returnResult[]= $newItem;
}
print json_encode($returnResult);
die();
}
My problem is, when I execute this function twice in a row, it still keeps returning the flashes. However, if I refresh the site, it shows the error, and then if I press refresh again, it's gone. My theory is that page refresh is causing some other kind of deletion of messages... but what? And how can I force the deletion of these messages after I receive the message in the above code?
More background info: I am using the flashes as ERROR messages, but i want them to appear at the top of my site AS THEY ARE CREATED. Flashes might get created via Ajax, so I have javascript running to check for new messages, and display them, but my problem is it shows the messages several times, because they are not getting deleted after calling getFlashes?
The flash messages are controlled by SESSION variables, which Yii destroys when the page is loaded (probably somewhere quite deep in the framework). You will have to manually destroy all the previous flash messages at the start of the ajax request
You can use: getFlashes() to get all the existing flash messages
For the other flash message methods have a look at the CWebUser docs here

Remote AJAX call when checking a ceckbox in Rails 3

If I have a checkbox in Rails3, How can I perform a remote AJAX call when the user changes the value of it.
It sound like a simple task, but I fail to find a good solution for it.
You can pass the value of check-box on change event to the form and by using :remote => true you can use AJAX in form_for.syntax of on changing the check box and submitting the form is ":onchange => "this.form.submit()
I hope this would help you.
Thanks.

Keeping browser from timing out in mvc3 app during long processing time

MVC3 vb.net. In my app I have a point where 500+ emails with attachments are sent out using a for each loop to accomplish this.. Nothing is returned to the browser the entire time this is running so eventually the browser think it has timed out... I tried just having it redirect to another actionresult function after every email and that function just passes it back to the email function. This is not working and I feel the reason is that nothing is actually being sent to the browser window its self.. Is there a way to fix this issue??
If _keepAlive = 1 Then
RedirectToAction("keepAlive", "Email")
End If
Function keepAlive() As ActionResult
Return RedirectToAction("SendClassSchedules", "Email")
End Function
You can try an async action and set the timeout to a large value:
http://msdn.microsoft.com/en-us/library/system.web.mvc.asynctimeoutattribute.aspx
http://blogs.claritycon.com/blog/2011/04/12/roll-your-own-mvc-3-long-polling-chat-site/
In the past, we have successfully started a background thread to do the processing, then set the page to refresh itself once a second - with each refresh reporting progress. I suppose If I was doing something like that today, I would use a page method and javascript ajax call to update the page with the progress.
Are you talking about this? http://msdn.microsoft.com/en-us/library/ms525473(v=vs.90).aspx
I think you could change Session.Timeout to suit your needs better..