At this stage I'm mostly used to backend Javascript and server side Java, so my HTML is not as savvy as it needs to be.
I've built several applications that require user input with Apps script, but I was using the now deprecated UI service, as I'm not a designer and this provided an easy way to design simple pages to pass data back and forth. With the UI service having been deprecated for some time, I'm begging the arduous task of migrating these services to the HTML service, and I'm noticing some difference in behavior.
For example, when submitting a form, the entire page refreshes to a blank page, and I can't seem to prevent that. The UI service would remain static for information re-entry, and I can't find a working method to get the HTML service to either stop refreshing or reload the form.
Simple code to reproduce my issue:
function doGet() {
return HtmlService.createHtmlOutputFromFile('test')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function logValues(value){
Logger.log('Something worked....');
}
With the index file being:
<form>
<input type="submit" value="Book Meeting" onclick="google.script.run
.logValues()">
</form>
Some things I've tried:
1) Adding a callback to the 'doGet' function, to attempt to get the page to load again.
2) Adding a whole new function to try and call a NEW HTML page.
The issue here is my poor understanding of the HTML service, but is there a simple way for me to just clear the form for re-submission, or alternatively just reload the page? None of the other questions I've found on SO adequately answer this question in a way I can understand.
Since you're technically submitting your form by clicking the submit button, then that creates the page refresh. You need to cancel the submit event with the preventDefault function, which "Cancels the event if it is cancelable, without stopping further propagation of the event."
See the docs here: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault
So maybe you can try something along these lines (straight from the docs):
function stopDefAction(evt) {
evt.preventDefault();
}
document.getElementById('my-checkbox').addEventListener('click', stopDefAction, false);
Another option is to remove the form/input elements and simply use a button element instead, which doesn't trigger a page refresh on click.
It's an interesting ride switching old UI services across, I just did that with one of my applications and it has really improved the readability of the code. I posted a copy of a basic version of what I was doing in another question
Once you get your head around it all it becomes a lot simpler. This is a really basic example of using multiple HTML files similar to your example using the HTMLService when submitting forms (you can pass in parameters instead)
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('Main')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
}
function onLogin(form) {
if (form.username == "fuzzyjulz") {
var template = HtmlService.createTemplateFromFile('Response');
//Setup any variables that should be used in the page
template.firstName = "Fuzzy";
template.username = form.username;
return template.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE)
.getContent();
} else {
throw "You could not be found in the database please try again.";
}
}
function include(filename) {
return HtmlService.createTemplateFromFile(filename)
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.getContent();
}
Main.html
<?!= include('CSS'); ?>
<script>
function loadPage(htmlOut) {
var div = document.getElementById('content');
div.innerHTML = htmlOut;
document.getElementById('errors').innerHTML = "";
}
function onFailure(error) {
var errors = document.getElementById('errors');
errors.innerHTML = error.message;
}
</script>
<div id="errors"></div>
<div id="content">
<?!= include('Login'); ?>
</div>
CSS.html
<style>
p b {
width: 100px;
display: inline-block;
}
</style>
Login.html
<script>
function onLoginFailure(error) {
var loginBtn = document.getElementById('loginBtn');
loginBtn.disabled = false;
loginBtn.value = 'Login';
onFailure(error);
}
</script>
<div class="loginPanel">
<form>
<p>
<b>Username: </b>
<input type="text" name="username"/>
</p>
<input type="button" id="loginBtn" value="Login" onclick="this.disabled = true; this.value = 'Loading...';google.script.run
.withSuccessHandler(loadPage)
.withFailureHandler(onLoginFailure)
.onLogin(this.parentNode)"/>
</form>
</div>
Response.html
<div class="text">
Hi <?= firstName ?>,<br/>
Thanks for logging in as <?= username ?>
</div>
Related
I've got a javascript for drawing a chart. I get my information out of my MySQL base. And I got 3 different buttons to get the different information out of the database.
My problem now is, I get the information out of my database, it shows it in the chart but when it shows the information it refreshes the page.
Is there a way to show the information after my page is refreshed? I actually tried to use the window.onload but that doesn't give me the wanted result.
in php I use the following code to get the info from my MySQL DB:
if(isset($_POST['btnProduct']))
{
....
}
in html it's like this:
<div class="content">
<form action="" method="post" enctype="multipart/form-data">
<input type="submit" name="btnProduct" id="btnFilterProduct">
</form>
</div>
And in JS I use this code:
<script type="text/javascript">
window.onload = function()
{
document.getElementById('btnFilterProduct').onclick = function()
{
....
}
}
I know the PHP needs to refresh to get the data. and Javascript doesn't. But can I change the order? Or is there a way to change my JS to let it load AFTER the page is refreshed?
To stop the page reload, modify your onclick function to be:
document.getElementById('btnFilterProduct').onclick = function(event) {
event.preventDefault();
...
}
event.preventDefault stops the default behavior of the event, which in this case is to refresh the page since you have an empty action. Another option would be to not use a form. Just use the <button> element instead.
Essetially, I am building a very rudimentary website builder that uses forms on a page to manipulate the HTML of the page,displayed below the input boxes, which eventually the user can get the source of to put onto their own website. I have not built it yet, but I was thinking that I would need more than one template in case anyone was trying to edit the same template at the same time, and having their edits overridden by others using the program. Here is a mockup for your leisure:
Html Displayed below input:
<h1 class="heading">Hi guys!</hi>
Form mockup:
<input id="headingEdit">
<script>
document.getElementById("heading").innerHTML = document.getElementById("headingEdit").value;
</script>
My problem is one that may or may not be relevant, and that is that should someone want to edit this template, when someone else is also editing it, then surely the html would keep on getting overridden by each other, and no-one would get anywhere. What I therefore want to do is be able to, when a user clicks on the 'Edit this Template' button on the homepage, they are taken to a randomly generated page, which is an exact duplicate of a master page, make their edits, and then that page is deleted, or (when I add integration) stored in a users account.
This might be a duplicate question, but the answer has not come up in my research so far.
Thanks in advance.
you can use AngularJS
http://www.w3schools.com/angular/default.asp
<!DOCTYPE html>
<html>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>
<div ng-app="">
<p>Input something in the input box:</p>
<p>Name : <input type="text" ng-model="name" placeholder="Enter name here"></p>
<h1>Hello {{name}}</h1>
</div>
</body>
</html>
Here's a short PHP solution
$pageid = uniqid();
copy('template.html', $pageid . '.html');
print "Editable page is at: " .$pageid . ".html";
Add this somewhere in the template.html:
<?php
if (str_replace(' ', '', preg_replace('/\.html/', '', basename($_SERVER['PHP_SELF']))) !== 'template') {
print "<script>
var elems = document.getElementsByTagName('*'),
i;
for (i = 0; i < elems.length; i += 1) {
elems[i].setAttribute('contentEditable', 'true');
}
window.onbeforeunload = function(){
var a = new XMLHttpRequest() || new ActiveXObject('Microsoft.XMLHTTP');
a.onreadystatechange = function (b) {
if(a.readyState==4&&a.status==200){
}
}
xmlhttp.open('POST','remove_template.php',true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.send('id=" . str_replace(' ', '', preg_replace('/\.html/', '', basename($_SERVER['PHP_SELF']))) . "');
}
//Custom JavaScript goes here
</script>";
}
?>
Then remove_template.php is:
if ($_POST['id'] != 'template' && ctype_alnum($_POST['id'])) {
unset($_POST['id']);
}
You should obviously change what urls to your needs, also remove_template.php is kinda insecure. I haven't tested this yet. If you ever add a user system. Made the $pageid link to their user account. Then just pass an if to not add the window.onbreforeunload
If you can't support PHP you can use an icky JavaScript solution
window.editPage () { document.body.contentEditable='true'; document.designMode='on'; }
window.savePage () { localStorage.setItem('savedPage', document.body.innerHTML); }
window.getPage () { document.body.innerHTML = localStorage.getItem('savedPage'); }
Then you can add the function to the onclick attribute
<div onclick="window.editPage()">Edit Page</div>
I've found something called Surreal CMS (Content Management System) which might be what you want. Or maybe something like create.js
I'm developing a project of "prettifying" of a part of an existing web application. There is a need of putting the existing code: search criteria form in one div, and search results in another div (forming a kind of tabs, but that's another story).
Using jQuery I was able to manage that, but right now I am struggling with the results page, which by itself is yet another form that auto-submits to another file (using document.form.submit()), which is the final search results view. This auto-submit causes that the final view quits the destination div and loads as a new page (not new window).
So, the flow is like that:
First file, let's call it "criteria.html" loads the search criteria form (inside of a div) + another div (empty) destined to be filled with search results.:
<div id="criteria">... form with search criteria here...</div>
<div id="results"></div>
On submit, using jQuery's "hide()" method, I hide the first div (surrounding the search criteria form), and make Ajax call to the second file, let's call it "results.php":
<script>
$("#criteria").hide();
$.ajax({
...,
url: "results.php",
success: function(data){
$("#results").html(data);
},
...
});
</script>
results.php searches according to given criteria, and displays an "intermediary form" (which returns as a data result of the ajax query above) with a lot of hidden fields, and at the end executes:
<script>document.form.submit();</script>
which submits to another file, let's call it "resultsView.php"
This line causes that a result page shows outside the div "results", as a new page.
As there is a lot of logic in those files (more than 700 lines each), the idea of rewriting this monster just gives me creeps.
And now the question: is this a normal behavior (opening the result outside div)?
I tried removing the document.form.submit() code and everything works fine (well, without showing the results from "resultsView.php"). It's this line that causes the viewport to reset. I also tried with empty pages (to eliminate the possibility of the interaction with contents of the pages) - still the same result.
I hope there is not too much text and the problem is clearly stated. Every suggestion of how to fix this will be greatly appreciated.
If I understand your question correctly, you need to process the final submit using ajax instead of <script>document.form.submit();</script> so that you can handle the results on-page. Traditional form submits will always reload/open the action page. If you want to avoid that you'll have to control the form submit response via ajax and handle the results accordingly... like you are doing with the first submit.
The only alternative I can think of is to make div id="results" an iframe instead, so that it contains the subsequent form submit. Of course, that unleashes further restrictions that may cause other troubles.
I am not sure if I understood your question, but maybe u can do something like this.
This is my JQuery script: [I just wait for the submission search. When it happens, I use the $.Post method to call a function that should return the Html results (You can include somenthing to hide any field you want using JQuery or css)].
<script type="text/javascript" src="http://code.jquery.com/jquery-1.3.2.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("form#searchForm").submit(function() {
var theCity = $("select#chooseCity").val();
var theName = $("input#searchInput").val();
$.post("callProvideSearchResults.php", {theCity: theCity, theName: theName}, function(data) {
$("div#searchResults").html(data);
});
return false
});
});
</script>
This is my Body: {it consists of the choice of a city, the a form to provide the name of the person you are lookng for and the place to provide the results.
<body>
<FORM id="searchForm">
<h2>Select the city: </h2>
<select id="chooseCity">
<?php
$theCitiesOptionsHTML = "cityOptions.html";
require($thePathDataFiles.$theCitiesOptionsHTML); / A large list of cities
?>
</select>
<h2> What is the name of the person </h2>
<P> <INPUT id="searchInput" TYPE="TEXT" SIZE=50></P>
<P><INPUT TYPE="submit" VALUE="search"></P>
</FORM>
<div id="searchResults">
<!-- Here: Search results -->
</div>
</body>
// Function callProvideSearchResults.php // Just call the function that makes all the job and echo the $Html page
<?php
include "provideSearchResults.php";
$theName=$_POST['theName'];
$theCity=$_POST['theCity'];
echo provideSearchResults($theName, $theCity);
?>
// provideSearchResults.php // Database connection and search
<?php
function provideSearchResults($theName, $theCity) {
include "databaseConnection.php";
//database Queries
// Generate $theHtml using strings or ob_start, for instance
return $theHtml;
}
?>
I am facing a problem in using the contact form 7 in wordpress, and need some help to all of you.
Problem:
I have radio box which have two options yes or no. if someone check the yes option then div one shoud be shown and if he clicks at no then 2nd div should be shown.
I write a code but how it will be us in contact form 7, i don't know.
here is the code.
$(document).ready(function() {
//Hide the field initially
$("#div one").hide();
$("#div two").hide();
$('[radio radio-928]').change(function()
{
if ($("[radio radio-928]").val() == "yes")
{
$("#div one").show();
}
else {
$("#div two").hide();
}
if ($("[radio radio-928]").val() == "no") {
$("#div two").show();
}
else {
$("#div one").hide();
}
});
});
This can be done in the Contact Form 7 editor box like this:
<script type="text/javascript">
function showdiv(element){
document.getElementById("div-one").style.display = element=="yes"?"block":"none";
document.getElementById("div-two").style.display = element=="no"?"block":"none";
}
</script>
<input type="radio" name="choice" value="yes" onclick="showdiv(this.value);"> Yes<br>
<input type="radio" name="choice" value="no" onclick="showdiv(this.value);"> No<br>
<div id="div-one" style="display:none;">Yes</div>
<div id="div-two" style="display:none;">No</div>
If your function works in JS console but not when saved in form, ensure it does not have blank lines.
For some reason these are turned into p tags, the editor is not really HTML aware at least on the sites I have used it on.
E.g. Capitalize first character of specific input boxes by a class.
<script language="javascript" type="text/javascript">
jQuery(function($){
// Capitalize first character as needed.
$.fn.capitalize = function() {
$(this).blur(function(event) {
var box = event.target;
var txt = $(this).val();
var stringStart = box.selectionStart;
var stringEnd = box.selectionEnd;
$(this).val(txt.replace(/^(.)/g, function($char) {
return $char.toUpperCase();
}));
box.setSelectionRange(stringStart, stringEnd);
});
return this;
}
$('input[type=text].capitalize').capitalize();
});
</script>
Once I remove the new line it works facepalm...
simply add you JavaScript function to your page then find the Additional Settings field at the bottom of the contact form management page and use the on_submit JavaScript action hook like so:
on_submit: "MY_JavaScript_function_Name();"
Add to your Wordpress the plugin: Insert Headers and Footers by WPBeginners
Activate the plugin and go to Settings - > Insert Headers and Footers
Add your javascript code inside script tags. When your page loads, this script will be in the head of your DOM
On Contact Form 7, add your buttons using HTML code adding the respective ID attributes mentioned on your code to control your document.
I do this all the time, specially to use jQuery.
You can copy the generated HTML of contact forms and add the javascript code. For example you have a submit form as:
[submit class:btn class:btn-lg class:btn-black "Enviar"]
If you look to the HTML code (Inspector or View Page HTML) you will have this code:
<input type="submit" value="Enviar" class="wpcf7-form-control btn-lg btn-black" disabled="">
Paste the code and add the javascript you need inside, for example:
<input type="submit" onclick="gtag('event','EnvioFormularioHome'); ga('send', 'event', { eventCategory: 'Formulario', eventAction: 'Enviado', eventLabel: 'Hernani'}) value="Enviar" class="wpcf7-form-control btn btn-lg btn-black" disabled="">
I know this is an old post but I wanted to share my discoveries in case anyone needs it later.
The OP problem is definetely the blank lines in the code, the form editor adds P elements to each new line. If you open the js console you will see the errors that points out to the code.
Also something we should pay attention, and that took me a lot of time to figure out, it that the editor removes backslashes.
I was adding some input masks validation and found this code:
v = v.replace(/\D/g, "");
becoming this after saving:
v = v.replace(/D/g, "");
So, a workaround is to declare like this:
v = v.replace(/\\D/g, "");
However, each time it is saved the backslashes would be removed, so I needed to keep its source code saved somewhere else then paste it to the editor each time.
In the end I've just added a custom html widget with all the custom js inside a script tag.
It will make the code work globally in the website but it was my way to ensure that users will not mess up the form masks and validation code.
I am using ASP.NET MVC 3 with the Yahoo API version 3. I am trying to get my YUI3 button to redirect to another page when I click on it, this button is my cancel button. The cancel button is a plain button type, but it is being treated like a submit button. It is not redirecting to the correct page, but acting like a submit button and it kicks off my page validation like what the submit button would do.
I thought that it might be with my HTML but I did validate it. It validated 100% correct. So I then stripped down the whole page to a bare minimum but the cancel button is still working like a submit button. Here is my HTML markup:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Create2</title>
</head>
<body class="yui3-skin-sam">
<h1>Test submit</h1>
#using (Html.BeginForm())
{
<button id="SaveButton" type="submit">Save</button>
<button id="CancelButton" type="button">Cancel</button>
}
<script src="http://yui.yahooapis.com/3.6.0pr4/build/yui/yui-min.js"></script>
<script>
YUI().use('button', function (Y) {
var saveButton = new Y.Button({
srcNode: '#SaveButton'
}).render();
var cancelButton = new Y.Button({
srcNode: '#CancelButton',
on: {
'click': function (e) {
Y.config.win.location = '/Administration/Department/List';
}
}
}).render();
});
</script>
</body>
</html>
I'm not sure what I am doing wrong here? Is this maybe a bug in their API? I am testing on IE8 and on the latest version of FireFox.
UPDATE:
I forgot to mention that if these buttons are not between form tags then the redirect works fine. If I put them in form tags then the redirect does not work.
I would use a link because you are redirecting to another page. Doing it this way you wouldn't need to initialize it with javascript or register the onClick listener.
<button id="SaveButton" type="submit">Save</button>
<a id="CancelButton" href='/Administration/Department/List'>Cancel</a>
Look at this link to style your link: http://yuilibrary.com/yui/docs/button/cssbutton.html
The Y.Button widget is removing the type attribute from the Cancel button. This makes that button behave like a submit button.
There are many possible paths to make this work. I'll start from simple to complex. The first is to avoid the issue entirely and not use JavaScript at all. Just use a link:
<form action="/Administration/Department/Create2" method="post">
<button class="yui3-button">Save</button>
<a class="yui3-button" href="/Administration/Department/List">Cancel</a>
</form>
After all, all that the Button widget is doing is adding a couple of css classes to each tag and a lot of other stuff that makes more complex widgets possible. As you can see in the Styling elements with cssbutton example, even <a> tags can look like nice buttons using just the YUI css styles. If you don't have to use JavaScript, better not to use it.
A second option is to avoid the Y.Button widget and use the Y.Plugin.Button plugin. It's more lightweight in both kb and processing power. And it doesn't touch the tag attributes, so your location code will work.
YUI().use('button-plugin', function (Y) {
Y.all('button').plug(Y.Plugin.Button);
Y.one('#CancelButton').on('click', function () {
Y.config.win.location = '/Administration/Department/List';
});
});
And finally you can hack around the behavior of the Y.Button widget by preventing the default action of the button:
var cancelButton = new Y.Button({
srcNode: '#CancelButton',
on: {
'click': function (e) {
e.preventDefault();
Y.config.win.location = '/Administration/Department/List';
}
}
}).render();