How to let menu item execute Javascript in Joomla 3.2? - joomla3.2

Before 3.2, I can set the menu item type to "external link" and then set the link as
"javascript:myFunction()"
When clicked, the menu item will call the JavaScript function. But after I upgraded to 3.2, when I did the same thing and tried to save the menu item, it said "Save not permitted".
Did 3.2 block this usage? If yes, how do I get my JS function executed by a menu item?

I've came up this problem a while ago, in Joomla version 3.2.1 concerning a 'Skype' link, e.g.
skype:myloginname
This has to do with the protocol types that are allowed and are defined in this file:
/administrator/components/com_menus/controllers/item.php, line ~180.
There is an array that defines the acceptable schemes:
$scheme = array('http', 'https', 'ftp', 'ftps', 'gopher', 'mailto', 'news', 'prospero', 'telnet', 'rlogin', 'tn3270', 'wais', 'url', 'mid', 'cid', 'nntp', 'tel', 'urn', 'ldap', 'file', 'fax', 'modem', 'git');
When adding skype at the end of the list Joomla! allowed saving the external link. The same applies for javascript. In any case you should consider any security risk that comeswith this solution.
In addition, you should take into mind that this override may be discarded in any future update of joomla.

Technically speaking Joomla thinks that javascript is a protocol, like HTTP & Co., it looks it up inside a list of known protocols, it does not find it and it throws an error.
Start reading at around line inside [MenusControllerItem::save()][1]. So basically it has nothing to do with the fact you are trying to use some JavaScript, this is just a side-effect.
While using JavaScript in the External Link is not really an advertised feature but rather said a loophole, it does break b/c if you have used before.
You can:
Open an issue in the Joomla Issue Tracker and report this issue, get some community feedback. The fix is really easy, it just needs to get accepted.
Use the suggestion below:
Instead of link put #
Set the field "Link CSS Style" to something that does not colide with other classes, eg. my-function
Save
You can use jQuery to intercept the click event on the link and to make it run your function. See code below:
jQuery(document).ready(function($){
// Select element based on the class set in Joomla backend
$( ".my-function" ).on( "click", function(e) {
// Do not follow the link
e.preventDefault();
// Call function
myFunction(1);
});
});
function myFunction(x)
{
alert("I was called" + x);
}
Update: after a short discussion with the commiter of the change, I understood that it may be related to a security issue. So it may be on purpose after all not to allow js.

Related

Contact Form 7 on_submit is not working

I am trying to show an alert when the form is submitted.
I added this code to "Additional Settings" on Contact Form 7 plugin (Version 4.2.2)
on_submit:"alert('Submitted');"
Nothing appears.
No errors nor warnings at console
No errors nor warnings at firebug
I guess no Javascript conflict since Contact Form 7 succesfully
sends emails
I am sure that form is "submitted" because i can see Contact
Form 7 form validation errors
Any ideas how to solve or debug further this issue?
It is not easy to take a guess without seeing the source code but I feel happy today.
Is your form working at all?
If not, it is probable that Contact Form 7’s JavaScript is not functioning on your site.
I’ll show you a few possible causes for this.
JavaScript file is not loaded
This is the cause that I’ve been seeing the most recently. This is due to your template, which is missing calling functions for queuing JavaScript. The functions required are wp_head() and wp_footer(), and they are in header.php and footer.php, respectively, in most correct themes.
Conflicts with other JavaScript
Many plugins and themes load their own JavaScript. Some of them may have been created incorrectly and therefore conflict with other plugins. In most cases, you can find JavaScript errors with Firebug, an add-on for Firefox, when such conflicts occur.
HTML structure is not valid
Like other JavaScript, Contact Form 7’s JavaScript traverses and manipulates the structure of HTML. Therefore, if the original HTML structure is not valid, it will fail to work. You can check whether your HTML is valid or not with an HTML validator. I recommend the W3C Markup Validation Service for use in such a case.
My advice is to use CF 7 default way of implementing your idea - we'll call it:
"1. Best option".
At WP Dashboard, go to Contact (CF7) and choose your form and go to the tab called "Additional Settings".
There, you can add similar code like this:
on_sent_ok: "alert('sent ok');"
on_submit: "alert('submit');"
If you set on_sent_ok: followed by a one-line JavaScript code, you can tell the contact form the code that should be performed when the mail is sent successfully. Likewise, with on_submit:, you can tell the code that should be performed when the form submitted regardless of the outcome.
On both of the actions, you can use every kind of JS code like you would in your .js file:
on_sent_ok: "some js code here"
You can use it to call functions like this:
on_sent_ok: "your_function();"
Or write some code (this one redirects to thank you page):
on_sent_ok: "document.location='/thank-you-page/';"
2. And another option is to handle it with jQuery:
Contact Form 7 is keen to emit a number of Javascript events that bubble up to the document object. In version 4.2 they can be found in contact-form-7/includes/js/scripts.js. If you're using jQuery you can access those events like this:
$(document).on('spam.wpcf7', function () {
console.log('submit.wpcf7 was triggered!');
});
$(document).on('invalid.wpcf7', function () {
console.log('invalid.wpcf7 was triggered!');
});
$(document).on('mailsent.wpcf7', function () {
console.log('mailsent.wpcf7 was triggered!');
});
$(document).on('mailfailed.wpcf7', function () {
console.log('mailfailed.wpcf7 was triggered!');
});
EDIT:
Some of these jQuery options are used but somehow deprecated so if you encounter problems, try using eg. 'wpcf7:mailsent' instead of 'mailsent.wpcf7'.
The same format goes for other option, actually all the options are observable in the mentioned file:
wp-content/plugins/contact-form-7/includes/js/script.js
do you have any link for us to further check this? It's pretty hard like this.
But: "I am sure that form is "submitted" because i can see Contact Form 7 form validation errors" -> is it server-validation or frontend-validation? Maybe it is NOT send?
All the best
I think something is blocking your popup.
Try debugging using "console.log", so you can eliminate this as a potential issue:
on_submit:"console.log('Submitted');"

