Simple AJAX query with CodeIgniter and jQuery - ajax

I'm simply trying to pull a div from a page called "Load-about.php" to my main page with AJAX.
I've been following tutsnet courses "30 Days to learn jQuery" but I'm stuck when it is about to load a content from another page since I'm using CI and I'm trying to adapt those courses.
So I have my main page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Load</title>
<link rel="stylesheet" href="<?php echo base_url('bootstrap/css/bootstrap.min.css'); ?>" >
<style>
</style>
</head>
<body>
Try to make AJAX working !
</br>
Contact
<div class="wrap"></div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script>
(function() {
var wrap = $('div.wrap');
$('a').on('click', function(e) {
var href = $(this).attr('href');
wrap.load(href +'.container' ) ;
e.preventDefault();
});
})();
</script>
</body>
</html>
I'm simply calling a very simple CI Controller that only call the asked view
And Everything was working fine when working without the links.
But now, I am redirected to the page instead of using the AJAX call. Why ? Why does
e.preventDefault();
or
return false;
isn't preventing the links to their default action ?
Thanks
EDIT: Thanks to Jai, I found my error, a simple coma.
But, now, I'm getting "GET http://www.localhost.com/CodeIgniterJQUERY/index.php/Ajax/lessonTwentyThree/Load-Contact.container 500 (Internal Server Error) "
the problem comes from the .container as I wanted to specify the class and Ci understand it as it is a parameter.
Here is the Controller :
class Ajax extends CI_Controller {
/**
* Nous allons ici nous occuper de toutes les fcts AJAX
*/
public function lessonTwentyThree($page)
{ // En fait, on a pas besoin de ca, on va directement loader la vue directement.
$this->load->view($page);
}
}
I just want to grab a div from Load-Contact to the main page.

In addition to what Jai said. you have a codeigniter logical error.
when you say:
$this->load->view($page);
it means that codeigniter will redirect internally to the view. In your case what you need is to get back the view content and not to load it.
So, codeigniter support a third parameter with function view() that asks it to get the view content as String. you can do that and send the view to be loaded like this:
$string = $this->load->view($page, '', true);
echo $string;
Hope this will solve your problem

You have to move it up:
(function($) {
var wrap = $('div.wrap');
$('a').on('click', function(e) {
e.preventDefault();
var href = $(this).attr('href');
wrap.load(href +'.container' ) ;
});
})(jQuery);
and you have to put a ',' after click handler.

also try to change
(function() {
})();
to
$(function() {
});

Related

Thymeleaf th:inline="javascript" issue

