Some questions about CodeIgniter with Javascript and AJAX - php

Just getting into Codeigniter and I'm planning out a large application. I'm a bit confused about how CI handles JS files and AJAX requests.
I am using mod_rewrite with my project.
In a regular webpage, I'd reference separate JS scripts at the header of my doc to keep my code segregated and clean. Since I'm using mod_rewrite, I need functions from the url helper to find my files. This is a problem in separate js docs because they don't execute php. So when it comes to AJAX calls, how am I supposed to reference a PHP controller function from my JS file when I don't have use of the site_url() function?
How would I go about writing functions that can be accessed through AJAX but not through the address bar? So, let's say I have a User Controller. You can go to user/pictures and you can see their pictures. You go to user/friends and you can see their friends. But I don't want you to be able to go to User/getData and see all the printed out raw data.
tl;dr What is standard JS and AJAX practice when using separate docs and mod_rewrite?
Cheers guys.

What I personally do is declare a js variable in the header section of my template before any js declaration like this:
var base_url = <?=base_url()?>
This base_url will then be accessible by any js file you integrate. About the second point you can always redirect the user from your controller like this:
public function some_function(){
if($this->input->post(null)){
//your ajax code here
}else{
redirect(base_url(), 'refresh')
}
}

I also declare a js variable in the <head> like
var baseUrl = '<?php print(base_url()); ?>';
Then when you do your AJAX call you can call the controller like
baseUrl + 'controller/method'
In terms of making sure that methods can only be called from AJAX calls and not through the address bar one option is to send a post value and check for this before you do anything like
if($this->input->post('ajax_call'))
{
//Do something
}
If you put all your ajax methods into the same controller you'd only have to have this check once in the __construct()

Related

How to include assets (JS) into the layout from a controller - CakePHP

This is probably a duplicate, but I am struggling to find the same question and certainly the answer.
I'm a little unsure and confused on how assets are handled in Cake (2). I want to include some JS on a specific page, not on every page of the app, so I would assume I would need to add that to my controller method? I can't find how I would do that. The close I have come is the JsHelper, but that seems more for constructing JS using PHP rather than just loading an assets.
I am well aware I can do $this->Html->script('script'), but this does not work in the controller, only in the view.
Although not needed right now, it would also be useful to be able to pass variables through to the included JavaScript. A good example of this may be an AJAX request on an 'edit' screen for something: $.ajax({ url: "/pages/edit_ajax/<?= $page->id ?>" });
Any help is gladly received.
In order to do this you will want to use Blocks (providing you are in v2.1+).
In your layout file you will no doubt have a line $this->fetch('script') which will go find the script block and output it into your layout.
Next, in the view for the Controller action, let's say index() you will have a matching view index.ctp. In this view you can append your script to the script block.
So in the view,
<?php $this->append('script'); // we want to append to the script block ?>
<script>
$(function() {
alert('Hey there, Im only on this page!');
})
</script>
<?php $this->end();?>
When you visit your controller action you will see that this will be output, hopefully at the bottom of your page, along with your other javascript.
As you've appended the script in the view, it will only ever execute when this view is loaded.
In regard to your second question, you can just set variables to the view in your controller, and then echo them into your javascript.
// Controller
$this->set('jsVar', 'JavascriptInBlocks');
// View
<?php $this->append('script'); // we want to append to the script block ?>
<script>
$(function() {
alert('Hey there <?php echo $jsVar;?>');
})
</script>
<?php $this->end();?>

Use of PHP code inside Javascript code

