HTML Form don't let me fill it with javascript - javascript

I'm new to javascript and I need to fill in this form and then click the button to login. Hope someone could guide me into the right direction of why it's not working.
On practically any other site I've tested, it works fine (basically just switching out the "Id's") - but not on this particular site.
The site is not available for public so I can't provide the URL for it.
The problem is if I manually fill username and password and then from the web console use the .click event below, the login works fine.
When I use the .value event to fill username and password, I can see both fields gets filled but when .click event happens, it triggers the login and it seems to work but after a few seconds, it just says invalid username and password, like if I typed the wrong username and password.
Since I can't see the password in clear text from the form, I don't know if it's right or not but if I use the console from the web browser, I can see both username and password returns the correct values.
I'm using the following code:
function doStuff(){
document.getElementById('loginUsername').value = "username#email.com";
document.getElementById('password').value = "password123"
document.getElementsByClassName('button ok')[0].click();
}
doStuff();
<form data-v-d9a0abfc="" data-v-48366e1e="" role="form" class="form loginForm">
<h2 data-v-d9a0abfc="" role="region" class="visuallyhidden">Login form</h2>
<label data-v-d9a0abfc="" for="loginUsername" class="loginLabel">Username</label>
<input data-v-d9a0abfc="" spellcheck="false" type="text" id="loginUsername" name="loginUsername" autofocus="autofocus" class="form-control loginField">
<label data-v-d9a0abfc="" for="password" class="loginLabel">Password</label>
<input data-v-d9a0abfc="" type="password" id="password" name="password" autofocus="autofocus" class="form-control loginField">
<div data-v-d9a0abfc="" class="">
<div data-v-304a83cb="" data-v-d9a0abfc="" role="alert" aria-relevant="additions removals" style="display: none;">
</div>
<div data-v-7224d6b7="" data-v-d9a0abfc="" class="ace-button" id="accept-button">
<button data-v-7224d6b7="" aria-describedby="11" tabindex="0" type="button" class="button ok">
Login
</button>
</div>
</div>
</form>

It's possible that the website stores the input value in memory by listening to the input onchange callback. Then when clicking on the submit button, it sends the in memory value instead of the one you set programatically. This is not triggered when you programatically update the input value.
What you could try is to programatically trigger the change Event like this:
function doStuff(){
var usernameInput = document.getElementById('loginUsername');
usernameInput.value = "username#email.com";
usernameInput.dispatchEvent(new Event("change"));
var passwordInput = document.getElementById('password');
passwordInput.value = "password123";
passwordInput.dispatchEvent(new Event("change"));
document.getElementsByClassName('button ok')[0].click();
}

As a comment pointed out already, i suspect a Framework is handling the Frontend. It could also be, that there is just an onChange Event or an onInput Event tracking the Value and already working some validation or something in the background.
I've put together an example why your code would fail.
If there is an EventListener inplace, to track the Inputs and handling the values somewhere else, you could emit the Event yourself after setting the value. This should do the trick, if there is a separate handling inplace.
let username = undefined;
let password = undefined;
document.addEventListener("DOMContentLoaded", function() {
// Code to update a variable in the background.
document.getElementById('textInput').addEventListener('change', updateUsername);
document.getElementById('passInput').addEventListener('change', updatePassword);
document.getElementById('btnSubmit').addEventListener('click', function(e) {
e.preventDefault();
e.stopImmediatePropagation();
const text = document.getElementById('textInput').value;
const pass = document.getElementById('passInput').value;
console.log(text,"|", pass);
console.log(username,"|", password);
});
// Your code, to manipulate the Inputfields.
const textInputEl = document.getElementById('textInput');
textInputEl.value = "Test value ...";
// This line triggers the change event, it could also be the 'input' event, depending which // events gets listened to. With this, if there is an event in the background listened to, to
// track the Value, it should update the variable accordingly.
// textInputEl.dispatchEvent(new Event('change'));
const passInputEl = document.getElementById('passInput');
passInputEl.value = "Test value ...";
// Same line as above
// passInputEl.dispatchEvent(new Event('change'));
});
function updateUsername(event){
username = event.target.value;
}
function updatePassword(event) {
password = event.target.value;
}
<div class="container">
<input type="text" id="textInput" />
<input type="password" id="passInput" />
<button type="submit" id="btnSubmit">Submit</button>
</div>

Related

cleaning DOM of JS, because of livewire