I don't know how to solve the following: I'd like to let my Model generate real javascript dynamically based on some model logic.
This final piece of javascript code then should be added inside the $(document).ready { } part of my html page.
The thing is: If I use inline="javascript", the code gets quoted as my getter is a String (that is how it is mentioned in the Thymeleaf doc but it's not what I need ;-)
If I use inline="text" in is not quoted but all quotes are escaped instead ;-) - also nice but unusable 8)
If I try inline="none" nothing happens.
Here are the examples
My model getter created the following Javascript code.
PageHelper class
public String documentReady() {
// do some database operations to get the numbers 8,5,3,2
return "PhotoGallery.load(8,5,3,2).loadTheme(name='basic')";
}
So if I now try inline="javascript"
<script th:inline="javascript">
/*<![CDATA[*/
jQuery().ready(function(){
/*[[${pageHelper.documentReady}]]*/
});
/*]]>*/
</script>
it will be rendered to
<script>
/*<![CDATA[*/
jQuery().ready(function(){
'PhotoGallery.load(8,5,3,2).loadTheme(name=\'basic\')'
});
/*]]>*/
</script>
Which doesn't help as it is a String literal, nothing more (this is how Thymeleaf deals with it).
So if I try inline="text" instead
<script>
/*<![CDATA[*/
jQuery().ready(function(){
PhotoGallery.load(8,5,3,2).loadTheme(name='basic')
});
/*]]>*/
</script>
Which escapes the quotes.
inline="none" I do not really understand, as it does nothing
<script>
/*<![CDATA[*/
jQuery().ready(function(){
[[${pageHelper.documentReady}]]
});
/*]]>*/
</script>
To be honest I have no idea how to solve this issue and hopefully anybody out there knows how to deal with this.
Many thanks in advance
Cheers
John
I would change the approach.
Thymeleaf easily allows you to add model variables in your templates to be used in Javascript. In my implementations, I usually put those variables somewhere before the closing header tag; to ensure they're on the page once the JS loads.
I let the template decide what exactly to load, of course. If you're displaying a gallery, then render it as you would and use data attributes to define the gallery that relates to some JS code. Then write yourself a nice jQuery plugin to handle your gallery.
A relatively basic example:
Default Layout Decorator: layout/default.html
<!doctype html>
<html xmlns:layout="http://www.thymeleaf.org" xmlns:th="http://www.thymeleaf.org">
<head>
<title>My Example App</title>
<object th:remove="tag" th:include="fragments/scripts :: header" />
</head>
<body>
<div layout:fragment="content"></div>
<div th:remove="tag" th:replace="fragments/scripts :: footer"></div>
<div th:remove="tag" layout:fragment="footer-scripts"></div>
</body>
</html>
The thing to notice here is the inclusion of the generic footer scripts and then a layout:fragment div defined. This layout div is what we're going to use to include our jQuery plugin needed for the gallery.
File with general scripts: fragments/scripts.html
<div th:fragment="header" xmlns:th="http://www.thymeleaf.org">
<script type="text/javascript" th:inline="javascript">
/*<![CDATA[*/
var MY_APP = {
contextPath: /*[[#{/}]]*/,
defaultTheme: /*[[${theme == null} ? null : ${theme}]]*/,
gallery: {
theme: /*[[${gallery == null} ? null : ${gallery.theme}]]*/,
images: /*[[${gallery == null} ? null : ${gallery.images}]]*/,
names: /*[[${gallery == null} ? null : ${gallery.names}]]*/
}
};
/*]]>*/
</script>
</div>
<div th:fragment="footer" xmlns:th="http://www.thymeleaf.org">
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/my_app.js"></script>
</div>
In the scripts file, there are 2 fragments, which are included from the decorator. In the header fragment, a helpful context path is included for the JS layer, as well as a defaultTheme just for the hell of it. A gallery object is then defined and assigned from our model. The footer fragment loads the jQuery library and a main site JS file, again for purposes of this example.
A page with a lazy-loaded gallery: products.html
<html layout:decorator="layout/default" xmlns:layout="http://www.thymeleaf.org/" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Products Landing Page</title>
</head>
<body>
<div layout:fragment="content">
<h1>Products</h1>
<div data-gallery="lazyload"></div>
</div>
<div th:remove="tag" layout:fragment="footer-scripts">
<script type="text/javascript" src="/js/my_gallery.js"></script>
</div>
</body>
</html>
Our products page doesn't have much on it. Using the default decorator, this page overrides the page title in the head. Our content fragment includes a title in an h1 tag and an empty div with a data-gallery attribute. This attribute is what we'll use in our jQuery plugin to initialize the gallery.
The value is set to lazyload, so our plugin knows that we need to find the image IDs in some variable set somewhere. This could have easily been empty if the only thing our plugin supports is a lazyloaded gallery.
So the layout loads some default scripts and with cleverly placed layout:fragments, you allow certain sections of the site to load libraries independent of the rest.
Here's a basic Spring controller example, to work with our app: MyController.java
#Controller
public class MyController {
#RequestMapping("/products")
public String products(Model model) {
class Gallery {
public String theme;
public int[] images;
public String[] names;
public Gallery() {
this.theme = "basic";
this.images = new int[] {8,5,3,2};
this.names = new String[] {"Hey", "\"there's\"", "foo", "bar"};
}
}
model.addAttribute("gallery", new Gallery());
return "products";
}
}
The Gallery class was tossed inline in the products method, to simplify our example here. This could easily be a service or repository of some type that returns an array of identifiers, or whatever you need.
The jQuery plugin that we created, could look something like so: my_gallery.js
(function($) {
var MyGallery = function(element) {
this.$el = $(element);
this.type = this.$el.data('gallery');
if (this.type == 'lazyload') {
this.initLazyLoadedGallery();
}
};
MyGallery.prototype.initLazyLoadedGallery = function() {
// do some gallery loading magic here
// check the variables we loaded in our header
if (MY_APP.gallery.images.length) {
// we have images... sweet! let's fetch them and then do something cool.
PhotoGallery.load(MY_APP.gallery.images).loadTheme({
name: MY_APP.gallery.theme
});
// or if load() requires separate params
var imgs = MY_APP.gallery.images;
PhotoGallery.load(imgs[0],imgs[1],imgs[2],imgs[3]).loadTheme({
name: MY_APP.gallery.theme
});
}
};
// the plugin definition
$.fn.myGallery = function() {
return this.each(function() {
if (!$.data(this, 'myGallery')) {
$.data(this, 'myGallery', new MyGallery(this));
}
});
};
// initialize our gallery on all elements that have that data-gallery attribute
$('[data-gallery]').myGallery();
}(jQuery));
The final rendering of the products page would look like so:
<!doctype html>
<html>
<head>
<title>Products Landing Page</title>
<script type="text/javascript">
/*<![CDATA[*/
var MY_APP = {
contextPath: '/',
defaultTheme: null,
gallery: {
theme: 'basic',
images: [8,5,3,2],
names: ['Hey','\"there\'s\"','foo','bar']
}
};
/*]]>*/
</script>
</head>
<body>
<div>
<h1>Products</h1>
<div data-gallery="lazyload"></div>
</div>
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/my_app.js"></script>
<script type="text/javascript" src="/js/my_gallery.js"></script>
</body>
</html>
As you can see, Thymeleaf does a pretty good job of translating your model to valid JS and actually adds the quotes where needed and escapes them as well. Once the page finishes rendering, with the jQuery plugin at the end of the file, everything needed to initialize the gallery should be loaded and ready to go.
This is not a perfect example, but I think it's a pretty straight-forward design pattern for a web app.
instead of ${pageHelper.documentReady} use ${pageHelper.documentReady}

How to make a ajax loading component by using angularjs service?

I want to make a specific component for showing loading icon when the browser waits to load data from json. Is there any possible way to do it by using a service ??
html :
<html ng-app="app">
<head>
<title> ERP </title>
</head>
<body >
<div ng-controller="data"><span class="loading" ng-show="loader"><img src="ajax-loader.gif"></span>
<table>
<tr><td>{{data1}}</td><td>{{data1}}</td><td>{{data1}}</td></tr>
</table>
</div>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script type="text/javascript" src="ctrl.js"></script>
</body>
</html>
js :
var app = angular.module('app',[]);
app.controller('data', ['$scope','$http',function($scope,$http){
$scope.loader = null ;
if($scope.loader == null )
{
$scope.loader = true ;
}
$http.get('events.json').
success(function(data) {
$scope.loader = false ;
console.log(data);
$scope.data1 = data ;
console.log($scope.data1);
}).
error(function(data, status, headers, config) {
});
}]);
You can wrap the original $http to provide a customizedHttp service. in this service, provide the same interface with $http. when sending GET request to the server, the customizedHttp broadcast an event to show the loading flag. and after receiving response, broadcast another event to hide the loading flag.
to control the flag, you'd better to write a directive.

jQuery mobile : Linking next page doesn't work on Windows phone using phonegap

