I'm trying out a more maintainable way to structure my code as learnt by some tutorials at nettuts+.
I've succeeded in making my header and footer files separate from the main content of each page so that they are loaded along with each different page, thus making it easier to manage changes to these two files.
I currently want to add some jQuery code to my footer, for only one page. This is where I've hit a wall in thinking. How can I allow this jQuery code to be present in my footer for only one page, and not all pages? Could someone please explain?
I was thinking of doing something like:
<?php if($title = "The jQuery Page"){?>
<script>
jquery code here....
</script>
<?php } ?>
But I think that is considered messy, as you are using one language to set off another.
Edit: Here's the requested code:
In my Controller I call the views:
$data['title'] = "The jQuery Page";
$this->load->view('header', $data);
$this->load->view('cool_page');
$this->load->view('footer');
Then in my footer I want to load a specific script in only this one pages footer:
<script src="<?php echo base_url();?>js/jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function() {
/*cool jquery stuff*/
});
</script>
Try to load a view into the main view
/application/controllers/test.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Test extends CI_Controller {
public function index() {
$data = array(
'title' => "The jQuery Page",
'script' => TRUE // if you omit or comment this variable the 'views/script.php' is not loaded
);
$this->load->view('test', $data);
}
}
/application/views/test.php
<html>
<head>
<title><?php echo $title;?></title>
</head>
<body>
<?php if (isset($script)) { $this->load->view('script'); } ?>
</body>
</html>
/application/views/script.php
<script>
jquery code here....
</script>
You could specify JS to include as part of the data passed to the view:
CONTROLLER1
$this->data['js'][] = 'alert(\'Hi\');';
$this->data['js'][] = 'alert(\'Hey\');';
$this->load->view('footer', $this->data);
CONTROLLER2
$this->data['js'][] = 'alert(\'Yo\');';
$this->data['js'][] = 'alert(\'Sup\');';
$this->load->view('footer', $this->data);
Footer VIEW
if(isset($js) && is_array($js) && count($js) > 0){
echo '<script>';
foreach($js as $key=>$value){
$value;
}
echo '</script>';
}
I don't think there is a way around making a conditional 'if' statement around the script, so I used the suggested solution in my question.
Check the title to see if it is the desired page:
<?php if($title = "Photo Albums - Hands of Humanity"):?>
Then add the script to the DOM if it is so:
<script>
$(document).ready(function() {
//jquery stuff
});
</script>
<?php endif;?>
If there are other ways which are better for maintainability, I would be happy to hear them
Related
I write the below code to a footer.php file. This works but is applied for all the pages. I want to apply page scroll in one page only.
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('body').animate({scrollTop: +400}, 1000);
});
</script>
Can any one help me on how to do it.
Thanks
Add a contidional statemnent on the footer.php file to only execute the jquery code if it is in only in the current page you wish for.
something like this example below
<?php
global $post;
$target_pageid = 7654;
$current_pageid = $post->ID;
if (current_pageid == $target_pageid){
?>
jQuery(document).ready(function() {
jQuery('body').animate({scrollTop: +400}, 1000);
});
<?php
}
?>
I have an issue with PHP. I have an index file like this:
<?php session_start(); ?>
<!doctype html>
<html lang="en">
<head>
...
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<?php
include $_SERVER['DOCUMENT_ROOT'] . '/config.php';
function __autoload($class_name) {
include $_SERVER['DOCUMENT_ROOT'] . '/classes/' . $class_name . '.php';
}
include '../shared/navigation-bar.php';
$user = new Users($db);
print_r($user);
//this prints fyi - so all is well here
?>
<div class="fill grey-bg">
<?php include(dirname(__FILE__) . '/sidebar.php');?>
<div id="content" class="col-md-10 white-bg">
</div>
</div>
<script src="../shared/js/bootstrap.js"></script>
<script src="./js/app.js"></script>
</body>
</html>
All is well here. Now I have a sidebar included, which does this:
<table class="table">
<tr>
<td>
Manage Users
</td>
</tr>
</table>
Which when clicked uses an ajax call to load a new page:
$("#manageUsers").click(function(){
$("#content").load('pages/manageUsers.php');
});
Ok so this loads the new page - manageUsers.php
<h3>List Users</h3>
<?php print_r( $user ) ;?>
Now, problem here as you can probably guess is that the $user doesn't print out in the loaded in page. I'm guessing it's a scope issue. I define it first time when the index page loads, and then when I load in the document with the click it can't pass the original $user variable through to the new page because PHP is serverside and has already loaded?
The question is, what is the way around this - I'm trying to code in an OOP manner, hence loading the classes and creating the object on the index for use in the other pages.
Problem is if I can't do that, I then have to re-include the classes and create a new object on each loaded in page. This seems frightfully inefficient. Is there a way round this?
If I have to use ajax, is there a smart way to do this via ajax? Or should I just drop the OOP plan and write a function list, including it and a new pdo instance in every loaded in page?
You cannot access php variables after the page is executed. So you need to store the data in javascript and send it to the pages using GET/POST where you want to use them.
Add the below code after "print_r($user);"
<script>
var users_list = <?php echo json_encode($user); ?>;
</script>
Change your javascript code as below
$(document).on('click', '#manageUsers', function(){
$("#content").load('pages/manageUsers.php', {"users": users_list});
return false;
});
Change manageUsers.php code to
<h3>List Users</h3>
<?php print_r($_POST['users']); ?>
If you are unaware of usage of JSON .. JSON is a simple way to interchange/maintain/access data ...
$users = array();
$users[1] = array('name' => 'mr.mad', 'age' => '22');
$users[2] = array('name' => 'miss.mad', 'age' => '22');
echo json_encode($users);
the above code will echo
{
"1": {
"name": "mr.mad",
"age": "22"
},
"2": {
"name": "miss.mad",
"age": "22"
}
}
Make sure even your users array is a structured array like above
Don't use 'click' event directly .. go with "$(document).on('click')" as you are thinking of an ajax application. With this you can use this handler even on newly added dom objects too ..
AJAX is the good way and you are doing it correct with your thought process .. go on ..
Is it possible to trigger a PHP function by just clicking a link? Or should I stick with the form submit method? If clicking the link will work, where should the link refer to?
Here is a sample code:
<?php
session_start();
function listMe($username){
$username = mysql_real_escape_string($username);
$query = mysql_query("INSERT INTO List (Usernames) VALUES ('$username')") or die(mysql_error());
}
?>
<html>
<head>
<title>SAMPLE</title>
</head>
<body>
Add my username to the list
<?php
listMe($_SESSION['Username']);
?>
</body>
</html>
Maybe someone can point me in the right direction. Thanks!
You can do this by means of loading the entire page over again by the use of form submission, or by loading specific page contents directly into the page without needing to go from page to page. The second method is called "AJAX" (Asynchoronous Javascript and XML). Here are two examples, one of each specified.
Form submission approach
form.php
<?php
function get_users(){
}
if(isset($_GET['get_users']))
{
get_users();
}
?>
...
<form method="get">
<input type="hidden" name="get_users">
<input type="submit">
</form>
AJAX approach
ajax_file.php
<?php
function call_me(){
// your php code
}
call_me();
?>
form.html
<html>
<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{
xmlhttp = new XMLHttpRequest();
}
else
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
// do something if the page loaded successfully
}
}
xmlhttp.open("GET","ajax_file.php",true);
xmlhttp.send();
}
</script>
</head>
<body>
click to call function
</body>
</html>
HTML
list me
PHP
<?php
if (isset($_GET['list_me'])) listMe();
(EDIT although this works, it's a bad idea as it is. One should never read from $_GET without sanitising it first)
You can pass it as a query parameter of the link.
http://example.com/?command=listMe&username=tom
However that way everybody will be able to run the function by loading that URL
List me
and in the PHP
<?php
if( isset($_GET['list_me']) && isset($_SESSION['Username'] ) ){
listMe( $_SESSION['Username'] );
}
?>
To trigger a function on link click with php the only way I know would be to append a param in the url of the link and then listen for that
Add my username to the list
Then check for link
if (isset($_GET['function'])){
runFunction();
}
This is because php is a server side technology if you want to fire something without refreshing the page you would need to look at something like javascript
I found this code in a plugin, they have user a foreach look to trigger the action:
$actions = unset($meta[$key]);
foreach ( $actions as $action => $value ) {
echo '<li>' . '<i class="fa fa-times"></i></li>';
}
In order to best organize JavaScript AJAX handlers in a web app, I'm taking the approach of using an AJAX controller to process the AJAX requests. Simple enough.
The second half of this decision is the result of the AJAX request, and specifically how, where, and if the JSON/data returned is added to DOM elements. Is it a good (or at least non-foolish idea) to put the JavaScript DOM manipulation logic within the view?
I normally handle AJAX and all JavaScript execution within a static .js file. This way, I can handle a request whether it's ajax or not, and I can keep my logic in one place. So, I might have the following setup:
// application/controllers/Mycontroller.php
class Mycontroller extends CI_Controller {
function index()
{
$content['text'] = "Lorem ipsum dolor sit amet...";
$data['content'] = $this->load->view('embeds/home_page', $content, TRUE);
$this->load->view('public_template', $data);
}
}
// embeds/home_page.php
<div id="container">
<h1>Home Page</h1>
<p><?php echo $text; ?></p>
Change Content
</div>
// public_template.php
<html>
<head>
<title>Home Page</title>
<script src="/jquery.js"></script>
<script src="/myscript.js"></script>
</head>
<body>
<?php echo $content; ?>
</body>
</html>
// myscript.js
$(function(){
$("#container a").live("click", function(e){
e.preventDefault();
$.ajax({
url: $(this).attr("href"),
success: function(data) {
$("#container p").html(data);
}
});
});
});
// my_other_controller.php
class My_other_controller extends CI_Controller {
function method(){
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']=="XMLHttpRequest") {
// is an ajax request
echo "This is new content for the page.";
} else {
// is not an ajax request, render whole page
$content['text'] = "This is new content for the page.";
$data['content'] = $this->load->view('embeds/home_page', $content, TRUE);
$this->load->view('public_template', $data);
}
}
}
I have a simple form which is inside IFRAME. When user click on SUBMIT, it redirects to a specific page on my server. The function I use for the redirect is
header ('Location: mypage2.html');
exit ();
But I want the new page to open in _top location, not inside the same IFRAME that I use. How can I tell the browser to open the new page in _top not inside the IFRAME?
Thanks in advance.
You are not able to achieve the desired effect in PHP. This is something you'd have to do from JavaScript or add target attribute to <form>:
<form ... target="_top">
You can use javascript to access the parent. You could echo out javascript in your PHP.. so your parent page has this:
function changeURL( url ) {
document.location = url;
}
and in your php script, you echo
<script>
parent.changeURL('mypage2.html' );
</script>
The reason you can't call parent.document.location is because it's read only - you have to have a function available on the parent to do it.
A simple way directly in PHP to redirect the parent page rather than the iframe:
echo "<script>top.window.location = '/mynewpage.php'</script>";
die;
The die; isn't necessarily necessary, but it is good "just in case" to prevent the script from continuing any further, for example, if javascript is disabled in the user's browser.
we can use javascript like this :
target.window.location='locationpage.html';
top.window.location='mypage2.html';
The best and simplest thing to do is to use the form target element
<form action="..." target="_top">
<form action="..." target="_parent">
either of the target parameters works fine
You can either link to the page using Break Out or use code
<?php header("Location: pagename.php?Break=Y"); ?>
You then use the following code in the header of the page with
if(isset($_GET['Break'])) //
{
$BreakFrame = true;
$BreakToPage = "pagename.php";
}
<script language="JavaScript" type="text/javascript">
function changeURL( url ) {
document.location = url;
}
</script>
<?php if($BreakFrame) { ?>
<script language="JavaScript" type="text/javascript">
parent.changeURL('<?=$BreakToPage?>' );
</script>
<? }?>
In the page that you want to load in _top, add the follow code in the header
<script type="text/javascript">
if (top != self) top.location.href = location.href;
</script>
For CakePHP 4, to redirect your parent page just add option 'target'=>'_top' in your iframe's link:
Example:
<?= $this->Html->link(__('Redirect Parent'), ['controller' => 'Users', 'action' => 'view'], ['target'=>'_top']) ?>
All the best!
You can add multiple headers to your redirect.
I use a little function that I created with this in mind.
public function redirect($url){
header('Window-target: _top');
header('Location:' . $url, true, 303);
exit();
}