Need help using jQueryUi in Plone - jquery-ui

I'm new to Plone and jQueryUI, and have not been able to get any jQueryUI working on a Plone page.
I installed Plone 4 (4.1.4 41143) and jQueryUI 1.8.16 (http://plone.org/products/collective.js.jqueryui),
Under Zope Management Interface > portal_javascripts, collective.js.jqueryui.custom.min.js is present and enabled.
To try to implement the example from http://jqueryui.com/demos/button/, I placed in the body text of a Plone page:
<script type="text/javascript">
jQuery({function($) {
$( "input:submit, a, button", ".demo" ).button();
$( "a", ".demo" ).click(function() { return false; });
});
</script>
<DIV class=demo>
<BUTTON type=submit>A button element</BUTTON> <INPUT value="A submit button" type=submit> An anchor
</DIV><!-- End demo -->
but the resulting page does not show the expected result.
I've tried replacing "jQuery" in the code above with "$", "collective.js.jqueryui.custom.min", but nothing has worked yet.
I was able to get some jQueryUI working outside of Plone, but would be interested in knowing how to use it within Plone. Any help appreciated.

The content of your script tags is probably being deleted by Plone's HTML filtering.
You can change that in "Site Setup", "HTML Filtering". (The dialog there is confusing, you have to click two buttons. First remove from 'nasty tags', then 'save' at the bottom of page.)
Be aware though, that there are good security reasons for not allowing users to use script, embed and other tags. It can lead to all kind of trouble, for instance when they are also allowed in comments, or less experienced users copy/paste dangerous code.
If you're just practicing, and not putting your site on the big bad Internet, it can be fine, but if you start deploying a real site it is much better to put script stuff into page templates of your own file-based add-on product.

Your syntax within the script tag is incorrect. Try this:
jQuery(function($) {
$( "input:submit, a, button", ".demo" ).button();
$( "a", ".demo" ).click(function() { return false; });
})($);​

Yes, you may need to allow script tags as described above, but the example still did not work for me until I replaced the word jQuery with the $ sign, at least when using collective.js.jqueryui 1.8.16.9 on Plone 4.2.1.1.
<script>
$(function() {
$( "#progressbar1" ).progressbar();
$( "#slider" ).slider();
$( "input:submit, a, button", ".demo" ).button();
$( "a", ".demo" ).click(function() { return false; });
});
</script>
Putting ($) just before the semicolon on the line above also worked but I saw no difference.
The script worked on a file system page template even when script was included in the "nasty tags" list. Also, the script can be inserted into the document's head with the following in a page template:
<metal:slot fill-slot="javascript_head_slot">
<script>
$(function() {
$( "#slider" ).slider();
$( "#progressbar1" ).progressbar();
$( "input:submit, a, button", ".demo" ).button();
$( "a", ".demo" ).click(function() { return false; });
});
</script>
</metal:slot>
(I'd love to hear if there is a more appropriate prefix, but I don't really know javascript.)

I've just had a similar issue trying to get my scripts and jquery UI to work with a plone/zope setup. The solution was to register them in the javascript registry (/portal_javascripts).
The scripts themselves were added to /portal_skins/custom which is also where the homepage I was working on resides.
Script tags are filtered out from the source as already mentioned above, and the scripts from the registry automatically added instead.
Keep in mind also that order is important in the javascript registry.
Hope this is of some help to other users who come across this question,.

Related

JQM 1.4 - What is the preffered way to use pagecontainer event on a specific page/selector?

jQuery Mobile v1.4, we are february 2014.
So, I've read here (gihub) that we are supposed to make an if statement on catched pagecontainer events to assume if the page loaded is the one intended.
Here is a little scenario trying to understand the intended behavior of the new pageContainer widget and it's intended use.
Simple as that, a login page, pre-fetch a welcome page programatically, then switch to welcome page on succesful login. Welcome page have some JS script to animate the page, must be launched only when page is visible. How do we do that ?
Here are the results I got while investigating the pagecontainer events through the console. My goal here is to find a way to detect that my welcome (any page in fact) page is active/visible.
I used this format as query for the sake of understanding:
$( 'body' ).on( 'pagecontainerbeforeload', function( event, ui ) {
console.log("beforeload");
console.log(event);
console.log(ui);
});
So fresh start, when I load a page & JQM for the first time (ie. /Users/login)
Events usable :
pagecontainercreate => empty ui
PCbeforetransition => ui.toPage usable
PCshow => only get a ui.prevPage (which is empty in that case)
PCtransition => ui.toPage usable
Now, these are always launched even if you disabled the transition effects ( See api )
Ok, then I want to programatically load a page (pre-fetch it), I do : (I want /Users/welcome)
$("body").pagecontainer("load", "/Users/welcome");
I get these event launched (the page is not yet visible):
PCbeforeload => I get a url which I could use to identify the page..
PCload => pretty much the same data as PCbeforeload
All right, now I go change my page : (to /Users/welcome)
$("body").pagecontainer("change", "/Users/welcome");
I get these events triggered:
PChide => ui.nextPage is the same as a ui.toPage...
PCbeforetransition => ui.toPage usable
PCshow => only gives ui.prevPage
PCtransition => ui.toPage present as expected
Fine, now I'm pretty sure the only pagecontainer event I want to use to be sure that this page is loaded is pagecontainertransition. Here is what I implemented on every page that needs to launch JS :
Set id of the page container (PHP)
<div data-role="page" data-theme='a' id="<?php echo $this->id_url()?>">
...at the end of the page (JS)
$( 'body' ).on( 'pagecontainertransition', function( event, ui ) {
if(ui.toPage[0] == $('#'+id_url )[0] ) {
functionToLaunchWhenPageShowUp();
}
} );
Now, as you can see, I'm referring to ui.toPage 1st child [0] to compare it to $('.selector') 1st child [0] . Is that the right way to do that ? I mean, the intended way by the new API. Thanks to share your knowledge ;)
I managed to do something that works, is relatively simple, and as close I could to the DRY principle (don't repeat yourself).
In the order they are "loaded" :
JS script in < head > of document
<script type="text/javascript" src="/js/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
(function(){
//Global settings for JQM 1.4.0
$( document ).on( "mobileinit", function() {
//apply overrides here
$.mobile.defaultPageTransition = 'flip';
});
// The event listener in question !
$( document ).ready(function () { //..only launched once the body exist
// The event listener in question :
$( 'body' ).on( 'pagecontainertransition', function( event, ui ) {
//gets the id you programatically give to your page
id_url = $( "body" ).pagecontainer( "getActivePage" )[0].id;
//compare the actual event data (ui.toPage)
if( ui.toPage[0] == $('#'+id_url )[0] ) {
// failsafe
if ( typeof( window[ id_url ].initPage ) === "function" ) {
// call the dynamically created init function
window[ id_url ].initPage();
}
}
} );
});
document.loadPage = function( url ){
$( "body" ).pagecontainer( "load", url , options);
};
document.changePage = function( url ){
$( "body" ).pagecontainer( "change", url , options);
};
})();
</script>
<script type="text/javascript" src="/js/jquery.mobile-1.4.0.min.js"></script>
Start of every returned page
<div data-role="page" data-theme='a' id="<?php echo $this->id_url()?>">
<div data-role="content">
<script type="text/javascript">
// we create dynamically a function named after the id you gave to that page
// this will bind it to window
this[ '<?php echo $this->id_url() ?>' ].initPage = function(){
// put anything you want here, I prefer to use a call
// to another JS function elsewhere in the code. This way I don't touch the
// settings anymore
NameOfThisPage.launchEverythingThatNeedsTo();
};
</script>
...
Here's the description for this code. First, I get one place for all those global query, JQM already forced me to put stuff in-between jquery.js & jquery.mobile.js, so let's use that.
Along with the global JQM settings, I use only one event listener bind to the body/document/(whatever it'll be in the future). It's only launched once the body exist.
Now, here's where the fun begins. I programatically give an id to every pages the server returns (namely the script route with _ instead of / ). You then create a function named after that id, it's attached to the window, (I suppose you could put it elsewhere..).
Then back to the event listener, on transition, you get that id you've set through pagecontainer( "getActivePage" ) method, use that id to grab the page jQuery style, then compare it with the data returned by the event listener.
If success, use that id to launch the init function you've putted in your page. There's a failsafe in case you don't put an init script in page.
Bonus here, are those document.loadPage / changePage . I've putted them there in case the methos to change page changes. One place to modify, and it'll apply to the entire app. That's DRY ^^
All in all, if you have comment on a way to improve this method, please share. There's a big lack of example for v1.4 methods (along with a bit of confusion with v1.3 examples). I've tried to share my discoveries the best I could (ps. I need those rep points :P )

jquery tooltip prevents another script from working

Problem: When I activate jQueryUI tooltip it prevents another script on the page from working.
Description: I have a floating button on a page:
<div id="buttonTOC">
Table Of Contents
</div><!-- End button <div> -->
This is used by the following script to open a hidden div:
jQuery(document).ready(function($){
$("div#buttonTOC").click(function() {
$("div#table-of-contents").animate({height:'toggle'},500);
});
});
This works correctly but if I add a script to use tooltips then it stops functioning and nothing happens on click. The tooltip does work as expected.
I've tried some experiments to get this working including the following attempt to disable 'tooltip' on the div in question but this doesn't make any difference.
jQuery(function($) {
$( 'a#buttonText' ).tooltip({
track: true
});
$('#buttonTOC *[title]').tooltip('disable');
});
I would suspect a conflict between the scripts but then again I assume that something like a tooltip would be able to work regardless of the presence of other scripts.
I'd appreciate any guidance on how to implement this successfully.
Thanks
Your code has a typo:
$( 'p#buttonText' ).tooltip({
track: true
});
It should be a#buttonText, not p
Aside from that, there seems to be no problem with the script.

jQuery UI tabs: How do I load a specific element from a different page?

I have jQuery UI tabs set up, but a problem that I'm having with links to different pages is that they load all contents of the page into the tab. This includes the footer, header, and other navbars that I don't want in the tab. What if I would only like to load a single ID from that page?
My tabs are set up this way:
<div id="mytabs">
<ul>
<li>Awesome page</li>
<li>Foo</li>
</ul>
</div>
Nothing much going on in the jQuery...
$(function() {
$( "#mytabs" ).tabs();
});
Let's say this is the html of "awesomepage" (that the first link targets):
<html>
<head>
<title>awesome page</title>
</head>
<body>
<div id="header">bla</div>
<div id="awesomeness">awesomeness!</div>
<div id="footer">fdsfd</div>
</body>
</html>
...And I only want the tab to load #awesomeness from the page. How would I go about doing this? I've read into some guides that do that by adding a data-target="#youridhere" attribute to the HTML, but I'm still confused on how to implement the javascript. It seems like this is a convenient solution, as I won't be targeting the same ID in every page. Any clues on how to get the javascript working?
Thanks in advance!
The function that allow to load partial code of the response is the $.load() function.
Unfortunately, the tabs() feature does not use this function but use $.ajax instead.
You can try this solution:
You can try to stop the default processing on the beforeLoad callback and manage your ajax call with the $.load() method.
(base on the 1.9 documentation, you may should adapt)
$('#tabs').tabs({
// Callback run when selecting a tab
beforeLoad: function(event, ui) {
// If the panel is already populated do nothing
if (ui.panel.children().size() > 0)
return false;
// Make your own ajax load (with fragment feature)
ui.panel.load(ui.tab.attr('href') + ' #yourFragment');
// stop the default process (default ajax call should not be launched)
return false;
});
NOTICE: I'm not sure about extracting the URL with ui.tab.attr('href'), check before what object is ui.tab, but it should be easy to retrieve the href parameter.
Good luck
Got the solution :) Using one of the answers as a reference point, the tabs can now load a single element specified in the data-target attribute. Here is the modified version:
$(function() {
$('#tabs').tabs(
{
beforeLoad: function(event, ui) {
if (ui.panel.children().size() > 0)
return false;
ui.panel.load($('a', ui.tab).attr('href') + $('a', ui.tab).attr('data-target'));
return false;
}
});
});

JqueryMobile Issues DIVs

I have created a simple .toggle script on one page to toggle a DIV. But when I put this exact same script on another page to toggle another DIV the second page script fails... I have tried multiple fixes but nothing works
Here is the script I am using on both pages The IDs are different but the script is the same
<script>
$(document).bind('pageinit', function() {
$('#slick-toggle').live('tap', function(event) {
$("#menu_box").toggle(400);
});
});
</script>
Any help would be greatly appreciated
Capt. Crunch
You may try the following:
<script>
$( document ).on( 'pageinit',function(event){
$('#slick-toggle').on('tap', function(event) {
$("#menu_box").toggle(400);
});
});
</script>
Hope this helps, let me know about your result.

can't hook JQuery quickSearch to the table - MVC

I am trying to use quickSearch from http://lomalogue.com/jquery/quicksearch/ website. I don't know how to hook to the table so I hoping someone could be kind enough to help me here. I am using VS 2010 MVC 3, in C#, ADO.NET. Thanks in advance. I had a look at related question on the website, if there is a technical gitch? Is there alternative solution? Thanks in advance.
View file Index.cshtml looks like this...
Edited
<script type="text/javascript">
$(function () {
$("table.tablesorter").tablesorter({ widthFixed: true, widgets: ['zebra'],
sortList: [[0, 0]] })
.tablesorterPager({ container: $("#pager"), size: $(".pagesize
option:selected").val() });
});
</script>
<script type="text/javascript">
$(function ()
{
$('input#search').quicksearch('table tbody tr', {selector:'th'});
}
);
</script>
</p>
<table class="tablesorter">
Also it could solve any code organisation problems if you are to wrap the JQuery statement in this
$(document).ready(function() {
$('input#search').quicksearch('table tbody tr', { selector: 'th' });
});
Also the table quick search plugin i use is JQuery table search plugin, it works well and if you just take a quick look at the demo it is rather easy to implement and does not clash with most other JQuery table plugins.
While I haven't used QuickSearch before, and I'm not sure if it'll solve all of your problems, but as a start it appears that you've put your first script element too early in your document.
You need to put it after the other script elements.
this:
<script type="text/javascript">
$('input#search').quicksearch('table tbody tr', { selector: 'th' });
</script>
should appear after the the jquery script, and the quicksearch script elements. If you include it before, the browser doesn't know what $ and $(selector).quicksearch is.
btw: this:'input#search' selector is not needed.
you can use the #search selector to same effect, becuase searching by id is a one command in JS.

Resources