ajax function and Grails controller - javascript

i'm just trying the ajax Jquery function in GSP, here is the GSP:
<%# page contentType="text/html;charset=UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta name="layout" content="main" />
<title>Insert title here</title>
<g:javascript library='jquery' plugin='jquery' />
<script type="text/javascript">
function callAjax(){
$(document).ready(function(){
$('button').click(function(){
var URL="${createLink(controller:'book',action:'checkJquery')}"
$.ajax({
url:URL,
data: {id:'1'},
success: function(resp){
console.log(resp);
$("#author").val(resp.author)
$("#book").val(resp.bookName)
}
});
});
});
}
</script>
</head>
<body>
<button class="testMe" onclick="callAjax();">test</button>
<div class="body" id="divBody">
<g:textField name="author" id="author"/>
<g:textField name="book" id="book"/>
</div>
</body>
</html>
here is the checkJquery action in the controller :
def checkJquery() {
def s=Book.get(params.id)
render s as JSON
}
the problem that when i click the button ,it doesn't do anything , but if i clicked it again it prints the below in chrome console, the question why from the first click it didn't work , and why printing the response twice.
Object {class: "test.Book", id: 1, author: "a1", bookName: "book1"}
Object {class: "test.Book", id: 1, author: "a1", bookName: "book1"}

So there are a couple things to point out here.
function callAjax(){
$(document).ready(function(){
$('button').click(function(){
var URL="${createLink(controller:'book',action:'checkJquery')}";
$.ajax({
url:URL,
data: {id:'1'},
success: function(resp){
console.log(resp);
$("#author").val(resp.author);
$("#book").val(resp.bookName);
}
});
});
});
}
Lets start with just the logic. So this is creating a function that contains a document ready. What this means is when the function executes it will give the function to the document ready method which will delay the execution of it until the page's body is parsed and in the dom.
Now lets look at the html.
<button class="testMe" onclick="callAjax();">test</button>
This is defining a button that will call the callAjax() method when it is clicked. So lets follow the logic. You create your function that will be executed later. Your page is rendered and the button exists.
You click the button which executes the method. That method then gives the function to the document ready to wait for the page to be parsed. But... we already know it is. Cause you called it based on an interaction with the page. So the document ready is pointless.
Another point, that call is going to happen -every- time that button is clicked. Meaning your method will happen multiple times, which means your binding will happen multiple times, and so on and so forth.
You should really consider binding in your javascript instead of inline in order to separate your concerns and to minimize/eliminate the redundancy.
So first off the html would change to be something like..
<button class="testMe">test</button>
And your javascript...
$(document).ready(function(){
$('.testMe').click(function(){
var URL="${createLink(controller:'book',action:'checkJquery')}";
$.ajax({
url:URL,
data: {id:'1'},
success: function(resp){
console.log(resp);
$("#author").val(resp.author);
$("#book").val(resp.bookName);
}
});
});
});
Now your markup would be only your markup, and your bindings would happen after the page loads, and only once.

Related

Handling script loading when loading page through Ajax

Is there a way to handle scripts loading through Ajax page calls? I would like to not load those already loaded in the first place by the base page as they are in conflict.
Is the solution to create multiple pages one for the normal call (with the scripts) one for the ajax ones (without the scripts that are duplicates)?
Example:
base_page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
</head>
<body>
<div id="ajax_page"> </div>
<div id="other_ajax_call"> </div>
<div id="second_result"> </div>
</script>
$(document).ready(function(){
$.ajax({
url: '/ajax_page',
type: 'GET',
success: function (result) {
$('#ajax_page').html(result)
}
});
});
$( "#other_ajax_call" ).on( 'click', function() {
$.ajax({
url: '/another_page',
type: 'GET',
success: function (result) {
$('#second_result').html(result)
}
});
});
</script>
</body>
</html>
ajax_page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
</head>
<body>
<div id="ajax_second_page"> </div>
</script>
$(document).ready(function(){
$.ajax({
url: '/a_third_page',
type: 'GET',
success: function (result) {
$('#ajax_second_page').html(result)
}
});
});
</script>
</body>
</html>
In this example, on the 'base_page' I load through Ajax 'ajax_page' that itself is using Ajax (this page is usually called without Ajax and therefore will need to keep the script).
The problem is that when this is done, the jquery scripts are in conflict and the second ajax call of the 'base_page' (for "#other_ajax_call") is not working and I receive the following exception :
Uncaught TypeError: $.ajax is not a function
This is a repost of Ajax call - Loading page script only if not there in the base page that was closed as I first didn't put enough details and my question was not clear enough and I have no way to reopen it.
Since you are getting the full pages anyway it doesn't make sense to do that with ajax, especially when it breaks proper HTML. What you could do is to use an iframe to display your pages, and then manage them with some simple javascript in the parent document.
For example:
<!-- iframe for one of your pages -->
<iframe id="page-foo-iframe"
title="page foo"
width="100%"
height="100%"
src="/a_third_page">
</iframe>
<script>
/*
* You can have a button, or something else, call these functions
* whenever you need to show/hide a page.
*/
function showIframePage(id) {
let page = document.getElementById(id);
page.style.display = "block";
}
function hideIframePage(id) {
let page = document.getElementById(id);
page.style.display = "none";
}
</script>
I would also suggest that you look into using a framework, in particular the JS ones like Vue/React/Angular, because they will make handling things like this a lot simpler and easier to maintain. If you have to load full documents though, iframes are the best way to do that.

