I have a 2-player boardgame with a lot of (changing) variables.
For testing purposes, I want to show all these javascripts variables inside a testdiv, like:
<div id="testdiv" style="margin-top:800px;background-color:yellow">
/** here the listing of js vars and arrays */
</div>
This boardgame uses a backend-file for updating the game, but i get lost when trying to follow what happens exactly with the javascript vars.
I do know the names of the vars and arrays.
After change of turn, i refresh the page, but I want to update the page via ajax (jQuery).
For checking the playersturn, i already use jQuery and the taconite plugin form http://www.malsup.com/jquery/taconite/
This plugin returns xml, like this:
### Taconite output
?><taconite>
<?php
echo $content_refresh; // refresh pagina indien nodig
echo $content_redirect;
echo $content_melding; // melding over verlaten tafel of afgewezen!
echo $content_inpartij; // tegenstander in partij??
echo $content_chataangevraagd; // chat door tegenstander aangevraagd?
echo $content_wachtopaanschuiven; // div leegmaken zodra 2e speler in partij is
echo $content_starttijd;
?>
</taconite>
Al content vars are generated xml, for example
## Taconite: refresh nodig??
if($refresh_needed == 'ja')
{
$content_refresh = '<eval><![CDATA[
window.location="http://www.xxxxxxxx.nl/v45/partij.php?gameID='.$_GET['gameid'].'";
]]>
</eval>';
//$meta_refresh = '<replaceContent select="#refresh"><META HTTP-EQUIV="refresh" CONTENT="0"></META></replaceContent>';
}
So, instead of refreshing I just want to update the boardgame, but just have not an overview of al (known) present javascript values.
Thanks in advance for any help!
I'm not familiar with your plugin nor is your serverside technology listed (guessing php) so I would say take a look at the json serialization abilities of php at http://php.net/manual/en/book.json.php
Then what you should be doing here is in the javascript on the client side, make an ajax request like you are, but have the server side code written using json to send down just the data that represents either the necessary changes or the whole board state. On the client side the JSON object will be recieved and usable as a direct javascript object which you can then have a method that processes it to manually update the board state based on the data the server sent down.
edit:
Sorry, forgot the scope was to get debug information here, for that the method which renders an update to the board, should also render said debug info into a separate div on the screen somewhere. I would use jquery for the ajax if you aren't already, and with jquery you can use the selectors to do:
$("#debugDiv").text("Var a: " + boardState.VarA);
$("#debugDiv").append("Var b: " + boardState.VarB);
Take a look at:
http://api.jquery.com/append/
http://api.jquery.com/id-selector/
http://api.jquery.com/element-selector/
http://api.jquery.com/category/selectors/
In javascript the variables that you declare globally are usually attached to the window object. So if your variables are in global Scope you can check them in DOM tab of firebug, and click on window.
The problem is that you will see a lot of other variables also there.
If your variables are in some other scope you can just check what is inside the particular scope.
If you want to print them in a div, you will need some way to distinguish your variables from other variables and then use a for in loop along with hasOwnProperty and typeof.
That being said, the best way is to restructure your application so that its atleast transparent to you.
Related
I’m trying to store the content of a div to a variable.
Example:
<div class="anything">
<p>We don't know the content of this div</p>
</div>
I want to search for <div class="anything"> and store everything between opening and the end tag.
We also want to avoid using absolute pathnames, so that it only searches the current HTML/PHP file for this div where the code is present.
Is this possible with PHP, or is this only possible with JavaScript ?
PHP is not that intelligent. He doesn't even know what he says.
PHP is a server-side language. It has absolutely NO clue about what the DOM (ie. what is displayed in your browser's window) is when it delivers a page. Yeah I know, PHP rendered the DOM, so how could it not know what's in there?
Simply put, let's say that PHP doesn't have a memory of what he renders. He just knows that at one particular moment, he is delivering strings of characters, but that's all. He kind of doesn't get the big picture. The big picture goes to the client and is called the DOM. The server (PHP) forgets it immediately as he's rendering it.
Like a red fish.
To do that, you need JavaScript (which is on the client's computer, and therefore has complete access to the rendered DOM), or if you want PHP to do this, you have to retrieve an full-rendered page first.
So the only way to do what you want to do in PHP is to get your page printed, and only then you can retrieve it with an http request and parse it with, in your case, a library such as simpleHtmlDom.
Quick example on how to parse a rendered page with simpleHtmlDom:
Let's say you know that your page will be available at http://mypage.com/mypage.php
$html = file_get_html('http://mypage.com/mypage.php');
foreach($html->find('div.anything') as $element)
echo $element->src . '<br>';
you probably need a combination of those.
In your Javascript:
var content = document.getElementsByClassName("anything")[0].innerHTML();
document.getElementByID('formfield').value(content);
document.getElementByID('hiddenForm').submit();
In your HTML/PHP File:
<form id="hiddenForm" action="path/to/your/script">
<input type="hidden" name="formfield" value="" />
</form>
In the script you defined in the form action:
if(!empty($_POST)){
$content = $_POST['formfield'];
// DO something with the content;
}
Alternatively you could send the data via AJAX but I guess you are new to this stuff so you should start slowly :)
Cheers!
steve
You could use JS to take the .innerHTML from the elements you wan and store them in .value of some input fields of a form and then use a submit button to run the PHP form handling as normal. Use .readOnly to make the input fields uneditle.
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 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.
Like this:
<script>
setSomeStuffUp();
<?php if ($otherStuffNeedsToBeDone === true) { ?>
doSomeOtherStuff();
<?php } ?>
breakSomeStuffDown();
</script>
Came across something like this at work- done with templating (Smarty), so it looks a bit cleaner- but not by much! Also echoes some template variables used for things such as jQuery selectors, and other little unpleasant-looking bits.
What's the proper way to do this? Load the data that needs to be used for logic in the JS as JSON via AJAX? HTML data attributes?
Something about it just smells bad, bad, bad.
Thanks everyone.
It is bad practice to use language X to generate code in language Y.
Try "decoupling" the two languages, for example, like this:
<script type="text/javascript">
var data = {
id: "<?php echo $id ?>",
...
};
$(document).ready(function(){
$("#" + data.id).on("click", function(){
/*do something*/
});
});
</script>
This way, PHP only cares about populating the data structure and JavaScript only cares about consuming the data structure.
Echoing configuration variables and some javascript initialization code from server doesn't sound too bad in general, but if such js-injection-from-server pieces are all over the place then you're right, it's ugly, at least because such code is difficult to manage.
Just try to centralize any kinds of initialization and do the rest in statically-defined client-side JavaScript logic.
UPD. #Oscar Jara is talking about the same thing and provided a good illustration. But often even such cases can be avoided if server-side logic provides data for JavaScript processing via HTML (after all, that's what HTML is for).
Here's a trivial example that you can often encounter. Say you want to output a gallery that will be enhanced into a carousel via JavaScript.
Server generated HTML:
<ul id="myGallery">
<li><img src="img1.jpg /></li>
<li><img src="img2.jpg /></li>
<li><img src="img3.jpg /></li>
...
</ul>
And then you have your static JavaScript code initialize the carousel when DOM is ready:
// when DOM ready...
AwesomeCarousel.init($('#myGallery'));
Here the data prepared by the server is this piece of HTML with a list of images, no need to generate JavaScript explicitly loading every image. You can pass arbitrary data via the data-* attributes.
Personally, I use PHP in JS in many instances. Sometimes it is to populate a variable with JSON data, a page id, or something of that nature. As far as I am concerned, PHP is designed to write the code that appears on the page, and JS is designed to interact with the user once the content is there.
I do get what you are saying, in that there are probably cleaner ways of doing this. You mentioned AJAX, which would probably be cleaner and would definitely help the flow of the document being output. The only issue is that you have to make a second request to the server for some very simple and meanial variable. A few milliseconds isn't huge, but in the a production website, you probably don't want to be making that additional request and bogging down server resources.
In response to what the cleanest way to do it would be, if it was that big of a deal... I would create a separate JS file with that code and then use the server to include that individual file if needed. Again, I don't do this, but I think it would look the cleanest in the template.
If you want to get really out-there, you can have the HTML page request a .js file, coupled with their session-id or some other indicator of who they are, operate the .js call as a PHP call, dynamically build the JS based on what their session requires and then output it back to the browser as a .js filetype.
But that's a lot of work.
If you'd like something that smells less, have PHP dump either a JSON-string at the end of your file:
var cfg_string = "{\"username\":\"Norguard\", \"new_messages\":[......]}"; // client
$cfg_obj = array(); // whole lot o'PHP
$json_encoded_cfg = json_encode($cfg_obj);
echo "var cfg_string = {$json_encoded_cfg};" //server-side
And then parse it, in the client for added safety...
...or just outright create a map in the template:
$cfg_string = "var dataMap = {";
foreach ($cfg_obj as $key => $val) {
// print key:val all pretty-like,
// handle commas (ie: no trailing comma at the end), indent with tabs or spaces
// if you want, count the number of items so that the object closes ({})
// without any newline operator, if there are no config settings
}
echo $cfg_string;
Both of these are clean and unobtrusive and keep everything separate.
The config data/text can go right above whatever your init/loading code is going to be, and be passed in as a parameter to that init-logic.
If all you're doing is passing data from the server-side language to the JavaScript code, then that's fine. Plenty of CMS packages out there do it.
I don't really see the need to conditionally generate JavaScript code on the server side. Maybe there's a use case for it but JavaScript is a language itself, so why not just put the logic in the JavaScript code?
I don't know the correct terminology to search for the solution. Please suggest a strategy to break up the php output into small chunks and pass them stepwise to ajax's responseText.
The project is an ajax webpage that takes a text string (lastname) and passes it to a php program. The php code takes the last name and randomly fetches 3 people with different first names, and puts it into an array. Once that is done, the php code will contact outside servers to retrieve info associated with each name, and output the info to a div of the webpage. The process of getting data from the outside servers is very slow.
This code is basically done, but the whole process takes a very long time to generate the output on the screen. Is there a way (a strategy) to output each step of the php code immediately instead of having to wait for the complete code?
My pseudo php code is like this:
<?
get 3 names; //output this immediately
foreach name { get phone number }
?>
Alternatively, I could get a name and the phone#, and output it immediately before moving to the next name.
Are there php or ajax codes/functions/strategies that would achieve this? Please suggest solutions or search keywords.
Addition/Edit:
Thanks for the suggestions. Is it possible to execute another ajax call after the parent ajax call? I initially went that route, but my testing of nested js/ajax call did not work. It could be due to syntax errors, please look over the code.
The test code in the testajax.php (or testajax.html) file for the ajax call XHR.responseText is
<div id="name" >JAM <div id="numa" >
<br />
<br />text holder >>
<script type="text/javascript">
var pid=document.getElementById("numa").parentNode.id;
alert (pid);
document.getElementById('numa').innerHTML += 'append text>> ';
document.write(' docwrite');
</script>
</div>
</div>
<br />
<br />ending text
If I view the file testajax.php (or testajax.html) directly, I would see
JAM
text holder >> (an alert window) append text>> docwrite
ending text
but if I do an ajax call of the testajax.php file, all I would see is
JAM
text holder >>
ending text
The code inside the <script> </script> tags does not run after the ajax call
can someone explain this, and offer a fix?
TIA
Without knowing the actual code and code-based answer is hard. But, here's an idea.
When you get the three names, return them to the page and display them. Then, for each one, in a different AJAX call, call the phone info. I'm not positive if javascript will make all three calls independently of each other, but that would at least display all 3 names, and then each phone info one at a time.
Edit
Workflow:
Javascript sends a name to php via ajax.
PHP returns 3 names to js
js appends 3 divs to the page, one with each name.
js makes 3 requests to php, sending 1 name per request.
php returns phone info / whatever else to js
js takes info and adds it to the respective div
In theory, yeah, you can call flush() (and ob_flush() as necessary) to ensure output is sent from PHP.
However, the web server may add buffering of its own outside of the scope of PHP (most commonly, if mod_deflate is in use on Apache); and you'd have to be careful about delimiting your response chunks so they're not read by the browser until a chunk is complete.
In any case not all browsers can read the responseText from an XMLHttpRequest until the request is fully complete. So for it to work on all clients, you'd have to try a different mechanism, such as the old-school HTML-iframe-containing-multiple-<script>s.
Summary: it's a bunch of hassle, and perhaps not really worth it. A simpler-to-deploy possibility would be separate AJAX requests for each name.