I'm just trying to write my first ajax enabled page. Needless to say, I've run into a problem. And I think it reveals a fundamental misunderstanding of how ajax is supposed to work.
Here's a description of what i'm trying to accomplish.
I have a page with a table containing records from my database. When the user clicks on my refresh button, i want to requery the database for all records and display them without refreshing the page.
Here's my controller:
class Dashboard extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->helper('date');
$this->load->helper('url');
}
public function index()
{
$this->load->model('locations_model');
$emess = '';
$data['clienthistory'] = $this->locations_model->get_locations();
$data['main_content'] = 'dashboard';
$this->load->view('includes/template', $data);
$this->output->enable_profiler(TRUE);
}
public function index2()
{
echo('inside the getlatest method');
$this->load->model('locations_model');
$data['clienthistory'] = $this->locations_model->get_locations();
//build HTML table to send back to view
$data['latestdashboardHTML']= "<table class='table table-bordered table-striped'><thead>";
$data['latestdashboardHTML']=$data['latestdashboardHTML'] & "<tr><th>IP</th><th>Name</th><th>Last Updated</th></tr></thead><tbody>" ;
foreach ($data['clienthistory'] as $histitem)
{
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "<tr>";
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "<td>" & $histitem['network'] & "</td>";
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "<td>" & $histitem['name'] & "</td>";
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "<td>" & $histitem['lastupdated'] & "</td>";
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "</tr>";
}
$data['latestdashboardHTML'] = $data['latestdashboardHTML'] & "</tbody></table>";
$data['main_content'] = 'dashboard';
echo ($data['latestdashboardHTML']) ;
$this->load->view($data['main_content'] );
}
}
And here's the code in my view:
<h2>Client Dashboard</h2>
<br/><p>
<?php echo form_open('Dashboard/index');
echo form_submit('submit', 'Refresh Data', 'id="submit" class="btn-primary"');
?>
</p>
<div class="row-fluid">
<div class="span12" id="ajaxcontainer">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>IP</th>
<th>Name</th>
<th>Last Updated</th>
</tr>
</thead>
<tbody>
<?php foreach ($clienthistory as $histitem): ?>
<tr>
<td><?php echo $histitem['network'] ?></td>
<td><?php echo $histitem['name'] ?></td>
<td><?php echo $histitem['lastupdated'] ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
</div>
</div><!--/row-->
<?php
echo form_close();
?>
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="../assets/js/jquery.js"></script>
<script src="../assets/js/bs-transition.js"></script>
<script src="../assets/js/bs-alert.js"></script>
<script src="../assets/js/bs-modal.js"></script>
<script src="../assets/js/bs-dropdown.js"></script>
<script src="../assets/js/bs-scrollspy.js"></script>
<script src="../assets/js/bs-tab.js"></script>
<script src="../assets/js/bs-tooltip.js"></script>
<script src="../assets/js/bs-popover.js"></script>
<script src="../assets/js/bs-button.js"></script>
<script src="../assets/js/bs-collapse.js"></script>
<script src="../assets/js/bs-carousel.js"></script>
<script src="../assets/js/bs-typeahead.js"></script>
<script type="text/javascript">
$('#submit').click(function() {
alert('here');
$.ajax({
url:"<?php echo site_url('Dashboard/index2'); ?>",
type: 'POST',
success: function(msg) {
alert(msg);
$('#ajaxcontainer').replaceWith(msg);
}
});
return false;
});
</script>
Problem:
the first time through, the page loads properly. all records show up with the correct values. But when i try the refresh button, the javascript executes, calls the index2 method.. but then it fails in the view on line 22 - which is where I'm trying to loop through the clienthistory array.
The error message is: Undefined variable: clienthistory.
SO here's my question. I thought the way ajax worked was that it only updated a section of the page. So I guess I don't understand why it's "redo-ing" this part of the view.
Can someone explain what I'm doing wrong, and more importantly, if my understanding of ajax is correct. I'd also prefer it if i could combine the two methods into one... i tried but had some problems so I ended up just copying index() to index2() and just working with that.
The other behavior that I'm noticing is that the title "Client Dashboard" as well as the button is showing up twice when execute the ajax method.
Thanks.
I found my problem. In index2() i'm loading the view again.
i shouldn't reload the view. i just need to pass the html string to the caller.
this in part resolves my problem.
so specifically in my controller i replaced:
$this->load->view($data['main_content'] );
with
return $htmlstring;
where $htmlstring contains the same string as $data['latestdashboardHTML']
the other problem is that i needed to specify the dataType that i was expected back from the controller.
so i added the following line to my .ajax function:
dataType: 'html'
Finally, I read online somewhere that it's not a good idea to have the controller create any HTML. this is supposed to be the job of the view.
i guess i will try to pass an array from controller to view. and then have the jquery code recreate the contents of my div.
thanks
Related
im a newbie in CI, i have some question
i have controller like below
public function show_admin()
{
$data['data_admin'] = $this->M_Admin->get_admin();
$data['page'] = 'show_admin';
$this->load->view('admin/template',$data);
}
and then i have template in my view folder, like below
<body>
<div id="wrapper">
<div id="header">
<?php
$data['session'] = $this->session->all_userdata();
$this->load->view('admin/header',$data);?>
<div id="content">
<?php
$this->load->view('admin/'.$page);?>
</div>
<div id="footer">
<?php $this->load->view('admin/footer');?>
</div>
</div>
</body>
and the show_admin (view file) like below
<div id="isi_content">
<span><img src="<?php echo base_url();?>assets/admin/images/add.png">Tambah</span>
<table class="table table-hover table-bordered">
<tr>
<th>No</th>
<th>Nama</th>
<th>Username</th>
<th>Login Terakhir</th>
<th>Aksi</th>
</tr>
<?php
$no=1;
foreach($data_admin as $admin){
$id = $admin['id_admin'];
$url = site_url('admin/C_Admin/c_delete_admin');
echo
'<tr>
<td>'.$no.'</td>
<td>'.$admin['nama_admin'].'</td>
<td>'.$admin['username'].'</td>
<td>'.$admin['tgl_last_visit'].'</td>
<td class=aksi><a href='.site_url('admin/C_Admin/c_edit_admin/'.$admin['id_admin'].'').'><img src='.base_url().'assets/admin/images/edit.png></a>
<img src='.base_url().'assets/admin/images/delete.png></td>
</tr>';
$no++;
}
?>
</table>
</div>
and that codes run nicely,
is that normal in codeIgniter use $this in view file??
im confuse about this..
thanks for your answer...
No, you should not use that session variable nor load any views on another view. This all should be done in the Controller. What you can do is break your code in pieces, like the header in its one view file and the footer in another view file, then you can load them in your controller like so:
public function show_admin()
{
$data['data_admin'] = $this->M_Admin->get_admin();
$data['page'] = 'show_admin';
$head_data['session'] = $this->session->all_userdata();
$this->load->view('header', $head_data);
$this->load->view('admin/template',$data);
$this->load->view('footer');
}
i have this code.
function index(){
$this->load->helper('url');
$this->load->view('EIM/home');
$this->loadGraphs();
}
but it executes loadGraphs first. I really have no idea why. Please help me. I'm having a hard time fixing my codes. thanks :)
here is my loadGraphs function:
`function loadGraphs(){
$this->load->helper('url');
$ctr=0;
$base_url = base_url();
$xml=new DOMDocument;
$xml->load("".$base_url."assets/EIM/xml/defaultChart.xml");
$module_names=$xml->getElementsByTagName("name");
$len_modules=$module_names->length;
$ctr_module=0;
while($ctr_moduleitem($ctr_module)->getElementsByTagName("report");
$len_reports=$reports->length;
$ctr_report=0;
while($ctr_reportitem($ctr_module)->getAttribute("value");
$title=$reports->item($ctr_report)->getElementsByTagName("title")->item(0)->nodeValue;
$dashboard_selected=$reports->item($ctr_report)->getAttribute("id");
if($dashboard_selected=="dashboard"){
echo "
$title
$module";
?>
var parameters=eval(getArray($title,$module));?>)
item($ctr_report)->getElementsByTagName("charts")->item(0)->getAttribute("value");
$defaultChart=$reports->item($ctr_report)->getElementsByTagName("charts")->item(0)->getAttribute("value");
echo "$defaultChart";
$charts=$reports->item($ctr_report)->getElementsByTagName("charts")->item(0)->getElementsByTagName("chart");
$len_charts=$charts->length;
$ctr_chart=0;
while($ctr_chartitem($ctr_chart)->nodeValue;
echo "
";
$ctr_chart++;
}
echo"
<input type='submit' value='Set Chart as Default' onClick='set_default_chart('chart$ctr',$ctr_module,$ctr_report)'/>
";
echo "
<button class='btn btn-box-right' data-toggle='collapse' data-target='#container".$ctr."'>
<i class='icon-reorder'></i>
</button>
</div>
<div class='box-content box-list collapse in'>
<div id='container".$ctr."' style='min-width: 310px; height: 400px; margin: 0 auto'></div>
</div>
</div>
</div>
";
$ctr++;
}
$ctr_report++;
}
$ctr_module++;
}
echo "<label id='containers' value='$ctr'></label></div>";
}`
its kinda long but what it does is that it makes the containers ready and my java script is there to load and completely show the graphs. its in the document.ready function. it is possible that it prioritizes the codes that have function before loading the view?
You could try loading that results of the loadGraphs() function via AJAX from the view once it loads? So basically remove that call after the $this->load->view('EIM/home'), and in that same view, in documentReady, use the simple jQuery.Get function to fetch that code you need in the view. That will load if after the view 100%.
http://api.jquery.com/jquery.get/
Not sure if your flow is the best approach, but this should work.
Hope it helps! :)
Hi everyone thank you for taking time to look at my question.
I have tried to run view (site_nav, site_header and site_footer) together only and it worked fine.
When I tried to run view (view_home) and the models it also worked fine.
However when I run all the views and models together, the view (site_nav, site_header and site_footer) does not work.
Could anyone please help?
public function home(){
$this->load->model("model_cms_home");
$data["results"] = $this->model_cms_home->getData("cms_home");
$this->load->view("site_nav");
$this->load->view("site_header");
$this->load->view("view_home", $data);
$this->load->view("site_footer");
}
VIEW("view_home")
<div id="home_hat1"> <img src="<?php echo base_url(); ?>pics/home_hat1.jpg"> </div>
<div id="content">
<div id="dinner">
<div class="home_title">
<?php
$query = $this->db->query("SELECT `title` , `text1` FROM `cms_home` WHERE `ID` =1");
if ($query->num_rows() > 0){
$row = $query->row_array();
echo $row['title'];
}
?>
</div>
<div class="home_content">
<?php
$query = $this->db->query("SELECT `title` , `text1` FROM `cms_home` WHERE `ID` =1");
if ($query->num_rows() > 0){
$row = $query->row_array();
echo $row['text1'];
}
?>
</div>
</div>
You cannot call multiple view in one controller function.
This can be done into view.
I suggest you that you should first create a templete and in that template call your views like this
templete.php
<html>
<head>
<body>
$this->load->view("site_nav");
$this->load->view("site_header");
<?php echo $content; ?>
$this->load->view("site_footer");
</body>
</head>
</html>
MY suggestion is to call other page in view_home using include();. You cant see other pages as the last page will be called according to your code. If you put an alert in each page you will know it has actually called all the pages.
I've created simple ajax voting plugin, it works fine.. till i start to use joomla methods in conf.php file. The file below is conf.php with simple php db query, if i put here for example $dbb = JRequest::getDbo(); it stops working .. or any other joomla methods. I can't get it what is wrong here?
$.ajax
({
type: "POST",
url: "plugins/system/ratingx/conf.php",
data: dataString,
cache: false,
success: function(html)
{
conf.php:
<?php
define( '_JEXEC', 1) or die;
defined( '_JEXEC' ) or die;
$mysql_hostname = "localhost";
$mysql_user = "px";
$mysql_password = "px";
$mysql_database = "jum";
$bd = mysql_connect($mysql_hostname, $mysql_user, $mysql_password)
or die("Opps some thing went wrong");
mysql_select_db($mysql_database, $bd) or die("Opps some thing went wrong");
if($_POST['id'])
{
$id=mysql_real_escape_string($_POST['id']);
$name=mysql_real_escape_string($_POST['name']);
mysql_query("update messages set $name=$name+1 where id='$id'");
$result=mysql_query("select up,down from messages where id='$id'");
$row=mysql_fetch_array($result);
$up_value=$row['up'];
$down_value=$row['down'];
$total=$up_value+$down_value;
$up_per=($up_value*100)/$total;
$down_per=($down_value*100)/$total;
?>
<div style="margin-bottom:10px">
<b>Ratings for this blog</b> ( <?php echo $total; ?> total)
</div>
<table width="700px">
<tr>
<td width="30px"></td>
<td width="60px"><?php echo $up_value; ?></td>
<td width="600px"><div id="greebar" style="width:<?php echo $up_per; ?>%"></div></td>
</tr>
<tr>
<td width="30px"></td>
<td width="60px"><?php echo $down_value; ?></td>
<td width="600px"><div id="redbar" style="width:<?php echo $down_per; ?>%"></div></td>
</tr>
</table>
<?php
}
Not sure what version of Joomla! you're using but...
The problem is that you're calling a file that exists "outside" the Joomla! framework, just because you've defined _JEXEC doesn't mean the framework is loaded.
To be able to use JRequest or even JFactory::getDBO() you will also need to initialise Joomla!'s front-end app and load the framework/classes required. Doing that can potentially leave your site with a security issue.
I would suggest you create a basic component with an appropriate AJAX/RAW controller that your plugin can call through the default Joomla! path (i.e. index.php).
If you do want to by pass the Joomla! application then look at the main index.php for your version of Joomla to give you a guide has to how to load the applications framework.
p.s. JRequest::getDBO() isn't valid, getDBO() is not a method of JRequest (any version)
I have a very strange problem when I using ajax in symfony 1.4. I've used the jobeet example (day 18) but it doesn't work
This is my indexSuccess.php
<script type="text/javascript" >
$(document).ready(function(){
$('#buscador').keyup(function(key)
{
if (this.value.length >= 3 || this.value == '')
{
$('#per').load( $(this).parents('form').attr('action'),
{ query: this.value + '*' });
}
});
});
</script>
<h1>Lista de personas</h1>
<p>Busque o cree registros de personas en el sistema (Estudiantes, funcionarios, docentes).</p>
<form action="<?php echo url_for('personas/index')?>">
<table>
<tr>
<td><input type="text" name="buscar" id="buscador"/></td>
<td><img src="/images/iconos/Search.png"/></td>
</tr>
</table>
</form>
<p style="font-size: 11px;color: gray;">Digite un nombre, apellido o número de identificación para buscar</p>
<div class="per" id="per">
<?php echo include_partial('personas/buscaPersonas',array('personass'=>$personass)); ?>
</div>
The jquery script detects characters in the input, when I write 3 or more characters it should load the div with id='per'. Here is my personasAction.class.php
public function executeIndex(sfWebRequest $request)
{
$this->personass = array();
if($request->isXmlHttpRequest())
{
$this->personass = $this->getRoute()->getObjects();
return $this->renderPartial('personas/buscaPersonas', array('personass'=> $personass));
}
}
When I load the page I dont want to see any result. So, when I do a ajax call, I should reload the partial "_buscaPersonas.php" with all results (just for try), but I load the _form.php partial.
This is my partial:
<table>
<?php foreach($personass as $personas): ?>
<tr>
<td colspan="5" class="tituloTD"><?php echo $personas->getNombre(); ?></td>
</tr>
<tr>
<th>Numero identificación: </th><td><?php echo $personas->getNumeroid() ?></td>
<th>Email: </th><td><?php echo $personas->getEmail(); ?></td>
<td> <img src="/images/iconos/editar.png"/></td>
</tr>
<?php endforeach; ?>
</table>
I've trying to find where is the problem but I not get it. When I use the button for normal search it works, load the correct partial but whit ajax load other partial.
Please somebody knows what is my error.
thanks
I think this due to the path of your load ajax function:
$('#per').load( $(this).parents('form').attr('action'),
{ query: this.value + '*' });
$(this).parents('form').attr('action') is certainly a wrong value.
Try this :
url_for('personas/index')
Finally I find the error. I dont know what happen but if I send data with the load function I have and error. So I had to send the data using the url, and is works:)
if (this.value.length >= 3 || this.value == '')
{
$('#per').load( "<?php echo url_for('personas/index')?>"+"?query="+this.value);
}