jquery mobile 1.4.5 single-page template href querystring ajax

I am a newbie to JQM (I use 1.4.5) and my webapp (asp.net C# apache Cordova) contains many separate pages of .cshtml (single-page template) only. I am testing my webapp on a Samsung Galaxy Grand using Android 4.2.2
A.
I am not sure about my understanding of 'linking pages', even after reading all the JQM docs on this and also after reading up many, many posts on this topic about passing querystring values to another page; mainly because I find that ALMOST ALL the examples are directed towards providing answers for internal pages (Multi-Page template) within a single html page.
So I request some of you JQM experts to confirm or correct the following understanding of mine....
From the JQM docs I understood that
I could use in any link (e.g button), href="page2.cshtml?par1=1&par2=2"; and JQM will automatically use Ajax for this link to work.
I also understood that use of querystring is always allowed in such cases of different html pages of the same domain and it will work via Ajax automatically ; so long as the attr such as rel="external", data-ajax="false" etc. are not used in the same link.
but querystrings are not allowed in case of the internal pages (multi-page template) only....;
and if I need to use the above href to link to a page in another domain e.g. www.anotherdomain.com/page2.cshtml?par1=1&par2=2, then I need to use rel="external".
Are all my above points (that reflect my understanding) CORRECT? KIndly confirm ro please correct me ...
B.
In my app, I find that most of the links work according to my understanding as above, to connect to different pages in the same domain; and I assume it happens via Ajax. Is it correct? I am also able to use the querystring params in page2 ( i.e. To-Page).
But in one case, though it works, in the To-Page the Panel features do not operate correctly, unless I introduce rel="external' in the href link !!! I suppose it means it IS NOT AJAX anymore? Also I am unable to find the reason..
Further independent of the above topic, I face another issue. The loading time (i.e. Time taken to display the To-Page) varies.
Mostly it is OK, but at times the loading-circle goes on forever.... and I presume it has crashed....??? then If I go back using the back button and come forward again, many times it loads immediately...!!!!!
Any thoughts or suggestions.....?
Thanks in anticipation...
Ratna
Before you can worry about how to pass attributes from one page to another you need to understand the difference between multi-page and multi-HTML templates.
Multi HTML page template
Smaller and lighter, each data-role=”page” is inside a separate HTML file and page structure is much more modular.
Can become even smaller if every subsequent HTML page is stripped from HEAD content, or anything that isn’t data-role=”page” div. Unfortunately in this case fallback if JavaScript is not supported is out of question.
DOM size is relatively small, only first page is permanently loaded into the DOM, any other page will also be loaded into the DOM but at the same time it will also be removed when not used actively, basically each time you move from it.
Better fallback if JavaScript is not supported. Works great in desktop browsers after a page refresh, mainly because every HTML page has an existing HEAD content. This also allows your app to behave like normal web app mainly because AJAX can be turned off.
Multipage template
Since all pages are already loaded, no additional requests are generated for navigating between pages.
First load is slower as the file size is larger, but subsequent page navigation is fast, thus making transitions much more smooth. Almost native-like smooth, emphasize on almost.
Suitable for relatively smaller applications and situations where you know the capabilities of your target platforms including presence of JavaScript support, thus making it a great solution for a hybrid app. It works much better as a Phonegap app then multi HTML template.
The “page” data-role element is required.
More about this topic can be found here: Multipage template vs Multi HTML template in jQuery Mobile
Now let's talk about how to properly pass data between jQuery Mobile pages.
jQuery Mobile uses AJAX by default
You can turn off AJAX using rel="external"
If you turn off AJAX you will lose almost everything good about jQuery Mobile, including animations. So if you don't want AJAX page handling better find some other responsive framework like Bootstrap or Foundation.
If you don't want to use AJAX you can still use querystrings but inside a href or via changePage function.
Better querystrings alternatives:
Global object.
If you're using AJAX you can simply use a global object(s) to store all of your data.
Something like this:
// Store object
var storeObject = {
parameter1: null,
parameter2 : null
}
Access data from the previous page
Again if you're using AJAX you don't need to pass any data because all that data is till in the DOM.
// Store object
$(document).on('pagebeforeshow', '#second', function(e, data){
alert("My name is " + data.prevPage.find('#test-input').val());
});
Localstorage or Sessionstorage
This solution will work no matter if you use AJAX or not.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#change-page-button', function(){
// store some data
if(typeof(Storage)!=="undefined") {
localStorage.firstname="Dragan";
localStorage.lastname="Gaic";
}
// Change page
$.mobile.changePage("#second");
});
});
$(document).on('pagebeforeshow', '#second', function(){
alert('My name is ' + localStorage.firstname + ' ' + localStorage.lastname);
// Lets change localStorage data before we go to the next page
localStorage.firstname="NewFirstNeme";
localStorage.lastname="NewLastName";
});
$(document).on('pagebeforeshow', '#third', function(){
alert('My name is ' + localStorage.firstname + ' ' + localStorage.lastname);
});
Send data through changePage function or via href
// Send
$.mobile.changePage('page2.html', { dataUrl : "page2.html?paremeter=123", data : { 'paremeter' : '123' }, reloadPage : true, changeHash : true});
or
Send parameter
receive that same data:
$(document).on('pagebeforeshow', "#index", function (event, data) {
var parameters = $(this).data("url").split("?")[1];;
parameter = parameters.replace("parameter=","");
alert(parameter);
});
If you need more information about this solutions including working examples find them here: Passing data between jQuery Mobile pages
Several methods mentioned here are deprecated (still usable) in the version 1.4. Though you don't need to worry about that, almost everything here will be unusable in version 1.5. This new version will overhaul jQuery Mobile from the bottom to the top.
Update
Yes, you can use any such link and jQuery Mobile will use AJAX. If you take a look at my previous examples you will find a working one.
If you want AJAX you CAN'T use rel="external", data-ajax="false" though stringquerys will work in bot cases.
Correct they will only work in multi-HTML template. Though there used to be a 3rd party plugin that allowed this to work with multi-page template but I don't think it works with newer jQuery Mobile versions.
Correct, if you want to link external page you need to use rel="external".