Currently im building a application using phonegap & jQuery Mobile
I have done the version which is perfectly working on iOS & Android.But the same code does not work on windows phone.When i click any link,redirection to the respective page is not loading..Its still says "Error Page loading".
<!DOCTYPE html>
Test
<div id="bg">
<div style="padding-top:14%;width:100%;text-align:center">
<div style="float:left;text-align:center;width:50%"><img src="pics/btn_1.png" /></div>
<div style="float:left;text-align:center;width:50%"><img src="pics/btn_2.png" /></div>
</div>
<div style="clear:both"></div>
</div>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>
Need help on this.
Solution
Add data-ajax=false or rel=external to your anchor tag. But, if you do this, you will lose transitions. This tells the framework to do a full page reload to clear out the Ajax hash in the URL. You could enable this if the incoming device is a windows phone if needed :
$(document).on("mobileinit", function () {
//check for windows phone
$.mobile.ajaxEnabled = false;
});
Else, make your code into a single page template. Here's a demo of that : http://jsfiddle.net/hungerpain/aYW2f/
Edit
Currently jQM doesn't support query string parameters. You could use the localStorage API to store the parameters in cache and retrieve them later. Assuming you want to go to index.html from here :
<img src="pics/btn_2.png" />
You'd add a click event for it :
$(document).on("click", "a", function() {
//gets qs=2 and changes it into ["qs",2]
var query = this.href.split["?"][2].split["="];
//construct an array out of that
var paramString = { query[0]: query[1]} ;
//store it in localstorage
locaStorage["query"] = JSON.stringify(paramString);
//continue redirection
return true;
});
In your index.html :
$(document).on("pageinit", "[data-role=page]", function() {
//store it in localstorage
var params = JSON.parse(locaStorage["query"]);
//now params will contain { "qs" : 2 }
//you could access "2" by params["qs"]
});
More info about localStorage here.
I had Also same issue and finally resolve it by using below code
my html page is index.html and i am writtinga all code in one html
Before
$.mobile.changePage( "#second", {});
After
var url = window.location.href;
url = url.split('#').pop().split('?').pop();
url = url.replace(url.substring(url.lastIndexOf('/') + 1),"index.html#second");
$.mobile.changePage(url, { reloadPage : false, changeHash : false });
and suppose you have multiple html page then for more one page to another you can use
var url = window.location.href;
url = url.split('#').pop().split('?').pop();
url = url.replace(url.substring(url.lastIndexOf('/') + 1),"second.html");
$.mobile.changePage(url, { reloadPage : false, changeHash : false });
There is no support of querystring in web application using phonegap for windows phone 7.
However we can replace ? with # or anything else to pass the data,
like convert
Sample.html?id=12312
to
Sample.html#id=12312

jQuery Mobile ajax request

I am trying to retrieve information from a javascript file in my jQuery mobile website. Ajax is enabled by default, yet when I try xmlHttpRequest.send(), the responseText is the source code for the page rather than a json structure. The initialize() function is run at pageinit, so my thinking is that the json it is retrieving should exist when called. Also, initialize() works fine on the non-mobile variant of the site so I think it has something to do with how JQM handles ajax requests. Thanks in advance for any assistance.
<!DOCTYPE html>
<html>
<head>
var xmlHttpRequest;
var json;
<script type="text/javascript">
function initialize()
{
xmlHttpRequest = (window.XMLHttpRequest) ? new XMLHttpRequest() :
new ActiveXObject("Msxml2.XMLHTTP");
if (xmlHttpRequest == null)
return;
xmlHttpRequest.open("GET", "pick.js", false);
xmlHttpRequest.send();
json = eval('('+ xmlHttpRequest.responseText +')');
}
</script>
......
</head>
<body>
<div data-role="page" id="map-page">
<script type="text/javascript">
$('#map-page').live('pageinit',function(){
initialize();
});
</script>
.....
</div>
</body>
</html>
Since you're using jQuery Mobile (and thusly, jQuery), you should consider using jQuery.ajax -- it handles all of the 'hard stuff' like creating XHR object for you.
For your situation your code would look like this:
function initialize() {
$.get("pick.js", function(data, status, jqXHR) {
//when the call succeeds, do something with the 'data' param
console.log(data);
}, "script");
}

Using Jquery in Controller Page-ASP.NET MVC-3

Could any one give an example, how to use Jquery in Controller Page. MVC3 -ASP.NET(How To put various tags like )
I want to show a simple alert before rendering a view in Controller.
Thank you.
Hari Gillala
Normally scripts are part of the views. Controllers shouldn't be tied to javascript. So inside a view you use the <script> tag where you put javascript. So for example if you wanted to show an alert just before rendering a view you could put the following in the <head> section of this view:
<script type="text/javascript">
alert('simple alert');
</script>
As far as jQuery is concerned, it usually is used to manipulate the DOM so you would wrap all DOM manipulation functions in a document.ready (unless you include this script tag at the end, just before closing the <body>):
<script type="text/javascript">
$(function() {
// ... put your jQuery code here
});
</script>
If you are talking about rendering partial views with AJAX that's another matter. You could have a link on some page that is pointing to a controller action:
#Html.ActionLink("click me", "someAction", null, new { id = "mylink" })
and a div container somewhere on the page:
<div id="result"></div>
Now you could unobtrusively AJAXify this link and inject the resulting HTML into the div:
$(function() {
$('#mylink').click(function() {
$('#result').load(this.href, function() {
alert('AJAX request finished => displaying results in the div');
});
return false;
});
});

Resources