How to access the TYPO3 settings in JavaScript - javascript

In my project we're using TYPO3. We're getting some data from the backend and they're assigned as follows in the html page itself.
var items = {};
items.item1 = {settings.item1};
items.item2 = {settings.item2};
items.item3 = {settings.item3};
and then the values are being assigned to the buttons. Those values will be sent back to the JS when an action has triggered. The {settings.item*} comes from the TYPO3 backend. What I wanted to know is how can I add the above code block in a separate JS file rather than adding it in the HTML page. When I tried adding it directly, it doesn't work as the {settings.item*} comes from TYPO3
Thanks

You have to pick up your settings from the HTML since this is what TYPO3 will render for you. but you could rather make use of the data-attributes of HTML, e.g.
You could also render the whole {settings} array as a JSON string into a data-attribute and pick that up with your JavaScript.

You can use javascript on html file (templates , partial , layouts )
You need to add javascript code between the
Syntax:
<![CDATA[ javascript code ]]> TYPO3 Code <![CDATA[ javascript code ]]>
<script type="text/javascript">
<![CDATA[
{
var items = {};
items.item1 = ]]>{settings.item1}<![CDATA[;
items.item2 = ]]>{settings.item2}<![CDATA[;
items.item3 = ]]>{settings.item3}<![CDATA[;
]]>
</script>
Thanks
I hope it helps !!

Can you define the context more precisely? Where are the settings defined, inside of TypoScript, Flexform, PHP (Extensionmanager)?
If you have settings defined in TypoScript you can use:
page.inlineSettings {
setting1 = Hello
setting2 = GoOnTop
}
To make them available in JavaScript as:
TYPO3.settings = {"TS":{"setting1":"Hello","setting2":"GoOnTop"}};
See: https://docs.typo3.org/typo3cms/TyposcriptReference/Setup/Page/Index.html#inlinesettings
Perhaps this will be removed in future versions as it's purpose is usage via ExtJS. Also it's not possible to use stdWrap and such.
Another, more flexible, way is using
page.jsInline {
10 = TEXT
10.stdWrap.dataWrap = var pageId = {TSFE:id};
}
This allows you to use full TypoScript like TEXT, dataWrap, etc.
See: https://docs.typo3.org/typo3cms/TyposcriptReference/Setup/Page/Index.html#jsinline

I wouldn't write JavaScript from PHP just for some configuration. I would store them in data-attributes of a DOM element and grab it via JavaScript. Maybe this is also an option for you.

Related

How to include an html file in javascript [duplicate]

I have some html pages with the same footer. With JavaScript and only JavaScript could I import another html page inside it?
Here's how you could use just javascript to add a footer to your page.
2022 code, using fetch and insertAdjacentHTML:
async function addFooter() {
const resp = await fetch("footer.htm");
const html = await resp.text();
document.body.insertAdjacentHTML("beforeend", html);
}
Original 2011 code, using XMLHttpRequest and innerHTML:
var ajax = new XMLHttpRequest();
ajax.addEventListener("load", function () {
document.body.innerHTML += ajax.responseText;
}
ajax.open("GET", "footer.htm");
ajax.send();
The 2011 code will still work in all browsers today, but fetch is more intuitive, and allows you to avoid coding an event handler callback. insertAdjacentHTML is also available for all browsers, so you could use that or innerHTML with either example. Only fetch is new, and won't work in IE without a polyfill.
As above, one method is to use jQuery load. I happened to be doing the exact same thing now, so will post a quick example.
Using jQuery:
$("#yourDiv").load('readHtmlFromHere.html #readMe');
And your readHtmlFromHere.html page would consist of:
<div><div id="readMe"><p>I'm some text</p></div></div>
You can use ajax to return a whole HTML page. If you wanted to replace the whole page you could replace the body tag and all it's children currently on the page with the body tag returned from the ajax call.
If you wanted to just replace a section you'd have to write a server-side script to create that section, then use ajax as above but just replace an element rather than the whole page.
Along with what #Alex mentioned, jQuery has a method .load() that you can use to fetch a specific portion of a page (See Loading Page Fragments heading on that page). You specify the URL you want to retrieve along with a selector (so if you wanted only a specific <DIV>'s contents for instance).
Following this answer example (one of the answer in this question), I made this little reusable function:
/**
* Render the array of html files, to the
* selected container.
* #param {*} pages - array of html file names
* #param {*} container - HTML element name
*/
function render(pages, container) {
const template = document.createElement("template");
var ajax = new XMLHttpRequest();
pages.forEach(element => {
// this is the route where the files are stored
ajax.open("GET", `./view/shared/${element}.html`, false);
ajax.send();
template.innerHTML += ajax.responseText;
});
document.querySelector(container).append(template.content);
}
export { render };
Which you can use in your index.js file, like so:
import { render } from "./tools/render.js";
var headerContent = ["siteName", "navbar"];
render(headerContent, "header");
This is rendering the html files siteName.html and navbar.html, into the <header> tag in the root index.html file of the site.
NOTE. This function works on localhost, but for whatever reason (which I still have to fix; I'll let you know when I do) it does not work correctly when working on GitHub Pages.
You could do a server side include, depending on your webserver.
but the quickest way would probably be to create a JavaScript file that uses document.write or similar to output the html syntax.
and then just include the created JavaScipt file the normal way.
more info at:
http://webdesign.about.com/od/ssi/a/aa052002a.htm
You definitely could, but if all you're doing is templating I recommend you do this on the server.
fetch("MyHTMLFile.html").then((response) => {
response.text().then((text) => {
targetHTMLElement.innerHTML = text;
});
})

How to pass arguments to external Javascript files? [duplicate]

I read the tutorial DIY widgets - How to embed your site on another site for XSS Widgets by Dr. Nic.
I'm looking for a way to pass parameters to the script tag. For example, to make the following work:
<script src="http://path/to/widget.js?param_a=1&param_b=3"></script>
Is there a way to do this?
Two interesting links:
How to embed Javascript widget that depends on jQuery into an unknown environment (Stackoverflow discussion)
An article on passing parameters to a script tag
I apologise for replying to a super old question but after spending an hour wrestling with the above solutions I opted for simpler stuff.
<script src=".." one="1" two="2"></script>
Inside above script:
document.currentScript.getAttribute('one'); // 1
document.currentScript.getAttribute('two'); // 2
Much easier than jQuery or URL parsing.
You might need the polyfill for document.currentScript from #Yared Rodriguez's answer for IE:
document.currentScript = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
It's better to Use feature in html5 5 data Attributes
<script src="http://path.to/widget.js" data-width="200" data-height="200">
</script>
Inside the script file http://path.to/widget.js you can get the paremeters in that way:
<script>
function getSyncScriptParams() {
var scripts = document.getElementsByTagName('script');
var lastScript = scripts[scripts.length-1];
var scriptName = lastScript;
return {
width : scriptName.getAttribute('data-width'),
height : scriptName.getAttribute('data-height')
};
}
</script>
Got it. Kind of a hack, but it works pretty nice:
var params = document.body.getElementsByTagName('script');
query = params[0].classList;
var param_a = query[0];
var param_b = query[1];
var param_c = query[2];
I pass the params in the script tag as classes:
<script src="http://path.to/widget.js" class="2 5 4"></script>
This article helped a lot.
Another way is to use meta tags. Whatever data is supposed to be passed to your JavaScript can be assigned like this:
<meta name="yourdata" content="whatever" />
<meta name="moredata" content="more of this" />
The data can then be pulled from the meta tags like this (best done in a DOMContentLoaded event handler):
var data1 = document.getElementsByName('yourdata')[0].content;
var data2 = document.getElementsByName('moredata')[0].content;
Absolutely no hassle with jQuery or the likes, no hacks and workarounds necessary, and works with any HTML version that supports meta tags...
JQuery has a way to pass parameters from HTML to javascript:
Put this in the myhtml.html file:
<!-- Import javascript -->
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<!-- Invoke a different javascript file called subscript.js -->
<script id="myscript" src="subscript.js" video_filename="foobar.mp4">/script>
In the same directory make a subscript.js file and put this in there:
//Use jquery to look up the tag with the id of 'myscript' above. Get
//the attribute called video_filename, stuff it into variable filename.
var filename = $('#myscript').attr("video_filename");
//print filename out to screen.
document.write(filename);
Analyze Result:
Loading the myhtml.html page has 'foobar.mp4' print to screen. The variable called video_filename was passed from html to javascript. Javascript printed it to screen, and it appeared as embedded into the html in the parent.
jsfiddle proof that the above works:
http://jsfiddle.net/xqr77dLt/
Create an attribute that contains a list of the parameters, like so:
<script src="http://path/to/widget.js" data-params="1, 3"></script>
Then, in your JavaScript, get the parameters as an array:
var script = document.currentScript ||
/*Polyfill*/ Array.prototype.slice.call(document.getElementsByTagName('script')).pop();
var params = (script.getAttribute('data-params') || '').split(/, */);
params[0]; // -> 1
params[1]; // -> 3
If you are using jquery you might want to consider their data method.
I have used something similar to what you are trying in your response but like this:
<script src="http://path.to/widget.js" param_a = "2" param_b = "5" param_c = "4">
</script>
You could also create a function that lets you grab the GET params directly (this is what I frequently use):
function $_GET(q,s) {
s = s || window.location.search;
var re = new RegExp('&'+q+'=([^&]*)','i');
return (s=s.replace(/^\?/,'&').match(re)) ? s=s[1] : s='';
}
// Grab the GET param
var param_a = $_GET('param_a');
Thanks to the jQuery, a simple HTML5 compliant solution is to create an extra HTML tag, like div, to store the data.
HTML:
<div id='dataDiv' data-arg1='content1' data-arg2='content2'>
<button id='clickButton'>Click me</button>
</div>
JavaScript:
$(document).ready(function() {
var fetchData = $("#dataDiv").data('arg1') +
$("#dataDiv").data('arg2') ;
$('#clickButton').click(function() {
console.log(fetchData);
})
});
Live demo with the code above: http://codepen.io/anon/pen/KzzNmQ?editors=1011#0
On the live demo, one can see the data from HTML5 data-* attributes to be concatenated and printed to the log.
Source: https://api.jquery.com/data/
it is a very old thread, I know but this might help too if somebody gets here once they search for a solution.
Basically I used the document.currentScript to get the element from where my code is running and I filter using the name of the variable I am looking for. I did it extending currentScript with a method called "get", so we will be able to fetch the value inside that script by using:
document.currentScript.get('get_variable_name');
In this way we can use standard URI to retrieve the variables without adding special attributes.
This is the final code
document.currentScript.get = function(variable) {
if(variable=(new RegExp('[?&]'+encodeURIComponent(variable)+'=([^&]*)')).exec(this.src))
return decodeURIComponent(variable[1]);
};
I was forgetting about IE :) It could not be that easier... Well I did not mention that document.currentScript is a HTML5 property. It has not been included for different versions of IE (I tested until IE11, and it was not there yet). For IE compatibility, I added this portion to the code:
document.currentScript = document.currentScript || (function() {
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
What we are doing here is to define some alternative code for IE, which returns the current script object, which is required in the solution to extract parameters from the src property. This is not the perfect solution for IE since there are some limitations; If the script is loaded asynchronously. Newer browsers should include ".currentScript" property.
I hope it helps.
This is the Solution for jQuery 3.4
<script src="./js/util.js" data-m="myParam"></script>
$(document).ready(function () {
var m = $('script[data-m][data-m!=null]').attr('data-m');
})
Put the values you need someplace where the other script can retrieve them, like a hidden input, and then pull those values from their container when you initialize your new script. You could even put all your params as a JSON string into one hidden field.
It's simpler if you pass arguments without names, just like function calls.
In HTML:
<script src="abc.js" data-args="a,b"></script>
Then, in JavaScript:
const args=document.currentScript.dataset.args.split(',');
Now args contains the array ['a','b']. This assumes synchronous script calling.
I wanted solutions with as much support of old browsers as possible. Otherwise I'd say either the currentScript or the data attributes method would be most stylish.
This is the only of these methods not brought up here yet. Particularly, if for some reason you have great amounts of data, then the best option might be:
localStorage
/* On the original page, you add an inline JS Script.
* If you only have one datum you don't need JSON:
* localStorage.setItem('datum', 'Information here.');
* But for many parameters, JSON makes things easier: */
var data = {'data1': 'I got a lot of data.',
'data2': 'More of my data.',
'data3': 'Even more data.'};
localStorage.setItem('data', JSON.stringify(data));
/* External target JS Script, where your data is needed: */
var data = JSON.parse(localStorage.getItem('data'));
console.log(data['data1']);
localStorage has full modern browser support, and surprisingly good support of older browsers too, back to IE 8, Firefox 3,5 and Safari 4 [eleven years back] among others.
If you don't have a lot of data, but still want extensive browser support, maybe the best option is:
Meta tags [by Robidu]
/* HTML: */
<meta name="yourData" content="Your data is here" />
/* JS: */
var data1 = document.getElementsByName('yourData')[0].content;
The flaw of this, is that the correct place to put meta tags [up until HTML 4] is in the head tag, and you might not want this data up there. To avoid that, or putting meta tags in body, you could use a:
Hidden paragraph
/* HTML: */
<p hidden id="yourData">Your data is here</p>
/* JS: */
var yourData = document.getElementById('yourData').innerHTML;
For even more browser support, you could use a CSS class instead of the hidden attribute:
/* CSS: */
.hidden {
display: none;
}
/* HTML: */
<p class="hidden" id="yourData">Your data is here</p>

Keeping javascript minified inside the database

I have written a script that is placed on different websites. It puts some html/css there. I have also written a website that enables to configure this html/css for each website.
That's why the script has to load html/css from the database. And that's why I have to keep javascript inside the database, and then use some eval to fire it from the script.
My question is - how can I keep something like this minified in the database, and then display it nicely formatted in some wysiwyg editor?
Sample text:
var el = document.createElement('body');
el.innerHTML = 'foobar';
document.getElementsByTagName('body')[0].appendChild(el);
This is what I want to get in my wysiwyg editor, but in DB I want this:
var el = document.createElement('body');el.innerHTML = 'foobar';document.getElementsByTagName('body')[0].appendChild(el);
So I have to somehow convert between those two.
I think you can use a regular expressions to do that (if you just want to place all code at the single line into the DB):
To store from the editor to the database do
var codeToDB = WYSIWYG_value.replace(/\r\n|\r|\n/g,"");
To restore from the database
var codeToWYSIWYG = codeFromDB.replace(/;/g,";\n")

javascript replace string in js file

Ok so another issue i got
I have a js file that i need to include on my page (i dont have access to edit this js file)
Inside that javascript there is a function wich has a line that i need to edit a variable in there.
lets assume:
Code:
var links = [{"offer_id":"1","title":"Text!","url":"http:\/\/www.site.com\/tracker\/1\/?http:\/\/site.com\/click.php?aff=9917&camp=5626&crt=13346&sid=e6a00014f247fe39de1b_1","footer_text":"text","blank_referrer":"1","active":"1","value":"0.40","creation_time":"1327785202"}];
notice : '&sid=e6a00014f247fe39de1b_1'
i need to add something right after sid=
so that i becomes for example:
Code:
&sid=AlssfIT_e6a00014f247fe39de1b_1
i added: AlssfIT_
any ideas how to achieve this ?
i tried something like
Code:
str.replace("&sid=","&sid="+kwd);
right after i "include" the js file but aparently is not working
I think you're going about it the wrong way. If notice is a variable in the global space you can just replace it normally.
window.someObject.notice = window.someObject.notice.replace("&sid=","&sid="+kwd);
This will of course only work if notice is a variable that is navigable to in the global namespace and is not inside a closure. It is inside a closure if it has a var declaration inside a function() {...}
But, assuming that there is global access to that variable, that will be your easiest way to achieve this.
If not, you can try grabbing the contents of the script and executing it hopefully overwriting the original code. This will only work if your script and the script you are fetching are from the same origin (domain, subdomain, port, protocol, a few other things) - it is impossible otherwise due to the _Same Origin Policy_
Assuming you are at the same origin, you could do something like this (using jquery for simplicity)
( function() {
// First we need the url of the script, we can grab it out of the element directly or it can be hard coded
var scriptLocation = $('script#the-id-of-the-script-element').prop('src');
// Now that we have the location fetch the script again so we can get it as plaintext
// this will usually not do another HTTP request since your browser has it cached
$.get(scriptLocation).done(function(text) { // I prefer the deferred syntax as being more explicit, this is equivalent to $.get(scriptLocation, function(text) {
var newText = text.replace("&sid=","&sid="+kwd);
eval(newText);
});
} )()
Something like this could work.
try regex: (not tested)
myregexp = new RegExp("/&sid=/", "gims");
str.replace(myregexp, "&sid=" + kwd);

How to get the currently loading script name and the url variable of the script?

I am loading a script using the script embed tag and I want to get the url variables and the loading script name inside the script. Is it possible? For Example,
<script src="test.js?id=12"></script>
Inside test.js is there any way to get the url variable id?
Any help would be appreciated.
Thanks,
Karthik
Aside from the answers in the linked post, FWIW with Firefox 4 only you can (with caveats); document.currentScript.src which will return the full url, including arguments.
Thanks for all your efforts I have made that working by assigning an id attribute in the script tag and accessed via jQuery,
<script src="test.js?id=12" id="myScript"></script>
var currentScript = $("#myScript").attr('src'); //This will give me my script src
Thanks,
Karthik
If you want to get a variable from the current URL you can use this:
function queryParser(url){
this.get=function(p){return this.q[p];}
this.q={};
this.map=function(url){
url=url || window.location.search.substring(1);
var url=url.split('&');
var part;
for(var i=0;i<url.length;i++){
part=url[i].split('=');
this.q[part[0]]=part[1];
}
}
this.map(url);
}
var query=new queryParser();
// assuming you have ?test=something
alert(query.get('test'));
I recommend you map the result, so you don't re-parse whenever you want to find a specific element.
I don't really know why you'd pass a query string in a script tag like that, unless you specifically want off-site includes with a simple robust system for various effects. Or are actually using PHP to handle that request.
If you want to "send" a variable to one of your scripts, you can always do:
<script type="text/javascript">
var myVar="I'm in global scope, all scripts can access me";
</script>
<script src="test.js?id=12"></script>
If you really need to get the URL of the currently included script, you can use the code supplied by my peers in the other answers, you can then use:
var query=new queryParser(scriptURL);
alert(query.get('id'));// would alert 12 in your case
Navigating through the link on your comments you can get the proper answer.
Anyway, to make things easier:
var allScripts=document.getElementsByTagName('script');
var indexLastScript= allScripts.length -1;
alert (allScripts[indexLastScript].src);
This will show up "test.js?id=12" as a regular String so its up to you to split it in order to get de param.
Hope it helps, I've tried it on the run over the Chrome Javascript Console. :D.

Categories

Resources