Upgrading to new asynchrous Google Analytics code - should you do it?

I had read somewhere and have now forgotten that upgrading to the new asynchronous code will not enable one to track actual clicks for downloading items when user stays on the same page and that for tracking that you need to use the old version of GA code.
My question is, is that still the case and does anyone have any other reasons for not upgrading to use the newer asynchronous tracking?
thanks
Hmm...are you sure the "old" version of GA automatically tracked downloads? AFAIK GA never automatically tracked download links, that you always had to attach GA code (like a _trackEvent call) to your links yourself. But in any case, it's pretty easy to do it yourself, so it's really not a big deal. Plus, you get lots of benefits upgrading, and one day it may not even be an option to stick with the old version...
If you have jQuery you can for example do this:
// file types you want to consider a download
var downloadFileTypes = ['pdf','doc','docx','mp4'];
$(document).ready(function() {
$('a').filter(function() {
var ext = $(this).attr('href').split('.').pop().toLowerCase();
return ( $.inArray(ext, downloadFileTypes )>-1 );
})
.click(function() {
_gaq.push(['_trackEvent', 'Downloads', $(this).attr('href')]);
});
});
If you do not have a framework like jQuery, you can still do this easy enough with .getElementsByTagName() and using regular loops and conditions instead of the jQuery conveniences like .filter and .inArray
edit: Some things to note about that example:
the jQuery code was an example to hook the GA code to standard links pointing to the file types you specify in downloadFiletypes. It will only apply to links that exist at the time the code is executed. If you have links that may be dynamically generated on the page later, consider looking into .on() instead of .click()
you will need to make tweaks to matching links you want to consider downloads if they do not point to regular files with extensions. For instance, some websites have a controller script that expects a parameter with an ID and it dynamically serves up a pdf or whatever..if your files are like this, you will have to alter the logic to look for that instead.

