Ajax response text correct but not displaying - ajax

i tried finding this problem using google but no luck so far , so im asking for some help.
im working with a webpage on JSP and im having a little problem with ajax responseText, im testing the page on firefox and using firebug.
the problem its that the operation its completed correctly and the response text show ok on the firebug console, but it doesnt display on the <div> i assigned.
when i put an alert() inside the function handling the onreadystatechange it displays correctly as if the response was just too late, so im a bit lost.
can anyone give me an idea?
my JS handling the submit is
function validate( form ) {
var expresion = /[\b\W\d]+/;
var error=0;
var nombre = document.getElementById("Addname");
var descripcion = document.getElementById("Adddescripcion");
if(nombre.value == "" ){
nombre.focus();
nombre.style.backgroundColor="red";
alert("Los Campos no deben estar vacios");
error = error+1;
}else{
if(!(expresion.test(nombre.value))){
var temp = nombre.value.toUpperCase();
nombre.value = temp;
}else{
nombre.focus();
nombre.style.backgroundColor="red";
alert("La entrada no es valida");
error = error+1;
}
}
if( descripcion.value == "" ){
descripcion.focus();
descripcion.style.backgroundColor="red";
alert("Los Campos no deben estar vacios");
error = error+1;
}
if(error == 0){
var url = "addCarrera";
var params = "name="+ nombre.value +"&descripcion="+descripcion.value;
ajaxPost(url,params,"addres");
document.getElementById("addres").setAttribute("class","visible");
clearing();
}
}
function clearing(){
var nombre = document.getElementById("Addname");
var descripcion = document.getElementById("Adddescripcion");
nombre.value="";
descripcion.value="";
nombre.style.backgroundColor="white";
descripcion.style.backgroundColor="white";
var timer = setTimeout("ocultar()", 1500);
}
an my code handling the Ajax request its
var ajaxCall;
function ajax_request() {
if(window.XMLHttpRequest){
//codigo para IE7+,Firefox,Chrome, Opera,Safari
ajaxCall=new XMLHttpRequest();
}else{
//codigo para IE6 y 5
ajaxCall=new ActiveXObject("Microsoft.XMLHTTP");
}
}
function ajaxPost(url ,params, respuesta){
ajax_request();
ajaxCall.onreadystatechange = statechangeHandle(respuesta);
ajaxCall.open("POST",url,true);
ajaxCall.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
ajaxCall.setRequestHeader("Content-length", params.length);
ajaxCall.setRequestHeader("Connection", "close");
ajaxCall.send(params);
//alert("respuesta? "+respuesta);
}
function statechangeHandle(text){
//alert("text?"+text);
//alert("ready?"+ajaxCall.readyState);
if(ajaxCall.readyState == 4 && ajaxCall.status === 200){
//alert("prueba");
document.getElementById(text).innerHTML=ajaxCall.responseText;
//alert(ajaxCall.responseText);
}
}
the html part
<h3>Agregar Carrera</h3>
<table>
<tr>
<td>Nombre:</td>
<td><input type="text" id="Addname" size="20" /></td>
</tr>
<tr>
<td>Descripcion:</td>
<td><textarea rows="2" cols="20" id="Adddescripcion" > </textarea></td>
</tr>
<tr>
<td><input type="button" value="Agregar" onclick="validate()"></td>
</tr>
</table>
<div class="ocultar" id="addres"></div>
thanks in advance.
by the way ,the ajax at ajaxPost doesnt show a thing but for example at statechangeHandle if active te alert before the asign the responseText the html its modified correctly but if not then the div stays the same, im not quite sure what that means, its like it has to wait i dont know if im just doing something really wrong

Related

Why controllers action doesn't send json data in response

I learn ASP.NET MVC and have some issue.
I create two links by ajax helper method in view. They send mailsType argument and response json data. Here is the code of links and AjaxOptions object
<div class="list-group" style = "text-align: center; margin-top: 10px;">
#Ajax.ActionLink("Incoming", "GetMails", new { mailsType = State.Incoming }, opts,
new{#class = "list-group-item active", data_type = "Incoming"})
#Ajax.ActionLink("Outgoing", "GetMails", new {mailsType = State.Outgoing}, opts,
new { #class = "list-group-item", data_type = "Outgoing" })
</div>
Here is ajaxoption, using in ajax helpers
AjaxOptions opts = new AjaxOptions
{
OnSuccess = "viewMail",
};
I handle response by javascript function
function viewMail(data) {
var html =
'<table class="table table-hover table-striped">' +
'<thead>' +
'<tr><th>' + (data.State == 'Incoming' ? 'From' : 'To') + '</th> <th>Subject</th> <th>Date</th></tr>' +
'</thead>' +
'<tbody>';
$(data.Mails).each(function(i, el) {
html += '<tr><td>' + el.From + '</td> <td>' + el.Subject + '</td> <td>' + el.Date + '</td></tr>';
});
html += '</tbody></table>';
$('#contentDiv').html(html);
}
And here is code of action method in controller
public ActionResult GetMails(State mailsType)
{
if (Request.IsAjaxRequest())
{
return Json(new
{
State = Enum.GetName(typeof (State), mailsType),
Mails = _serviceManager.GetMessages(mailsType)
}, "application/json", JsonRequestBehavior.AllowGet);
}
else
{
ViewBag.State = Enum.GetName(typeof(State), mailsType);
return PartialView(_serviceManager.GetMessages(mailsType));
}
}
When I use second link all works good, but when I use first one, i have internal server error with code 500 and response type is text/html.
I use this links to return partialviews and they all works before.
I tried to use my own ajax request, but result was still the same. I can't understand what's wrong. I understan't that question is abstract, but may be you had same problem or know why it happens.
Edit1
When I write address from link in address bar, I have this error:
System.InvalidOperationException: Timeouts are not supported on this stream.
I tryed set big timeout in ajax request, but it didn't help. Reqest executes successfuly when I send less data in response.
I think it related with size of data sending in response. Am I wrong? What reasons of this error can be?
I will by happy all yours advice. Thanks to all!

<g:remoteForm> redirect is not happening

I am using a to handle a login. In the case of incorrect credentials, I use Ajax to print an error message on the same web page but in the case of success I would like to forward to another web page. What is happening is that even in the case of success it is printing results on the same page. I know that this has partially to do with the fact that you can't send a redirect to Ajax. However, still a newbie to know how to go about it. Any suggestions?
Here is my gsp section having to do with this form:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" update = "error_message">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
and here is the controller method 'authenticate':
def authenticate = {
try {
MongoClient mongoClient = new MongoClient("localhost", 27017)
DB db = mongoClient.getDB("admin");
def userName = params.username
def passWord = params.password
boolean auth = db.authenticate(userName, passWord.toCharArray())
if (auth)
redirect (action: loggedin)
else {
render "Login or Password incorrect!"
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (MongoException e) {
e.printStackTrace();
}
}
def displayerror = {
render "Login or Password incorrect!"
}
def loggedin = {}
As it is, I can't get the gsp corresponding to the 'loggedin' method to display. Any ideas?
Minor adjustments needed to previous poster's most helpful suggestions. This is the code that will actually solve the issue.
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(data)">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
javascript below:
function doResult(data) {
if (data.success == true) {
window.location.href = data.url;
} else {
$("#error_message").html(data.message);
}
}
controller code section below
//success case
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')]
}
}
else {
render(contentType: 'text/json') {
["success": false, "message": 'Login or Password is incorrect.']
}
importing JSON converter in last set of code isn't needed either.
You are correct that you can't send a redirect using ajax. What you can do, however, is send something back in your ajax response that you can read and redirect if needed.
Instead of just updating the div with the response from your ajax call you will need to send back some JSON data and use the onSuccess attribute of the formRemote tag to pass the results to a function which can act accordingly.
I would suggest you start by reading over the documentation for the formRemote tag, then consider something like the following:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(e)">
<br><br><label>User Name (email): </label><g:textField name="username" /><br><br>
<label>Password: </label><g:field name="password" type="password" /><br><br><br><br>
<div id="error_message" style="text-align: center"> </div>
<div style="text-align: center">(for TWC employees only)</div>
<g:submitButton id="submit_button" name="Submit"/>
</g:formRemote>
Notice in the above that onSuccess is now set on the formRemote tag and update is removed. The response from the form submission will now be passed to the javascript function doResult.
This is what the function might look like:
<script>
function doResult(response) {
var result = eval('(' + response.responseText + ')');
if (result.success == true) {
window.location.href = result.url;
} else {
$("#error_message").html(result.message);
}
}
</script>
The only thing left is to change how your controller responds to the form submission. First you will need to add the import for import grails.converters.JSON into your controller. Then change the way it responds. It might look like this:
import import grails.converters.JSON
...
// in the case of an error
render [success: false, message: "Login or Password incorrect!"] as JSON
return
...
// in the case of success
render [success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')] as JSON
return
It may seem like a lot to take in all at once, but once you do it a few times it becomes quite simple. One thing that helps a lot is to read the Grails documentation. It's long, but it's very well written and will help a lot.

How to POST to database through URL

I'm writing a web application in Spring/Hibernate that handles basic voting functionality. I want to have a link to /vote/{gameId} which will add that vote to the database for that specific ID. I'm really at a loss as for how to accomplish this though. Here's what I've tried in my controller:
#RequestMapping(value="/vote/{gameId}", method = RequestMethod.POST)
public String addVote(#PathVariable("gameId")
Integer gameId) {
Vote vote = new Vote();
vote.setGameId(gameId);
voteService.addVote(vote);
return "redirect:/games/wanted.html";
}
Here's where the link shows up in a jsp:
<c:if test="${!empty games}">
<table>
<tr>
<th>Game Title</th>
<th>Votes</th>
<th> </th>
</tr>
<c:forEach items="${games}" var="game">
<tr>
<td><c:out value="${game.title}"/></td>
<td>Placeholder</td>
<td>Vote!</td>
</tr>
</c:forEach>
</table>
</c:if>
When I try this though I just get a 404 error. Any insight would be great.
This is how you make a post call with plain Javascript:
var url = "vote";
var params = "id=1";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
You need to call this in the onclick of your link.
On the other hand it is a lot easier if, for example, you use the jQuery Javascript library:
For your particular case it would be something like:
$.post("vote", { id: "1" } );
Or the full jQuery answer (remember to replace #linkid with the id of you tag):
$(document).ready(function() { //this runs on page load
// Handler for .ready() called.
$('#linkid').click(function(event) { //this finds your <a> and sets the onclick, you can also search by css class by type of tag
$.post("vote", { id: "1" } );
return false; //this is important so that the link is not followed
});
});

need to make sure my ajax script is set up right

ajax code:
try {
xmlhttp = new XMLHttpRequest();
}
catch(ee) {
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(E) {
xmlhttp = false;
}
}
}
div_base = "";
valor = 0;
function abre(arquivo,metodo,div) {
div_base = div;
valor++;
xmlhttp.open(metodo,arquivo+"?valor="+valor);
xmlhttp.onreadystatechange=response
xmlhttp.send(null)
}
function response() {
nova_div = div_base;
document.getElementById(nova_div).innerHTML="<div>Loading...</div>"
if (xmlhttp.readyState==4) {
document.getElementById(nova_div).innerHTML=xmlhttp.responseText
}
}
html code:
<form>
<select name="menu" style="width:400px; height:25px;">
<option>Change Theme:</option>
<option></option>
<option onclick="javascript: abre('Chat_Themes/Default.html','GET','response2');">Default - Shadow Hunters</option>
<option onclick="javascript: abre('Chat_themes/Custom.html','GET','response2');">Custom - Shadow Hunters</option>
</select>
</form>
<br />
<div id="response2"></div>
i changed the "div = responce" to "div = responce2" without changing the ajax code at the top, im not sure if i have to change the ajax code or not or i can leave it and it works fine the way it is, but it does not work on google chrome idk if its just google chrome being retarded, but it works in ff and ie just fine, any thoughts?
Try indenting your code: you'll find that your try-catch statements don't have matching braces. You can also try a Javascript-validating service like jshint, but indenting should come first.
You might want to consider using a third-party library which already has cross-browser AJAX capability, like jQuery.

Ajax Parent Form Submit not working for Calendar

I have a popup calendar that is being called from the parent form. What I am wanting to happen is when the user clicks on the date after it updates parent form field it automatically submits the parent form (where certain date checks will happen upon refresh). Ive tried using Ajax and for some reason the calendar popup window closes after the selection is made but the parent form wont submit. Is there anything Im missing here?
Here is the ajax code in the actual calendar popup window.
<script type=”text/javascript”>
// function create GetXmlHttpObject
function GetXmlHttpObject()
{
if (window.XMLHttpRequest)
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
}
if (window.ActiveXObject)
{
// code for IE6, IE5
return new ActiveXObject(“Microsoft.XMLHTTP”);
}
return null;
}
function submitFormWithAjax(){
var myAjaxPostrequest=new GetXmlHttpObject();
var t2lrequestend=document.docreq.request_end.value;
var t2lrsubmit="Submit Request";
var parameters=”request_end=”+t2lrequestend+"rsubmit="+t2lrsubmit;
myAjaxPostrequest.open(“POST”, “rm_new_arp_request_NEW_TIME_RESTRICTION.php”, true);
myAjaxPostrequest.setRequestHeader(“Content-type”, “application/x-www-form-urlencoded”);
myAjaxPostrequest.send(parameters);
myAjaxPostrequest.onreadystatechange=function(){
if(myAjaxPostrequest.readyState==4){
if(myAjaxPostrequest.status==200){
document.getElementById(“result”).innerHTML=myAjaxPostrequest.responseText;
document.getElementById(“docreq”).style.display = “none”;
}
else {
document.getElementById(“docreq”).innerHTML=”An error has occured making the request”;
}
}
}
}
</script>
And here is where it is supposed to submit the form and close the child window.
function set_datetime(n_datetime, b_close) {
if (!obj_caller) return;
var dt_datetime = obj_caller.prs_time(
(document.cal ? document.cal.time.value : ''),
new Date(n_datetime)
);
if (!dt_datetime) return;
if (b_close) {
obj_caller.target.value = (document.cal
? obj_caller.gen_tsmp(dt_datetime)
: obj_caller.gen_date(dt_datetime)
);
submitFormWithAjax();
window.close();
}
else obj_caller.popup(dt_datetime.valueOf());
}
if (obj_caller && obj_caller.time_comp)
document.write('<form onsubmit="javascript:set_datetime('+dt_current.valueOf()+', true)"><tr><td colspan="7" bgcolor="#87CEFA"><font color="White" face="tahoma, verdana" size="2">Time: <input type="text" name="request_end" value="'+obj_caller.gen_time(this.dt_current)+'" size="8" maxlength="8"><INPUT TYPE="hidden" NAME="rsubmit" VALUE="Submit Request" ></font></td></tr></form>');
</script>
</table></tr></td>
</table>
</body>
</html>
Any ideas on how I can get this to submit the parent form with the date still being used?

Resources