Since I know many consider the use of PHP code inside Javascript code bad practice, I wonder how to execute a javascript function provided that a certain PHP variable has a certain value.
This is the way I currently write the code:
<script type="text/javascript">
function execute_this() {
some code;
}
<?php
if(!empty($_SESSION['authorized'])) :
?>
execute_this();
<?php
endif;
?>
</script>
Any ideas how to avoid using PHP inside Javascript in this particular example?
If you don't want to include any PHP code inside the javascript code but want to know the value of a php variable, you have to integrate a communication between the server side (PHP) and the client (JS)
For example you could use a ajax request to call a small php snippet that provides the value in its reply. With that value you can go on in you java script code.
In my opinion you should decide if its worth the effort.
Edit:
In regard to the edited question: If it is important that the JS function is never ever called if the PHP session value isn't present I would stay with the PHP code but would do it that way:
<?php
if(!empty($_SESSION['authorized'])) :
?>
<script type="text/javascript">
function execute_this() {
some code;
}
execute_this();
</script>
<?php
endif;
?>
If you evaluate the value of the session variable in javascript, you have to make sure that nothing bad happens to your code if the provided value was manipulated.
It's a matter of code style. The time your project grows, you will find it increasingly difficult to maintain it or to extend its functionality. A better solution would be to initialize all needed variables in the beginning of the file and to externalize the main JavaScript functionality.
Example PHP:
<script type="text/javascript">
MYCONFIG = {
authorized: '<?php echo $_SESSION['authorized']; ?>',
foo: 'something else'
}
$(document).trigger('init'); // fire init event, you can call it as you like
</script>
Example JS with jQuery (note that i use the custom trigger 'init', you can call it however you like):
$(document).on('init', function() {
function execute_this() {
document.write(MYCONFIG.foo);
}
if(MYCONFIG.authorized) {
execute_this();
}
})
This should be in an external JS file and does not need any PHP tags.
You have to store the php variables somewhere in the html code and then access it.
For example:
<input type="hidden" id="hidval" value=<?php echo $_SESSION['authorized'] ?>/>
then in your js:
var somevar=document.getElementById(hidval).value;
if(somevar==what you want){
execute_this();
}
I think you have some basic design issues, and we are only seeing the tip of the iceberg and can't fully help you.
There is nothing inherently wrong with calling a php function this way, but you have several issues:
1) you cannot separate your js file & allow for caching or cdn
2) while MVC is certainly not "mandatory", it is definitely a good idea to try to separate this type of logic from your "view" - your rendered output
3) I suspect elsewhere you have a massive security hole - if you are setting certain parameters based on whether or not they are "authorized" in their session, this means you are most likely sending back info on which to base a permissions decision in your php code somewhere. Never do that from the page - all data should be "neutral" on the page itself, because you have no control over it.
Give this a read if you are not clear why I say that: http://www.codebyjeff.com/blog/2012/12/web-form-security-avoiding-common-mistakes
There are three possible ways to do it.
Use hidden field and add necessary variable value inside each fields and get those using jQuery.
User jQuery Session plugin and access php session variable.
make a ajax call to php and get response in json format and access response.

Placing javascript/jquery functions in a universally accessible page

I am trying to clean up my pages, and one of the major ways that I am doing so is to put JavaScript and JQuery functions into a file called 'scripts.js' that is automatically accessed upon page load.
I've run into a problem with functions that use php to call from the page itself. For example, the following function doesn't work, and in fact 'kills' the script for all pages (so now things that were supposed to be hidden are not, and things are not loading properly). I've narrowed it down to the fact that I use to call a variable. I would really like to be able to keep functions using PHP in this universal file as opposed to clogging up the HTML template pages, any thoughts on either how to make this work, or if not how else I may be able to call the values needed? They are always extracted to the page before rendering if that helps.
function positiveSelect()
{
var size = <?php echo $idea[0]["size"]; ?> * 1;
if (size > 5)
return true;
else
return false;
}
if you can't retrive your data form the DOM itself you can store values with the corresponding object:
<div data-size=20>
and then retrive it with:
$(element).data("size");
or if you have global data you want to store you can create a value "container" in the head of you html document like this:
<script type="text/x-json" class="global-data">{"value1":"1","value2":"2"}</script>
and then read the content of that element and parse it with JSON.parse
If this function is that specific to a certain page, you might want to add a second js script that just gets loaded on that page.
An alternative would be to echo out a js variable in that php page and have your code call that function with that variable as a parameter.
You can give the javascript a ".php" extension and call it in the script in the same exact way:
<script type="javascript" src="path/to/scripts.php"></script>
You could just name the generate scripts file scripts.php or scripts.js.php; then the PHP preprocessor will process the file and the PHP statements will be evaluated.
When mixing php or any server side language with javascript you need to be aware that the php gets executed only once when the javascript file is created on the client side.
This is probably why you are getting unexpected results. As you move from page to page the php snippet in your global scripts.js will not get updated.

