Pages refreshes on form submit even though I am using preventDefault - javascript

I am trying to stop the page from refreshing when submitting a form by using this:
window.addEventListener("load", function () {
let settings_form = document.getElementById("settings_form");
// handle form submit
settings_form.addEventListener("submit", function (e) {
e.preventDefault(); // before the code
save_settings();
// Should be triggered on form submit
console.log("hi");
return false;
});
});
But it does not work.
If I comment the save_settings method the page won't reload. Obviously, I need that method.
function save_settings() {
// let form = document.getElementById("settings_form");
let json_data = toJSONstring(settings_form);
console.log(json_data);
post_data("api/settings/change", json_data).then((send_response) => {
console.log(send_response);
conn_status = 1;
// logs to page
// get_settings() // update interface with newer settings
get_info();
});
}
I don't know which function makes e.preventDefault(); to not work.
For more context:
// parse form data into json
function toJSONstring(form) {
let object = {};
console.log(form);
let formData = new FormData(form);
formData.forEach((value, key) => {
// Reflect.has in favor of: object.hasOwnProperty(key)
if (!Reflect.has(object, key)) {
object[key] = value;
return;
}
if (!Array.isArray(object[key])) {
object[key] = [object[key]];
}
object[key].push(value);
});
console.log(JSON.stringify(object));
return JSON.stringify(object);
}
// send/post json
async function post_data(api_path, json_data) {
let post_url = ROOT_URL + api_path;
const response = await fetch(post_url, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: json_data,
});
//check
if (!response.ok) {
conn_status = 0;
const message = `An error has occured: ${response.status}`;
throw new Error(message);
}
return await response.json();
}
<form id="settings_form" class="settings_form">
<label for="wifi_ssid">Change SSID</label>
<input type="text" name="wifi_ssid" id="wifi_ssid" />
<label for="wifi_pass">Change Password</label>
<input type="text" name="wifi_pass" id="wifi_pass" />
<label for="ap_ip">Change IP Address</label>
<input type="text" name="ap_ip" list="ap_ip" />
<datalist id="ap_ip">
<option>192.168.100.20</option>
</datalist>
<input type="button" value="Save Settings" id="submit_btn">
</form>
I have also tried listening to the click event on the button:
window.addEventListener("load", function () {
let button = document.getElementById("submit_btn");
// handle form submit
button.addEventListener("click", function (e) {
e.preventDefault(); // before the code
save_settings();
// Should be triggered on form submit
console.log("hi");
return false;
});
});
Later Edit:
I am running a local mock-up JSON server in order to test my code.
I've tried the code here: https://jsbin.com/xogozovawe/1/edit?html,js,output and it works.
Might this be the local server's fault ?

Related

Having an issue with the JS form validator. Console in Chrome shows no errors but the validation is not working

