Rendering AJAX view in Cakephp - php

I have a method which will render a standard view file index.ctp or an AJAX view file index_ajax.ctp depending on the request type
Within my controller - I have the following code
public function index() {
if ($this->request->is(array('get', 'post))) {
// .... do normal stuff
} elseif ($this->request->is('ajax')) {
$this->autorender = false;
echo 'blah blah'; // this shows
$this->render('index_ajax', 'ajax'); // this does not render
exit;
}
}
The Javascript that invokes this AJAX view is as below
$('#myModal').on('show.bs.modal', function (event) {
$.ajax({
url: '/cake/myController/index',
type: 'ajax',
success: function(data) {
alert(data);
$('#link-list').html(data);
}
});
});
Now the normal index view renders just fine - no problems at all, however the AJAX view is not rendering. If I put an echo statement in the controller, that statement does get outputted to the view but the actual view file itself is not getting picked up and rendered. I am not sure what my mistake is - any help is appreciated.

Try this :
if ($this->request->is(array('get', 'post'))) {
// .... do normal stuff
} elseif ($this->request->is('ajax')) {
$this->view="index_ajax";
$this->layout="ajax";
}
After this, look in your layout ajax if you use blocks or something like this which don t show your code or something like that.

Ok - after lots of trial and error and experimenting around, I figure out the solution.
For the original problem that I posted, #mark gave the right answer and I have since then incorporated the plugin available here - essentially, we download and include the plugin mentioned in that link and in the AJAX method in our controller we put a line as below
$this->viewClass = 'Tool.Ajax'
And in your AJAX javascript include the following line that extracts content from the parsed JSON array and embeds in the HTML selector provided
$.ajax ({
url: '/myajaxurl',
type: 'ajax',
success: function(data) {
$('myDiv').html(data.content);
}
});
Vola! the AJAX view now gets rendered. I examined the plugin source code and noticed that Mark has essentially extended the Basic view class and overridden the render method to render AJAX views via a JSON array. However that caused a problem for me since I also had pagination in my AJAX view. So while the links would get rendered fine and the first page would load fine, the second and subsequent pages would load as unparsed JSON array.
To overcome this I had to do a lot of fiddling around and I finally figure out that we need to discard the default AJAX pagination specified within CakePHP manual and use the AJAX pagination provided by Mark at this link (along with the appropriate source code). Essentially, instead of using the default echo $this->Pagination->numbers() we should now use echo $this->element('Tools.pagination') and we should include a javascript that binds the generated pagination links in the following manner -
Assume that pagination links are within a div identified as 'pagination' and these links are generated dynamically by Mark's plugin
$(document).on('click', 'div.pagination a', function(evt) {
evt.preventDefault();
$('#myDiv').load($(this).attr('href'), function(data) {
var res = $.parseJSON(data);
$('#myDiv').html(content);
});
});
Essentially what is happening above is that we are binding each of the pagination links with a different event as opposed to what is automagically generated by CakePHP. So we are loading the content of hyperlink via load method but since a JSON array is returned by AJAX view, we are parsing it and setting the DIV's content accordingly.
Hope this helps someone else down the line!!

Related

How to load a view file from within another view with Codeigniter WITHOUT having to pass through a controller?

I'm struggling to find a solution to this problem, I need to load a view from within another view. I know, usually, i would just have to do :
<?php $this->load->view("smthg");?>
But this time, the file path is passed to a data-file tag's property.
I have :
<a data-file="<?php echo site_url('main/loadCocktailRecipient') ?>/{{Id}}" href="#">
and actually, this is used by a javascript function to load the view by itself. so when doing like so, It load the controller instead of the view file. (or it maybe even do not load anything)
Let say I've put my view into the app/views folder. how can I make sure this script actually loads this file without the need of the controller ?
If this is not possible, how can I adapt the js script to load, not the file itself (which here, would be the controller first) but the final view returned by CI' controller ?
EDIT: JS script:
$(".cocktail .cocktail-item a").on('click', function(event) {
event.preventDefault();
var fileToLoad = $(this).data('file');
if(portfolioActive) {
closePortfolio(true, fileToLoad);
} else {
loadPortfolio(fileToLoad);
}
});
and load portfolio function is :
function loadPortfolio(fileToLoad) {
$portfolioSingle.load(fileToLoad, function() {
portfolioSingleH = $portfolioSingle.find('.container').outerHeight();
$portfolioSingle.css({
'top': -portfolioSingleH
});
$('#portfolio').animate({ scrollTop: 0 }, "slow");
$portfolioSingle.stop().animate({
'top': 0
}, 500, 'easeOutCubic');
$portfolioContainer.stop().animate({
'marginTop': portfolioSingleH
});
portfolioActive = true;
bindClosePortfolio();
bindFancybox();
setupFlexslider();
});
}
if this is too complex, then how can I simply tell him to look for a handlebar script by id and load the content that would be generated dynamically ?
Thanks
Don't do that, is a bad idea. To do that you need to remove the .htaccess file from the views folder.
Instead, use the jquery get function that makes an ajax request.
$.get("main/loadCocktailRecipient/1");
The best way is to do a new controller that returns a json object with the data requested. Then, with a $.get you retrieve that json, and finally, you iterate over that json to put the contents whenever you want.
From the jQuery Documentation:
$.ajax({
url: "main/loadCocktailRecipient", //the url to retrieve the data
data: { id: "1" }, //you can send the get parameters here
success: success, //the data returned (your json or html)
dataType: dataType //html, json, etc... if the dataType returned is not what you specify it will enter on a .error function. check the jquery documentation
});

Getting another page via ajax and showing data -> unable to display correct formatting

I have an issue:
I have Discussions.php page that shows threaded discussions. I also have generateDiscussion.php page that creates a tree with discussions.
When I embedd the code from generateDiscussion.php into Discussions.php, it works fine. By embed I mean hardcoding same stuff like I have in Discussions.php. By works fine I mean that my discussions have proper formatting and expand and group icons work as expected.
When Iam getting Discussions.php via AJAX, and adding response from AJAX to generateDiscussion.php; it does not work as expected.
I also tried generating tree first in the Discussions.php, and then updating it over with new tree. As a result, first load (internal to page) works fine, but AJAX calls mess it up.
<ul id="browser" class="filetree">
Please select a case first
</ul>
<script>
function getResolutionBoard(caseId) {
idcase=caseId;
jQuery(function($) {
$.ajax( {
url : "generateDiscussion.php?caseid="+caseId+"ts=" +new Date().getTime(),
type : "GET",
success : function(data) {
document.getElementById('browser').innerHTML = data;
}
});
});
}
</script>
I incorporated this script: http://jquery.bassistance.de/treeview/demo/
See the screenshots
How do you initialize the javascript on the ajax load ?
You need to call the plugin's initialization method ($('#browser').treeview()) in your success callback, after you have loaded the html code in the DOM.
... ajax({ ...
success : function(data) {
document.getElementById('browser').innerHTML = data;
$('#browser').treeview(/*your options*/);
}
});

Javascript functions on same DIV not working

I have two Ajax functions that are on the same div, the first one executes when complete page is fully loaded and call the ccslider method, instead the second one checks which menu ID I clicked, on the menu, to load dynamically different contents for different pages.
I can see the content loaded (eg: pictures) but unfortunately I don't see them in the ccslider; it seems that the slider is not executed.
But I know that works just because if I test it, removing the swapContent() function and place my PHP code with the MySQL query inside my main page the pictures are loaded inside the working ccslider.
Any hint on how to fix this problem?
$(window).load(function(){
$('#sliding').slider({
_Options: {
imageWidth: 300,
imageHeight: 200
}
});
});
function swapContent(cv) {
var url = "testing_cover.php";
$.post(url, {contentVar: cv}, function(data) {
$("#sliding").html(data).show();
});
}
You might have to call the slider method again inside the swapContent() function. Try this.
function swapContent(cv) {
var url = "testing_cover.php";
$.post(url, {contentVar: cv}, function(data) {
$("#sliding").html(data).show();
$('#sliding').slider({
_Options: {
imageWidth: 300,
imageHeight: 200
}
});
});
}
I have no access to the kind of plugin you're using, but from what it seems, you're probably modifying the HTML structure needed for it's functionality. Try inserting the HTML to a wrapper inside the #sliding element as opposed to directly in it.

jQuery.get() - How do I use the entire result?

I read this question, and I'm pretty sure it's 90% of what I need, but I'm after something more than just this, and my success formulating my query in Google has been less than stellar.
What I'd like to do
I have a form on a site that, when submitted, needs to connect with a database, and then the user needs to be apprised of the result. I'm trying to get the result page to load in a modal jQuery dialog instead of forcing a full page reload. At present, I'm just trying to create a jQuery dialog that replaces the contents of a <div> with the product of a PHP file. I know I will get the PHP file's execution result this way. That's what I'm after, but it currently is not working.
My code currently looks like this:
$(document).ready(function() {
$("#dialog").get('include.php', function(data) {
$("div#dialog").html(data);
});
});
And include.php is simply:
<?
echo "<h1>Loaded</h1>";
?>
When I load the page, the original contents of #dialog are still there. I have a strong suspicion that what I'm failing to grasp isn't major, but I've had bad luck finding the fix. I'm a web dev newbie. How do I wwebsite as on the internet?
You are calling get on a jQuery result. That'a a different method than $.get, the one you should be using:
$(document).ready(function() {
$.get('include.php', function(data) {
$("div#dialog").html(data);
});
});
i have been using Ajax call for the same purpose. So try this :
$(document).ready(function() {
$.ajax('include.php',
success : function(data) {
$("#dialog").html(data);
});
});
If you want to replace the entire contents of the #dialog DOM object with the HTML you load, then you probably want to use .load():
$(document).ready(function() {
$("#dialog").load('include.php', function(data) {
// no need to set the html here as .load() already does that
});
});

JQuery/AJAX: Loading external DIVs using dynamic content

I need to create a page that will load divs from an external page using Jquery and AJAX.
I have come across a few good tutorials, but they are all based on static content, my links and content are generated by PHP.
The main tutorial I am basing my code on is from:
http://yensdesign.com/2008/12/how-to-load-content-via-ajax-in-jquery/
The exact function i need is as follows:
Main page contains a permanent div listing some links containing a parameter.
Upon click, link passes parameter to external page.
External page filters recordset against parameter and populates div with results.
The new div contains a new set of links with new parameters.
The external div is loaded underneath the main pages first div.
Process can then be repeated creating a chain of divs under each other.
The last div in the chain will then direct to a new page collating all the previously used querystrings.
I can handle all of the PHP work with populating the divs on the main and external pages.
It's the JQuery and AJAX part i'm struggling with.
$(document).ready(function(){
var sections = $('a[id^=link_]'); // Link that passes parameter to external page
var content = $('div[id^=content_]'); // Where external div is loaded to
sections.click(function(){
//load selected section
switch(this.id){
case "div01":
content.load("external.php?param=1 #section_div01");
break;
case "div02":
content.load("external.php?param=2 #section_div02");
break;
}
});
The problem I am having is getting JQuery to pass the dynamically generated parameters to the external page and then retrieve the new div.
I can currently only do this with static links (As above).
I'm not sure if you've solved this already, but I'm surprised no one's mentioned to use the ajax() function.
This would allow you to define the request type as GET:
function loadContent(id) {
$.ajax({
type: "GET",
url: "external.php",
dataType: 'html',
data: {param: id},
success: function(html){
$("#container").html(html);
},
error: function(){
},
complete: function(){
}
});
}
Just call this function instead of using load. Obviously you'll have to tinker with the code (mainly what goes in the success function) a little, but this should give you a good starting point.
You can use the optional data argument to pass parameters to the GET request. Read the documentation. This is far better than building the URL yourself. You can of course add dynamic generated data to the parameters list.
function loadDiv(evt)
{
// these params will be accessible in php-script as $_POST['varname'];
var params = {name:'myDiv', var1:123, var2:'qwer'};
$.post('http://host/divscript.php', params, onLoadDiv);
}
function onLoadDiv(data)
{
$('#myContainer').html(data);
}
$(document).ready(function() {
$('#divButton').click(loadDiv);
});
In this example server-side script should return inner content of your div. Sure you can return XML-serialized data or JS to eval etc... it depends on task. The example is simplified, so extend it to fit your needs.
This tutorial on loading AJAX content is good:
http://net.tutsplus.com/tutorials/javascript-ajax/5-ways-to-make-ajax-calls-with-jquery/
Especially the part explaining how to read the results with Firebug.
Use this :
function GetDiv(id) {
$.ajax({
type: "GET",
url: "external.php"
dataType: 'html',
data:id,
success: function(html){
$("#container").append(html);
},
});
}
var params = {
param: 1,
otherParam: 2
};
content.load("external.php #section_div01", params);
will load "external.php?param=1&otherParam=2"

Categories