Using jquery to process actions which require passing PHP variables within MVC framework

I am using codeigniter. What i want to achieve is as follows.
I am on a page /profile/username (Controller profile, function username).
This function loads a view which has a submit button.
<input type=submit value=apple>
I then have a jquery file which has ajax processing such that when the submit button is clicked /profile/process_click (a private function) is called with $.post.
The function process_click in the controller profile calls a method function which inserts the value of the submit button into the database (in this case 'apple'). Alongside this function needs to insert the username of the person on whos profile the link was clicked (in this case 'username').
So.. my question is, how do I pass username from my profile controller to my jquery file such that it can be passed to process_click by $.post?
I need a secure and safe and ideally not resource intensive way to do this..
Cheers
First of all, the process_click function cannot be private or you won't be able to call it via Ajax.
Jquery post method has a callback function which is called when the PHP script returns an answer, so in your js file do:
var userData = $("#form1").serialize();
$.post('http://localhost/profile/process_click',userData, function(data) {
//some code that handles data returned from php
});
in the php script:
public function process_data(){
$userName = $_POST['userName'];//or whatever the input name is
...//do some processing
echo $username;
}
i assume all of us would like to help but your question is not understandable, i think this is the reason you have received one answer only. Please edit and explain your problem in a wilder context. Don't save words, and use reference properly. for example, what is to 'jquery file' ??? what is to pass value to jquery? i assume you refer to javascript variable, and jquery $.ajax{} call, but can't be sure. can you be more oriented in your description. i also assume your english is much better than mine according to your residence so it shouldn't be an issue for you.
i can try and post back if you fix,
thanks and goodluck

ajax in zend frame work

I am new to Zend Frame Work.
I am using $ajaxContext = $this->_helper->getHelper('AjaxContext'); for adding action contexts. I have one Index.phtml page and all other views are ajax.phtml pages. I have to do some java script methods in the ajax.phtml pages. But i didn't find a way to refer the js files in the ajax.phtml pages. I have tried adding those in the controller init and index action, using $this->view->headScript()->appendFile, though i have the reference added in the page source, none of htese seems to be working on the ajax content. Then i tried to add it in the action for the ajax page, then it is not coming in the page source itself. As far as i understood, $this->view->headScript()->appendFile will append the file reference to the layout page and for the ajax.phtml pages, the layout will be disabled.
Is there any way that i can refer my js files in the ajax.phtml pages?
You are on the right way, but where does you echo the ViewHelper?
After adding the Files with the headScript view Helper try:
echo $this->headScript();
I found two ways to resolve this issue. One is we can bound the click event of the ajax postbacked content button with a jquery.live() method. This will register the element in the DOM, even if the element is not present at the time of page load.
Another way is to reload the javascript in the success of each ajax postback using the getScript() method. In this way all the newly added elements will get registered and active. if you are using jquery dialogs, using variables, you may have to destroy those, before reloading the js.
Put this code to your Controller public function:
public function indexController(){
$this->_helper->viewRenderer->setNoRender();
$Response = $this->getResponse();
$Response->setBody(Zend_Json::decode($foo))
->setHeader('content-type', 'application/json', true);
return null;
}

Categories