We have an edit form that only allows one user to edit a form at a time. The form is quite large and has quite a bit of Knockout.js code in it and this code intercepts the Submit button click to do validation, then if everything is fine it submits the form.
Nothing has changed on the server side or view side, yet just in the last few days we are having a large amount of OptimisticConcurrency errors being logged.
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
The only other correlation is that some users are complaining about the site running slow. I was hoping someone may have a guess as to what is causing this? It is probably affecting less than 1% of our forms but this still causes a lot of inconvenience. It is a MVC 5 site on a load balanced server.
Aside from what may be causing this, is there some other idea of what I should do to solve the problem, like switching to a client wins concurrency exception? These are medical records so any data loss could be detrimental.
Update
From the comments, here is the code that runs when the submit button is pressed.
self.saveClick = function () {
validationTests();
if (self.validationError()) {
return false;
} else {
return true;
}
}
So that wouldn't disable the button from being pressed multiple times, would it? This may be the problem, now that the site is running slow.
As you're getting multiple submits from the same user it's probably worth ensuring that your submit button is disabled on a click.
Here's a question with an example of how to do this
Disable submit button on form submit
worth noting that as you're doing lots of validation then you need to re-enable the button if it fails validation.
Related
Our app allows users to submit data to our servers.
Sometimes, users will need to make 3 submission in a row. After checking that the submission works properly (and thankfully it does), we call CustomForm().show() and the Form shows correctly. (CustomForm obviously extends Form.)
We use InteractionDialogs, just as in all other iterations, to handle validation by providing feedback to the user. We do so to mimic the Android Snackbar that provides a prompt and a Button to do an action. In the 1st 2 iterations, the InteractionDialogs show and dispose properly; in the 3rd iteration, the InteractionDialogs start acting erratically.
We also noticed that once that CustomForm (or any other submission forms) is shown 3 times (either the same Form 3 times in a row, or any combo of our submission forms 3 times altogether), a different Form displaying a BrowserComponent will fail – the BrowserComponent will not show anything at all, despite using a strong, unfiltered internet connection and having worked properly prior to the submissions being done. Neither the app nor the Form housing the BrowserComponent crashes -- the BrowserComponent simply does not show anything.
Is there a limit on how many instances of a given Form can be shown, or is there a memory issue?
Please, any ideas on how to solve this?
Thank you.
EDIT: I am adding a screenshot of the EDT thread -- it seems to have invokeAndBlock() called twice and then wait() is called, even though I wrapped my call to show the Form with the BrowserComponent with this try-catch:
try {
CN.invokeWithoutBlocking(() -> {
new FormWithBrowser().show();
)};
} catch (BlockingDisallowedException ex) {
e.getMessage();
}
The other issue is how do I fix InteractionDialogs in my submission form from being affected by invokeAndBlock() and wait() as well? I also don't get any BlockingDisallowedExceptions in my logs. Does that mean that wait() is really the issue?
Thanks again.
I need to check if an element is appearing after refreshing a page continuously, cause it takes a while for the changes to be reflected and the element to appear in that page.
Is there any built in method in selenium using Ruby as the programming language ?
Just to confirm, it sounds like the page does not dynamically update once the content is available, so you have to wait until that is true, and then manual refresh, right?
I don't know of anything built into selenium to handle this. It feels like it might even be a symptom of a UI that needs a little more design work (pardon my critique). If the user is experiencing the same thing as the test -- kicking off an action, waiting some unspecified period of time, and then manually refreshing to see the results -- that's a kind of lousy user experience. If that's a bad assumption, and there IS feedback (e.g. a spinner), then your best option will be to conditionally wait for the spinner to appear and then disappear, and then refresh a single time.
If there's really no visible feedback, then you still have a couple of options:
Easy: Hardcode a sleep that's longer than the operation will ever take to complete, and refresh once.
Medium: In a loop, sleep for a constant delay, refresh, repeat until some timeout.
Hard: If the delay required varies widely (sometimes seconds, sometimes minutes), you might consider an exponential back off solution, that sleeps for increasingly longer delays each iteration, before ultimately timing out. The upside is that you're not frantically refreshing dozens of times, the downside is that your delay might be unnecessarily long, if the content arrives just after the next big delay begins.
You can use wait method for the element to be available.
If you need to refresh the page continuously just make sure to wait after each refresh.
I use react.js + es6 + webpack to develop my application.
recently, I find if I click a button multiple times in short time, the click handler will trigger multiple times.
I think it's a common case, code snippet like this:
#debounce()
onMidCardClick(url) {
console.count('onMidCardClick trigger times : ');
window.location.href = url;
}
before navigate to the url address, onMidCardClick event handler will triggers multiple times.
So, my way is create a debounce.decorator.js to handle this situation.
I think my way's advantage is easy to read and keep maintainability.
My question is:
1. Is it necessary to handle this? I mean, maybe react synthetic event will handle this for me?
2. My application has many events, I add debounce decorator for many of them. I test it, it works fine, but I am not sure I am correct. Because I saw many applications not deal with this.
No, all you need to do is, the moment user clicks a button, disable the button till you get the response. You can also disable other buttons too if required. Ex.
<button type="button" disabled={!this.clicked}>Button</button>
From a usability point of view, if the user clicks on a button/li/div element and you are executing some logic, it is better to give a visual indicator that some processing is happening, with a loader or a progress bar.
You can write a react component for a full page loader like this and show it to the user, which effectively prevents the user from clicking the element again while giving a visual clue as well.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
If a user clicks a cancel button should it pop up a dialogue asking for confirmation?
If so, should this be all the time, or only when there are unsaved changes on a form?
No unless it's something that is very vital/potentially harmful. Having popups followed by popups is annoying.
If canceling the action will destroy data or a device, yes. For instance, canceling in the middle of upgrading the firmware of some device.
If the action being performed takes a long time and an accidental cancelation will require starting over, yes.
For instance, I don't find the pop-up here on StackOverflow annoying when I decide to close a tab rather than making an edit I started on one of my questions.
"Cancel" means to give up on an action before it begins. If the action has already started, the command should be named "Stop" instead. That makes it clear to the user that the button might interrupt something in mid-stream.
A real Cancel action doesn't need confirmation because it doesn't cause any problems. A Stop action might, but only if stopping partway through could leave things in a messed-up state. (And in that case, you should consider finding a way to have the stop back out all the already-made changes so that the state reverts back to what it was before the action began. This isn't always possible, of course, like if you're deleting files.)
It really depends on the situation.
Encoding a video for example, a process that may take hours, should have a confirmation, just because you may accidentally hit the button at 99%.
The initialization process of an installer or other app, on the other hand, doesn't need a confirmation since it can typically be restarted quickly enough and doesn't take long to begin with.
If clicking Cancel starts a process that will potentially take a long time (let's say it needs to reverse changes), the user should be informed about that, possibly with a popup, but some text next to the button might suffice as well.
The general rule is to minimize Confirmation Dialogs as much as possible, if for example it could be replaced with an Undo action. I don't think this applies to most Cancel buttons though.
Use the following algorithm to determine the answer to your question:
if (1-p)*w > p*a then ask for confirmation
where
p is the probability that the user really wanted to cancel (0.7 or so)
w is the amount of lost (work-) time due to inadvertent cancelling
a is the time lost due to an anoying confirmation (5 seconds or so)
Of course you have to estimate p, w and a. Using my default values, you should ask for confirmation when unintentional canceling would cost the user more than 10.5 seconds of time.
So, in the case of a long-time operation, e.g. encoding a video, you shouldn't ask if the user clicks cancel within 10 seconds after starting that task. In the case of data entry, don't ask if the form is still completely empty, but ask if the user has already entered data.
Make the action easy to do without confirmation (don't annoy your users!). But, also make it easy to undo. Read Alan Cooper's About Face for lots of good UI advice.
Basically, if undo-ing a cancel is difficult, time-consuming, or impossible, you should prompt the user. Those are usually the case when the user has done some actions that they might wish to preserve (e.g. writing a blog post and closing a tab, updating firmware on a hardware device, running system updates, installing large pieces of software) instead of just deleting the current state. After all, sometimes the cancel button may be clicked accidentally. You just need to use common sense to determine whether it would be a really bad experience for the user if an operation was accidentally cancelled (which would call for a cancel prompt), or whether they could easily restart whatever operation was accidentally cancelled without much loss. The strategy I use for solving such problems is by putting myself in the user's shoes, i.e. imagining myself as a user of this program. How would I feel if I accidentally clicked cancel??? If that mentality is grim, add a prompt in case.
It would be better to not prompt, but make it easy to undo the cancellation once it is done, if possible. GMail does this well. You click 'Delete', it deletes, but you get a link at the top to say 'Undo delete'.
I think the answer in terms of data.
If user made changes on data , not talking about clicking somewhere on interface, user should be asked to confirm exiting.
But if no change happenned, no reason for confirmation. Because confirmation is an effort for user.
I'm putting together a small web app that writes to a database (Perl CGI & MySQL). The CGI script takes some info from a form and writes it to a database. I notice, however, that if I hit 'Reload' or 'Back' on the web browser, it'll write the data to the database again. I don't want this.
What is the best way to protect against the data being re-written in this case?
Do not use GET requests to make modifications! Be RESTful; use POST (or PUT) instead the browser should warn the user not to reload the request. Redirecting (using HTTP redirection) to a receipt page using a normal GET request after a POST/PUT request will make it possible to refresh the page without getting warned about resubmitting.
EDIT:
I assume the user is logged in somehow, and therefore you allready have some way of tracking the user, e.g. session or similar.
You could make a timestamp (or a random hash etc..) when displaying the form storing it both as a hidden field (just besides the anti Cross-Site Request token I'm sure you allready have there), and in a session variable (wich is stored safely on your server), when you recieve a the POST/PUT request for this form, you check that the timestamp is the same as the one in session. If it is, you set the timestamp in the session to something variable and hard to guess (timestamp concatenated with some secret string for instance) then you can save the form data. If someone repeats the request now you won't find the same value in the session variable and deny the request.
The problem with doing this is that the form is invalid if the user clicks back to change something, and it might be a bit to harsh, unless it's money you're updating. So if you have problems with "stupid" users who refresh and click the back-button thus accidentally reposting something, just using POST would remind them not to do that, and redirecting will make it less likely. If you have a problem with malicious users, you should use a timestampt too allthough it will confuse users sometimes, allthough if users is deliberately posting the same message over and over you probably need to find a way to ban them. Using POST, having a timestam, and even doing a full comparison of the whole database to check for duplicate posts, won't help at all if the malicious users just write a script to load the form and submit random garbage, automatically. (But cross-site-request protection makes that a lot harder)
Using a POST request will cause the browser to try to prevent the user from submitting the same request again, but I'd recommend using session-based transaction tracking of some kind so that if the user ignores the warnings from the browser and resubmits his query your application will prevent duplication of changes to the database. You could include a hidden input in the submission form with value set to a crypto hash and record that hash if the request is submitted and processed without error.
I find it handy to track the number of form submissions the user has performed in their session. Then when rendering the form I create a hidden field that contains that number. If the user then resubmits the form by pressing the back button it'll submit the old # and the server can tell that the user has already submitted the form by examining what's in the session to what the form is saying.
Just my 2 cents.
If you aren't already using some sort of session-management (which would let you note and track form submissions), a simple solution would be to include some sort of unique identifier in the form (as a hidden element) that is either part of the main DB transaction itself, or tracked in a separate DB table. Then, when you are submitted a form you check the unique ID to see if it has already been processed. And each time the form itself is rendered, you just have to make sure you have a unique ID.
First of all, you can't trust the browser, so any talk about using POST rather than GET is mostly nerd flim-flam. Yes, the client might get a warning along the lines of "Did you mean to resubmit this data again?", but they're quite possibly going to say "Yes, now leave me alone, stupid computer".
And rightly so: if you don't want duplicate submissions, then it's your problem to solve, not the user's.
You presumably have some idea what it means to be a duplicate submission. Maybe it's the same IP within a few seconds, maybe it's the same title of a blog post or a URL that has been submitted recently. Maybe it's a combination of values - e.g. IP address, email address and subject heading of a contact form submission. Either way, if you've manually spotted some duplicates in your data, you should be able to find a way of programmatically identifying a duplicate at the time of submission, and either flagging it for manual approval (if you're not certain), or just telling the submitter "Have you double-clicked?" (If the information isn't amazingly confidential, you could present the existing record you have for them and say "Is this what you meant to send us? If so, you've already done it - hooray")
I'd not rely on POST warnings from the browser. Users just click OK to make messages go away.
Anytime you'll have a request that needs to be one time only e.g 'make a payment', send a unique token down, that gets submitted back with the request. Throw the token out after it comes back, and so you can now tell when something is a valid submission (anything with a token that isn't 'active'). Expire active tokens after X amount of time, e.g. when a user session ends.
(alternately track the tokens that have come back, and if you have received it before then it is invalid.)
Do a POST every time you alter data, but never return an HTML response from a post... instead return a redirect to a GET that retrieves the updated data as a confirmation page. That way, there is no worry about them refreshing the page. If they refresh, all that will happen is another retrieve, never a data-altering action.