Difference between revisions of "6CS028 Workshop - Ajax"

From mi-linux
Jump to navigationJump to search
 
(15 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
[[Main Page]] >> [[6CS028|Advanced Web Development]] >> [[6CS028 - Workbook|Workbook]] >> Week 04 - Ajax
 
[[Main Page]] >> [[6CS028|Advanced Web Development]] >> [[6CS028 - Workbook|Workbook]] >> Week 04 - Ajax
  
Today we are going to use Ajax to create a simple jQuery Live Search in Code Igniter:
+
'''Important''': this is a CodeIgniter example, but it is easily adaptable to Laravel.
  
* Step 1 – Create the data controller/view
+
== The JSON data ==
* Step 2 – Create the web page controller/view
 
  
'''Important''': we will be using Javascript, so remember to have your error console open at all times.
+
First, let's create a page that will output JSON data from our existing "news" database table, like this:
 
+
* https://mi-linux.wlv.ac.uk/~in9352/ci4/public/index.php/ajax/get/hello
== Include jQuery ==
 
 
 
Please note that we will be using the [http://jquery.com/ jQuery] library, so you need to include it in your <head> section. You can do this by adding the following <script> line to your templates/header.php file:
 
  
 +
Create a '''new''' controller called '''Ajax.php''', with the following code:
 
<pre>
 
<pre>
<html>
+
<?php
<head>
 
  <title><?php echo $title ?> - CodeIgniter Tutorial</title>
 
  <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
 
</head>
 
<body>
 
<h1>CodeIgniter Tutorial</h1>
 
</pre>
 
  
== Step 1 – Create the data controller/view ==
+
namespace App\Controllers;
  
First we need to create the page (i.e. model + controller + view) that will return the Ajax data.
+
use App\Models\NewsModel;
  
For now let's keep our controller simple:
+
class Ajax extends BaseController
 +
{
 +
public function get($slug = null)
 +
{
 +
$model = model(NewsModel::class);
 +
$data = $model->getNews($slug);
  
<pre>
+
print(json_encode($data));
<?php
+
}
 
+
// application/controller/Ajax.php
 
 
 
class Ajax extends CI_Controller
 
{
 
  public function getdata($param = '')
 
  {
 
      // Get data from db
 
      $data['ajaxdata'] = "Search result for $param";
 
 
 
      // Pass data to view
 
      $this->load->view('ajax/index', $data);
 
  }
 
 
}
 
}
 
</pre>
 
</pre>
 +
Note: it is very similar to our previous news controller. The function above selects a given news items from our model (as per before), but converts the data to JSON and simply prints it to the browser.
  
As you can see we are using dummy data. You'll have to add the model part yourselves (as per [http://www.codeigniter.com/user_guide/tutorial/news_section.html News section tutorial] on the Code Igniter website)
+
== The Ajax call ==
 
+
Next, we need to write some JavaScript that will "fetch" data from the URL above.
Note that we are NOT including the header and footer views, as our Ajax data will be embedded in an existing page (see later).
 
  
Our view is very simple:
+
In your '''existing overview.php''' view, make the following changes:
  
 +
Add a container paragraph (maybe right at the top for now), that will be used to display the data coming back from the request:
 
<pre>
 
<pre>
<!-- application/views/ajax/index.php-->
+
<p id="ajaxArticle"></p>
 
 
<p><?=$ajaxdata?></p>
 
 
</pre>
 
</pre>
  
It simply displays the data passed in by the controller.
+
Next, add a button for each article, that calls the JavaScript code, passing the current article's slug:
 
 
You should now be able to browse to your ajax controller:
 
*[http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/ajax/getdata/ http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/ajax/getdata/]
 
 
 
You can pass it a term to be searched in the URL:
 
*[http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/ajax/getdata/batman http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/ajax/getdata/batman]
 
 
 
Next we need to call this controller via an Ajax request from our search form (see step 2!)
 
 
 
== Step 2 – Create the web page controller/view ==
 
 
 
The "Search" controller is very simple, it simply loads our search page:
 
 
 
 
<pre>
 
<pre>
<?php
+
<p><button onclick="getData('<?= esc($news_item['slug'], 'url') ?>')">View article via Ajax</button></p>
 
 
// application/controller/search.php
 
 
 
class Search extends CI_Controller
 
{
 
  public function form()
 
  {
 
      $data['title'] = 'Ajax search';
 
 
 
      $this->load->view('templates/header', $data);
 
      $this->load->view('search/form');
 
      $this->load->view('templates/footer');
 
  }
 
}
 
 
</pre>
 
</pre>
 +
Note: the above should be inside the foreach loop, right after the existing "view article" link.
  
The view itself is more complicated:
+
Finally, add the JavaScript block at the bottom of the file:
 
 
 
<pre>
 
<pre>
<!-- application/views/search/form.php -->
 
 
<h2>Ajax search</h2>
 
 
 
<script>
 
<script>
 +
function getData(slug) {
 +
 +
// Fetch data
 +
fetch('https://mi-linux.wlv.ac.uk/~in9352/ci4/public/ajax/get/' + slug)
 +
 +
  // Convert response string to json object
 +
  .then(response => response.json())
 +
  .then(response => {
  
  // This is the jQuery Ajax call
+
// Copy one element of response to our HTML paragraph
  function doSearch()
+
document.getElementById("ajaxArticle").innerHTML = response.title + ": " + response.text;
  {
+
  })
      $.ajax({
+
  .catch(err => {
        type: "GET",
+
        url:"http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/ajax/getdata/" + $("#mysearch").val(),
+
// Display errors in console
        success:function(result){
+
console.log(err);
        $("#searchresults").html(result);
+
});
      }});
+
}
  }
 
 
 
 
</script>
 
</script>
 
<!-- Search box -->
 
<input type="search" id="mysearch" placeholder="Search">
 
 
<!-- Search button -->
 
<input type="button" id="searchbutton" value="Search" onClick="doSearch();">
 
 
<!-- The DIV that will contain the search results -->
 
<div id="searchresults"></div>
 
 
</pre>
 
</pre>
 +
Notes:
 +
* you will have to change the URL in the fetch statement, to match yours.
 +
* the document.getElementById("ajaxArticle").innerHTML allows you to write to the HTML element specified earlier. You could have more than one!
 +
* you might eventually wish to move this to an external JS file, as it's more efficient and tidy.
  
Some pointers:
+
Here is mine:
* First, note that the search button calls a function doSearch() when clicked.
+
* [https://mi-linux.wlv.ac.uk/~in9352/ci4/public/index.php/newsajax https://mi-linux.wlv.ac.uk/~in9352/ci4/public/index.php/newsajax]
* The function doSearch() does the jQuery Ajax call. It calls the URL tested at the end of step 1, passing the value typed in the "mysearch" text box as a parameter.
+
* Try pressing the various "View article via Ajax" buttons, and see how the article is displayed at the top.
* If successful, the result is simply inserted in the "searchresults" DIV.
+
* Look in the developer tools / network tab, and note how each button triggers an HTTP request behind the scenes! Look at their preview.
 
 
Improvements:
 
* The doSearch function is included in the file for clarity's sake, but should really be in an external .js file (see notes for [[6CC001_Workshop_-_week_02b#Link_to_external_CSS.2C_JS.2C_Images_etc|week 2]])
 
* You should try using the base_url() helper instead of hard-coding your full URL (again see note for [[6CC001_Workshop_-_week_02b#Link_to_external_CSS.2C_JS.2C_Images_etc|week 2]])
 
 
 
Here is my finished page:
 
*[http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/search/form/ http://mi-linux.wlv.ac.uk/~in9352/codeigniter3/index.php/search/form/]
 
 
 
For more information on the jQuery Ajax method, please see documentation (the examples right at the bottom are especially useful):
 
*[https://api.jquery.com/jQuery.ajax/ https://api.jquery.com/jQuery.ajax/]
 

Latest revision as of 17:12, 9 March 2023

Main Page >> Advanced Web Development >> Workbook >> Week 04 - Ajax

Important: this is a CodeIgniter example, but it is easily adaptable to Laravel.

The JSON data

First, let's create a page that will output JSON data from our existing "news" database table, like this:

Create a new controller called Ajax.php, with the following code:

<?php

namespace App\Controllers;

use App\Models\NewsModel;

class Ajax extends BaseController
{
	public function get($slug = null)
	{
		$model = model(NewsModel::class);
		$data = $model->getNews($slug);

		print(json_encode($data));
	}
	
}

Note: it is very similar to our previous news controller. The function above selects a given news items from our model (as per before), but converts the data to JSON and simply prints it to the browser.

The Ajax call

Next, we need to write some JavaScript that will "fetch" data from the URL above.

In your existing overview.php view, make the following changes:

Add a container paragraph (maybe right at the top for now), that will be used to display the data coming back from the request:

<p id="ajaxArticle"></p>

Next, add a button for each article, that calls the JavaScript code, passing the current article's slug:

<p><button onclick="getData('<?= esc($news_item['slug'], 'url') ?>')">View article via Ajax</button></p>

Note: the above should be inside the foreach loop, right after the existing "view article" link.

Finally, add the JavaScript block at the bottom of the file:

<script>
	function getData(slug) {
		
		// Fetch data
		fetch('https://mi-linux.wlv.ac.uk/~in9352/ci4/public/ajax/get/' + slug)
			
		  // Convert response string to json object
		  .then(response => response.json())
		  .then(response => {

			// Copy one element of response to our HTML paragraph
			document.getElementById("ajaxArticle").innerHTML = response.title + ": " + response.text;
		  })
		  .catch(err => {
			
			// Display errors in console
			console.log(err);
		});
	}
</script>

Notes:

  • you will have to change the URL in the fetch statement, to match yours.
  • the document.getElementById("ajaxArticle").innerHTML allows you to write to the HTML element specified earlier. You could have more than one!
  • you might eventually wish to move this to an external JS file, as it's more efficient and tidy.

Here is mine: