Imagine I have a script abc.js, which has one global variable userid. Several AJAX requests are made instantly after it is loaded (it can happen after or before DOM is parsed by browser). I need the script to have different variable value for different users. Requests has to be made instantaneously after JS is available. Here is what I am looking for:
Browser makes a request to /js/abc.js?userid=12345
Server parses userid=12345 and adds userid = 12345 to the script
Server returns the script to user
Browser parses the script and userid is set to 12345, then everything is processed normally.
Is there a way to do this with some Apache/Lighttpd extension? Since I can't rely on <script>userid=12345</script> at the begining of the document, as abc.js will most probably be executed before userid=12345 is evaluated.
You can simply use PHP to output the javascript variables at a point before when the abc.js script is called. In this case the parameter would be passed to the main PHP script (i.e the page). Like this:
<script type="text/javascript">
var userid = <?php echo $_GET['userid']; ?>;
</script>
<script type="text/javascript" src="/js/abc.js">
Of course you probably want to sanitize the parameter value in PHP before using it.
Here, abc.js can just reference the value of userid in global scope. There is no need to pass userid to the script in URL and have Apache use PHP to dynamically generate the js file. In fact, you likely don't want that approach as it prevents optimal browser caching of the script.
If you don't want PHP involved you have other options to pass this data such as the URI parsing option presented by #yent, HTML5 localStorage, cookies, etc.
You can parse window.location.search and set window properties :
var p = window.location.search.substr(1).split(/&/);
if(p.length && p[0]) for(var i=0; i<p.length; i++) {
var a = p[i].split(/=/);
window[a[0]] = a[1];
}
Related
I have been facing an issue with the communication between java and javascript through zk framework in a iframe.
In simple words, I want to save a string in the current session and access it (or even overwrite it) in javascript.
my java lines:
HttpSession session = (HttpSession)(Executions.getCurrent()).getDesktop().getSession().getNativeSession();
session.setAttribute("key","testing");
my zul lines:
<iframe id = "change_option" src="select_one_option.html" scrolling="no" width="700px" height="400px" > </iframe>
my javascript lines in the html file:
var session= /SESS\w*ID=([^;]+)/i.test(document.cookie) ? RegExp.$1 : false; //finds the correct session id + desktop name?
session = session.substring(0, session.indexOf('.')); //removes desktop name and keeps just the session id in a string
//another try
console.log("Saved: " + sessionStorage.getItem("key")); //returns "Saved: null"
//another try
var username = '<%= Session["key"] =%>'
console.log ( " Variable is : " + username) //returns "<%= Session["key"] %"
Since the html file is big I thought it would be better to do it through iframe and not try to rewrite inside the zul file. Any suggestion is highly appreciated.
There are a few approaches you can consider depending on your full requirement.
#1 The page located inside of the iframe and the outer page may communicate directly, using the window postMessage API:
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
This require a bit of setting up, but allows the page located in the iframe to post an event to the parent page. The event has a data field, which you can use to transfer data.
The parent page can subscribe to such event, and read the event data.
With this method, you don't actually need to write stuff to the session at server-side, since this communication happen fully at client-side.
This is good if the server doesn't care about knowing the value.
#2 saving the object in session from the inner page, using it from the outer page
You are already setting the session attribute in the native session:
HttpSession session = (HttpSession)(Executions.getCurrent()).getDesktop().getSession().getNativeSession();
session.setAttribute("key","testing");
Note that session attributes are Java-side only. They are not automatically returned to the client as cookies.
You can add a cookie with the same value to your response, if you want to handle this by cookies:
https://www.zkoss.org/wiki/ZK_Developer%27s_Reference/UI_Patterns/Communication/Inter-Application_Communication#Use_Cookie
However, this is a bit overkill because ZK is a communication framework and you can already pass the value to the outer zul page in a number of ways.
First, you can just execute arbitrary JS on the page using the Clients#evalJavascript method.
https://www.zkoss.org/wiki/ZK_Developer's_Reference/UI_Patterns/Useful_Java_Utilities#evalJavaScript
With that, you can just build a JS call containing your value retrieved at server side, and execute it in client. Should look like this:
String myValue = ... //retrieve your server-side value;
Clients.evalJavascript("myClientSideFunction('"+myValue+"')"); //executed in an execution of the zul page.
But you can also use that value as a client-attribute, pass it as a component value, etc.
There are a lot of arbitrary things you can do to pass that value back to the client, all with pros and cons.
For example, if you want to put that value back into a textbox, you can simply use the textbox#setValue method. It really depends on what you are looking to achieve.
I would like to output a global variable "elemenId" that is created by a javascript in typo3.
The javascript writes the ID of the touched html element in the global variable elementId:
document.addEventListener("touchstart", (e) => {
// get elementId of touched element and save as global variable elementId for further processing
window.elementId = e.target.id;
});
I would like to display the elementId value in typo3.
Is there any chance to access this variable in typo3 using typoscript? Something like:
lib.global_variable = COA_INT
lib.global_variable {
20 = TEXT
20.data = GP : elementId
}
Is there any other way to achieve that?
Thanks a lot for your help!
What do you mean with global variable elementId?
global in what context? PHP? javascript? TYPO3?
You need to distinguish between server(webserver with PHP/TYPO3) and client(Browser with javascript).
How can data be exchanged?
Anything in PHP can be written in the rendering process. The output is HTML, including CSS and javascript. Alternatively TYPO3/PHP can generate other formats like JSON, XML, PDF or CSV.
In this way PHP can transfer some information to Javascript by generating a piece of javascript which assigns the value to a (global) javascript variable:
$output = '<script>js_var = "' . $php_var . '";</script>';
echo $output;
Now the client/browser can use the value by executing this javascript code.
On the other hand any value from your client/browser can only be transferred to the server/PHP by doing a new server request. This can be done with a new page request with arguments (either POST or GET) and the server can respond with a appropriate reaction.
Or you do an AJAX call and you will get a appropriate response and some javascript can insert the response in the current document.
Another option would be that javascript only acts locally in the browser and used the information available to generate or modify the current HTML-document. that might be showing the ID of any clicked HTML element in a special HTML object.
<html>
<head>
<meta charset="utf-8">
<title>Test page for Query YQL</title>
<link rel="stylesheet" href="http://hail2u.github.io/css/natural.css">
<!--[if lt IE 9]><script src="http://hail2u.github.io/js/html5shiv.min.js"></script><![endif]-->
</head>
<body>
<h1>Test page for Query YQL</h1>
<div id="content"></div>
<input type="button" name="bt1" value="click" onclick="pesquisa()">
<form name="s2">
<input type="text" name="s1">
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.query-yql.min.js"></script>
<script type="text/javascript">
function pesquisa(){
$(function () {
var t = $('#content').empty();
var url= document.s2.s1.value;
var statement = 'select * from feed where url="'+url+'"';
$.queryYQL(statement, function (data) {
$('<h2/>').text('Test: select * from feed').appendTo(t);
var r = data.query.results;
var ul = $('<ul/>');
$.each(r.item, function () {
$('<li/>').append(this.title).appendTo(ul);
$('<li/>').append(this.link).appendTo(ul);
<?php
$titulo = "<script>document.write(titulo);</script>";
$site = "<script>document.write(site);</script>";
//echo $titulo;
//echo $site;
?>
});
ul.appendTo(t);
});
});
};
</script>
</body>
</html>
How can you save the this.title and the this.link values into 2 different variables an then call them into php so you can insert the data into a DB?
It's just a simple YQL query to search on rss feeds.
After doing the query, I want the results to be saved in a database, but I can't discover how to do that.
First of all, you have to understand that you are working on a Client-Server architecture.
This means:
Let's say that this file you are showing us is called "TestYQL.php" (because you did not say the name of it). This file is executed by php (server side), which reads line by line the contents of it, and generates another new file from the original. For educational purposes, let's say the generated file is called "GeneratedTestYQL.html". This file no longer has any php code inside, since it is directly html and js flat. It knows nothing about php. So there are no php functions, variables, nothing. This last file is the one that reaches the client, and the code is executed by a web browser like Chrome, Firefox, etc.
In your case, the file "TestYQL.php" all you have of php is what is inside the <? Php ....?> Tags. With php you creates 2 variables, each with a tag inside, but without any purpose since they are not used in any way. So, the generated "GeneratedTestYQL.html" file is the same as the original, but without the lines inside the <? Php ...?>.
This means that: The contents of the variables that you use in PHP can be sent to the browser, because with PHP you will generate the file that will be executed in the browser.
Now, when the file "GeneratedTestYQL.html" arrives, the browser starts to show all the contents of the file, it generates the form in which, when you click the button, executes the function pesquisa() and now starts javascript (JQuery) bringing data of the feeds, and for the first time, these variables "this.title" and "this.link" begin to exist in javascript.
Since there is no such thing as php here, you can NOT access those variables from php.
So, how to save that data in a DB?, well, the common way is to send all the data you want from the browser, to the server, then the server sees what to do with that data. To send data from the browser to the server, you do it by making GET or POST requests to a php file from the server (preferably another file, let's say it will be called "saveFeeds.php").
Data can be sent with a GET request, but it is semantically incorrect since GET means you want to fetch data from the server. So to send that data to the server, you will have to make a POST request from the browser, which is more appropriate.
There are now 2 simple ways to make a POST request. The first and most common of these is from a form in the browser, the other way is using Ajax.
How to do it from a form?
Currently in your code, you have already put a form (That is called "s2"), although currently the same is not necessary, but leave that now.
If you wanted to send the data through a form, you should do 2 things. First and most obvious, create the form; second, the data received from the internet (title and link of feed), send them to the server.
Assuming you fetch data from a single feed per url, and the designated file in charge of receiving the request will be "saveFeeds.php". So, you could create a form like the following after the previous one:
<Form class = "sender" action = "saveFeeds.php" method = "post">
<Input type = "hidden" name = "title" value = ""> <br>
<Input type = "hidden" name = "link" value = ""> <br>
<Input type = "submit">
</ Form>
Then you need to put the feed data inside the form, because, at this moment, you can't send anything. You could add a function like:
Function appendFeedToForm (title, link) {
Var form = $ (". Sender");
Form.title.value = title;
Form.link.value = value;
}
And then call it from inside the $ .each of the result as
AppendFeedToForm(this.title, this.link);
The second case, the easiest way to make a request to the same file using Ajax is with a JQuery shortcut:
$.post("saveFeeds.php", r.item);
If you are interested in validations, you can take a look at the JQuery documentation. The important thing about ajax requests is that you can send all the data you want without having to force you to reload the page. Therefore, you can send as many feeds as you want in the same way you would send one.
Now with the data sent from the client to the server, it is necessary to handle the reception of the data. Currently we were pointing all the data to the file "saveFeeds.php", so, now, finally we can put the content from javascript. To access them, simply in that file, you should check the fields:
$ _POST ['title'] // This names are from input names of form
$ _POST ['link'] // or properties sended through Ajax
So, here, you have tp prepare the connection to your database and save those parameters. Currently you did not mention which database engine you are using, so, for this moment, I'll shorten the answer here.
Note: I was not giving you the best practices to solve your problem, but rather the minimum necessary.
I understand that this a bit odd of a question but here I go. I am writing an application that will be switching environments (dev, test, prod, etc). I need the base URL for my REST calls to change as I switch environments. Well, our current solution (and I am all ears for better solutions) is a local REST call asking the server what environment I am in and what URL I should be using for my base. The external REST calls are separated from the front end completely.
With the local REST call I could do an ajax call to get the data somewhere in my javascript or I could include the REST call as follows:
<script src="/rest/configs"></script>
The problem with the above solution is that it returns an object that is not assigned to a variable thus throwing errors. So my over all question is, Can you load a REST call through a script tag straight into a variable and if so, how?
If you do this with a script tag the response of the request ( not AJAX at all ) will be parsed and executed as javascript.
What you could do is to return valid Javascript, rather than JSON object. Something like
window.config = {"env":"test"};
rather than
{"env":"test"}
Other option is not to do this with script tag and just write inline javascript with an ajax call. If you use jQuery it would look like :
<script>$.get("/rest/configs", function(config) { window.config = config; });</script>
This will do the Ajax call and assign it to a global variable config. Of course you should make some adjustments and execute the rest of your javascript after this is executed.
Anyway as a standard, this value is usually hard-coded in the scripts. I would suggest to create a script that is modified for test/dev/production environments.
Can't your rest call just return a Javascript object, like so:
var env = "experimental";
Your webpage should be able to interpret this as Javascript and the env variable should be usable in the rest of your page:
<html>
<head>
<script type="text/javascript" src="/rest/configs"></script>
<script type="text/javascript">
console.log("env: " + env); // prints env: experimental
</script>
</head>
<body></body>
</html>
We've been working on a web application and we've just about got it finished up, but there's one thing that bothering us (although by no means is it going to stop production.)
When we call one of the pages (index.html), we sometimes have to pass it a variable in the URL (searchid). So we get a page like http://domain.com/index.html?searchid=string.
We'd ideally like to not show the ?searchid=string, but I'm not sure how we'd do that.
My group doesn't own the index.html page (but we are working with the group that does), so I don't know how much we'd be able to do with anything like .htaccess or similar.
I was thinking about POSTing the variable, but I don't know how to receive it with just HTML and jQuery. Another person in my group thought that after the page loaded we could remove it from the URL, but I assume we would need a page refresh which would then lose the data anyway.
I'm trying to avoid XY problem where the problem is X and I ask about Y, so what's the right way to remove the variable from the URL?
You can use the History API, but it does require a modern browser
history.replaceState({}, null, "/index.html");
That will cause your URL to appear as /index.html without reloading the page
More information here:
Manipulated the browser history
Your question seems to indicate that the target page is not and will not be powered by some server-side script. If that's the case, I'd suggest changing the querystring to a hash, which has the advantage of being directly editable without triggering a page-load:
http://yourdomain.com/page.html#search=value
<script type='text/javascript'>
// grab the raw "querystring"
var query = document.location.hash.substring(1);
// immediately change the hash
document.location.hash = '';
// parse it in some reasonable manner ...
var params = {};
var parts = query.split(/&/);
for (var i in parts) {
var t = part[i].split(/=/);
params[decodeURIComponent(t[0])] = decodeURIComponent(t[1]);
}
// and do whatever you need to with the parsed params
doSearch(params.search);
</script>
Though, it would be better to get some server-side scripting involved here.
It's possible to rewrite the URL using JavaScript's history API. History.js is a library that does this very well.
That being said, I don't think there's any need for removing the query-string from the URL, unless you're dynamically changing the contents of the page to make the current query-string irrelevant.
You could post the data, then let the server include the posted data in the page, e.g.:
echo "<script> post_data = ".json_encode($_POST)." </script>";
This works cross-browser.