I'm working on a webapp locally and I have a 'settings' page. The user can change the variables and the Javascript is supposed to save the values but it seems to reset them back to 1 straight after it changes them.
HTML:
<body onload="getSettings()">
<h1>Instance Load Manager - Settings</h1>
<div id="uploader">
<h2>Terraform file upload:</h2>
<input type="file" id="file" name="files[]" multiple onchange="moveFile()" />
</div>
<a href="index.html">
<div id="settingsButton">
<h3>Back</h3>
</div>
</a>
<div id ="settingsForm">
<form>
Maximum instances:<br>
<input type="text" id="maxInst" name="max instances"><br>
<br>
<input type="submit" value="Save Changes" onclick="updateSettings()">
</div>
</body>
Javascript:
var maxInstances = 1;
function updateSettings()
{
maxInstances = document.getElementById("maxInst").value;
alert(maxInstances);
}
function getSettings()
{
document.getElementById("maxInst").value = maxInstances;
}
Help appreciated :)
You need to prevent your page from refreshing after submitting the form.
function updateSettings(e)
{
e.preventDefault();
maxInstances = document.getElementById("maxInst").value;
alert(maxInstances);
}
Related
I am trying to show a loader in the google sheets sidebar on the button click either on the complete page or at least on the button so that users submitting the form should not press again until the earlier form is submitted. I have added loader through js/jquery. Although they work fine but they are too quick to be even shown to users. I can add some delays but again I don't know how much time will the script take to complete. Therefore it may be good to run it from the apps script/server-side.
Html page:
<form >
<div class="inputbox">
<label for="name"><strong>Client Business Name</strong></label>
<input type="text" placeholder="Client Business Name" name="name" required>
</div>
<div class="inputbox">
<label for="description"><strong>Client Description</strong></label>
<input type="text" placeholder="Client Description" name="description" required>
</div>
<div class="inputbox">
<label for="domain"><strong>Domain</strong></label>
<input type="url" placeholder="www.example.com" name="domain">
</div>
<div class="inputbox">
<label for="homepage"><strong>Home Page</strong></label>
<input type="url" placeholder="www.example.com/home" name="homepage" >
</div>
<div class="inputbox">
<label for="kpi"><strong>Link Goal Per month</strong></label>
<input type="url" placeholder="www.example.com/home/blog" name="kpi" >
</div>
<button id="btn" onclick="addvalues" >Add</button>
</form>
JS:
<script>
function addvalues() {
document.getElementById("btn").innerHTML = "Adding.."
document.getElementById("btn").setAttribute('disabled', 'disabled')
google.script.run.clientAdd()
}
</script>
Apps Script:
function clientAdd(form) {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Clients');
sheet.getRange(sheet.getLastRow() + 1, 2).setValue(form.name);
sheet.getRange(sheet.getLastRow(), 3).setValue(form.domain);
sheet.getRange(sheet.getLastRow(), 4).setValue(form.homepage);
sheet.getRange(sheet.getLastRow(), 5).setValue(form.description);
sheet.getRange(sheet.getLastRow(), 6).setValue(form.kpi);
}
Modification points:
addvalues of <button id="btn" onclick="addvalues" >Add</button> should be addvalues();
In your situation I thought that withSuccessHandler might be suitable.
When these points are reflected to your script, it becomes as follows.
Modified script:
HTML
From:
<button id="btn" onclick="addvalues" >Add</button>
To:
<button id="btn" onclick="addvalues();return false;" >Add</button>
Javascript
From:
function addvalues() {
document.getElementById("btn").innerHTML = "Adding.."
document.getElementById("btn").setAttribute('disabled', 'disabled')
google.script.run.clientAdd()
}
To:
function addvalues() {
const button = document.getElementById("btn");
button.innerHTML = "Adding..";
button.setAttribute('disabled', 'disabled');
google.script.run.withSuccessHandler(_ => {
// Please set the loading animation here.
// In this sample modification, when the button is clicked, the button is disabled, when Google Apps Script is finished, the button is enabled.
button.removeAttribute('disabled');
button.innerHTML = "Add";
}).clientAdd();
}
When the above modifications are reflected in your script, as a simple sample, when the button is clicked, the text of the button is changed from Add to Adding.. and the button is disabled, when Google Apps Script is finished, the button is enabled and the text of the button is changed from Adding.. to Add.
Please modify the script in withSuccessHandler to your loader.
Note:
I'm not sure about your whole script. So I proposed a simple modification from your showing script.
Reference:
withSuccessHandler(function)
I have a code, who helps me switch between forms, however, when I submit the form, the page will reset and display first(default) tab again. Could anyone help me understand how I can make it so the tab I submit the form from stays there if the submision fails or even if the submision was successfull?
Forms are switching using a little JS code and are submited from a PHP POST method form.
Please find the code below:
Javascript responsible for switching between tabs:
function onTabClick(event) {
let activeTabs = document.querySelectorAll('.active');
// deactivate existing active tab
for (let i = 0; i < activeTabs.length; i++) {
activeTabs[i].className = activeTabs[i].className.replace('active', '');
}
// activate new tab
event.target.parentElement.className += 'active';
document.getElementById(event.target.href.split('#')[1]).className += 'active';
}
const elements = document.getElementsByClassName('nav-tab-element');
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', onTabClick, false);
}
CSS:
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
And here is the HTML forms:
<body>
<header>
<h1 class="main-header">
Add a New Product
</h1>
</header>
<main>
<ul id="nav-tab" class="nav">
<li class="active">
<a class="nav-tab-element" href="#books">Books</a>
</li>
<li>
<a class="nav-tab-element" href="#dvds">DVD's</a>
</li>
<li>
<a class="nav-tab-element" href="#furniture">Furniture</a>
</li>
</ul>
<form method="POST">
<div class="tab-content active" id="books">
<div class="book-tab">
<input type="text" name="sku" placeholder="test form for books" autocomplete="off">
</div>
<div class="btn">
<input type="submit" value="Submit">
</div>
</div>
</form>
<form method="POST">
<div class="tab-content " id="dvds">
<div class="dvd-tab">
<input type="text" name="sku" placeholder="test form for DVD" autocomplete="off">
</div>
<div class="btn">
<input type="submit" value="Submit">
</div>
</div>
</form>
<form method="POST">
<div class="tab-content " id="furniture">
<div class="furniture-tab">
<input type="text" name="sku" placeholder="test form for furniture" autocomplete="off">
</div>
<div class="btn">
<input type="submit" value="Submit">
</div>
</div>
</form>
</main>
<script src="main.js"></script>
</body>
Clicking submit submits the form data to the page given in the action attribute in form. If you don't put this attribute in (as you have not done) the default is to submit to the current page.
To fix the issue you have, I would suggest that rather than using vanilla form submit, you do you submission via ajax. Making an ajax call is quite simple in jQuery, so I recommend you look into that.
There is an event that is triggered when you send a form. You can prevent your page to reload doing the following:
event.preventDefault()
you can find more about here: https://www.w3schools.com/jsref/event_preventdefault.asp
or here https://www.w3schools.com/jquery/event_preventdefault.asp
All you have to do is add event.preventDefault() to the first line of your onTabClick(event) function. After you preventDefault you can run whatever logic you want right there.
The way vanilla html/js interact is: On form submission, the page attempts to send the info to a server and then it refreshes to update with new information. The rise of SPAs has shifted the desired behavior, and you need to override the browser default behavior to stop the refresh.
Adding Ajax/Axios would work as most of those API libraries have built in functions to override the default, but it is not necessary.
I'm a newbie in coding and I need your expertise help.
This is my index.php codes
<div class="container">
<div class="row text-center"><h1>Stamford Network</h1></div>
<div class="row">
<div class="col-md-9">
<input type="textarea" name="text" placeholder="What's on your mind?" class="form-control" id="info" />
<input type="button" name="post" value="Post" class="btn btn-primary" id="post" />
</div>
<div class="col-md-3">
<h3>Hello,
<?php echo $_SESSION['username']; ?>
</h3>
<a class="btn btn-primary" href="login.php" role="button" >Logout</a>
</div>
</div>
<div class="row">
<div class="col-md-9">
<h4 id="display"></h4>
</div>
<div class="col-md-3"></div>
</div>
</div>
My .js code which link to the above index.php
window.onload = function() {
var button = document.getElementById("post");
button.addEventListener("click",
function() {
document.getElementById("display");
});
}
Can anyone tell me how create a post and display it without refreshing the page. Simply just click on the Post button then the information should appear below the posting form. While the words in the textarea should be gone when the button is clicked.
Please only show me the javascript way
var button = document.getElementById('post'),
info = document.getElementById('info'),
display = document.getElementById('display');
button.addEventListener('click', function(){
display.innerText = info.value;
info.value = '';
});
If you want the value to be uploaded to server for processing, you will need to add ajax XMLHttpRequest in the event listener.
Learn more about ajax here.
You should do it asynchronously.
First, use the tag to surround the data that you want to post:
<form>
...
</form>
Tutorial about forms:
https://www.w3schools.com/html/html_forms.asp
To post form asynchronously, you can use jquery or js. The simple and quick way is jquery. Here is a link to the documentation:
https://api.jquery.com/jquery.post/
There is an example at the end of the page of the jquery post doc's page, that explains how to use it, and basically do the thing that you wanted.
try this.
<script type="text/javascript">
window.onload = function() {
var button = document.getElementById("post");
button.addEventListener("click",
function() {
//document.getElementById("display");
document.getElementById('display').innerHTML = document.getElementById('info').value;
document.getElementById("info").style.display = "none";
});
}
</script>
We have a magento site that is using the WebForms2 plugin and ends up using something like the following generated code for a form:
HTML
<form action="http://example.com/magento/index.php/webforms/index/iframe" method="post" name="webform_2" id="webform_2" enctype="application/x-www-form-urlencoded" class="webforms-lg-test" target="webform_2_iframe">
<input type="hidden" name="submitWebform_2" value="1"/>
<input type="hidden" name="webform_id" value="2"/>
<div id="fieldset_0" class="fieldset fieldset-0 ">
<ul class="form-list">
<li class="fields ">
<div id="field_11" class="field type-text webforms-fields-11 webforms-fields-name">
<label id="label_field11" for="field11">Name</label>
<div class="input-box">
<input type='text' name='field[11]' id='field11' class='input text ' style='' value="" />
</div>
</div>
</li>
</ul>
</div>
<div class="buttons-set">
<p class="required">* Required Fields</p>
<button type="button" class="button" id="webform_2_submit_button" onclick="webform_2_submit()" title="submit">
<span>
<span>Submit</span>
</span>
</button>
<span class="please-wait" id="webform_2_sending_data" style="display:none;">
<img src="http://example.com/magento/skin/frontend/default/default/images/opc-ajax-loader.gif" alt="Sending..." title="Sending..." class="v-middle"/>
<span id="webform_2_progress_text">Sending...</span>
</span>
</div>
</form>
JS
var webform_2 = new VarienForm('webform_2', 0);
var webform_2_submit = function(){
var form = webform_2;
if(form.validator && form.validator.validate()){
form.submit();
$('webform_2_submit_button').hide();
$('webform_2_sending_data').show();
}
};
The tricky part is that we have an additional tool that works with all forms. Previously we just had it hook into the forms submit handler, but this particular method that Magento/WebForms uses, does not trigger the submit handler.
An example of our tool's code:
var forms = document.getElementsByTagName('form');
for(i=0; i<forms.length; i++) {
forms[i].addEventListener('submit', function() {
alert('form submitted');
}
}
We were also using a jQuery approach, but pared it down to reduce dependancies. It also did not work.
$('form').on('submit', function(e) {
alert('form submitted');
});
Question
Is there something specific in Magento that I could use with this implementation that I could hook into instead of a standard submit handler? Or a different/better way to observe a form's submit handler?
Using Prototype I was able to override the existing submit handler.
VarienForm.prototype.submit = VarienForm.prototype.submit.wrap(function($super, url) {
//-- your code can go before OR after the default form behavior
//-- include this if you want to include the previous submit behavior
$super(url);
return false;
});
I have an div element ("main") on my page who's contents changes back and forth between two different screens (their id's are "readout" and "num"), the contents of which are stored as hidden div elements (using display:none). Each screen has a button which sets mainto the other hidden div.
Since I struggled to get javascript to put num.innerHTML into main on load, I've ended up putting virtually identical content to num (with a different form name) into main:
<p>Number of Passengers per Carriage:</p>
<form method="post" action="javascript:void(0);" name="applesForm" onSubmit="setPassengers();">
<input type="text" name="numApples" id="numPassengers" />
<br/><br/>
<input type="submit" name="Submit" value="OK!"/>
</form>
setPassengers() successfully sets main's contents to readout. readout successfully sets main's contents to num (virtually identical to the original content of main). But then it won't go back to readout.
Here are setPassengers() and setPassengersAgain(), which is the same but for a different form name:
function setPassengers()
{
passengers=document.applesForm.numPassengers.value;
document.getElementById('main').innerHTML=readout.innerHTML;
}
function setPassengersAgain()
{
passengers=document.applesFormAgain.numPassengers.value;
document.getElementById('main').innerHTML=readout.innerHTML;
}
So my question is:
1)Why isn't num changing to readout?
2)Is there a way to load num straight away on page load so as to simplify the code?
EDIT: I can use onload, which means that num is the only bit that's broken...
EDIT 2: Here are the hidden div's:
<div id="readout" style="display:none">
<p>Throughput per hour:</p>
<p id="output">--</p>
<p>Average Dispatch Time:</p>
<p id="avDisTime">--</p>
<form method="post" action="javascript:void(0);" name="dispatchForm" onSubmit="dispatch();i++;">
<input type="submit" name="Submit" value="Press on Dispatch!"/>
</form>
<br/>
<form method="post" action="javascript:void(0);" name="resetTimesForm" onSubmit="resetTimes();">
<input type="submit" name="Submit" value="Reset Times"/>
</form>
<form method="post" action="javascript:void(0);" name="resetAllForm" onSubmit="resetAll();">
<input type="submit" name="Submit" value="Reset All"/>
</form>
</div>
<!--back to default page-->
<div id="num" style="display:none">
<p>Number of Passengers per Carriage:</p>
<form method="post" action="javascript:void(0);" name="applesFormAgain" onSubmit="setPassengersAgain();">
<input type="text" name="numApples" id="numPassengers" />
<br/><br/>
<input type="submit" name="Submit" value="OK!"/>
</form>
</div>
You didn't post your HTML code, so I don't know how it looks like, but you could use somethin like:
HTML:
<button id="changeMain">Change #main</button>
<div id="main">
<div id="readout" class="screen show">
Readout
</div>
<div id="num" class="screen">
Num
</div>
</div>
CSS:
#main>.screen{display:none;}
#main>.screen.show{display:block;}
JavaScript:
var els=[document.getElementById('readout'),document.getElementById('num')],current;
function addClass(el,c){
var arr=el.className.split(' ');
if(arr.indexOf(c)>-1){return;}
arr.push(c);
el.className=arr.join(' ');
}
function delClass(el,c){
var arr=el.className.split(' ');
var i=arr.indexOf(c);
if(i===-1){return;}
arr.splice(i,1);
el.className=arr.join(' ');
}
document.getElementById('changeMain').onclick=function(){
if(!current){
for(var i=0,l=els.length;i<l;i++){
if(els[i].className.indexOf('show')>-1){
current=i;
break;
}
}
}
delClass(els[current],'show');
current=(current+1)%els.length;
addClass(els[current],'show');
}
DEMO: http://jsfiddle.net/CUgqh/
Explanation:
If you want some content insode #main, you should place inside it (hidden or shown). Then, we hide all .screen with #main>.screen{display:none;} except .screen.show: #main>.screen.show{display:block;}.
Then, JavaScript code:
First we create an array with the elements:
var els=[document.getElementById('readout'),document.getElementById('num')],current;
And a function which adds/removes a class c to the element el:
function addClass(el,c){
var arr=el.className.split(' ');
if(arr.indexOf(c)>-1){return;}
arr.push(c);
el.className=arr.join(' ');
}
function delClass(el,c){
var arr=el.className.split(' ');
var i=arr.indexOf(c);
if(i===-1){return;}
arr.splice(i,1);
el.className=arr.join(' ');
}
And we create an event to the button:
document.getElementById('changeMain').onclick=function(){
if(!current){
for(var i=0,l=els.length;i<l;i++){
if(els[i].className.indexOf('show')>-1){
current=i;
break;
}
}
}
delClass(els[current],'show');
current=(current+1)%els.length;
addClass(els[current],'show');
}
The code above does:
If it's the first time the current els' index (current) is undefined, we search which element has the class show by default.
It removes the class show to the current shown element, so it disappears.
It adds 1 to current (or it becomes 0 if it was the last els' element
It add class show to the current element, so it appears.