Form validation used in autosaving? - javascript

I'd like to make a question <form> with autosaving similar to this one on Stackoverflow. I understand that unobtrusive autosaving can we done with setInterval() and $.ajax() (ref.1 ref.2) but I'm more interested in the form validation Stackoverflow uses to determine whether or not the form submits after a given interval of time.
My question is, should I just keep the validation simple and make sure the user has inputed, say more than 5 characters (or that more than 5 characters have changed)? What else should I be thinking about for the form validation specifically in the case of autosaving (or in contrast with user-initiated submit()).

You can keep it simple by updating user's input after few seconds of last key strokes.
This is what a jquery code my looks like.
var timer = null;
$(inputElem).on('keyup',function(){
clearTimeout(timer);
// Update user input after 5 seconds of last keystroke
timer = setTimeout( updateUserInput , 5 * 1000 );
});
And important thing to take in consideration is keeping track of revisions. In case user may not want to keep it's current changes, then it should be able to revert back to last copy.
Still all these things depends on the type of app you want to develop.

this example for test if user change or add/remove 5 characters or not
by testDeff function
http://jsfiddle.net/alaa13212/PSJ4z/

Related

Javascript, check a field for any value, and skip if occupied

Okay folks,
I apologize if this has been asked before, I searched all of yesterday for a solution and came up empty handed. Perhaps I am searching the incorrect terms... but I digress. My issue is I have a PDF document that is actually ten documents in one, a series of letters and forms that require about a dozen redundant fields over all 10 documents.
TopmostSubform.ControlSheetPG1.RCN::initialize - (JavaScript, client)
RCN.rawValue = app.response("Enter the Report Control Number (RCN)");
if (RCN.rawValue < "" || RCN.rawValue == RCN.rawValue) {
TopmostSubform.ControlSheetPG1.RCN::exit - (JavaScript, client)
RCN.rawValue = RCN.rawValue;
As you can see, I have the user enter the information upon initialization, and upon exit I have it update the global data for RCN. My issue is the "if" statement. I need to have the javascript check to see if the field is occupied before it creates the popup box asking for the info. So if the field is occupied with data it skips it and leaves the data alone and goes onto the next field and repeats until all fields have been updated, or checked. I hope all of this makes sense.

How to store number of times a button was clicked?

I have hosted a basic webpage on amazon S3. The page is implemented in HTML, CSS and Javascript. I wish to record the number of times a button (which is present on the page) was clicked. Also since S3 support static web hosting only and considering my requirement needs server side scripting, is this question even valid? I do not need a fancy solution, I just need to record the number of times a button was clicked and store it in some simple text file residing in the bucket.
By number of times the button was clicked , I mean in all how many times was this button clicked. This web page will be accessed by many users. I want a cumulative number of clicks that occurred. So if i access the web page today and click the button, the number of click becomes 1, if i do the same tomorrow, the number of clicks becomes 2
EDIT: Scenario
Consider the scenario. I have three users A, B and C. Suppose for one week, 'A' visits the website 3 times a day and clicks the button 4 times in all. B visits the website only once and clicks it 2 times. C visits it twice and clicks the button 1 time. So the total number i should be seeing by the end of the week is 7 (4 + 2 + 1). Ill add it in the edit.
This cannot be accomplished totally on the client (web browser) because it would need the ability to "read the current value" and then "write the new value" somewhere. This opens security holes because anyone reading the Javascript could modify its behavior.
Instead, you need to be able to trigger some server-side code that will increment the count without giving any additional capabilities.
The simplest option (depending upon your abilities) would probably be:
Create an Amazon DynamoDB table to store the count
Create an AWS Lambda function that increments the count in some database
Create an API using AWS API Gateway that calls the Lambda function
DynamoDB pricing is only about half a cent per hour at the slowest speed (probably sufficient for your need) and 25c per GB/month. That's not going to cost much.
You'd possibly fit within the free usage tier for Lambda and the (first year) free tier for API Gateway.
The Lambda function would merely be an Update expression to increment the value.
Or, quick and dirty...
If all of this sounds too complex, you could simply update DynamoDB directly from JavaScript (see DynamoDB for Javascript – cheatsheet for examples). The downside is you'd need to provide some security credentials to the code, but you could limit them to only being able to call the Update function on a specific table. Not as secure, but the worst thing they could do is update your value to some very strange numbers (whereas the server version would only allow one increment at a time).
Frankly, you'll probably want to start getting smarter about recording clicks, by dividing it into time periods (eg hour, day) and possibly by User or demographics, so you might end up recording more details about each click and then calculating totals separately.
Guess what... this is known as website analytics!
You might be better off simply implementing a service like Google Analytics that gives you all of this functionality with very little effort.
Well, as you mentioned, you will gonna need a server-side language to do this properly and save your data in a database, but still you can use some tricks to do this with only javascript, one of them is storing your click counts in local storage, so at least until user not removed the storage data, your value is valid!
I create a simple example.
Javascript :
function countClicks(){
console.log("Counting Start...");
var counts = localStorage.getItem('click-counts');//You can use
if (counts!==null){
var newClick = parseInt(counts) + 1;
localStorage.setItem('click-counts', newClick);
}
else{
localStorage.setItem('click-counts', "1");
}
document.getElementById("showCounts").innerHTML = counts;
}
HTML :
<button onclick="countClicks()" >
Click!
</button>
<div>
<p id="showCounts"></p>
</div>
You can try it here :
https://jsfiddle.net/emilvr/35v60xt5/21/
The better option is using some third-party services like Firebase :
https://firebase.google.com/docs/database/web/start
You have to use client side code for check times of button clicked and
store this value into your database for future use :
/*------------// By Using JQuery //----
$(function() {
var i = 0;
$('button').click(function() {
i++;
$("#count").val(i);
// run ajax to save this value dynamically into database
});
});
--------------------------------*/
// By using javascript
var i = 0;
function countClick() {
i++;
//alert('here');
document.getElementById("count").value = i ;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<button onClick="countClick()">Click Me</button><br>
Total Count<input type="text" id="count" disabled >

Search & LazyLoad can't keep up w/ typing speed?

So, all of the code works quite well. A database a queried, the node/parent IDs are lazily passed to jsTree, and, if one types a term into the search bar—a similar process goes on, but the nodes passed to jsTree are those returned by another SQL query (using something like SELECT nodeID FROM table WHERE name LIKE %searchTerm%).
There's only one problem:
If I type too quickly into the search bar, the results get all mixed up with one another. If I type slowly (I'd estimate 2 letters a second max), everything works well. Any faster and everything is blurred together. (That is, if I'm searching for names which contain the term "test", and type this quickly, I'll get names that contain "t", "te", "tes", and "test" instead of just names that contain "test".)
Anyone have this problem before? Is there some "wait until ready" function I should be using?
I can suggest you to do the 'Timeout' workaround. Basically, you create a SetTimeout function with a delay of 200-400 miliseconds and launch your lazyload ajax there. Every inputbox.change event restarts the time. See example in pseudo-javascript:
$('#your-input').keydown(function(){
if(ajaxTimer != undefined) {
clearTimeout(ajaxTimer);
}
ajaxTimer = setTimeout(function(){
$.ajax({...}).done(function() {...}
},400);
})
Use a throttle on the typing input, basically guarantees that a function will be called a maxmimum of once every X seconds. Sure you could write your own however there is a great library out there already.
check it out if you're interested http://benalman.com/projects/jquery-throttle-debounce-plugin/

Filtering with large dataset

I have a large data-set with roughly 10,000 records. I want to be able to have a filter mechanism on this data-set. That basically performs a LIKE sql expression on a field and returns the matching results.
To do this, I've used JQuery to bind the "input" event on my filter textbox to my filter handler function.
The issue at the moment is, that If a load of keys are pressed at once in the textbox, then the filter function gets called many times, thus making many SQL calls to filter which is very inefficient.
Is there a way I can detect in my handler when the user has finished typing or when there's a gap of a certain period and only then performing the filtering? So i only make one database call when loads of characters get input at once. If the characters get input slowly though, I want to be able to filter each time.
Cheers.
Here is a way of doing it jsfiddle
var test = 0;
$('body').on('keyup','input',function(){
var val = $.trim($(this).val());
test++;
if(val !== ""){
doSomething(test);
}
});
function doSomething(t){
setTimeout(function(){
if(t === test){
//Place to Call the other Function or just do sql stuff
alert($.trim($('input').val()));
}
},500);
}
There is a global variable to test against, if the user typed another letter. And the setTimeout function waits 500ms to see if they did type another letter.
I'm sure there are better ways to do this, but that will probably get you started.

Executing ajax code after a few seconds of inactivity from the user

I'm new here so please go easy on me. This is somewhat of a confusing situation. :)
I'm working on a search input in which a user enters a name of another user (or part of a name) in a search text box and then a list of users matching that search string is returned. The problem is that it is a bit slow when there are tens of thousands of users involved. Due to this slowness, when the user quickly enters a name into the search input, the screen will begin to flash search results for each key stroke (well after the user has already entered the search string in). It's like a severely delayed reaction.
For instance, if I enter in the name 'Wendy', the search results for the search string 'W' (the first character I entered) will not even be displayed yet. The search results for the letter 'W' will then be displayed, followed by 'We' and so on and so forth even though i've already typed the full name and just want to see the results for 'Wendy'.
What I want to do is only perform the search when the user has not entered anything for a certain period of time (i'm thinking two seconds). Otherwise, the word 'Searching' will be displayed. The code of the Javascript method is below. Just as a note, that code currently works for searching through the users, I just need to implement the delayed execution.
function updateSearchResults() {
if($F('searchString').length > 0){
Element.update($('searchResultsScrollBox'), '<h3>Searching...</h3>');
$('searching').style.display = 'block';
var url = '<c:url value='ajaxFrontGetUsers.html'/>';
var ajax = new Ajax.Updater({success: 'searchResults'}, url,
{method: 'post', parameters: $('searchForm').serialize(true)});
$('searching').style.display = 'none';
}
}
I hope this all makes sense. Thanks in advance for anyone that can help.
Try the following steps:
Every few milliseconds, check to see if the textbox has new data in it.
If the textbox has new text, execute your Ajax, and copy the text to a variable (for comparison in step 1).
If you want to improve performance from there, activate the timer whenever the user types something, and deactivate it when the Ajax call is made.
Hey, thanks for your answer.
I ended up setting 500 millisecond intervals in which a javascript function would continuously check to see if new characters were entered in the search string within that 500 millisecond time period. If they were, the search function would be called to search on the string the user had entered. Otherwise, it would wait another 500 milliseconds until the user had stopped typing. In the end, it's very similar to what you proposed.
Thanks again!
Or you could put an "onkeypress"event handler on the item that clears some global variable or cancels a timer to keep the AJAX event from firing. I know Prototype implements this for you via it's in-place editor and the "frequency" option. (I believe it sets a timeout timer that it cancels after every key press.)
I know this is an old question, but for others taking a look, I think your going about this the wrong way. I think you should date/time stamp each ajax call, and keep track of the data time stamps in your javascript. Then, when an ajax call is returned you can check the date/time stamp and make sure it is the result set for the most resent ajax call. This way you do make the ajax call for each keystroke immediately, but only display results if the ajax results catches up to the typing.
Also, are you sending over ALL matching results? Like thousands for just the letter W? To speed up the javascript side maybe you should rank the results on the database and return only the top 10-20. The doesn't want to see more than 10-20 results anyways.
Additionally, is your SQL query optimal? Seems like the query is taking too long. If your doing a one sided like search (ie. like input+'%') not a two sided like search (ie. like '%' + input + '%') then there are some really good indexes you can put on the table to help you out.

Categories