This is supposed to handle the form validation for a simple contact form with name, email address, website url, and 10 line comment section for project description, then hand the information as a JSON object to a php file to send to a designated email address.
When I had action="emailprocessor.php in the HTML code, the form validation went through the PHP file and not JS, and it sent properly to the designated email address.
Without the action in the html, it's supposed to flow through the JS and then to the PHP. It's not doing that.
Here is my code:
(function () {
"use strict";
const contactForm = document.getElementById('contactform');
contactForm.addEventListener('submit', validateForm);
//Messages to be put in the message element when there is an error or success...
// The last element in this array loads the preloader css.
const feedBackMessage = [
'<div class="error"><h3>Ooops!</h3><p>The name field is reqired, that\'s how I know who you are. Please fix that and try again!</p></div>',
'<div class="error"><h3>Ooops!</h3><p>You forgot to give me a valid email address. Please fix that and try again!</p></div>',
'<div class="error"><h3>Ooops!</h3><p>You forgot to enter your website. Please fix that and try again!</p></div>',
'<div class="error"><h3>Ooops!</h3><p>Please enter your project description or comment.</p></div>',
'<div class="success"><h3>Thank you!</h3><p>Your information has been sent, and we will be in touch.</p></div>',
'<div class="preloader"><div class="loading-dot"></div></div>'
];
// The actual form validation function. Added url regex.
function validateForm(event) {
event.preventDefault();
const nameField = document.getElementById('name');
const emailField = document.getElementById('email');
const siteField = document.getElementById('website');
const commentField = document.getElementById('comment');
const reName = /^[a-zA-Z]+(([\'\- ][a-zA-Z])?[a-zA-Z]*)*$/;
const reEmail = /^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$/;
const reUrl = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/;
let errors = 0;
if (!reName.test(nameField.value)) {
displayMessage(nameField, feedBackMessage[0]);
errors++;
}
else if (!reEmail.test(emailField.value)) {
displayMessage(emailField, feedBackMessage[1]);
errors++;
}
else if (!reUrl.test(siteField.value)) {
displayMessage(siteField, feedBackMessage[2]);
errors++;
}
else if (commentField.value == "") {
displayMessage(commentField, feedBackMessage[3]);
errors++;
}
else if (errors === 0) {
sendData();
}
}
// This displays error / success messages
function displayMessage(field, message) {
document.getElementById('message').className = "show-message";
document.getElementById('message').innerHTML = message;
setTimeout(function () {
document.getElementById('message').classList.add("fadeOutElement");
setTimeout(function () {
if (field != 'success') {
document.getElementById('message').className = "hide-message";
document.getElementById(field.id).focus();
}
else {
document.getElementById('message').setAttribute("class", "hide-message");
document.getElementById('name').value = '';
document.getElementById('email').value = '';
document.getElementById('website').value = '';
document.getElementById('comment').value = '';
}
}, 2000);
}, 2000);
//puts messages in the DOM??
}
function sendData() {
document.getElementById('message').className = "show-message";
document.getElementById('message').innerHTML = feedBackMessage[5];
setTimeout(async () => {
const formdata = new FormData(contactForm);
const fetchPromise = await fetch('emailprocessor.php', { method: 'POST', body: formdata });
const data = await fetchPromise.json();
console.log(data.result);
if (data.result == "success") {
displayMessage('success', feedBackMessage[4]);
}
}, 2000);
}
//actually sends the data asynchronously or so it claims
});

How can I redirect to an action in .Net Core after making an Ajax call?

I have a script that makes an ajax call to an action in the controller and save some records.
The whole process is working fine but my little issue is to redirect to another page after saving records successfully.
With my code below, the records were added successfully with an alert indicating as it is described in the code "msg + "Courses were Registered"". Rather than doing that I want it to redirect to an action.
Javascript code:
<input type="submit" value="Register Courses" id="register" class="btn btn-rose" />
<script>
$(document).ready(function () {
$("#register").click(function () {
var items = [];
$('input:checkbox.checkBox').each(function () {
if ($(this).prop('checked')) {
var item = {};
item.CourseID = $(this).val();
item.CourseCode = $(this).parent().next().html();
item.CourseName = $(this).parent().next().next().html();
item.Units = $(this).parent().next().next().next().html();
items.push(item);
}
});
var options = {};
options.url = "/Course/SaveCourse";
options.type = "POST";
options.dataType = "json";
options.data = JSON.stringify(items);
options.contentType = "application/json; charset=utf-8;";
options.success = function (msg) {
alert(msg + " Courses were Registered");
};
options.error = function () {
alert("Error while Registering Courses");
};
$.ajax(options);
});
});
</script>
Controller
[HttpPost]
public IActionResult SaveCourse([FromBody]List<CourseRegModel> courseIDs)
{
var user = HttpContext.Session.GetString("currentUser");
if (user == null)
{
return RedirectToAction("Login", "Account");
}
ViewBag.student = user;
var pendingPayment = (from row in _context.BursaryTransactions where row.MatricNo == user && row.ResponseCode == "021" select row).Count();
if (pendingPayment > 0)
{
return RedirectToAction("PaymentSummary", "Student");
}
var student = _context.StStudentInfo.Include(m =>m.AdmInstProgramme.AdmInstDepartment).Include(m =>m.AdmInstClassLevels).FirstOrDefault(m => m.MatricNo == user);
var session = _context.AdmInstProgrammeTypeSession.Include(m => m.AdmInstSemesters).Include(m => m.AdmInstSessions).Include(m => m.AdmInstProgramType).Where(m => m.IsActive == true).FirstOrDefault(m => m.ProgramTypeId == student.ProgrammeTypeId);
foreach (CourseRegModel courseID in courseIDs)
{
courseID.Level = student.AdmInstClassLevels.ClassLevel;
courseID.Semester = session.AdmInstSemesters.Semester;
courseID.Session = session.AdmInstSessions.SessionName;
courseID.Department = student.AdmInstProgramme.AdmInstDepartment.Department;
_context.CourseRegModel.Add(courseID);
}
int courses = _context.SaveChanges();
return Json(courses);
}
Objective is to return RedirectToAction("MyCourses","Courses"); after SaveChanges();
If you want to redirect to another action method why would you use AJAX? But I think you can work around that by performing the redirect in the client side AJAX after it is successfully receive a response you use JavaScript to do the redirect
You can simply redirect your page inside ajax's success handler,
options.success = function (msg) {
window.localtion.href = "/Courses/MyCourses";
// or window.location.href = '#url.Action("MyCourses","Courses")';
};

Session TImeout after logon?

Below is a logon code I have set up with html. I would like to set a timeout setting to initiate a log off function after x minutes idle time. Is this possible? I currently have a log off button that initiates the log off, so possibly have that timeout select that function. Thank you.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<fieldset>
<legend>Enter credentials</legend>
<p>
<label for="username">User name:</label>
<input type="text" id="username" name="username" />
</p>
<p>
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
</p>
</fieldset>
<input type="submit" id="login-button" name="login-button" value="Log On" />
</form>
<script src="scripts/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
// Web Proxy request to fetch the configuration
ajaxWrapper({ url: 'Home/Configuration', dataType: 'xml', success: configSuccess });
$('form').submit(function () {
var username = $('#username').val(),
password = $('#password').val();
clearMessage();
if (!username || !password) {
showMessage('Enter a username and a password');
return false;
}
// Ensure the user name is correct...
// If the username has the domain string at position 0, then
// the username is correct and just use it as normal, but if
// not, username needs to have the domain prepended.
// Because of the backslashes in the strings, they need to be
// escaped with "\\"
username = username.indexOf("domain\\") === 0 ? username : "domain\\" + username;
// Web Proxy request to log the user on
ajaxWrapper({
url: 'PostCredentialsAuth/Login',
dataType: 'xml',
success: loginSuccess,
error: loginError,
data: { username: username, password: password }
});
return false;
});
});
</script>
Below is the code I added to the section after the logonsuccess form is selected.
function loginSuccess(data) {
var $loginXml = $(data),
result = $loginXml.find('Result').text();
if (result == 'success') {
$('form').hide();
$('#log-off').show();
// Set timeout variables.
var timoutWarning = 60000; // Display warning in 14 Mins.
var timoutNow = 30000; // Warning has been shown, give the user 1 minute to interact
var logoutUrl = '($configXml.find('authManager').attr('logoffURL'));'; // URL to logout page.
var warningTimer;
var timeoutTimer;
// Start warning timer.
function StartWarningTimer() {
warningTimer = setTimeout("IdleWarning()", timoutWarning);
}
// Reset timers.
function ResetTimeOutTimer() {
clearTimeout(timeoutTimer);
StartWarningTimer();
$("#timeout").dialog('close');
}
// Show idle timeout warning dialog.
function IdleWarning() {
clearTimeout(warningTimer);
timeoutTimer = setTimeout("IdleTimeout()", timoutNow);
$("#timeout").dialog({
modal: true
});
// Add code in the #timeout element to call ResetTimeOutTimer() if
// the "Stay Logged In" button is clicked
}
// Logout the user.
function IdleTimeout() {
window.location = logoutUrl;
}
And below is the Log Off button that is shown where a user can manually log off.
$('#log-off').click(function () {
// Web Proxy request to log the user off
url = ($configXml.find('authManager').attr('logoffURL'));
ajaxWrapper({ url: url, dataType: 'text', success: logoffSuccess });
return false;
});
});
Your code doesn't call incativityTime function. Call the function on window onload (or jquery onready) like window.onload = function() { inactivityTime() };
<html>
<body>
<script>
window.onload = function() { inactivityTime() };
var inactivityTime = function ()
{
var t;
window.onload = resetTimer;
// DOM Events
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;
function logout() {
alert("You are now logged out.")
//location.href = 'logout.php'
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(logout, 3000)
// 1000 milisec = 1 sec
}
}
</script>
</body>
</html>
I added it with no success. Below is how the logon success code looks.
function loginSuccess(data) {
var $loginXml = $(data),
result = $loginXml.find('Result').text();
if (result == 'success') {
$('form').hide();
$('#log-off').show();
// Web Proxy request to enumerate the resources available to the user
url = $configXml.find('resourcesProxy').attr('listURL');
ajaxWrapper({ url: url, success: listResourcesSuccess });
} else {
showMessage('Login failed - try again');
}
var inactivityTime = function () {
var t;
window.onload = resetTimer;
// DOM Events
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;
function logout() {
alert("You are now logged out.")
//location.href = 'logout.php'
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(logout, 3000)
// 1000 milisec = 1 sec
}
};
}

Fetch callback in React

I am trying to have a simple print run statement to ensure the callback is working correctly.
var CsvUpload = React.createClass({
uploadfile: function() {
console.log('trying')
var file = this.refs.file.files[0];
var formData = new FormData()
formData.append('files', file)
fetch('http://127.0.0.1:5000/add_csv_to_db', {
method :'POST',
body : formData
})
.then(() => {console.log('this worked')})
.catch((err) => {console.log(err)})
},
render: function() {
return (
<div>
<h4 className='sub-header'>CSV Upload</h4>
<form onSubmit = {this.uploadfile} encType="multipart/form-data">
<input type="file" name="file" ref="file"/>
<button type="submit" className="btn btn-primary">Submit</button>
</form>
</div>
)
}
})
On the server:
#app.route('/add_csv_to_db', methods=['GET','POST'])
def add_rows():
file = request.files['files']
x = io.StringIO(file.read().decode('UTF8'), newline=None)
csv_input = csv.reader(x)
for row in csv_input:
if row[0] == 'Email':
pass
else:
print(row)
tasks.add_User(row)
print('completed')
return json.dumps('success!')
I see "completed" print out in the server.
In the console I see "trying" but it doesn't print "This worked"
What am I doing wrong?
Have you tried adding submission event as your uploadFile function's parameter and then calling preventDefault() on it? Your app might be refreshing on submission, and that is why you never see "this worked" printed out.
This is what I mean:
var CsvUpload = React.createClass({
uploadfile: function(e) {
e.preventDefault();
console.log('trying')
...

using WinJS.xhr to post variables to a URL

Am trying to create a login page for my windows 8 app, am using Html5 and javascript.. so have tried to use winjs.xhr to post what is in the textboxes as variables to a specific url which is a php script so this is my example of the url "http://example.com/api/username=username&password=password" am using winjs.xhr to post these variables to the url but am not getting any response even in the console.log
this is my code
<script>
function handlelogin(){
document.getElementById("box").onsubmit = function(){
if(document.getElementById("email_address").value ==""){
document.getElementById("errormessage").innerHTML= "Please Provide Your Email Address";
return false;
}else{
var email_address = document.getElementById("email_address");
var password = document.getElementById("password");
var formparams = "?username=" + email_address.value + "&password=" + password.value;
document.getElementById("errormessage").innerHTML = "";
WinJS.xhr({type: "POST",
url: "http://example.com/api/",
data: formparams,
headers: { "Content-type": "application/x-www-form-urlencoded" }
}).then(
function (success) {
console.log(success.statusText);
if(success == 1703){
WinJS.Navigation.navigate("home.html");
}
},
function (error) {
console.log(error);
}
);
}
};
}
window.onload = function () {
handlelogin();
}
</script>
<form id="box" method="post" name="loginform">
<p>Email address</p>
<div class="email_address"><input type="text" id="email_address" /></div>
<p>Password</p>
<div class="password"><input type="password" id="password" /></div>
<p><span id="errormessage"></span></p>
<div class="button"><input type="submit" id="login" value="Sign In"/></div>
<p>ForgotPassword?</p>
</form>
First - don't use a submit button. Use a input type="button". No submit required, you are simply reading the values on the page.
Second - attach the event handler for the button's click event. Doing this 'onload' for the window isn't the right place.
Third - don't use 'onsubmit' for your 'box' element. There is no form submission going on here. There shouldn't usually be a form submit in WinJS - that's for a browser posting the page to the server. You already are POSTing your data. See the updated code:
I highly recommend putting ALL javascript into separate files, as you'll get bytecode optimization that way. Inline Javascript isn't optimized for the next load. A common way you could do this is include the onload code below (where I assign onclick) in your js file like so
app.onactivated = function (args) {
..
..
..
args.setPromise(WinJS.UI.processAll().then(function () {
document.getElementById("login").onclick = handlelogin;
}));
..
..
}
};
But the answer directly for your question above is:
<script>
function handlelogin() {
if (document.getElementById("email_address").value == "") {
document.getElementById("errormessage").innerHTML = "Please Provide Your Email Address";
return false;
} else {
var email_address = document.getElementById("email_address");
var password = document.getElementById("password");
var formparams = "?username=" + email_address.value + "&password=" + password.value;
document.getElementById("errormessage").innerHTML = "";
WinJS.xhr({
type: "POST",
url: "http://example.com/api/",
data: formparams,
headers: { "Content-type": "application/x-www-form-urlencoded" }
}).then(
function (success) {
console.log(success.statusText);
if (success == 1703) {
WinJS.Navigation.navigate("home.html");
}
},
function (error) {
console.log(error);
}
);
}
}
window.onload = function() {
document.getElementById("login").onclick = handlelogin;
};
</script>
Check out some of the sessions in App Builder where they discuss JavaScript projects http://aka.ms/stackbuilder

Categories