Jquery Submit is causing a serious issue while processing the callback function - javascript

I've made program via which I am trying to create grids after taking value for number of boxes in rows and columns. When I submit the form by clicking on submit button; I'm unable to view effects as they disappear in seconds.
Now when I handle the same event using click event handler I am able to see all my effects. Why submit event handler is failing while click event handler is becoming a success? What is logic behind the disappearance of my output in seconds after pressing submit button whereas on the other hand the same output is visible for a long time when I am using the click event handler?
required output is given by below script ->
$(()=>{
function grid(row, col){
for(let i=1; i<=(row*col); ++i)
$('.Grid').append($('<div></div>').addClass("Tile"));
}
$('button').click(()=>{
$('.Grid').width($('#a').val() * 40);
$('.Grid').height($('#b').val() * 40);
grid($('#a').val(), $('#b').val());
});
});
.Grid{
font-size: 0px;
border: 2px solid blue;
}
.Tile{
height: 40px;
width: 40px;
border-radius: 6px;
background-color: grey;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Grid"></div>
<button>Display!</button>
<form>
columns -> <input id="a" type="number"> <br/>
rows -> <input id="b" type="number"> <br/>
</form>
momentary(not required) output is given by below script ->
$(()=>{
function grid(row, col){
for(let i=1; i<=(row*col); ++i)
$('.Grid').append($('<div></div>').addClass("Tile"));
}
$('form').submit(()=>{
$('.Grid').width($('#a').val() * 40);
$('.Grid').height($('#b').val() * 40);
grid($('#a').val(), $('#b').val());
});
});
.Grid{
font-size: 0px;
border: 2px solid blue;
}
.Tile{
height: 40px;
width: 40px;
border-radius: 6px;
background-color: grey;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Grid"></div>
<form>
columns -> <input id="a" type="number"> <br/>
rows -> <input id="b" type="number"> <br/>
<input type="submit" value="submit">
</form>

When you submit a form, browsers will perform a full page reload as they attempt to "submit" the data, usually to the location specified in the form's action attribute. This is 100% expected behaviour.
You can prevent this default behaviour by intercepting the event when the form is submitted. In your code, when you add the submit handler, you have access to the underlying event and a function called preventDefault().
When you call this, the event is stopped. Here's a more in-depth explanation of how it all works: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
And I've updated your code snippet below with a working example:
$(() => {
function grid(row, col) {
for (let i = 1; i <= (row * col); ++i)
$('.Grid').append($('<div></div>').addClass("Tile"));
}
$('form').submit((event) => {
event.preventDefault();
$('.Grid').width($('#a').val() * 40);
$('.Grid').height($('#b').val() * 40);
grid($('#a').val(), $('#b').val());
});
});
.Grid {
font-size: 0px;
border: 2px solid blue;
}
.Tile {
height: 40px;
width: 40px;
border-radius: 6px;
background-color: grey;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Grid"></div>
<form>
columns -> <input id="a" type="number" /> <br/> rows -> <input id="b" type="number" /> <br/>
<input type="submit" value="submit" />
</form>

Related

Google Sheets modal dialog is clearing html after form submission (code is at the bottom)

Goal
I'm trying to execute a piece of code in a Google Spreadsheets modal dialog after pressing a submit button in a form. After the submit button is pressed, I want the dialog to display a loading wheel (I've already made that), then close itself using google.script.host.close() after a 1.5 second delay (using setTimeout() for that one).
Previous Attempt
I was able to get it working before without the submit button and without the <form> element, and instead using onclick attributes on normal buttons, but I wasn't able to have the validation work properly with that solution.
Outcome
What ended up happening was immediately after pressing the submit button, the contents of the modal dialog disappeared and it just stayed open until I had to close it manually, and none of the code that I wanted to be executed was executed. When I used the Inspector to look at the source html for the dialog, the block was completely empty. All that was left was this:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body></body>
</html>
I tried doing the classic debugging solution of console.log(). I put a pair of log functions in the submission event handler, one before and one after the e.preventDefault(). Neither were logged. I can only assume that this means the function wasn't being executed at all.
Desired Solution
I need help identifying what went wrong, or if this is some kind of bug with Google's platform, and how I can improve or fix this (if at all).
Edit 1
I have attempted to use event.preventDefault(), as has been suggested by the answers given in the linked posts (I have edited the snippet to show how I have attempted to use it). This has not worked, and results in the same outcome described above. (Also elaborated what happened in the outcome).
Code Snippets
The snippets following are (in order) JavaScript, CSS, and HTML.
var x;
let ID = t => document.getElementById(t);
var loader = ID('loader');
document.addEventListener("DOMContentLoaded", () => {
loader.style.visibility = 'visible';
google.script.run.withSuccessHandler(res => {
x = res.arr[1];
google.script.run.callLibraryFunction('CharacterSheetCode.clearClassEdit');
switch (res.arr[0]) {
case 'edit':
ID('class').value = res.arr[2].class;
ID('subclass').value = res.arr[2].subclass;
ID('level').value = res.arr[2].level;
ID('hitdie').value = res.arr[2].hitdie;
ID('spellcasting').value = res.arr[2].spells;
makeEditable();
break;
case 'add':
makeEditable();
break;
}
function makeEditable() {
ID('class').readOnly = false;
ID('subclass').readOnly = false;
ID('level').readOnly = false;
ID('level').max = (20 - res.lvl) + (res.arr[2] ? Number(res.arr[2].level) : 0);
ID('hitdie').readOnly = false;
ID('spellcasting').readOnly = false;
ID('addedit').disabled = false;
ID('remove').disabled = false;
loader.style.visibility = 'hidden';
}
})
.callLibraryFunction("CharacterSheetCode.getClassInfo");
});
ID("form").addEventListener("submit", e => {
e.preventDefault();
loader.style.visibility = 'visible';
var className = ID('class').value,
subclass = ID('subclass').value,
level = ID('level').value,
hitdie = ID('hitdie').value,
spells = ID('spellcasting').value;
if (hitdie % 2 == 0 && hitdie >= 6 && hitdie <= 12) {
setTimeout(() => google.script.host.close(), 1500);
google.script.run.callLibraryFunction("CharacterSheetCode.addEditInfo", [className.trim(), subclass.trim(), level, hitdie, spells, x]);
} else {
alert(`Error: You must use a d6, d8, d10, or d12 as a hit die. A d${hitdie} will not be accepted.`);
loader.style.visibility = 'hidden';
}
}
function removeClass() {
loader.style.visibility = 'visible';
setTimeout(() => google.script.host.close(), 1500);
google.script.run.callLibraryFunction("CharacterSheetCode.addEditInfo", ['', '', '', '', '', x]);
}
.container {
background-color: white;
padding: 15px;
height: 200px;
width: 300px;
font-family: Georgia;
color: black;
font-size: 15px;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
text-align: center;
}
input {
border-radius: 1em;
text-align: center;
font-family: Georgia;
font-size: 15px;
}
select {
border-radius: 1em;
font-family: Georgia;
font-size: 15px;
}
button {
border-radius: 1em;
font-family: Georgia;
font-size: 15px;
}
button:active {
filter: brightness(80%);
}
.loader {
border: 5px solid #f3f3f3;
border-radius: 50%;
border-top: 5px solid #3498db;
border-bottom: 5px solid #3498db;
position: absolute;
top: calc(50% - 30px);
left: calc(50% - 30px);
width: 50px;
height: 50px;
z-index: 10;
animation: spin 2s linear infinite;
}
#keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div id="loader" class="loader" style="visibility: hidden;"></div>
<div id="container" class="container">
<form id="form">
<label for="class">Class</label>
<input type="text" id="class" required readonly="readonly"><br>
<label for="subclass">Subclass</label>
<input type="text" id="subclass" readonly="readonly"><br>
<label for="level">Level</label>
<input type="number" id="level" style="width: 50px;" min="1" max="20" required readonly="readonly" onkeypress="return event.charCode >= 48 && event.charCode <= 57">
<label for="hitdie">Hit Die: d</label>
<input type="number" id="hitdie" style="width: 50px" min="6" max="12" step="2" required readonly="readonly" onkeypress="return event.charCode >= 48 && event.charCode <= 57"><br>
<label for="spellcasting">Spellcasting:</label>
<select id="spellcasting" readonly="readonly">
<option>None</option>
<option>Full</option>
<option>Half</option>
<option>Third</option>
<option>Pact</option>
</select><br>
<button id="addedit" type="submit" disabled>Add/Edit</button><br>
<button id="remove" onclick="removeClass()" disabled>Remove Class</button>
<div>Note: The process of updating the sheet can sometimes take up to 20-40 seconds.</div>
</form>
</div>

How do I delete only one row of appended information in a table using jQuery?

I am trying to make a "My Favorite Movies" list page where users can add and rate movies. This program should include:
1) a form where you can add to the list and rate it
2) a table of all the things you've added
3) delete button for each row of the table that lets you remove elements from the list (what i'm having trouble on)
Instead of deleting only one row, it deletes every appended movie/rating in the table. Also if you click anywhere else, it deletes everything as well.
4) bonus: sort feature, so i can sort entries in the table by the their title or their rating.
example here: rithm school example
$(function() {
$('#addMovieButton').click(function() {
var addToTitle = $('#title').val();
$('#tableTitle').append('<tr><td>' + addToTitle + '</td></tr>');
var addToRating = $("#rating").val();
$('#tableRating').append('<tr><td>' + addToRating + '</td></tr>');
$('#tableDelete').append('<tr><td><input type="button" value="Delete All"</tr></td>');
$('#tableRow').on('click', function() {
$('#tableTitle').last().children().remove();
$('#tableRating').last().children().remove();
$('#tableDelete').last().children().remove();
});
});
});
h1 {
text-align: center;
}
table {
width: 100%;
border-radius: 10px;
}
table,
td {
border: 1px solid black;
padding: 15px;
}
th {
height: 50px;
text-align: center;
}
td {
text-align: center;
}
body {
font-family: helvetica;
}
form {
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><b>Title</b></label>
<input id="title" type="text" value="Movie Title">
<label><b>Rating</b></label>
<input id="rating" type="text" value="Rate The Movie from 0 to 10">
<button type='button' id="addMovieButton">Add Movie</button>
</form>
<table>
<tr id="tableRow">
<th id="tableTitle">Title</th>
<th id="tableRating">Rating</th>
<th id="tableDelete">Delete</th>
</tr>
</table>
<table> Structure
The structure of the appended "row" are not valid HTML. A <table> will have at least one <tbody>. If the user doesn't add it the browser will. Although most methods, function, and properties will treat the <table> as the direct parent of <tr>, there are some advantages to targeting <tbody> instead. If there's a <thead> then targeting the <tbody> can free you from extra steps trying to avoid the <th>.
Keep these rules in mind when structuring a <table>
<tbody> can only have <tr> as children (direct descendants)
<tr> can only have <td> and <th> as children
<td> and <th> can have anything as descendants.
Make sure rows are structured like so:
<tr><td</td>...<td></td></tr>
Add row to <table> or <tbody>
Demo
The following demo has detailed comments within the HTML, and CSS, as well as step by step details commented in the JavaScript
$(function() {
/*
Bind the <form> to the 'submit', 'click', and 'change' events.
Pass the Event Object thru
*/
$('form').on('submit click change', function(event) {
// Reference the type of event
let eType = event.type;
// if the 'submit' event was triggered...
if (eType === 'submit') {
// Stop the <form> from sending data to a server and resetting
event.preventDefault();
// Get the values of the <input>
let name = $('.title').val();
let rate = $('.rating').val();
// Declare a htmlString using a Template Literal
const row = `
<tr><td>${name}</td>
<td>${rate}</td>
<td><input class='sel' type='checkbox'>
</td></tr>`;
// Render the htmlString as the last child of the <tbody>
$('.data').append(row);
// Reset <form>
$(this).trigger('reset');
// ...otherwise if the 'click' event triggered...
} else if (eType === 'click') {
// ...and the clicked tag has class 'del'...
if ($(event.target).hasClass('del')) {
/*
Collect all checked <input class='sel'>
then on .each() one...
*/
$('.sel:checked').each(function(i) {
/*
Get the ancestor <tr> of the current .sel
and remove it
*/
$(this).closest('tr').remove();
});
// Reset the <form>
$('form').trigger('reset');
}
// ...otherwise if the 'change' event was triggered...
} else if (eType === 'change') {
// ...and the changed tag id is 'all'...
if (event.target.id === 'all') {
// Check if #all is checked or not
let allChk = $('#all').is(':checked');
// Loop thru each() <input class='sel'>...
$('.sel').each(function(i) {
/*
and check current .sel if #all is checked
or uncheck current .sel if #all is NOT checked
*/
$(this).prop('checked', allChk);
});
}
}
// Stop any events from bubbling any further up the event chain
event.stopPropagation();
});
});
:root {
font: 400 3vw/1.2 Arial;
}
form {
text-align: center;
}
table {
width: 100%;
border-radius: 10px;
table-layout: fixed;
margin: 12px auto
}
table,
td {
border: 1px solid black;
padding: 15px;
}
th {
height: 30px;
width: 20%;
}
th:first-of-type {
width: 60%;
}
td {
text-align: center;
}
button,
input,
label {
display: inline-block;
font-size: initial;
}
.all {
font-weight: 400;
padding: 3px 6px;
border: 1.5px inset rgba(0, 28, 255, 0.3);
margin-top: 3px;
}
.all::after {
content: 'Selected'
}
/*
When input#all is :checked the label.all that follows
#all will change
the content of its pseudo-element from 'Selected' to 'All'
*/
#all:checked+.all::after {
content: 'All'
}
button:hover {
cursor: pointer;
outline: 3px outset rgba(0, 28, 255, 0.4);
color: rgba(0, 28, 255, 0.6);
}
.all:hover {
cursor: pointer;
color: rgba(0, 28, 255, 0.8);
background: rgba(0, 28, 255, 0.2);
}
.rating {
text-align: right;
width: 4ch;
}
.title {
padding-left: 5px;
width: 27ch;
}
/*
The checkbox #all is not visible to user but is accessible through the label.all
which it is synced with (see comments in HTML
*/
#all {
display: none
}
<form>
<label>Title</label>
<!--
The [required] attribute enables built-in form validation
If the submit event is triggered
and either <input> is blank, the submit event is interrupted and
a tooltip will notify
user that the <input> cannot be empty
-->
<input class="title" type="text" placeholder="Pulp Fiction" required>
<label>Rating</label>
<!-- See previous comment -->
<input class="rating" type="number" min='0' max='10' placeholder="10" required>
<!--
<button type='submit'> or <input type='submit'>
or <button> within a <form> will trigger a submit event by default
-->
<button>Add Movie</button>
<table>
<thead>
<tr>
<th>Title</th>
<th>Rating</th>
<th>
<button class='del' type='button'>Remove</button>
<!--
A <label> and a form control (ie <input>, <textarea>, <select>, etc) can be synced by
matching the [for] attribute value to the form controls #id:
1. <label for='XXX'>
2. <input id='XXX'>
When synced, clicking one will remotely click the other
-->
<input id='all' type='checkbox'>
<label class='all' for='all'></label></th>
</tr>
</thead>
<!--
See post on <table> structure
-->
<tbody class='data'></tbody>
</table>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
you've put all titles in a parent, and all rating in another parent ,and all delete buttons in another one . you should place the information about each row in a parent and then you can delete by row easily.
(also you can add td,tbody it's just sample to showing the way)
$('#addMovieButton').click(function () {
var addToTitle = $('#title').val();
var addToRating = $("#rating").val();
$('#table').append('<tr><th>' + addToTitle + '</th><th>' + addToRating + '</th><th><input type="button" value="Delete All" class="tableDelete"></th></tr>');
$('.tableDelete').click(function () {
$(this).parents('tr').remove();
});
});
h1 {
text-align: center;
}
table {
width: 100%;
border-radius: 10px;
}
table,
td {
border: 1px solid black;
padding: 15px;
}
th {
height: 50px;
text-align: center;
}
td {
text-align: center;
}
body {
font-family: helvetica;
}
form {
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<label><b>Title</b></label>
<input id="title" type="text" value="Movie Title">
<label><b>Rating</b></label>
<input id="rating" type="text" value="Rate The Movie from 0 to 10">
<button type='button' id="addMovieButton">Add Movie</button>
</form>
<table id="table">
</table>

dynamically update css content using javascript

There is a need to update css to dynamic value and I am not sure what's the best approach to it.
<div id="app" style="zoom: 0.XX;">
...
</div>
The zoom level will trigger based on window resize and the app will zoom according. I loaded this app into cordova and have it run within iPAD, then I realize the font-size needs to be adjusted to the same as zoom level using "-webkit-text-size-adjust" in order for it to not break the design layout.
My challenge is to set the css dynamically like this:
#app * {
-webkit-text-size-adjust : nn%
}
Where nn is the zoom X 100 + '%'
I have tried:
1) Set the style on the app div, but this doesn't help to apply to inner elements
<div id="app" style="zoom: 0.XX; -webkit-text-size-adjust: XX%">
2) Use javascript to set to all inner nodes, but not only I think this is less efficient, but it won't get trigger if my window doesn't resize, that means if I navigate to other pages, this logic won't get called.
REF: https://stackoverflow.com/questions/25305719/change-css-for-all-elements-from-js
let textSizeAdjust = function(zoom) {
let i,
tags = document.getElementById("app").getElementsByTagName("*"),
total = tags.length;
for ( i = 0; i < total; i++ ) {
tags[i].style.webkitTextSizeAdjust = (zoom * 100) + '%';
}
}
3) I tried using javascript, and most likely they are technically incorrect because querySelector return null.
document.querySelector('#app *').style.webkitTextSizeAdjust = zoom *100 + '%';
document.querySelector('#app').querySelector('*').style.webkitTextSizeAdjust = zoom * 100 + "%";
Ultimate, I believe I need to dynamically create the css, for the browser to apply this setting to the DOM:
#app * {
-webkit-text-size-adjust: nn
}
Please let me know if this is the right, or how to use javascript to create the above css and change the value dynamically?
CSS Variables
Requirements
HTML
Each form control that has numerical data should have:
value={a default, don't leave it blank}
class='num'
data-unit={unit of measurement or a single space}
The select/option tag should have the selected attribute
CSS
CSS Variable Signature: propertyName: var(--propertyValue)
// Declare CSS Variables at the top of a stylesheet
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--zm0: 1.0;
--sp0: 360deg;
}
JavaScript
There's step by step details commented in the JavaScript Demo. Here's the most important statement in the code:
CSSStyleDeclaration CSS Variable
🢃 🢃
`ele.style.setProperty(`--${node.id}`,
${node.valueAsNumber}${node.dataset.unit})
🢁 🢁
HTMLInputElement DataSet API
Demo 1
// Reference form#UI
var ui = document.forms.UI;
// Register form#UI to change event
ui.addEventListener('change', setCSS);
// Callback passes Event Object
function setCSS(e) {
// Collect all form controls of form#UI into a NodeList
var fx = ui.elements;
// Reference select#pk0
var pk0 = fx.pk0;
// Get select#pk0 value
var pick = pk0.options[pk0.selectedIndex].value
// if the changed element has class .num...
if (e.target.className === 'num') {
// Reference Event Target
var tgt = e.target;
// Then reference is by its #id
var node = document.getElementById(tgt.id);
// DOM Object to reference either html, square, or circle
var ele;
/* Determine which tag to test on: html (affects everything),
|| #sQ<uare> and #ciR<cle> shapes.
*/
switch (pick) {
case "rT":
ele = document.documentElement;
break;
case "sQ":
ele = document.getElementById('sQ');
break;
case "cR":
ele = document.getElementById('cR');
break;
default:
break;
}
/* Sets a target element's Transform:
|| translateXY, scale, and rotate
*/
ele.style.setProperty(`--${node.id}`, `${node.valueAsNumber}${node.dataset.unit}`);
}
}
/* Declare CSS Variables on the :root selector at the top of sheet
All CSSVar must be prefixed with 2 dashes: --
*/
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--sp0: 360deg;
}
.set {
border: 3px ridge grey;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
padding: 5px;
}
/* The var() function's signature is:
propertyName: var(--propertyValue)
*/
#sQ {
position: relative;
background: rgba(0, 100, 200, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
z-index: 1;
transition: all 1s ease;
}
#cR {
position: relative;
background: rgba(200, 100, 0, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
border-radius: 50%;
transition: all 1s ease;
}
#sQ::before {
content: '\1f504';
text-align: center;
font-size: 2.25rem;
transform: translate(1px, -8px)
}
#cR::after {
content: '\1f3b1';
text-align: center;
font-size: 2.25rem;
}
input,
select {
display: inline-block;
width: 6ch;
font: inherit;
text-align: right;
line-height: 1.1;
padding: 1px 2px;
}
select {
width: 9ch
}
.extension {
overflow-y: scroll;
overflow-x: auto;
min-height: 90vh;
}
/* For debugging on Stack Snippets */
/*.as-console-wrapper {
width: 25%;
margin-left: 75%;
min-height: 85vh;
}*/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style></style>
</head>
<body>
<!--
HTML Requirements
Each form control that has numerical data should have:
1. value={a default, don't leave it blank}
2. class='num'
3. data-unit={unit of measurement or a single space}
4. The select/option tag should have the selected attribute
-->
<form id='UI'>
<section class='set'>
<label>X: </label>
<input id='mx0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Y: </label>
<input id='my0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Size: </label>
<input id='rz0' class='num' type='number' min='0' max='5' value='1' step='0.1' data-unit=' '>
<label>Spin: </label>
<input id='sp0' class='num' type='number' min='0' max='1440' value='360' step='180' data-unit='deg'>
<label>Pick: </label>
<select id='pk0' class='num'>
<option value='rT' selected>Root</option>
<option value='sQ'>Square</option>
<option value='cR'>Circle</option>
</select>
</section>
</form>
<section class='set extension'>
<div id='sQ' class='test shape' width="50" height="50"></div>
<div id='cR' class='test shape' width="50" height="50"></div>
</section>
</body>
</html>
Update
This update is specifically for OP, so this may be of help or not for other users.
Deno 2
:root {
--opc: 0;
--zoom: 1;
}
.fc {
display: inline-block;
width: 18ch;
margin:0 0 10px 0
}
#app * {
opacity: var(--opc);
transform: scale(var(--zoom));
}
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<form id='app' action='https://httpbin.org/post' method='post' target='view'>
<fieldset class='sec'>
<legend>App of Mystery</legend>
<input id='A0' name='A0' class='fc' type='text' placeholder='User Name'>
<input id='A1' name='A1' class='fc' type='password' placeholder='Password'>
<input type='submit'>
<input type='reset'>
<input id='zBtn' type='button' value='Zoom'>
<iframe name='view' frameborder='1' width='100%'></iframe>
</fieldset>
</form>
<script>
var node = document.querySelector('#app *');
var zBtn = document.getElementById('zBtn');
var flag = false;
document.addEventListener('DOMContentLoaded', function(e) {
node.style.setProperty("--opc", "0.5");
});
document.addEventListener('click', function(e) {
node.style.setProperty("--opc", "1");
});
zBtn.addEventListener('click', function(e) {
if (flag) {
flag = false;
node.style.setProperty("--zoom", "1");
} else {
flag = true;
node.style.setProperty("--zoom", "1.25");
}
});
</script>
</body>
</html>
I don't have much knowledge about -webkit-text-size-adjust
However, this should work for creating a dynamic stylesheet and inserting it:
I have added code to dynamically update it as well
const form = document.getElementById('colorChooser');
form.addEventListener('submit', (e) => {
e.preventDefault();
color = document.getElementById('colorInput').value;
const style = document.getElementById('colorStyle');
style.innerHTML = `#app * {
background-color: ${color};
}`;
});
const style = document.createElement('style');
style.id = 'colorStyle';
style.type = 'text/css';
style.innerHTML = `#app * {
background-color: red;
}`;
document.head.appendChild(style);
#app {
margin-bottom: 10px;
}
#inner {
width: 50px;
height: 50px;
background-color: black;
}
<div id="app">
<div id="inner"></div>
</div>
<form id="colorChooser">
<input id="colorInput" type="text" placeholder="red" />
<input type="submit" value="Update color"/>
</form>

Force HTML form validation via JavaScript

I have created a HTML form which has two buttons (instead of a submit button), each programmatically sending the form to a unique form action address.
<form id="formExample">
<input type="text" id="input1" required>
<label type="button" onClick="form1()">Form Action 1</label>
<label type="button" onClick="form2()">Form Action 2</label>
</form>
The scripts:
form = document.getElementById("formExample");
function form1() {
form.action="example1.php";
form.submit();
}
function form2() {
form.action="example2.php";
form.submit();
}
Work well, responding to which button you press. However, the same html form validation that worked before (when using a 'submit' button), no longer shows a hint and the form sends regardless of whether there is input or not.
I have read that because I am calling the form.submit() programmatically, it bypasses the onSubmit() function of a form, which is where the validation takes place.
My question is: Can I programmatically force the onSubmit() so that I get the validation pop up? I must make clear that I am NOT wanting to create a JavaScript form validation, i.e. using an alert; rather, use JavaScript to enforce the HTML validation as found here, when you click submit: https://jsfiddle.net/qdzxfm9u/
You can merely change your button's type to submit and drop the form.submit() from your JS part.
So the HTML part becomes:
<form id="formExample">
<input type="text" id="input1" required>
<button type="submit" onClick="form1()">Form Action 1</button>
<button type="submit" onClick="form2()">Form Action 2</button>
</form>
This way, clicking any button does submit by itself, but before is executed the JS part:
form = document.getElementById("formExample");
function form1() {
form.action="example1.php";
}
function form2() {
form.action="example2.php";
}
EDIT
Warning: I originally based my solution on a copy of the OP HTML part, where the "pseudo-buttons" used a strange element <label type="input"...>, so I read (too quickly) as if it was <button type="button"...> and simply changed type from input to submit!
This way, it couldn't work as expected.
It is now corrected in the above code.
Maybe something like this :
var form = document.getElementById("formExample");
function form1() {
form.action="example1.php";
}
function form2() {
form.action="example2.php";
}
<form id="formExample">
<input type="text" id="input1" required>
<input type="submit" onClick="form1()" value="Form Action 1" />
<input type="submit" onClick="form2()" value="Form Action 2" />
</form>
How about making a dropdown list - could be radio buttons instead - containing the form two actions with one submit button like in this JS Fiddle, then having one function on form submit
var form = document.getElementById("formExample"),
select = document.getElementById("slct");
form.addEventListener('submit', function() {
if (select.value == 1) {
form.action = "example1.php";
} else {
form.action = "example2.php";
}
// alert for demo only
alert(form.action);
form.submit();
});
<form id="formExample">
<input type="text" id="input1" required>
<select id="slct" required>
<option></option>
<option value="1">Form Action 1</option>
<option value="2">Form Action 2</option>
</select>
<button type="submit">Submit</button>
</form>
function togglePassword(el){
var checked = el.checked;
if (checked) {
document.getElementById("password").type = 'text';
document.getElementById("toggleText").textContent= "Hide";
} else {
document.getElementById("password").type = 'password';
document.getElementById("toggleText").textContent= "Show";
}
}
function login()
{
var uname = document.getElementById("uname").value;
var password = document.getElementById("password").value;
if(uname === '')
{
alert("Please enter the user name.");
}
else if(password === '')
{
alert("Enter the password");
}
else
{
alert('Login Successful. Thank You!');
}
}
function clearFunc()
{
document.getElementById("uname").value="";
document.getElementById("password").value="";
<script type="text/javascript">
function togglePassword(el){
var checked = el.checked;
if (checked) {
document.getElementById("password").type = 'text';
document.getElementById("toggleText").textContent= "Hide";
} else {
document.getElementById("password").type = 'password';
document.getElementById("toggleText").textContent= "Show";
}
}
function login()
{
var uname = document.getElementById("uname").value;
var password = document.getElementById("password").value;
if(uname === '')
{
alert("Please enter the user name.");
}
else if(password === '')
{
alert("Enter the password");
}
else
{
alert('Login Successful. Thank You!');
}
}
function clearFunc()
{
document.getElementById("uname").value="";
document.getElementById("password").value="";
}
</script>
/* heading */
h1 {
display: block;
font-size: 2em;
font-weight: bold;
/* padding: 0% 1% 3% 6.5%; */
margin: 0% 35% -10% 36%;
}
h1:hover{
color:#4499d9 ;
transform: translateY(-5px);
}
/* bg image */
body {
background-image: url('img/bg4.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
background-size: 100% 100%;
}
/* Bordered form */
form {
/* border: 13px solid black; */
width: 27%;
height: auto;
position: absolute;
left: 10%;
margin-left: -3px;
top: 18%;
}
/* Full-width inputs */
input[type=text], input[type=password] {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
box-sizing: border-box;
}
/* Set a style for all buttons */
button {
background-color: #17234b;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
cursor: pointer;
width: 49%;
}
/* Add a hover effect for buttons */
button:hover {
background-color: #4499d9;
transform: translateY(-5px);
box-shadow: 1px 3px 7px #6f6d72;
}
#toggleText {
display: block;
}
/* Center the avatar image inside this container */
.imgcontainer {
text-align: center;
margin: 24px 0 12px 0;
}
/* Avatar image */
img.avatar {
width: 30%;
border-radius: 20%;
box-shadow: 1px 3px 9px #6f6d72;
}
img.avatar:hover{
transform: translateY(-5px);
box-shadow: 7px 9px 9px #6f6d72;
}
/* Add padding to containers */
.container {
padding: 16px;
}
span.buttons{
width: 100%;
display: flow-root;
}
#toggleText{
float: left;
}
#toggle{
float: left;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>LOGIN PANEL</h1>
<!-- Login Form -->
<div class="form">
<form >
<div class="imgcontainer">
<img src="img/Login.jfif" alt="Login Avatar" class="avatar">
</div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" id="uname" name="uname"/>
<label for="password"><b>Password</b></label>
<input type='password'placeholder="Enter Your Password" name="password" id='password'/>
<input type='checkbox' id='toggle' onchange='togglePassword(this)'><span id='toggleText'>Show</span>
<span class="buttons">
<button type="submit" value="Reset" onclick="clearFunc()" class="btn">Reset</button>
<button type="submit" value="Login" class="btn" onClick="login()">Login</button>
</span>
</div>
</form>
</div>
</body>
</html>

Javascript if slider value = 20 , display text

I made a slider using html and CSS which displays its value on change. I styled it using CSS using the <style> tag. I then went on to making the value display text. I want to display "Starter" when the slider hits 20.
I don't know what I am doing wrong and why this isn't working for me. I would like to use the most user-friendly version of this. If possible, please explain what I did wrong.
<html>
<style>
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 25px;
border: 1px solid;
background-color: #0066FF;
}
input[type="range"]::-webkit-slider-thumb{
-webkit-appearance: none;
width: 25px;
height: 25px;
border: 1px solid;
background-color: #FFF;
}
</style>
</html>
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" step="20" value="0">
<div align="center" style="font-size:25px;"><output name="amount" for="rangeInput">0</output></div>
</form>
<script type="text/javascript">
var rangeInput = document.getElementById("rangeInput").value
if(rangeInput = 20){
text = "starter"
}
How can i get my slider to RESET on value 0?
at the moment, if i go from 20 to 0, it stays displaying Starter , i would like it to remove that. Is this possible?
you need '==' instead of '=' with your if statement
var rangeInput = document.getElementById("rangeInput").value
if(rangeInput == 20){
text = "starter"
}
See this question, as well: Range Slider Event Handler Javascript
You're going to want to look into event listeners-- you want to have a listener bound to the slider so that when the user changes the value, your code can respond accordingly.
You need to listen for onchange event. Also, you need to use == instead of = to compare values. The following code should work -
function updateValue() {
var rangeInput = document.getElementById("rangeInput").value
if (rangeInput == 20) {
document.getElementById("text").innerHTML = 'starter'
} else {
document.getElementById("text").innerHTML = ''
}
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 25px;
border: 1px solid;
background-color: #0066FF;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 25px;
height: 25px;
border: 1px solid;
background-color: #FFF;
}
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" step="20" value="0" onchange="updateValue()">
<div align="center" style="font-size:25px;">
<output name="amount" for="rangeInput">0</output>
</div>
</form>
<div id="text"></div>

Categories

Resources