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();?>
Related
I've looked at a lot of StackOverflow answers but can't find an answer that is working. This seems like it should be so simple.
I have a PHP single page web app. It has a nav bar that loads pages as includes. Clicking the nav bar invokes a jQuery function to load a different include and inject a class into a div. This works in the nav.
In one of the includes, I have an HTML link:
<div class="page-content">
<a class='btn-primary'>See Examples</a>
</div>
This is the jQuery I want it to execute:
$(".btn-primary").click(function() {
alert('you clicked me');
$('.page').attr('class', 'page examples');
// REPLACE THE CURRENT INCLUDE
$('.page-content').load('includes/page-examples.php');
window.scrollTo(0, 0);
});
But the link does not execute the function. Changing it to a div does not work. Clicking will not even execute the alert.
I've tried to put the link in php echo or php print, but it makes no difference. I've checked all my naming and there isn't a typo.
What is the best way to make it work?
----- EDIT -----
The jQuery is being called from a js file called from the index.php head tag, and is in the DOM ready statement. It looks like the DOM is ready before the include with the link loads. If I remove the link's js from the js file and put it in the include with the link, then the link works, but this will create a problem as other internal links are added to the site in other includes.
What is the best way to fix ?
It sounds like your javascript click binding $(".btn-primary").click(...); is executed on DOM-ready.
But at that time the .btn-primary is not yet in the DOM as it only gets inserted into the DOM after you include it (if I understood it right).
Therefore the binding never happens and after your first include gets loaded the click binding code is never executed again and therefore the .btn-primary element has no onClick event.
You need to run your javascript snippet after that .btn-primary element gets inserted in the DOM, eg. like this:
$('.page-content').load('includes/first-include.php', function(){
$(".btn-primary").click(function() {
whatever...
});
});
First step
Check if you are importing jQuery library (it seems obvious, but we
can forget to import the library sometimes or the library URL is wrong
and the browser cannot recognize it as well). And remember you need import jQuery before the function you wrote.
Second step
If you need to inject a class into some element using jQuery, the easiest way to do this is:
Instead...
$('.page').attr('class', 'page examples');
Change to...
$('.page').addClass('examples');
In this example above, you can omit the 'page' and let only 'examples', because the class ".page" is already there.
Another thing, this will only work if the element with ".page" class already exists in your HTML.
Third step:
Add a callback to .load function and see if it worked properly:
$('.page-content').load('includes/page-examples.php', function(){
alert("Nice, my content was loaded!");
// You can put this action here, so it will execute after the content is loaded
window.scrollTo(0, 0);
});
First, I want to apologize if this is somewhere else. I'm looking for something simple. I have a PHP script that uses glob to retrieve a list of files from a directory. The directory is determined by a request sent though the address bar. ie. http://somewebsite.com/?loc=mydirectory
I'm looking for a way to create a button that you can click on and the file list will display without refreshing the page.
Here is the PHP code.
<?php
$BaseLoc='./';
$SecLoc='archives';
$FullLoc=$BaseLoc.$SecLoc.'/';
$loc=$_GET["loc"];
parse_str($_SERVER['QUERY_STRING'], $urlparams);
$GFloc=$urlparams['loc'];
function DirList() {
global $FullLoc;
$DirList=glob($FullLoc.'*',GLOB_ONLYDIR);
foreach ($DirList as $dirlist) {
$edl=explode ('/',$dirlist);
$dirlist=end($edl);
echo '<li>'.$dirlist.'</li>';
}
}
function ListFiles($GFloc){
global $FullLoc,$GFloc;
$FileLoc=$FullLoc.$GFloc;
$FileList=glob($FileLoc.'/*');
foreach ($FileList as $filelist) {
echo $filelist.' - '.$GFloc.'<br />';
}
}
?>
keep in mind that this is a test project for the purposes of getting a handle on how to do this type of AJAX. I know there is some Jquery with .get and I could have sworn I'd done this before but for the life of me I just can't seem to wrap my head around it. I know it's got to be something simple with a button click and then write the result into a div. Any help would be appreciated or even a link to an answer that I missed.
Thanks.
I'm editing this on 1-28-2017 to try and clarify what I'm attempting to do.
With the current php code above. When this .php page is visited it generates a list of sub-folders inside a folder and turns that list into clickable links. Inside each of those sub-folders is a group of media files. Currently if I click on one of the now generated sub-folder links. The entire page refreshes and I get a display of all the files inside that sub-folder. This is done by using php get and a variable inside the url. The only thing I 'm trying to change is that I get the same result, without refreshing the page. If you want to see an example of this functionality as it currently is, you can go to my test page. http://testbed.myreth024.tk/ajax/ I keep thinking it's something simple with the jquery .get. I just can't seem to find a good example of how to pass those url parameters through. Anyway. Thanks again for all the responses.
<button type="button">Click Me</button>
<div id="iamdiv"></div>
<script type="text/javascript">
$(document).ready(function(){
$("button").click(function(){ //you can use class(with .yourclass) or id(with #yourid) instead of button if you need to be.
$.ajax({
type: 'POST',
url: 'script.php',
success: function(data) {
alert(data);
$("#iamdiv").html(data);
}
});
});
});
</script>
In script.php
<?php
echo "You win";
?>
I hope that helps cheers!
I want to thank everyone for their time and input. I want to point out that I feel as programmers we have a tendency to over-complicate things. Eventually I arrived at a solution to this question. It's entirely possible I didn't ask the question as clearly as I could have. Before I post the code let me walk through the basics of what occurs. Hopefully this will help someone else who is looking for a similar solution.
The index page opens and the php code executes and generates a directory listing. Each of the directory names is clickable through javascript. When a directory is clicked, the space below the directory listings displays a list of files in that directory.
Here is the index file:
<style>.menu{cursor:pointer;padding:1%;float:left;}</style>
<?php
$loc=$_GET["loc"];
function DirList() {
global $loc;
$dlist=glob("./files/*",GLOB_ONLYDIR);
$dend=$dlist[0];
$dende=explode ('/',$dend);
$default=end($dende);
foreach ($dlist as $Dlist) {
$edl=explode ('/',$Dlist);
$DList=end($edl);
echo '<div class="menu" id="'.$DList.'">'.$DList.'</div> ';
}
if(!$loc){header("Location: ?loc=".$default);}
}
?>
<p></p>
<div><?php DirList();?></div>
<div><div id="flist" style="clear:both;border:1px solid black;min-height:25px;"></div></div>
<p></p>
<script type="text/javascript">
$(".menu").click(function() {
var dloc=this.id;
$.get("file-list.php?loc="+dloc,function(data) {
$("#flist").html(data);
});
});
</script>
Then I have a file-list.php for the purposes of generating the list of files.
<?php
function FileList() {
$loc=$_GET["loc"];
$dloc = "./files/".$loc.'/';
$flist=glob($dloc.'*');
foreach ($flist as $fList)
{
$efl=explode ('/',$fList);
$FList=end($efl);
echo '<div style="padding:1%;width:45%;margin:0px auto;">'.$FList.'</div>';
}
}
FileList();
?>
Ultimately what I was missing was how I could take the data and put it into a div. When creating my links, I used the css id to store the directory name as well. This allowed me to reference it more easily in the code. Ultimately it was essentially about retrieving the "data" from the file-list.php and then simply writing that "data" into the div with the jquery .html. It ended up being a simple .get command which if I understand it, is a jquery ajax solution. If anyone has any questions or comments on how I could have asked the question better or ways to improve the code, feel free to let me know. I'm still learning some of this and I'm always open for improvement.
I thought this would be really simple but obviously after a couple of days trial and no success I have to ask the people to help, looked everywhere.
right im basically creating a php template without much guidance on the foundation 4 framework with is a responsive framework. Now this framework is rather basic and so to add page transitions ive had to use jquery to do what i believe is an ajax call to take "content" from another page and display it on the template page index.html
for which I am currently using the following
<script>
$(document).ready(function() {
$('nav.top-bar > section.top-bar-section > ul.right > li > a').click(function() {
var toLoad = $(this).attr('href')+' #content';
$('#content').hide(1000,loadContent);
$('#load').remove();
$('#main_wrapper').append('<span id="load">LOADING...</span>');
$('#load').fadeIn('fast');
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-0);
function loadContent() {
$('#content').load(toLoad,showNewContent);
}
function showNewContent() {
$('#content').show(1000,hideLoader);
}
function hideLoader() {
$('#load').fadeOut('fast');
}
return false;
});
});
</script>
NOW before i changed over to using ajax and jquery i was operating the menu "active" class and the page name with a simple variable set on each page in the first line listed as $page='' and then the page name
now that im loading the content with ajax even if i include this variable in the content of the new page it will not update in either the or the menu title
im very sorry i dont write things correctly im new to this forum thing
thank you for the help in advance
:) I prefer someone to explain what i need to do and how to do it rather than just copy and pasting code as im a learner :)
You probably want to load the page and parse the result in jQuery to get the new page’s <title> tag and set the requesting page’s <title> tag.
The only thing I’d ask is: why are you doing this? Are you just wanting AJAX page navigation in your website instead of the traditional propagating navigation?
I am only able to answer one part of your question due to extreme confusion, so:
First off, here's why your url changes:
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-0);
You are modifying it with that line. That line, however, has an interesting little quirk:
attr('href').length-0
at the end. Why the -0? That would make no difference. I'd clean it up.
Outside of that, I'm incredibly confused with what you're asking so let me try rephrasing it and you can tell me what I'm missing.
You want to have a user click on a navigation link, and load that link's content via an AJAX call using jQuery, and then replace the content on the page with the newly loaded page, correct?
When you say "right on top main page i have variable $page = then the page name", what do you mean by "main page"? Do you mean it's a line of text in HTML? Part of a script that you haven't included here? Part of your PHP code?
And then you say "ive tried including the tag in a div that changes along with the above content"- what is "the tag"?
By reading this 4 or 5 times I could barely discern the above understanding of what you're trying to do.
Please make heavy edits to you question- it's incredibly hard to understand.
Lastly, why are you trying to replace the browser's functionality of a user clicking a link and loading content? That's what the browser is for. The browser also, conveniently, has a loading indicator in the url bar usually (or some form thereof), letting the user know the content is still loading.
function loadContent() {
$('#content').load(toLoad,showNewContent);
}
So first off, look at the jQuery doc for the load method:
http://api.jquery.com/load/
Your issue is that it is calling for three arguments, and you are passing two. If there are multiple arguments listed and you only want to pass SOME of them, you still need to supply a null value for the ones you want to "skip". Try changing your call to this:
function loadContent() {
$('#content').load(toLoad, null, showNewContent);
}
You'll notice that I'm passing "null". If that doesn't work, pass an empty string, like this:
function loadContent() {
$('#content').load(toLoad, "", showNewContent);
}
That second argument is data to be passed with the request. It's the THIRD argument that you list as your callback, which as far as I can tell is where you're making the mistake.
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.
I have a form at the bottom of a long page, if a user fills out the form but it doesn't validate the page is reloaded in the typical codeigniter fashion:
$this->load->view('template',$data);
however because the form is way down at the bottom of the page I need the page to load down there like you do with HTML anchors. Does anyone know how to do this in codeigniter?
I can't use the codeigniter
redirect();
function because it loses the object and the validation errors are gone. Other frameworks I've used like Yii you can call the redirect function like:
$this->redirect();
which solves the problem because you keep the object. I've tried using:
$this->index()
within the controller which works fine as a redirect but the validation errors are in another method which is where the current page is loaded from:
$this->item($labs)
but when I use this it get stuck in a loop
Any ideas? I've seen this question a lot on the net but no clear answers. I'm researching using codeigniter "flash data" but think it's a bit overkill.
cheers.
I can't personally vouch for this, but according to this thread if you append the anchor to the form's action, it will work.
CodeIgniter helper:
<?php echo form_open('controller/function#anchor'); ?>
Or vanilla HTML:
<form method='post' action='controller/function#anchor'>
If you were open to using Javascript, you could easily detect a $validation_failed variable and appropriately scroll. Or, even better, use AJAX.
Another option is to put the form near the top of the page?
Ok, as far as I understood your problem, it isn't much related to the back end(codeigniter). You want the form at the bottom of the page to be 'what-users-sees-on-page-load' (since you mention anchors).
Now, what you can do is, you can set delimiters for your validation error messages using:
echo validation_errors('<div id="bottom_form_error">', '</div>');
Using jQuery ScrollTo, do:
$( function() { $('#bottom_form_error').ScrollTo(); } );
And, the user will be scrolled to the errors at the bottom of the page. Don't forget to include jQuery too.
Anchor hash fragment click is different - it is scrolling at ∞ speed.
I hope that is what you wanted.
P.S. I am ignoring what you said below this line:
Does anyone know how to do this in codeigniter?
as I felt it is not really relevant to the question.