Form fields gets cleared on POST data with knockout binding - javascript

I'm working with PHP on backend with Slim microframework, in case it be relevant.
Well, the problem is that the form gets cleared after submit. The server return an error code, in case of error, ofcourse, and the error message is showed to the user, but the fields are clean.
I must mention that I'm using the jquery-validation plugin.
HTML
<form action="{{ path_for('save_data') }}" method="POST" id="myForm" name="myForm" data-bind="submit: sendForm">
<input type="text" name="foo" data-bind="value: foo" required>
<button type="submit">Save data</button>
</form>
Javascript/Knockout JS
function MyView($) {
var self = this;
self.foo = ko.observable();
/* ... code ... */
self.sendForm = function(theForm) {
if (!$(theForm).valid()) {
return;
}
$.post(theForm.action, ko.toJS(self.foo), function(response) {
alert(response);
})
.fail(function(failResponse) {
alert(failResponse);
});
};
}
ko.applyBindigs(new MyView(jQuery));
Just for better understanding, the server code is something like this:
public function postSaveData($request, $response) {
if (TRUE) { // Some validations here
return $response->withJson("Error message", 400);
}
// save
return $response->withJson("OK", 200);
}
UPDATE
After some tests, occurs to me to test with pure javascript code, with no jQuery. Like as follows:
self.sendForm = function(theForm) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log("Response text: ", xhttp.responseText);
}
else if (this.status == 400) {
console.log("Response text: ", xhttp.responseText);
}
};
xhttp.open("POST", formElement.action, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(ko.toJS(self.imovel));
};
And voilá! Form perfect filled, as before send data. Somehow jQuery post is clearing the form.

Related

Response text from AJAX is blank

I am trying to do an AJAX call and I'm getting a successful (200) response but the response text is blank.
I've looked at several other SO answered to this question but none of them seemed to work.
<form id="status-code-form" v-on:submit="processStatusForm">
<input type="text" id="status-code-url" v-model="ajInput" />
<input type="submit" value="Submit">
</form>
<script type="text/javascript">
var appForm = new Vue({
el: '#status-code-form',
// our data
data: {
ajInput: ''
},
// our methods
methods: {
processStatusForm: function(e) {
e.preventDefault();
// start ajax
if (this.ajInput !== "") {
var newInputtedText = this.ajInput;
xhr = new XMLHttpRequest();
xhr.open('POST', './processes/check-url-code.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
if (xhr.status === 200 && xhr.readyState === 4) {
console.log("Response text was successfull" + xhr.responseText);
}
else if (xhr.status !== 200) {
alert('Request failed. Returned status of ' + xhr.status);
}
};
var data = {action: 'content_fetch', inputtedText: newInputtedText };
xhr.send('action=content_fetch&inputtedText=' + newInputtedText);
} // end if input was empty
} // end process form
} // end methods
});
</script>
In my PHP file, it's very simple:
<?php
function content_fetch() {
echo "hello";
}
I would think that the response text is equal to "hello", but it's blank. I just get the console log of "Response text was successfull".

Html code in body executes after script runs

