Hey guys i was wondering how to acquire information from form in javascript and i found the method with object forms, but i doesnt want to work(returns undefined), because object is undefined. Do you know what i am doing wrong in that, could you attach some explanations? I know what it is possible to do it by getElement function,but i would like to understand why this solution doesn't work.
Regards!
<script type="text/javascript">
function cos(sth){
var par = document.getElementById("para1");
par.style.color = 'blue';
par.style.fontSize="30px";
par.style.fontFamily="Impact,Charcoal,sans-serif";
}
function getFormValue(){
document.write(5+6);
var doc = document.forms["myForm"]["email"].value;
// OR
var doc = document.forms[0].elements["name"];
document.write(doc);
}
</script>
</head>
<body>
<p id ="para1">JavaScript Exercises - w3resource</p>
<div>
<button onclick="cos();">Style</button>
</div>
<form name="myForm">
<input type="text" name="email"/>
<button onclick="getFormValue()">
</form>
</body>
</html>
document.write(5+6);
var doc = document.forms["myForm"]["email"].value;
Since the page has loaded, the document is in a closed state.
Calling document.write implicitly calls document.open which creates a new document.
You then write 11 to this document.
Next you try to get the form element. It doesn't exist in this new document.
Then you try to get the email field from it. Since you don't have a form, you get an error.
If you fix that:
var doc = document.forms["myForm"]["email"].value;
// OR
var doc = document.forms[0].elements["name"];
document.write(doc);
You read the value of the email field and assign it to doc.
Then you overwrite it with elements["name"].
There is no form control called name, so you get undefined.
var doc = document.forms["myForm"]["email"].value;
document.write(doc);
… works fine. You just need to remove the junk you put around it to break it.
I'm working on a project where the front end is powered by React. I'm not even sure if this is relevant (maybe the problem lies in another obvious place), but since I've been able to make everything work without React so far, it would be fair to guess that it's my relationship with React that is resulting in this error.
In my React template (?) I added this most simple piece of code, that is rendered inside a form:
if (this.state.indexColumns['0'].show === true) {
cols.splice(xKey + idxMod, 0, (
<DataTableStaticCell key={'index-' + k}>
{content}
</DataTableStaticCell>
<input type="hidden" name="order_id" value={indexId} />
));
} else {
cols.splice(xKey + idxMod + 1, 0, (
<input type="hidden" name="order_id" value={indexId} />
));
}
When I check using developer tools in browsers, everything is rendered correctly and the field is there, it has the correct value, is located inside a form like it's supposed to be.
Rendered:
<input type="hidden" name="order_id" value="1" data-reactid=".0.2.0.0.1.0.0.$2.2.0.$2.$0.$0.$0.$rows.0.0.2.0.0.1.$0.1">
Now, whenever I post my form, no data is submitted from this field at all. I use Chrome developer tools to catch the form send request (any better methods?) and it does not appear there.
I've tried everything I could think of so far: visible field, not-prefixed-value field, different types of input, different names and such... Some stupid idiotic mistake is ruining my life at the moment, been stuck with this for two days now. I can't even believe that myself.
Appreciate your help :)
EDIT: Form handling:
getFormData: function (validate) {
var invalid = false;
if (validate) {
invalid |= !this.state.form.validate();
if (invalid) {
logger.warn(this.state.form.errors().asData());
}
}
var formData = _.extend({}, this.state.form.cleanedData);
var dataTableKeys = this.findLayoutKeysByType('data_table');
dataTableKeys.forEach(function (tableKey) {
var ref = this.refs['dataTable' + tableKey];
}.bind(this));
return [!invalid, formData];
},
EDIT 2: I should add that <DataTableStaticCell> was already in place before I started working on the project and also contains an <input> field, which is rendered like this for example:
<input type="text" value="" data-reactid=".0.2.0.0.1.0.0.$2.2.0.$2.$0.$0.$0.$rows.0.0.2.0.0.1.$0.$0.1.0">
That is the main reason I started with this approach. Are there any fundamental differences between my data flow and with the example presented later?
I am trying to replicate a question posed by Pieter Jaspers regarding a conversion of a form from UIApp to HTML. The original question is:
Original question by Pieter Jaspars answered by Sandy Good
If I replicate the code exactly I get the correct result, but when I try to recreate my inline form and amalgamate the two I am not getting a result. The inline form question is here:
HTML inline form formatting question answered by Mogsdad
The code I have so far is in the requisite number of parts, a form and two .gs sheets. I have checked for spelling mistakes and I have tried editing out each line to see what and where I get, but with my limited experience I am drawing a blank. The only minor success is if I run the function InsertInSS() from within the code editor. This posts the word "undefined" in the correct cell in the correct spreadsheet, but not the date as I am trying to do!
Form:
<!-- Use a templated HTML printing scriptlet to import common stylesheet. -->
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<html>
<body>
<div>
<!-- Page header title & 'completion warning -->
<span class="grey"><b>ProReactive Log Form v3.0.74</b></span>
<h4>Complete ALL fields to ensure the form is processed successfully</h4>
<div class="block">
<!-- First input box created -->
<div class="inline form-group">
<label form="date">Date</label>
<input type="date" id="date" style="width: 125px;">
</div>
</div>
</div>
<!-- End of fields for completion, finish form with submission button -->
<button class="share" onclick="runGoogleScript()">submit</button>
</body>
</html>
<script>
function onSuccess(argReturnValue){
alert('was successful ' +argReturnValue);
//ResetFields on Screen
Document.getElementById("date").value = "";
}
function runGoogleScript() {
logger.log('v3.0.74 ran!');
var inputValue = document.getElementById("date").value;
google.script.run.withSuccessHandler(onSuccess)
.InsertInSS(inputValue);
};
</script>
The Code.gs:
function doGet(e) {
return HtmlService.createTemplateFromFile('myForm')
.evaluate()
.setTitle('ProReactiveLog')
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
};
and the seperate.gs:
function InsertInSS(argPassedInName) {
var ssKey = '1cZuEMDrIyzIFm4lGCT20s-Wpv27o0hbbZAsxD1WJFL8';
var SS = SpreadsheetApp.openById(ssKey);
var Sheet = SS.getSheetByName('LOG');
Sheet.getRange(Sheet.getLastRow()+1,1,1).setValue(argPassedInName);
}
Any ideas where I am going wrong? All help as ever, greatly appreciated.
An Apps script HTML App, will not allow a date object to be passed to the server.
google.script.run Parameter Documentation
The documentation states:
Requests fail if you attempt to pass a Date, Function, DOM element besides a form, or other prohibited type, including prohibited types inside objects or arrays.
You will need to pass the date as a string. Convert the date to a string in client side code, and convert it back to a date, if need be, in the server code. However, even if you set the value in the spreadsheet as a string, it may get coerced back into a date without you needing to do anything. Especially if you have that column defined as a date in the spreadsheet.
I have several <input> fields within a <form>. Angular takes the value from those fields regardless of the <form> (which is actually there only for Bootstrap to apply the right styles to inner fields).
Now, I want to be able to reset the fields, and so get Angular update the output associated to them as well. However, a regular <input type="reset"/> button is not working. It resets the values of all the <input> fields, but Angular is not refreshing the output that is based on the fields after it.
Is there any way to tell Angular to refresh the outputs based on the current state of the fields? Something like a ng-click="refresh()"?
Let's say you have your model called address. You have this HTML form.
<input [...] ng-model="address.name" />
<input [...] ng-model="address.street" />
<input [...] ng-model="address.postalCode" />
<input [...] ng-model="address.town" />
<input [...] ng-model="address.country" />
And you have this in your angular controller.
$scope.reset = function() {
$scope.defaultAddress = {};
$scope.resetAddress = function() {
$scope.address = angular.copy($scope.defaultAddress);
}
};
JSFiddle available here.
You should have your values tied to a model.
<input ng-model="myvalue">
Output: {{myvalue}}
$scope.refresh = function(){
delete $scope.myvalue;
}
JSFiddle: http://jsfiddle.net/V2LAv/
Also check out an example usage of $pristine here:
http://plnkr.co/edit/815Bml?p=preview
Consider this form:
<form action="http://www.blabla.com?a=1&b=2" method="GET">
<input type="hidden" name="c" value="3" />
</form>
When submitting this GET form, the parameters a and b are disappearing.
Is there a reason for that?
Is there a way of avoiding this behaviour?
Isn't that what hidden parameters are for to start with...?
<form action="http://www.example.com" method="GET">
<input type="hidden" name="a" value="1" />
<input type="hidden" name="b" value="2" />
<input type="hidden" name="c" value="3" />
<input type="submit" />
</form>
I wouldn't count on any browser retaining any existing query string in the action URL.
As the specifications (RFC1866, page 46; HTML 4.x section 17.13.3) state:
If the method is "get" and the action is an HTTP URI, the user agent takes the value of action, appends a `?' to it, then appends the form data set, encoded using the "application/x-www-form-urlencoded" content type.
Maybe one could percent-encode the action-URL to embed the question mark and the parameters, and then cross one's fingers to hope all browsers would leave that URL as it (and validate that the server understands it too). But I'd never rely on that.
By the way: it's not different for non-hidden form fields. For POST the action URL could hold a query string though.
In HTML5, this is per-spec behaviour.
See Association of controls and forms - Form submission algorithm.
Look at "4.10.22.3 Form submission algorithm", step 17. In the case of a GET form to an http/s URI with a query string:
Let destination be a new URL that is equal to the action except that
its <query> component is replaced by query (adding a U+003F QUESTION
MARK character (?) if appropriate).
So, your browser will trash the existing "?..." part of your URI and replace it with a new one based on your form.
In HTML 4.01, the spec produces invalid URIs - most browsers didn't actually do this though...
See Forms - Processing form data, step four - the URI will have a ? appended, even if it already contains one.
What you can do is using a simple foreach on the table containing the GET information. For example in PHP :
foreach ($_GET as $key => $value) {
$key = htmlspecialchars($key);
$value = htmlspecialchars($value);
echo "<input type='hidden' name='$key' value='$value'/>";
}
As the GET values are coming from the user, we should escape them before printing on screen.
You should include the two items (a and b) as hidden input elements as well as C.
I had a very similar problem where for the form action, I had something like:
<form action="http://www.example.com/?q=content/something" method="GET">
<input type="submit" value="Go away..." />
</form>
The button would get the user to the site, but the query info disappeared so the user landed on the home page rather than the desired content page. The solution in my case was to find out how to code the URL without the query that would get the user to the desired page. In this case my target was a Drupal site, so as it turned out /content/something also worked. I also could have used a node number (i.e. /node/123).
If you need workaround, as this form can be placed in 3rd party systems, you can use Apache mod_rewrite like this:
RewriteRule ^dummy.link$ index.php?a=1&b=2 [QSA,L]
then your new form will look like this:
<form ... action="http:/www.blabla.com/dummy.link" method="GET">
<input type="hidden" name="c" value="3" />
</form>
and Apache will append 3rd parameter to query
When the original query has array, for php:
foreach (explode("\n", http_build_query($query, '', "\n")) as $keyValue) {
[$key, $value] = explode('=', $keyValue, 2);
$key = htmlspecialchars(urldecode($key), ENT_COMPAT | ENT_HTML5);
$value = htmlspecialchars(urldecode($value), ENT_COMPAT | ENT_HTML5);
echo '<input type="hidden" name="' . $key . '" value="' . $value . '"' . "/>\n";
}
To answer your first question yes the browser does that and the reason is
that the browser does not care about existing parameters in the action URL
so it removes them completely
and to prevent this from happening use this JavaScript function that I wrote
using jQuery in:
function addQueryStringAsHidden(form){
if (form.attr("action") === undefined){
throw "form does not have action attribute"
}
let url = form.attr("action");
if (url.includes("?") === false) return false;
let index = url.indexOf("?");
let action = url.slice(0, index)
let params = url.slice(index);
url = new URLSearchParams(params);
for (param of url.keys()){
let paramValue = url.get(param);
let attrObject = {"type":"hidden", "name":param, "value":paramValue};
let hidden = $("<input>").attr(attrObject);
form.append(hidden);
}
form.attr("action", action)
}
My observation
when method is GET and form is submitted, hidden input element was sent as query parmater. Old params in action url were wiped out. So basically in this case, form data is replacing query string in action url
When method is POST, and form is submitted, Query parameters in action url were intact (req.query) and input element data was sent as form data (req.body)
So short story long, if you want to pass query params as well as form data, use method attribute as "POST"
This is in response to the above post by Efx:
If the URL already contains the var you want to change, then it is added yet again as a hidden field.
Here is a modification of that code as to prevent duplicating vars in the URL:
foreach ($_GET as $key => $value) {
if ($key != "my_key") {
echo("<input type='hidden' name='$key' value='$value'/>");
}
}
Your construction is illegal. You cannot include parameters in the action value of a form. What happens if you try this is going to depend on quirks of the browser. I wouldn't be surprised if it worked with one browser and not another. Even if it appeared to work, I would not rely on it, because the next version of the browser might change the behavior.
"But lets say I have parameters in query string and in hidden inputs, what can I do?" What you can do is fix the error. Not to be snide, but this is a little like asking, "But lets say my URL uses percent signs instead of slashes, what can I do?" The only possible answer is, you can fix the URL.
I usually write something like this:
foreach($_GET as $key=>$content){
echo "<input type='hidden' name='$key' value='$content'/>";
}
This is working, but don't forget to sanitize your inputs against XSS attacks!
<form ... action="http:/www.blabla.com?a=1&b=2" method ="POST">
<input type="hidden" name="c" value="3" />
</form>
change the request method to' POST' instead of 'GET'.