jQuery script fails executing for some of the users - javascript

I am using a custom form to submit data to Google Spreadsheets. When user attempts to submit the form, it is validated (with jQuery) and if the validation is passed, the main input field is being modified with jQuery and then the submission continues.
The user inputs a URL and during submission the script cuts off unnecessary parts of the link and adds IP (that is also gathered with jQ) of the user to it. After the modification is completed, the form continues submission and in result, only the modified data is being sent to Google Spreadsheet.
It works pretty well with 99% of submissions but there are several users whose browsers do not execute the script properly; i.e.: the URL they input is not being modified during the submission and thus, wrong data (unmodified) is sent to the Spreadsheet. I am not completely sure, but the problem may be caused by Firefox (but I am not 100% sure that all the faulty submission come from Firefox, if you want I could research and confirm whether it is only Firefox's issue). I have asked some of them (users, whose browsers seem not to execute script) about addons/if they had turned JS off but they say they did not do anything special with their browsers.
I am posting whole js file below so you could check whether I did some errors that could cause problems. Also, the script is running here (link), you can inspect the code to see what other jQuery stuff I use.
$(document).ready(function() {
//Tabbiing page is being initialised, doesn't really matter, I think
$.ionTabs("#fppp_taby");
//Script that checks whether user has been redirected back after submission, that's not the main problematic part yet
if (window.location.search != 0) {
var query = window.location.search.substring(1);
ideo = query.split("=")[1];
if (isNaN(ideo) || (ideo.length < 3) || (ideo.length > 10)) {
$("form").html("Wystąpił błąd podczas wysyłania Twojego zgłoszenia. Powiadom mnie o tym poprzez prywatną wiadomość podając również obecną godzinę za pomocą <a class='uline' href='http://www.erepublik.com/pl/main/messages-compose/2417512'>tego linka</a>.");
} else {
$("form").html("Dziękujemy za zgłoszenie!<br /><br />Możesz teraz przeczytać któryś z artykułów epolskiej prasy - lista wartch uwagi znajduje się po lewej stronie!");
var poZglosz = "Dziękujemy za zgłoszenie!<br />Spodziewaj się chlebków i broni od któregoś z tych graczy: Kijek93, twatwaratwa, Gregoric bądź Zawa99";
$("#poZglos").html(poZglosz);
$("#poZglos").removeClass();
}
} else {
var query = 0;
}
//Some simple stuff
$("#wlaczirc").click(function() {
$(this).hide();
$("#irc").html("<iframe src='http://webchat.quakenet.org/?channels=fppp&uio=OT10cnVlJjExPTM0OQ1f'></iframe>");
$("#irc").show("slow");
$("#info_irc").show("slow");
});
//Some data
infoPodkr = "Wklej tutaj prawidłowy link do twojego profilu!";
inputLink = $("#ffpolelinku");
//Resetting validation info in input
$(inputLink).focus(function() {
if ($(this).hasClass("podkresl") || $(this).val() == infoPodkr) {
$(this).val("");
$(this).removeClass("podkresl");
}
});
//Gathering ip
$.getJSON("http://jsonip.com/",
function(data) {
ip = data.ip;
});
//MAIN PART (executed when user pressses 'submit')
$("form").submit(function() {
//Form is being hidden (display:none class is being added)
$('aside').addClass("hidden");
//Check whether input is empty or contains error message (infoPodkr = error message vlaue), if yes, add class 'podkresl'
if (($(inputLink).val() == "") || ($(inputLink).val() == infoPodkr)) {
$(inputLink).addClass("podkresl");
$(inputLink).val(infoPodkr);
} else {
$(inputLink).removeClass("podkresl");
}
//Tesing whether user added proper link, if not, 'podkresl' is added
//if (!/\b(https?|ftp|file):\/\/[\-A-Za-z0-9+&##\/%?=~_|!:,.;]*[\-A-Za-z0-9+&##\/%=~_|]/.test(inputLink.val())){
if (!/http\:\/\/www\.erepublik\.com\/[a-z]{2}\/citizen\/profile\/\d{5,}$/i.test(inputLink.val())) {
$(inputLink).addClass("podkresl");
$(inputLink).val(infoPodkr);
}
//Split link, and get the last part of it ('wycId'), check if it's numeral, if not - add 'podkresl' class
podzielony = $(inputLink).val().split('/');
wycId = podzielony.pop();
if (isNaN(wycId)) {
$(inputLink).addClass("podkresl");
$(inputLink).val(infoPodkr);
}
//Check whether the input class 'podkresl' class (= something was wrong in some of the steps above). If yes, remove the 'hidden' class from 'aside' which holds the form and show it to the user. If there were no errors, add the IP to the 'wycId' and additional "-n" to the end of the value and put it into input. Then, submit form.
if ($(inputLink).hasClass("podkresl")) {
$('aside').removeClass();
return false;
} else {
if (ip !== '') {
$(inputLink).val(wycId + "-" + ip + "-n");
} else {
$(inputLink).val(wycId + "-0-n");
}
}
return true;
});
});

Related

Parse text file into three categories and display as html

I have a text file which has 100+ email ids with various domains of my vendor and clients.
Example:
raj#xyz.com,John#gyx.com
I want to place a button which extracts and displays email id with xyz.com and another one which retuns gyx.com likewise. Without PHP I don't have a local server installed.
I have no idea where to start.
This is the code I currently use to read the text file.
<!DOCTYPE html>
<html>
<head>
<title>Read File (via User Input selection)</title>
<script type="text/javascript">
var reader;
function checkFileAPI() {
if (window.File && window.FileReader && window.FileList && window.Blob) {
reader = new FileReader();
return true;
} else {
alert('The File APIs are not fully supported by your browser. Fallback required.');
return false;
}
}
function readText(filePath) {
var output = ""; //placeholder for text output
if(filePath.files && filePath.files[0]) {
reader.onload = function (e) {
output = e.target.result;
displayContents(output);
};//end onload()
reader.readAsText(filePath.files[0]);
}//end if html5 filelist support
else if(ActiveXObject && filePath) { //fallback to IE 6-8 support via ActiveX
try {
reader = new ActiveXObject("Scripting.FileSystemObject");
var file = reader.OpenTextFile(filePath, 1); //ActiveX File Object
output = file.ReadAll(); //text contents of file
file.Close(); //close file "input stream"
displayContents(output);
} catch (e) {
if (e.number == -2146827859) {
alert('Unable to access local files due to browser security settings. ' +
'To overcome this, go to Tools->Internet Options->Security->Custom Level. ' +
'Find the setting for "Initialize and script ActiveX controls not marked as safe" and change it to "Enable" or "Prompt"');
}
}
}
else { //this is where you could fallback to Java Applet, Flash or similar
return false;
}
return true;
}
/**
* display content using a basic HTML replacement
*/
function displayContents(txt) {
var el = document.getElementById('main');
el.innerHTML = txt; //display output in DOM
}
</script>
</head>
<body onload="checkFileAPI();">
<div id="container">
<input type="file" onchange='readText(this)' />
<br/>
<hr/>
<h3>Contents of the Text file:</h3>
<div id="main">
...
</div>
</div>
</body>
</html>
Here's the high level approach I would take:
Once the document has loaded up, using jQuery I would grab all of the data output.
var output = $('#main').val()
Then, I would write some logic to parse out the data from the output variable into two different sets (#xyz list and #gyx list). Also, I would format the output too so that it's ready to be called on. Now you have the two data sets that you need, and can call on them when you push your button.
Create an event with jQuery based on the button click state. Depending on the state, the method would select the appropriate list, and then display the output.
So rather than extracting the appropriate data on every button press, you can front load all of it in the initial page load. Since the data won't be changing until you refresh the page again, you should just use the button to switch between which list gets displayed.
It sounds like you want to search your email address list, displaying ids that match a domain or a domains matching an id. First I would take the advice given above and offload your file content into a variable.
This is easy given a comma separated list of email addresses, and here's a plnkr demonstrating the functionality you want (sans the file loading code etc.).
Here's a function to find matches in the address lists based on your criteria.
/**
#emails is a comma separated list of email addresses.
#term is the search term e.g. email id or domain.
#compareById if truthy the function returns email domains with
email id == #text otherwise the function returns email id's
with email domain == #text.
*/
function getEmailMatches(emails, term, compareById) {
let matches = [],
compareIndex = compareById ? 0 : 1,
valueIndex = compareById ? 1 : 0;
emails.split(",").forEach(function (email) {
let terms = email.split("#");
if (terms[compareIndex] == term)
matches.push(terms[valueIndex]);
});
return matches;
}

Why is my validation method for zip codes not working correctly

I have a form that uses asp:requiredvalidator and some custom javascript to apply a red 1px border around any field that hasn't been correctly filled in.
This works perfectly, but now I want to be able to immediately remove the red border when the user correctly fills in the field.
To achieve this, I am using Jquery's focusout() method to compare the user input to a regular expression. So far I have this correctly working on every field (including email validation) except zip code. For some reason, all the validation methods I have written work perfectly except for zip code.
Here is a working email validation for example
if (id == "email1" || id == "email2") {
emailValue = e.target.value;
if (validateEmail(emailValue)) {
$("#" + id).removeClass("ErrorControl");
}
else {
}
}
function validateEmail(email) {
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
}
This works perfectly and removes the red border as soon as the field losses focus and the email is valid.
But I cannot get my zip validator working, even though it works almost the exact same way.
Here is the non working zip example
//Zip code also require special validation to confirm
if (id == "zip") {
zipValue = e.target.value;
if (validateZip(zipValue)) {
$("#" + id).removeClass("ErrorControl")
}
}
//Simple zip validator
function validateZip(zip) {
var re = /^[0-9]{5}$/;
return re.test(zip);
}
Unfortunately this still removes the red border, even when I enter just letters in it! Why is this happening?
https://jsfiddle.net/hhjvstp3/
I have given both email and zip a class of ErrorControl since I cannot run asp validators on jsfiddle. This works exactly like I am describing. Email validates well, zip code removes the border no matter what.
Updated fiddle
You can see which line removes the ErrorControl class from zip
if (id == "firstname" || id == "lastname" || id == "address1" || id == "city" || id == "amount") {
//id == "zip" shouldn't be here
if (e.target.value != "") {
$("#" + id).removeClass("ErrorControl");
}
}

Uncaught TypeError: Cannot set property 'display' of undefined

I am in the process of migrating an existing platform to a new server. I am taking the opportunity to upgrade PHP ect and standardise/debug the code as the previous maintainers have had different standards.
I have opted for PHP version 5.4.33 for now, once I have managed to move everything over to mysqli I will look to go to a more recent version. I didnt think anything server side would make a difference to AJAX/JS? As far as I am aware is it not client side?
Since I have moved the code over I am having issues with AJAX/JS. I am not the greatest at AJAX/JS and could use some assistance please. Even though every submit works differently through the entire platform I do not want to remove the AJAX/JS that already exists. I will most likely use it as an opportunity to how to use it as it makes end user experience smoother.
Using Chrome to debug I am receiving the following error on clicking the Save button:
Uncaught TypeError: Cannot set property 'display' of undefined
email_user
onclick
This is the Save button code
<span id="loading" style="color: red; font-size: x-small; display: none; text-decoration: blink;">Loading... Please wait..</span><input type="button" value="Save" class="save" onclick="if(validate()){ email_user(); }" />
This is the function code for validate()
function validate() {
var errorString = "";
if(isBlank(document.getElementById("forename").value)) {
errorString += " - Please input a forename\n";
}
if(isBlank(document.getElementById("surname").value)) {
errorString += " - Please input a surname\n";
}
if(isBlank(document.getElementById("company_name").value)) {
errorString += " - Please select a company\n";
}
if(document.getElementById("username").value != "" || document.getElementById("password").value != "") {
if(isBlank(document.getElementById("username").value)) {
errorString += " - Please input a username\n";
}
if(isBlank(document.getElementById("password").value)) {
errorString += " - Please select a password\n";
}
}
//if not a solicitor then cases mandatory
if(document.getElementById("company_role_type_id").value == 2) {
if(document.getElementById("other_view_if").value == "") {
errorString += " - Please select who can view your cases\n";
}
}
if(document.getElementById("company_role_type_id").value == 3) {
if(document.getElementById("other_view_ea").value == "") {
errorString += " - Please select who can view your cases\n";
}
}
if(errorString) {
alert('Please correct the following items:-\n\n'+ errorString);
return false;
}
else {
return true;
}
}
This is the function code for email_user()
function email_user(){
if(skip_email == true){ $('user').submit(); }
var url = 'email_user.php';
var params = '?' + $('user').serialize() + '&from_edit=1';
$('loading').style.display = 'inline';
var myAjax = new Ajax.Request(
url,
{
method: 'get',
parameters: params,
onComplete: show_response
});
function show_response(this_request){
//alert(this_request.responseText);
var reply = this_request.responseText.evalJSON(true);
if(reply['status'] == false){ var blah = ''; }
else{ alert(reply['message']); }
//$('loading').style.display = 'none';
$('user').submit();
}
}
Thinking about it, maybe it is more to do with the Apache version?? Just in case Apache version is 2.2.15.
Any assistance you guys can give me will be greatly appreciated! If you need any more information please let me know.
Kind Regards,
n00bstacker
As previously stated in comments, your code has some issues, your line (the one that is triggering the error, can be optimized in the following way:
$('#loading').css("display","inline"); //Selector is ok now...
In the other hand, I also noticed that you have a second selector $('user') that won´t work. Remember that anything without a dot, or a sharp will be considered as an element selector (loading, and user elements, won´t exist in your document unless you created it.
Remember:
$("#myId") //id selector
$(".myClass") //class selector
If "user" is the form name, the code may work. Remember that you want to catch the form submit event.
Regards,
Guillermo
Try changing $('loading') to $('#loading')?

How to repopulate form variables?

I've got a page that should warn if the user tries to leave the page having unsaved data. This dialog means "You have unsaved data. Do you want to conitnue?"
The problem is that the form values go blank when the user clicks a link to move on and is presented with the dialog. I want to form values to stay in place so that the user actually can choose not to continue and then still have left what was entered to the form.
The way the code is now is that it keeps a flag for whether the form has dirty data and that is a hidden variable:
<input type="hidden" name="saveStatus" value="<%=saveStatus%>" />
Touching the form sets this hidden variables with onclickand onkeypressed.
On the server I've got some logic that checks whether data is dirty:
public boolean returnToUnsavedData(ISessionHandler sessionHandler,
Action action) {
String saveStatus = sessionHandler.getRequestParameter("saveStatus");
if (saveStatus != null && !saveStatus.trim().equals("")) {
setHasUnsavedData(true);
} else {
setHasUnsavedData(false);
}
if (hasUnsavedData()) {
if (!"menuHasUnsavedDataOk".equalsIgnoreCase(action
.getActionCommand())
&& !action.getActionName().equals("Administrera")) {
ResourceBundle messages = ResourceBundle.getBundle("messages");
UserMessage um;
if (action.getActionCommand().equals("fastsearch")) {
um = new ExtendedUserMessage(
messages.getString("PV24"), UserMessage.TYPE_WARNING,
"Varning", action.getActionName(),
action.getActionCommand(), sessionHandler.getRequest().getParameter("fastsearch"));
} else {
um = new ExtendedUserMessage(
messages.getString("PV24"), UserMessage.TYPE_WARNING,
"Varning", action.getActionName(),
action.getActionCommand());
}
action.addUserMessage(um);
action.setReturnPage(action.getCurrPage());
setLatestActionTarget(action.getActionTarget());
return true;
} else {
setHasUnsavedData(false);
}
}
return false;
}
I suppose this is where I could check serverside for the variables and repopulate everything and then use a technique like above with the hidden variable to keep form values.
Do you think that this idea will work or can you present alternative solutions?
I don't think you need server-side involvement here, you can achieve this by using just javascript:
<input type="hidden" id="saveStatus" name="saveStatus" value="<%= saveStatus %>"/>
Register an observer before the page gets unloaded and check your saveStatus variable in there:
window.onbeforeunload = function() {
if (document.getElementById('saveStatus').value) {
return 'You have unsaved changes, are you sure you want to leave the page?');
}
};
However, by using this you will not have your own 'custom' confirmation screen, the browser's built in confirmation will be used (similar to stack-overflow's).

Multiple form fields with same 'name' attribute not posting

I'm dealing with some legacy HTML/JavaScript. Some of which I have control over, some of which is generated from a place over which I have no control.
There is a dynamically generated form with hidden fields. The form itself is generated via a Velocity template (Percussion Rhythmyx CMS) and JavaScript inserts additional hidden form fields. The end result is hidden form fields generated with the same 'name' attribute. The data is being POSTed to Java/JSP server-side code about which I know very little.
I know that form fields sharing the same 'name' attribute is valid. For some reason the POSTed data is not being recognized the back end. When I examine the POST string, the same-name-keys all contain no data.
If I manipulate the code in my dev environment such that only a single input field exists for a given name, the data IS POSTed to the back end correctly. The problem is not consistent, sometimes, it works just fine.
Is there something I can do to guarantee that the data will be POSTed? Can anyone think of a reason why it would not be?
I should really update my answer and post code here, because POST requests without
variable strings indicates the problem is on the client side.
How about this:
<script type="text/JavaScript">
function disableBlankValues()
{
var elements = document.getElementById("form1").elements;
for (var i = 0; i < elements.length; i++)
{
if (elements[i].value == "")
elements[i].disabled = true;
}
}
</script>
<form action="page.php" method="POST" onsubmit="disableBlankValues()" id="form1">
<input type="hidden" name="field1" value="This is field 1."/>
<input type="hidden" name="field1" value=""/>
</form>
EDIT
I now realize the actual problem (multiple variables with the same name should be passed to JSP as an array) and my solution is probably not what the OP is looking for, but I'm leaving it here just in case it happens to help someone else who stumbles upon this post.
you could use something like:
var form = document.getElementById('yourformid');
var elements = form.getElementsByName('repeatedName');
var count = 0;
for(var item in elements){
elements[item].name += count++;
}
this way you will get each hiddenfield with the names:
name0
name1
name2
...
I've worked out a brute-force solution. Note that I'm pretty aware this is a hack. But I'm stuck in the position of having to work around other code that I have no control over.
Basically, I've created an ONSUBMIT handler which examines the form for the repeated hidden fields and makes sure they are all populated with the correct data. This seems to guarantee that the POST string contains data regardless of how the form gets rendered and the Java back end appears to be happy with it as well.
I've tested this in the following situations:
Code generates single instances of the hidden fields (which does happen sometimes)
Code generates multiple instances of the hidden fields
Code generates no instances of the hidden fields (which should never happen, but hey...)
My 'else' condition contains a tiny bit of MooTools magic, but it's otherwise straight-forward stuff.
Maybe someone else will find this useful one day...
Thanks for the help!
<form method="post" name="loginform" id="loginform" action="/login" onsubmit="buildDeviceFP(this);">
<script type="text/javascript">
function insertFieldValues( fields, sValue )
{
if ( 'length' in fields )
{
// We got a collection of form fields
for ( var x = 0; x < fields.length; x++ ) {
fields[x].value = sValue;
}
}
else
{
// We got a single form field
fields.value = sValue;
}
}
function buildDeviceFP( oForm )
{
// Get the element collections for Device Fingerprint & Language input fields from the form.
var devicePrintElmts = oForm.elements.deviceprint;
var languageElmts = oForm.elements.language;
// 'devicePrintElmts' & 'languageElmts' *should* always exist. But just in case they don't...
if ( devicePrintElmts) {
insertFieldValues( devicePrintElmts, getFingerprint() );
} else if ( oForm.deviceprint ) {
oForm.deviceprint.value = getFingerprint();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'deviceprint', 'value':getFingerprint()} )
);
}
if ( languageElmts) {
insertFieldValues( languageElmts, getLanguage() );
} else if ( oForm.language ) {
oForm.language.value = getLanguage();
} else {
$('logonbox').adopt(
new Element( 'input', {'type':'hidden', 'name':'language', 'value':getLanguage()} )
);
}
}
</script>

Categories

Resources