# **Chapter 4: Page Events - Handling Browser Requests**
> **File Extension Reference:**
> - Gate Files: `*.gate.php` (e.g., `Index.gate.php`)
> - Front Files: `*.front` (e.g., `index_main.front`)
> - Master Files: `*.mast.php` (e.g., `default/master.mast.php`)
> - Front Places: `*.place.front` or `*.place.php`
---
## **4.1 Understanding Page Events**
Page Events are the methods in your Gate class that handle actual browser requests. Unlike lifecycle events which fire automatically, Page Events are triggered by URLs.
The URL pattern is:
```
gate-event-parameter.html
```
Examples:
- `index.html` → Gate: index, Event: new
- `product.html` → Gate: product, Event: new
- `product-view-5.html` → Gate: product, Event: view, Parameter: 5
- `user-edit-10.html` → Gate: user, Event: edit, Parameter: 10
## **4.2 Built-in Page Events**
SartajPhp provides several built-in Page Events for common scenarios:
### **page_new() - Default Page Load**
Triggered when browser simply loads a page (GET request).
```php
// URL: index.html
public function page_new()
{
// Display the main page
$this->setFrontFile($this->frtMain);
}
```
### **page_submit() - Form Submission**
Triggered when form is submitted (POST request). This is the main handler for form processing.
```php
// URL: index.html (when form with action POST is submitted)
public function page_submit()
{
// Get submitted values
$name = $this->Client->post("txtName");
$email = $this->Client->post("txtEmail");
// Get submitted Component values
$password = $this->frtMain->getComponent("txtpassword")->getValue();
// Process the data
// check any validation,sql or any other error set with setErr
if (!getCheckErr()) {
echo "Form submitted successfully!";
}
}
```
### **page_insert() - Insert New Record**
Auto-triggered AFTER `page_submit()` when no record ID exists (new record).
```php
public function page_submit()
{
// Check if validation passed
if (!getCheckErr()) {
// If no record ID = new record
// page_insert() will be called automatically
}
}
public function page_insert()
{
// Insert new record into database
$data = [
"name" => $this->Client->post("txtName"),
"email" => $this->Client->post("txtEmail")
];
$this->dbEngine->runSQL("users", $data);
echo "Record inserted!";
}
```
### **page_update() - Update Existing Record**
Auto-triggered AFTER `page_submit()` when record ID exists (update record).
```php
public function page_submit()
{
// Check if validation passed
if (!getCheckErr()) {
// If has record ID = update
// page_update() will be called automatically
}
}
public function page_update()
{
$recordId = $this->frtMain->form->getRecID();
// Update existing record
$data = [
"name" => $this->Client->post("txtName"),
"email" => $this->Client->post("txtEmail")
];
$sql = $this->dbEngine->updateSQL("users", $data, "WHERE id='$recordId'");
$this->dbEngine->executeQueryQuick($sql);
echo "Record updated!";
}
```
### **page_view() - View Single Record**
Triggered when viewing a specific record.
```php
// URL: user-view-5.html
public function page_view()
{
// $this->page->evtp contains "5"
$userId = (int)$this->page->evtp;
// Fetch user from database
$user = $this->getUser($userId);
// Display in FrontFile
$this->frtMain->getComponent("txtName")->fu_setValue($user["name"]);
$this->frtMain->getComponent("txtEmail")->fu_setValue($user["email"]);
$this->setFrontFile($this->frtMain);
}
```
### **page_delete() - Delete Record**
Triggered when deleting a record.
```php
// URL: user-delete-5.html
public function page_delete()
{
$userId = (int)$this->page->evtp;
// Delete from database
$this->dbEngine->executeQuery("DELETE FROM users WHERE id = $userId");
// Redirect to list
$this->page->forward(getGateURL("user"));
}
```
## **4.3 Custom Page Events**
Create your own events using the `page_event_*` naming pattern:
### **Basic Custom Event**
```php
// URL: product-search-laptop.html
public function page_event_search($evtp)
{
// $evtp = "laptop"
$results = $this->searchProducts($evtp);
$this->frtMain->getComponent("divResults")->setInnerHTML($results);
$this->setFrontFile($this->frtMain);
}
```
### **Multiple Parameter Custom Event**
```php
// URL: shop-filter-category-electronics-price-100-500.html
public function page_event_filter($evtp)
{
// $evtp = "category-electronics-price-100-500"
// Parse the parameter
$parts = explode('-', $evtp);
// $parts = ["category", "electronics", "price", "100", "500"]
$category = $parts[1]; // "electronics"
$minPrice = $parts[3]; // "100"
$maxPrice = $parts[4]; // "500"
$products = $this->filterProducts($category, $minPrice, $maxPrice);
$this->frtMain->getComponent("divProducts")->setInnerHTML($products);
$this->setFrontFile($this->frtMain);
}
```
### **AJAX Custom Event**
```php
// Called via AJAX: getAJAX('product', 'checkstock', '123')
public function page_event_checkstock($evtp)
{
// $evtp = "123" - product ID
$stock = $this->getProductStock($evtp);
// Return JSON response
$this->JSServer->addJSONReturnBlock([
"product_id" => $evtp,
"in_stock" => $stock > 0,
"quantity" => $stock
]);
}
```
## **4.4 Getting Request Data**
In your Page Events, access request data using `$this->Client`:
### **GET Parameters**
```php
public function page_new()
{
// From URL: product.html?sort=price&order=asc
$sort = $this->Client->request("sort"); // "price"
$order = $this->Client->request("order"); // "asc"
$products = $this->getProducts($sort, $order);
}
```
### **POST Parameters (Form Data)**
```php
public function page_submit()
{
// From form submission
$name = $this->Client->post("txtName"); // text field
$email = $this->Client->post("txtEmail"); // text field
$country = $this->Client->post("sltCountry"); // dropdown
$agree = $this->Client->post("chkAgree"); // checkbox
}
```
### **All Request Types**
```php
public function page_new()
{
// Get any parameter (GET or POST)
$value = $this->Client->request("param");
// Get Raw POST data without security, same as $_POST["json1"]
$rawData = $this->Client->post("json1", true);
// Check if parameter exists
if ($this->Client->isRequest("search")) {
// do search
}
}
```
## **4.5 Sending Responses**
### **HTML Response (Most Common)**
```php
public function page_new()
{
// Set FrontFile to render
$this->setFrontFile($this->frtMain);
}
```
### **JSON/AJAX Response**
```php
public function page_event_checkstock($evtp)
{
// Send JSON data
$this->JSServer->addJSONReturnBlock([
"success" => true,
"stock" => 50
]);
// Or update HTML element
$this->JSServer->addJSONHTMLBlock("divStatus", "In Stock!");
// Or execute JavaScript
$this->JSServer->addJSONJSBlock("$('#btnBuy').prop('disabled', false);");
}
```
### **Redirect Response**
```php
public function page_submit()
{
// After processing, redirect to another page
$this->page->forward(getGateURL("product"));
// Or redirect with event
$this->page->forward(getEventURL("view", $newId));
}
```
## **4.6 Complete Example - Blog Application**
Here's a complete Blog Gate showing various Page Events:
```php
<?php
// apps/Blog.gate.php
use Sphp\tools\BasicGate;
class Blog extends BasicGate
{
private $frtList;
private $frtPost;
private $frtEdit;
public function onstart()
{
// Allow guests to view, require login to create/edit
$this->getAuthenticate("GUEST,MEMBER,ADMIN");
// Create FrontFiles
$this->frtList = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_list.front");
$this->frtPost = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_post.front");
$this->frtEdit = new \Sphp\tools\FrontFile($this->mypath . "/fronts/blog_edit.front");
}
/**
* URL: blog.html
* Display list of blog posts
*/
public function page_new()
{
$this->dbEngine->connect();
$result = $this->dbEngine->executeQuery(
"SELECT * FROM posts ORDER BY created_at DESC LIMIT 10"
);
$html = "";
while ($post = $this->dbEngine->row_fetch_assoc($result)) {
$html .= "<h2>{$post['title']}</h2><p>{$post['excerpt']}</p>";
}
$this->dbEngine->disconnect();
$this->frtList->getComponent("divPosts")->setInnerHTML($html);
$this->setFrontFile($this->frtList);
}
/**
* URL: blog-view-5.html
* View single post
*/
public function page_view()
{
$postId = (int)$this->page->evtp;
$this->dbEngine->connect();
$result = $this->dbEngine->executeQuery(
"SELECT * FROM posts WHERE id = $postId"
);
$post = $this->dbEngine->row_fetch_assoc($result);
$this->dbEngine->disconnect();
if (!$post) {
$this->page->forward(getGateURL("blog"));
return;
}
$this->frtPost->getComponent("txtTitle")->fu_setValue($post['title']);
$this->frtPost->getComponent("txtContent")->fu_setValue($post['content']);
$this->setFrontFile($this->frtPost);
}
/**
* URL: blog-create.html
* Show create form (requires MEMBER or ADMIN)
*/
public function page_event_create($evtp)
{
if (!$this->page->isAuthenticate("MEMBER,ADMIN")) {
$this->page->forward(getGateURL("login"));
return;
}
$this->setFrontFile($this->frtEdit);
}
/**
* URL: blog.html (POST)
* Handle form submission - insert or update
*/
public function page_submit()
{
// Validation already done by Components
if (getCheckErr()) {
// Show form again with errors
$this->setFrontFile($this->frtEdit);
return;
}
// Check if insert or update
if ($this->frtEdit->form->getRecID() == "") {
// Will trigger page_insert() automatically
// But we can also handle here
$this->insertPost();
} else {
$this->updatePost();
}
// Redirect to list
$this->page->forward(getGateURL("blog"));
}
/**
* URL: blog-delete-5.html
* Delete a post
*/
public function page_event_delete($evtp)
{
// Require ADMIN
$this->getAuthenticate("ADMIN");
$postId = (int)$evtp;
$this->dbEngine->executeQuery("DELETE FROM posts WHERE id = $postId");
// Redirect back to list
$this->page->forward(getGateURL("blog"));
}
/**
* URL: blog-search-keyword.html
* Search posts
*/
public function page_event_search($evtp)
{
$keyword = $evtp; // "keyword"
$this->dbEngine->connect();
$result = $this->dbEngine->executeQuery(
"SELECT * FROM posts WHERE title LIKE '%$keyword%' OR content LIKE '%$keyword%'"
);
$html = "";
while ($post = $this->dbEngine->row_fetch_assoc($result)) {
$html .= "<h2>{$post['title']}</h2><p>Found in: {$post['excerpt']}</p>";
}
$this->dbEngine->disconnect();
$this->frtList->getComponent("divPosts")->setInnerHTML($html);
$this->setFrontFile($this->frtList);
}
// Helper methods
private function insertPost() { /* ... */ }
private function updatePost() { /* ... */ }
}
```
## **4.7 URL Mapping Reference**
| URL | Gate | Event | Parameter | Page Event Called | Parameter Access |
|-----|------|-------|-----------|-------------------|------------------|
| `index.html` | index | new | - | `page_new()` | `$this->page->evtp` |
| `blog.html` | blog | new | - | `page_new()` | `$this->page->evtp` |
| `blog.html` (POST) | blog | submit | - | `page_submit()` → `page_insert()`/`page_update()` | `$this->page->evtp` |
| `blog-view-5.html` | blog | view | 5 | `page_view()` | `$this->page->evtp` returns "5" |
| `blog-delete-5.html` | blog | delete | 5 | `page_event_delete($evtp)` | `$evtp = "5"` |
| `blog-search-php.html` | blog | search | php | `page_event_search($evtp)` | `$evtp = "php"` |
| `blog-create.html` | blog | create | - | `page_event_create($evtp)` | `$evtp = ""` |
**Note:** Built-in page events (`page_new`, `page_view`, `page_delete`, etc.) do NOT receive parameters directly in the method signature. Access parameters via `$this->page->evtp`. Custom events (`page_event_*`) DO receive `$evtp` as a parameter.
## **4.8 Chapter Summary**
1. **Page Events** handle browser requests mapped from URLs
2. **Built-in events**: `page_new()`, `page_submit()`, `page_insert()`, `page_update()`, `page_view()`, `page_delete()` - access parameter via `$this->page->evtp`
3. **Custom events**: Use `page_event_name($evtp)` pattern - parameter passed directly to method
4. **Get data**: `$this->Client->request()`, `$this->Client->post()`
5. **Send responses**: `setFrontFile()`, `JSServer` for AJAX, `page->forward()` for redirect
## **4.9 What's Next?**
In the next chapter, you'll learn about FrontFile Events - how to interact with your templates from within your Gate class.
---
*Next: Chapter 5 - FrontFile Events: Interacting with Templates*