Run php script from html form with Ajax request

I've been trying to make a small php script run through an ajax request. The bigger picture is that I want to store the data in an html form to my database on the click of a button, without actually submitting that form on the same click. However, since I'm new to programming, I'm trying to get the basic principles to work first.
For testing, I made a minimal example. In ajaxtest.hml, I made a button that should execute the function click(). That function is supposed to execute an ajax request to execute testing.php (located in the same folder). testing.php should just return 'Hello World'. However, the button does nothing, and I can't figure out what's wrong.
My code for ajaxtest.html:
<html>
<meta charset="UTF-8">
<body>
<button type="button" onclick="click()">Click Me</button>
<p id="p"></p>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js">
function click(){
$.ajax({
type: 'POST',
url: 'testing.php',
success: function(data) {
alert(data);
}
});
}
</script>
</body>
</html>
and for testing.php:
<?php
echo "Hello World"; ?>
It is probably a typical rookie mistake I'm making here, but the jungle of different posts on this and similar topics hasn't helped me so far... Any help is greatly appreciated!
There are a few things wrong with your code:
First of all, it is not a proper HTML file. Every HTML file should have a <head></head> tag and <body></body> tag within the <html></html> tag.
Secondly, you want to load your scripts in the <head> section. Where you can also define a title, meta tags, stylesheets, etc.
Thirdly, your <script>tag is wrong. You load a script and at the same time, you define a function. This should be two actions.
I think your script then will look something like:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js">
</head>
<body>
<button type="button" onclick="click()">Click Me</button>
<p id="p"></p>
</body>
<script>
function click(){
$.ajax({
type: 'POST',
url: 'testing.php',
success: function(data) {
alert(data);
}
});
}
</script>
</html>
For information about HTML see W3schools
You should delete the parenthesis in the attribute "onclick=click()", otherwise the function will be immediately executed on page load, and this is why you are not able to see the action of the button.
I suggest this way: (replace it instead of your code into Body tag.)
<button type="button" id="ajaxBtn">Click Me</button>
<p id="p"></p>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
const btn=document.getElementById('ajaxBtn');
btn.addEventListener('click',click);
function click(){
$.ajax({
type: 'POST',
url: 'testing.php',
success: function(data) {
alert(data);
}
});
}
</script>
It seems to me that you have 3 things you need to fix:
You are missing the opening <script> tag for your function since the opening script tag you have at the moment is for the jquery library you are referencing.
Also, don't use the reserved word "click" for your function name. I have changed it below to "myfunction"
Move the function definition to an appropriate place within your page.
If you try the code below it should work. I hope this helps.
<html>
<meta charset="UTF-8">
<body>
<script>
function myclick(){
alert('posting!');
$.ajax({
type: 'POST',
url: 'testing.php',
success: function(data) {
alert(data);
}
});
}
</script>
<button type="button" onclick="myclick()">Click Me</button>
<p id="p"></p>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"/>
</body>
</html>
You can try calling the function implicitly
<html>
<meta charset="UTF-8">
<body>
<button id="testbutton" type="button">
Click Me
</button>
<p id="p"></p>
<script type="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$('body').on('click', '#testbutton', function(){
$.ajax({
type : 'POST',
url : 'testing.php',
success : function(data) {
alert(data);
}
});
});
</script>
</body>

How do make jquery code executed within order