I'm new in Javascript and i'm trying to make an http request to fetch some data and display the results in html. I'm fetching the results and update the html code, but then the html code inside body reloads and shows the default values. My code is,
<head>
<script>
function httpGetAsync() {
var results = new Array(3);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.addEventListener("readystatechange", processRequest, false);
xhr.onreadystatechange = processRequest;
function processRequest() {
if (xhr.readyState == 4 && xhr.status == 200) {
// populate here results array
// i change the value with the following line
document.getElementById("title_1").innerText = "fetched_value";
}
}
}
</script>
</head>
<body>
<div class="search_btn">
<form id="search_form" method="get" onSubmit="return httpGetAsync()">
<input type="text" class="search" placeholder="Search" id="search">
<input type="submit" value="search" class="search_button">
</form>
</div>
<div id="one">
<p id="title_1">default</p>
</div>
</body>
The 'title_1' changes its text to 'fetched_value' but it then reloads and becomes 'default' again. What am i doing wrong?
It's because your onSubmit does not receive false. Simply add return false to httpGetAsync end
function httpGetAsync() {
var results = new Array(3);
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.send();
xhr.addEventListener(
"readystatechange",
function processRequest() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById("title_1").innerText = "fetched_value";
}
},
false);
xhr.onreadystatechange = processRequest;
return false;
}
You need to prevent the default action on submit, which is to use the "action" attribute on the form element to reload the page (if it's not present the current page is reloaded).
function httpGetAsync(event) {
event.preventDefault();
...
}

$_POST not returning a value

I've been searching for an answer to this for several days now, but if I missed the answer in another post, let me know.
I'm trying to get into Ajax, so I have a very simple form in my index.php, with separate php and javascript files:
index.php
<div id="ajax-test">
<form action="ajax/ajax.php" method="POST">
<textarea name="someText" id="some-text" placeholder="Type something here"></textarea>
<button type="button" onclick="loadDoc()">Submit</button>
</form>
<div id="ajax-text"></div>
</div>
main.js:
function getXMLHttpRequestObject() {
var temp = null;
if(window.XMLHttpRequest)
temp = new XMLHttpRequest();
else if(window.ActiveXObject) // used for older versions of IE
temp = new ActiveXObject('MSXML2.XMLHTTP.3.0');
return temp;
}// end getXMLHttpRequestObject()
function loadDoc() {
var ajax = getXMLHttpRequestObject();
ajax.onreadystatechange = function() {
if(ajax.readyState == 4 && ajax.status == 200) {
document.getElementById('ajax-text').innerHTML = ajax.responseText;
console.log(ajax.responseText);
}
};
ajax.open("POST", "ajax/ajax.php", true);
ajax.send();
}
ajax.php:
<?php
print_r('\'' . $_POST['someText'] . '\' is what you wrote');
?>
Whenever I try to print, it prints: " '' is what you wrote " - what am I missing/not doing/doing incorrectly that isn't allowing me to access the content of someText? I've changed my naming convention, swapped from single quote to double quote, tried GET instead of POST, but nothing worked.
You can try to set a header request and also put the data inside the send. Here an example as like as-
ajax.open("POST", "ajax/ajax.php", true);
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajax.send("someText="+document.getElementById('some-text').value);
This is probably beacuse of the error
Undefined index: someText in C:\xampp\htdocs\ssms\sandbox\ajax\ajax.php on line 3
You had a couple of issues with your code which i don't have time to list out now. This should work fine, plus i used the onkeyup() function to display the text live without even clicking on the submit button.
The Index File
<div id="ajax-test">
<form method="POST" onsubmit="return false;">
<textarea onkeyup="loadDoc()" name="someText" id="someText" placeholder="Type something here"></textarea>
<button type="button" onclick="loadDoc()">Submit</button>
</form>
<div id="ajax-text"></div>
</div>
<script type="text/javascript" src="main.js"></script>
The Main Javascript file
function _(x) {
return document.getElementById(x);
}
function ajaxObj ( meth, url ) {
var x = new XMLHttpRequest();
x.open( meth, url, true );
x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
return x;
}
function ajaxReturn(x){
if(x.readyState == 4 && x.status == 200) {
return true;
}
}
function loadDoc() {
var someText = _("someText").value;
var ajax = ajaxObj("POST", "ajax/ajax.php");
ajax.onreadystatechange = function() {
if(ajaxReturn(ajax) == true) {
_('ajax-text').innerHTML = ajax.responseText;
console.log(ajax.responseText);
}
}
ajax.send("someText="+someText);
}
The PHP AJAX File
if(isset($_POST['someText'])){
$someText = $_POST['someText'];
echo "\"$someText\"" . ' is what you wrote';
exit();
} else {
echo "An error occured";
exit();
}

call js function from form action then call php from js

We can call php directly from form action in html:
<form name='x' action = "filename.php">
in this case, php will receive all inputs in the form even we don't pass them.
Can we call js function from form action in html?
<form name='x' action = "javascript:jsFunction();">
Then, call the php from the js function?
jsFunction()
{ var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("result").innerHTML = xhttp.responseText;}
};
xhttp.open("POST", filename.php, true);
xhttp.send();
}
Hint
I cannot use onsubmit because it log me out from the platform. in other words, it reload the platform from the beginning of the login page.
I am working on integration and I don't have a clear idea about the platform.
Edit 1:
Now, in the HTML file:
<form enctype='multipart/form-data' id = "myform">
<input type='submit' value='Basic search' onclick = "i2b2.BLAST.jsFunction();">
JS file:
i2b2.BLAST.jsFunction = function ()
{
var myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function(event)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (xhttp.readyState == 4 && xhttp.status == 200)
{
document.getElementById("result").innerHTML = xhttp.responseText;
}
};
xhttp.open("POST", blastresult.php, true);
xhttp.send();
event.preventDefault();
});
}
it reloads the platform from the beginning of the login page!
Edit2:
I put some alert to see if the button call the javascript.
i2b2.BLAST.jsFunction = function ()
{
alert('hi');
this.yuiTabs = new YAHOO.widget.TabView("BLAST-TABS", {activeIndex:1});//this two lines navigate to second tab
this.yuiTabs.set('activeIndex', 1);
alert('hi');
myForm.addEventListener('submit', function()
{
alert('hi');
preventDefault();
The button call the js and display first 'hi' then navigate to second tab then reload the page. It stop at the second 'hi'.
Any help is highly appreciated.
Thanks.
Yes you can, First give your FORM an id
<form id="myForm"></form>
then in javascript try this:
var myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function(e)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (xhttp.readyState == 4 && xhttp.status == 200)
{
document.getElementById("result").innerHTML = xhttp.responseText;
}
};
xhttp.open("POST", filename.php, true);
xhttp.send();
e.preventDefault();
});
Instead of:
<form name='x' action = "javascript:jsFunction();">
Use:
<form name='x' onsubmit="jsFunction();">
You can POST via AJAX as you have shown in your code:
function jsFunction(event) {
// prevent default event from taking place (submitting form to file)
event.preventDefault();
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
{
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("result").innerHTML = xhttp.responseText;}
};
xhttp.open("POST", filename.php, true);
xhttp.send();
}
Though you will need to serialize your data and pass it to xhttp.send(), it will need to be form url encoded like: key1=value1&key2=value2. You are probably better off using jQuery in the manner #mmm suggests.

