I am trying to create a proof of concept webpage that changes text in response to a button press using an MVC pattern (or at least as I understand it), and Ajax to avoid reloading the page. (I would like to implement Ajax in a larger MVC program I am working on but thought I would try to get it to work small-scale first). From playing around with examples here and here:
https://www.sitepoint.com/the-mvc-pattern-and-php-1/ http://www.w3schools.com/php/php_ajax_php.asp
I have the program working with each component individually (it works with the MVC pattern if I don't mind reloading the page to update the text, or it works without reloading the page if I don't mind essentially scrapping the MVC pattern). However, I'm trying to get both to work at once. I have combined the two examples so that the view uses Ajax to call the appropriate controller function, which successfully modifies the model (I'm sure this part works from debugging the program). However, when I try to refresh the content of the page using the output function of the view, nothing happens without reloading the page.
Here is my code so far:
<html>
<head>
<meta charset="UTF-8">
<!--ajax attempt-->
<script>
function callTextChange ()
{
var xmlhttp = new XMLHttpRequest();
//if uncommented, this changes the text, but it doesn't fit with my MVC pattern
/*xmlhttp.onreadystatechange = function()
{
if (this.readyState == 4 && this.status == 200)
{
document.getElementById("text").innerHTML = "changed with purely Ajax, without using MVC";
}
};*/
xmlhttp.open("GET", "index.php?action=changeText", true);
xmlhttp.send();
}
</script>
</head>
<body>
<?php
class Model
{
public $text;
public function __construct()
{
$this->text = 'default';
}
function changeText ()
{
$this->text = 'changed';
}
}
class View
{
private $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function output()
{
//regular MVC method using button as a link
//return $this->model->text.'<a href="?action=changeText"><button>change text</button></a>';
//attempted ajax method using button on click attribute to make an Ajax call
return '<p id="text">'.$this->model->text.'</p>'.'<button onclick="callTextChange()">change text</button>';
}
}
class Controller
{
private $model;
public function __construct(Model $model)
{
$this->model = $model;
}
function changeText()
{
$this->model->changeText();
}
}
$model = new Model();
$controller = new Controller($model);
$view = new View($model);
if (isset($_GET['action']))
{
$controller->{$_GET['action']}();
}
echo $view->output();
?>
</body>
Any idea how to do what I'm trying to do? Is this even possible?
Help would be much appreciated
EDIT: According to the suggestions in the comments below, I switched to trying to call Ajax through Jquery instead of purely JavaScript. I removed the onclick event from the button, and replaced the script tags in the head with the following:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$(document).ready(function()
{
$("button").click(function()
{
//if uncommented, this changes the text, but it doesn't fit with my MVC pattern
//$("#text").replaceWith("text changed without MVC framework");
//not sure how to call controller method from here
});
});
</script>
It certainly seems like jquery is simpler to work with, but unfortunately I still don't know how to solve my underlying problem. In fact, I'm also not sure how to replicate the
xmlhttp.open("GET", "index.php?action=changeText", true);
xmlhttp.send();
lines from the original javascript using jquery.
Actually, I figured it out using jQuery as suggested in the comments. I added a div tag with the ID of "content" surrounding all the content, and replaced the script tags with:
<script>
$(document).ready(function()
{
$("button").click(function()
{
$("#content").load("index.php?action=changeText");
});
});
</script>
Works like a charm! Thanks for the suggestions.