Open a link in a new window in reStructuredText

I want to open a link in a new window using reStucturedText. Is this possible?
This opens link in the same window:
You can `check your location here. <http://geoiptool.com>`_
To open a page in a new window or tag you can add the attribute target="_blank" to your hyperlink although I'm not sure how you can add attributes to inline hyperlinks in reStructuredText. However, from the Docutils FAQ, is nested inline markup possible, you can use the raw directive to include raw HTML into your document, for example
You can |location_link|.
.. |location_link| raw:: html
check your location here
Update to address comments
I've had the question "why does reStructuredText not have [insert some awesome feature]".
In this case, "why does reStructuredText not have a way to specify how links are opened" — I think reStructuredText doesn't have an easy way of doing this since the behaviour of how clicking a link works isn't really it's responsibility. reStructuredText transforms markup — how that markup is ultimately displayed is not up to reStructuredText, but whatever browser or viewer the user chooses to use.
In the case of opening a link in a web browser, good useability practice dictates that you should not force a user to open a link in a new tab (which is what adding target="_blank" is doing). Rather, you should leave the choice of how to open the link up to the user. If a user wants to open a link in a new tab, then they can use their middle mouse button (or whatever their favourite shortcut key is).
So I think that it is perfectly acceptable that reStructureText does not have an easy target="_blank" feature. The fact that it is possible is nice for people who really want to do this is good, and the fact that it is a bit of pain to do so is good for discouraging this practice.
If you don't want to modify the theme, you can do what Ivonet did but with a custom.js file in the _static/js folder, then adding it to the conf.py like this:
html_js_files = [
'js/custom.js'
]
Leave out the html tags in _static/js/custom.js if you do this:
$(document).ready(function () {
$('a[href^="http://"], a[href^="https://"]').not('a[class*=internal]').attr('target', '_blank');
});
This will also work if you'd like a shorter version.
$(document).ready(function () {
$('a.external').attr('target', '_blank');
});
I agree completely with the accepted answer, especially with the part where reStructuredText is not responsible for how a link behaves.
I still want it though so it should be solved in the theme. As I want all my external links to open in a new tab it becomes very cumbersome to do it as described above.
In my case I use a third party theme (sphinx_rtd_theme) and I put the following script near the end of the layout.html:
<script type="text/javascript">
<!-- Adds target=_blank to external links -->
$(document).ready(function () {
$('a[href^="http://"], a[href^="https://"]').not('a[class*=internal]').attr('target', '_blank');
});
</script>
It seems to do the job just fine.
Hope it helps.
I recommend that you should use JavaScript to set target="_blank" for each external links.
See https://github.com/sphinx-doc/sphinx/issues/1634

Trying to use the swfobject.js youtube object inside of WordPress

I need to use the extra powers of the swfobject api. This object is a new way of embedding Youtube videos into web sites.
Pasting code that I found from Google's tutorial directly into the WordPress editor was in-effective. WordPress would not treat this as active code.
So, I created a new template file and inserted my code into that file. This worked relatively well. The code went live and I got the extra feature that I was looking for, which was that I am able to have the visuals of the video autoplay, and to have the sound muted by default.
However, this has messed up the layout and flow of my menus which where just above the video.
Can anyone tell me where to proper place to put this code is, or is this question too specific. If it will help you can see the messed up page at:
http://bestoftimesusa.com/home-mute-test/
and how it is supposed to look at:
http://bestoftimesusa.com
The fully functional code that got embedded is this:
<script type="text/javascript" src="/wp-includes/js/swfobject/swfobject.js"></script>
<div id="ytapiplayer">
You need Flash player 8+ and JavaScript enabled to view this video.
</div>
<script type="text/javascript">
var ytplayer = false;
var params = { allowScriptAccess: "always" };
var atts = { id: "myytplayer" };
swfobject.embedSWF("http://www.youtube.com/v/IBjstQceGBk?enablejsapi=1&playerapiid=ytplayer&version=3&autoplay=1",
"ytapiplayer", "370", "238", "8", null, null, params, atts);
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
ytplayer.mute();
}
</script>
</div>
Unless you want the same youtube video to appear on all pages (of a certain type), I don't think putting that entire block in your template files makes sense. The only part that really makes sense for a template file is the first line. The lines after that are video-specific.
By default, WordPress filters out javascript from posts. You can disable that filtering with a plugin which would allow you to include javascript in your posts.
Using that plugin, you can set javascript filters on a global or per-post basis. It seems like a per-post basis would work for you so I'd go with that, just enabling it on the page I wanted.
Two last things:
You could put the first line in one of your template files to eliminate having to put that in every post
You have one opening <div> tag but two closing </div> tags, that could be expected, but I'd double check.

Resources