Can I test XMLHttpRequest() in SDK with localhost?

The following code does not seem to work because when I try to get the "chooser" in Google App Engine (Python) it is undefined:
chooser = self.request.get("chooser")
self.response.out.write("chooser: %s " % chooser)
#returns "chooser:" without any value
Is this valid javascript?
var formData = new FormData();
formData.append("chooser", user);
var xhr = new XMLHttpRequest();
//is it ok to test this with localhost?
xhr.open("POST", "http://localhost:8086/g/choicehandler", true);
xhr.onreadystatechange = function (aEvt) {
if (xhr.readyState == 4 && xhr.status == 200){
console.log("request 200-OK");
}
else {
console.log("connection error");
}
};
xhr.send(formData);
Is the problem with the XHR call or with the App?
UPDATE
I am including the code in /choice to clarify what "chooser" is as per Daniel Roseman's comment:
In /choice handler I have writeToStorage() which assigns a username in the form user1, user2 and so on, and writes that to localStorage.
After writing user name to localStorage I also need to write it to database in the app, and I use xhr to send it to /g/choicehandler handler.
So, "chooser", I believe is a string, made of
var user = "user" + count;
I copy /choice handler below:
class Choice(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<head>
<script type="text/javascript">
var count = 0;
function writeToStorage()
{
var user = "user" + count;
count++;
localStorage.setItem("chooser", user);
var formData = new FormData();
formData.append("chooser", user);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:8086/g/choicehandler", true);
xhr.onreadystatechange = function (aEvt) {
if (xhr.readyState == 4 && xhr.status == 200){
console.log("request 200-OK");
}
else {
console.log("connection error");
}
};
xhr.send(formData);
};
</script>
</head>
<body>
<form name="choice_form" id="choice_form" action="/g/choicehandler" method="post" onsubmit="writeToStorage()">
<textarea name="choice" rows="7" cols="50"></textarea><br />
<input type="submit" value="submit your choice">
</form>
</body>
</html>""")
UPDATE 2
I noticed in the logs that the text from textarea which is "choice" and "chooser" which is sent with xhr are not shown together, one of them is always without a value:
INFO ... chooser: user0 choice:
INFO ... chooser: choice: abcd
INFO ... chooser: user0 choice:
INFO ... chooser: choice: efgh
This is the code for the above log:
chooser = self.request.get("chooser")
choice = self.request.get("choice")
logging.info("chooser: %s choice: %s" % tuple([chooser, choice]))
new_choice = User(
choice = choice,
owner = chooser)
new_choice.put()
so in the datastore i see "chooser" and "choice" written in 2 different rows. What am I doing wrong?
Actually you're submitting the form twice. Once in writeToStorage via AJAX and also with the normal way with the the form. You will have to change two things.
writeToStorage has to return false as the last action
Change your onsubmit to onsubmit="return writeToStorage()"
This way you will prevent the default submission of your form, as it will be done via AJAX in writeToStorage

Categories

Resources