I have the code:
<html>
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('form').submit(function(e) {
if (!$('.text').val()) {
e.preventDefault();
console.log('error');
return false;
}
});
});
</script>
</head>
<body>
<form>
<input type="text" class="text" value="" />
<input type="submit" value="Send" />
</form>
<script type="text/javascript">
$('form').submit(function(e) {
e.preventDefault();
$.ajax({
url: 'send.php',
type: 'post',
success: function() {
console.log('done');
}
});
});
</script>
</body>
</html>
I have insert to javascript into the <head> and the end of <body>.
The problem I have is that when I click on the submit button, seems browser executing both my code at the same time.
I don't want combining the both code into one, I just want to execute the javascript code on <head>, the stopped if an error occurred, otherwise it would execute the code in <body>.
If you just take a look at my problem and share a bit of your science, I'd be very grateful. Thanks!
JQuery will execute the event handlers in the order they are bound, but as #KevinB has pointed out in a comment, the one in the <body> is bound first because that code is executed as it is encountered, while the one in the <head> is bound second because it is executed during the page-ready event.
You could rearrange the code so the two handlers are bound in the correct order and then use e.stopImmediatePropagation() in the first handler when you want to prevent the second from executing, but it would be better to bind just a single handler.
Just place one <script> block in the <head > and bind one submit handler.
<script type="text/javascript">
$(document).ready(function() {
$('form').submit(function(e) {
if (!$('.text').val()) {
e.preventDefault();
console.log('error');
$.ajax({
url: 'send.php',
type: 'post',
success: function() {
console.log('done');
}
});
}
});
});
</script>
when you use
.submit( handler )
you bind a event handler actually you are binding two handlers.
if you only want to send the form after a validation
you can validate and then a simple
.submit()
which is different according with jQuery documentation
https://api.jquery.com/submit/

jQuery $.get() and $.ajax() doesn't get data from PHP

I have a script that is supposed to alert a message taken from a PHP file after a click event. I've tried both jQuery $.get() and $.ajax(), but both didn't worked.
$.ajax() works but alerts an empty message, $.get() alerts "null".
load.php
<?php
$string = "prova";
echo json_encode($string);
?>
jquery_save.js
$(document).ready(function(){
$("#carica").click(function(){
loadPHP();
});
});
function loadPHP() {
$.get( "load.php", function( data ) {
alert(data)
}, "json" );
};
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>This is just a test for Stackoverflow</title>
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery_save.js"></script>
</head>
<body>
<form>
<input style="background-image:url(img/lc-load.png);" type="submit" value="Carica" name="carica" id="carica">
</form>
</body>
</html>
In this way I get the alert but with a "null" output.
I've tried this too:
load.php
<?php
$string = "prova";
echo $string;
?>
jquery_save.js
$(document).ready(function(){
$("#carica").click(function(){
loadPHP();
});
});
function loadPHP() {
$.ajax({
type: 'GET',
url: 'load.php',
success: function(data) {
alert(data);
}
});
};
This gives me an alert with noting inside. Both ways makes the page refresh after closing the alert message (and I don't want this happens).
I used another function with $.ajax() to give variables to another PHP file without problem, but I'm not able to take variables from PHP files.
You have to prevent the default click action -
$("#carica").click(function(event){
event.preventDefault();
loadPHP();
});
Your alert does not occur because of the page redirection.
You are using a submit button which causes a submit event which isnt being handled.
try changing it like this
<input style="background-image:url(img/lc-load.png);"
type="button" value="Carica" name="carica" id="carica" />
Are you using a submit button to provide a fallback for browsers with javascript disabled? if that's the case you need to prevent the submit event

This is an interesting situation. Calling ajax delete function from another js file results

I have a page where I autoload records(infinite scroll) using a js and ajax file. What I want to do is add a delete function for each record using ajax.
The ajax/js function I have works great normally; but with this infinite scroll records loaded, I am having trouble making it work.
My page is rather complicated looking so here is a simplified version.
Normal index.php without ajax delete function.
ajaxload.php // this is the file with query that loads the results of infinitescroll
<html>
<head>
<title>Home page</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="js/infinitescroll.js"> </script>
</head>
</html>
<body>
<div id="results">
// results of infinitescroll/ajaxload go here. For eg.
<div id="record">
<h1>Title of record</h1>
<p>Post description</p>
Delete
</div>
</div>
</body>
</html>
index.php with ajax delete function
<html>
<head>
<title>Home page</title>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="js/infinitescroll.js"> </script>
<script>
$(document).ready(function() {
$(".del-action").click(function() {
var commentContainer = $(this).parent();
var id = $(this).attr("id");
$.ajax({
type: "GET",
url: "delete.php",
data: {id: id},
cache: false,
success: function(){
commentContainer.slideUp('slow', function() {$(this).remove();});
}
});
return false;
});
});
</script>
</head>
</html>
<body>
<div id="results">
// results of infinitescroll/ajaxload go here. For eg.
<div id="record">
<h1>Title of record</h1>
<p>Post description</p>
<a class="del-action" href="#" id="32">Delete</a>
</div>
</div>
</body>
</html>
I do not get any errors when I try to delete the record. It simply doesn't call the delete.php file.
Please note that you attach click handler only on document ready. I'm assuming that your infinite scroll solution is loading new elements dynamically. Those new elements does not have any click handlers attached.
There are two solutions of this problem.
You may attach handlers after creation on new items
You may attach handler to element higher in dom structure which is static and listen to click event of his children. To create such handler you should use 'on' method (https://api.jquery.com/on/) with selector specified. For example:
$('#parentElement').on('click', '.del-action', function() { //handler });

Categories