i have a project that have combination of: php(laravel) in backend AND front end of javascript+css+html.
my strategy:
I have an input for inserting password(input type: password).
I have an icon for show, password digits, when user click on that icon.
handle that process, by "onclick" event inside "icon" element:
when user clicks on "eye icon", javascript changes the property of input tag, the type="password" to type="text",(user can see her/his inserted password digits ).
MY PROBLEM:
but, because of livewire property inside input tag ,after of showing password digits,
by typing more password digits, password numbers being convert to * again!
livewire property that used inside input tag: wire:model.debounce.700ms="password" .
I think, it is because of that:
the livewire, reloads the input tag.
Anyone knows the solution?
the div, that contains input password and eye icon(for clicking by user for show password digits):
<div class="o-form__field-frame o-form__field-frame--password #error('password') has-error #enderror">
<input type="password" wire:model.debounce.700ms="password" id="password" value="{{$password}}" placeholder="PLEASE INSERT YOUR PASSWORD" class="o-form__field">
<i class='fa fa-eye hSh_eye_show_pass' onclick='showPass()'></i>
</div>
the function that handle that:
//for show pass:
function showPass(){
document.getElementById('password').type="text";
}
Since livewire changes the input stuff you could have a second input of type text hidden and if the user clicks the other input is shown instead:
// used for being able to apply the inputs values correctly..
// u can omit that this is only for making code snippet working..
let pwHidden = true
function togglePassVisibility() {
const passVisible = document.getElementById('password-visible')
const passHidden = document.getElementById('password-hidden')
// toggle the .hidden class on both..
passVisible.classList.toggle('hidden')
passHidden.classList.toggle('hidden')
// make this code snippet work since I cannot access {{$password}}
// you can omit this..
if(pwHidden) {
passVisible.value = passHidden.value
} else {
passHidden.value = passVisible.value
}
pwHidden = !pwHidden
}
.hidden {
display: none;
}
<!-- you need ofc to pass {{$password}} as value to make it work in your environment. -->
<input type="text" class="hidden" id="password-visible"></input>
<input type="password" id="password-hidden"></input>
<button onClick="togglePassVisibility()">toggle</button>

Display error style with javascript using html 5 validations

I have a form with HTML validations and I am using JS to add or remove error style.
<form action="" id="addForm">
<div>
<label for="name">Name</label>
<input type="text" id="name" name="name" required minlength="3" />
</div>
<button type="submit">Add</button>
</form>
window.onload = handleLoad;
function handleLoad() {
const form = document.forms.addForm;
const name = form.name;
name.onkeyup = function () {
if (name.checkValidity()) {
name.classList.remove("error");
} else {
name.classList.add("error");
}
};
}
In this case the error class gets applied as the user is typing in the field. Is there a way to prevent this?
You are using the onkeyup event, which means the event is triggered every time the user releases a key.
If you want to check the input field only when the user moves to the next field, you could use the onfocusout event.
name.onkeyup = function () {
if (name.checkValidity()) {
name.classList.remove("error");
} else {
name.classList.add("error");
}
}
P.S., If you have a small form, you could also implement validation when the submit button is clicked.

Javascript redirect to html

I've been trying to let javascript redirect to another html file using window.location but it keeps reloading. Here is the Javascript
var myStorage = window.localStorage;
let accounts = [{
username: 'admin',
pass: 'admin123!',
email: 'admin#gmail.com'
}];
myStorage.setItem("account", accounts);
//check login account
var checkLogin = function() {
let uname = document.getElementById("Uname").value;
let pass = document.getElementById("Pass").value;
if (uname == "admin" && pass == "admin123!") {
myStorage.setItem("user", {
username: 'admin',
pass: 'admin123!',
email: 'admin#gmail.com'
});
alert("Login admin");
window.location = "../account/myaccount.html";
alert("redirect");
} else {
myStorage.setItem("user", undefined);
document.getElementById("incorrectAccount").style.color = "red";
document.getElementById("incorrectAccount").innerHTML = "Incorrect Username or Password";
}
};
<form id="login" method="post" onsubmit="return checkLogin();">
<div>
<label><b>Username:
</b>
</label>
<input type="text" name="Uname" id="Uname" placeholder="admin"><br><br>
</div>
<div>
<label><b>Password: </b></label>
<input type="Password" name="Pass" id="Pass" placeholder="admin123!"><br><br>
</div>
<div>
<input type="submit" name="log" id="log" value="Log In"></a>
<span id="incorrectAccount"></span>
<br><br>
</div>
<div>
<input type="checkbox" id="check">
<span>Remember me</span>
</div>
<div>
Forgot Password?
<br><br>
Register
</div>
</form>
After typing the same username and the password, the first alert works and then it skips the redirect link and goes straight for the 2nd alert message
Submitting a form will cause the page to load the URL specified in the action attribute, which defaults to the current URL, which gives that effect though.
You must be trigging the JS when you submit the form. The JS runs, then the form submits, and the URL being navigated to changes.
You need to prevent the default behaviour of the form submission event.
e.g.
var checkLogin = function(event){
event.preventDefault();
and
document.querySelector('form').addEventListener('submit', checkLogin);
Re edit.
This is the problem. However, you are using event binding methods from before they introduced addEventListener (which became a standard in November 2000).
If you want to use intrinsic event attributes (I don't recommend them, they have some confusing gotchas) then you need to return false from the event handler.
onsubmit="return checkLogin();"
You are currently returning the return value of checkLogin, but that doesn't have a return statement so it returns undefined. You need to return false and not any falsy value.
function myRedirect() {
location.replace("https://stackoverflow.com")
}
<button onclick="myRedirect()">Replace document</button>

Clear a field when the user starts filling a form

I have a view with a form in it:
<form asp-controller="UrlP" asp-action="RegisterInput" method="post">
Url: <input asp-for="Url" />
<br />
<button type="submit">Go!</button>
and, on the same view, I have a result from the previous submission:
#if (!string.IsNullOrEmpty(Model.Result))
{
<div class="result">The result is: #Model.Result</div>
}
How can I make the div above (class 'result') disappear as soon a the user starts typing in the form?
To give some context, the app is a single page where you provide a url and you get a result below and I would like to clear the result as soon as a new url is entered.
Since you are using ASP.net Core, it can be handled from the Action and Model State
So after the post, just clear your ModelState and return view like :
ModelState.Clear();
return View(<some View>);
Here's one way.
window.onload = function () {
// attach onkeypress event handler to all text inputs
document.querySelectorAll('form [type=text]').forEach(function (input) {
input.onkeypress = hideResult;
});
};
function hideResult () {
var result = document.querySelector('.result');
// remove result if it exist
if (result) {
result.parentNode.removeChild(result);
}
}
<div class="result">The result is: #Model.Result</div>
<form>
<input type="text" value=""><br>
<input type="text" value="">
</form>

Jquery not returning the values in form INPUTs

I have a login form on a modal jquery dialog with the usual 2 text INPUTs. When I enter a login name and password then click the submit, the call back function is called.
The first thing the callback does is try to extract the values of the two INPUTs, but the values returned are empty strings (I have a breakpont here, and have even stepped through the jquery processing of the objects - they objects are correctly identified as the fields on the form, but value="" for both).
At this point I can still see the values in the form, and when the callback exits and the focus goes back to the form, the values are still in the INPUTS. I also tried .prop("value") rather than .val(), but the result was the same.
I just can't figure why I can't read the values - any help appreciated.
<form id="cp-loginform" action="/cypo/index.php" method="POST" >
<input type="hidden" name="Login" value="Login">
<input type="hidden" name="pp" value="0" />
<input type="text" id="cp-loginname" name = "loginname" placeholder = "Login ID" class="loginforminput cp-width-50" autofocus >
<input type="password" id="cp-password" name = "password" placeholder = "password" class="loginforminput cp-width-50"></p>
<input type="submit" id="cp-submit" name = "submit" onclick="ProcessLogin()" ></p>
</form>
function ProcessLogin() {
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
console.log(loginval.concat(" ",passwordval));
}
PROBLEM RESOLVED:
I felt that this was a scope issue. The form itself was obviously OK (if submitted from the dialog it worked) - it was just the attempt to check the INPUT values using jquery that wasn't working.
I found that my select had to start with the dialog element and include a descendent path to my INPUTs. It's as if the dialog puts a wrapper around the elements inside so they are no longer visible as owned by the document.
If I login with xxx and zzz and step therough the following code I see this:
var loginval = $("#cploginname").val(); << = ""
var passwordval = $("#cppassword").val(); << = ""
var loginval = $("#cp-loginform #cploginname").val(); << = ""
var passwordval = $("#cp-loginform #cppassword").val(); << = ""
var loginval = $("#cpdialog #cp-loginform #cploginname").val(); << = "xxx"
var passwordval = $("#cpdialog #cp-loginform #cppassword").val(); << = "zzz"
console.log(loginval.concat(" ",passwordval));
I can't say I understand what's going on, but I have a solution so I am happy. Thanks to all who answered.
FINAL WORD
Thanks to #CMedina, I now understand. The form was defined in a hidden DIV at the top of my BODY section, and I passed $("#loginform") to a f() that created the dialog. The dialog was added to the DOM just before the . I had missed the fact that my original form was still in the DOM, so I was referencing that, not the dialog copy. When I included the dialog wrapper in the path, I finally 'found' the second copy.
Your button is the type submit (their natural behavior is to send the form). Remove the onclick in your button html.
<input type="submit" id="cp-submit" name = "submit">
You must add preventDefault to prevent submit the form and do what you want. Add the code JS for the button onclick event
$("#cp-submit").on("click", function(e){
e.preventDefault();
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
console.log(loginval.concat(" ",passwordval));
});
Result: https://jsfiddle.net/cmedina/svjqb2a4/
Try it :
<html>
<head>
</head>
<body>
<form id="cp-loginform" action="/cypo/index.php" method="POST">
<input type="hidden" name="Login" value="Login">
<input type="hidden" name="pp" value="0" />
<input type="text" id="cp-loginname" name = "loginname" placeholder = "Login ID" class="loginforminput cp-width-50" autofocus >
<input type="password" id="cp-password" name = "password" placeholder = "password" class="loginforminput cp-width-50">
<input type="submit" id="cp-submit" name ="submit" onclick="ProcessLogin(event)">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
function ProcessLogin(e) {
e.preventDefault();
var loginval = $("#cp-loginname").val();
var passwordval = $("#cp-password").val();
alert(loginval.concat(" ",passwordval));
}
</script>
</body>
</html>

Categories