Copy link to clipboard
Copied
CP9 - HTML5 only
Hello,
I need to hide Groups using Javascript stored in an external library.
It appears that Javascript cannot hide a Group using the Group name.
The only way to do it is to hide each individual item in the group.
Although this is tedious and requires the names of the items in the Group to be numbered, it is the only way I know of doing this.
If anyone can suggest a better way I would really appreciate it, as I have about 100 groups that I need to do this with.
Thank you
Peter
This is my code:
function myHideGroup(GroupName){
// Hide all items in a Group.
// Items in the Group must be named with the Group name followed by a number.
// Example item names, 'doctor01' 'doctor02' etc.
// Name of the group to be hidden.
var tmpGroupName = GroupName;
// Define vars to use.
var tmpItemName = "";
var tmpItemNumber = "";
// Loop through all the items in the group.
var myLoop;
for (myLoop = 1; myLoop <= 50; myLoop++) {
//Convert item number to a string so it can be used in the item name.
var tmpItemNumber = myLoop.toString();
//Pad the item number with zeros to match my names in captivate.
while (tmpItemNumber.length < 2) {tmpItemNumber = '0' + tmpItemNumber;}
//Concat the GroupName and ItemNumber to create the name of item to be hidden, such as 'doctor01'.
var tmpItemName = tmpGroupName.concat(tmpItemNumber);
//Hide the item
cp.hide(tmpItemName);
}
End of message.
You are correct that there are no groups when the file is published. Captivate just executes script to hide all of the individual objects the same as what your script is doing.
I use a script that resets the slide to all objects original visibility state and then shows the objects with the specific naming convention.
Your script could be modified slightly to get all of the items on a slide and check if the GroupName is in the name of the element.
Since jQuery is available you can just do this:
hideG
...Copy link to clipboard
Copied
Sorry, corrected a typo in the subject because Java is a totally different language than JavaScript.
I suppose you mean an external JS-file? External Library in Captivate has another menaing to me: library from a previous project opened in the present project (File, Import menu) that allows you to reuse assets, including Shared Actions.
Grouping happens on the stage. Is there any reason why you cannot simpy choose 'Hide Group' command, either with a simple, an advanced or a shared action. All will be converted to JS on runtime. Beware: you may have a reason for preferring JS, but that is not clear from the description.
Can you check the version number: it should be 9.0.2.437.
Copy link to clipboard
Copied
Lilybiri,
Thank you for the correction.
I need to use Javascript as there are lots of other actions taking place that are already in the java library.
The solution I would like to use is to be able to somehow get a list of the item names of the items in the group, and then hide each of them.
Thank you
Peter
Copy link to clipboard
Copied
IWhy no combination? I mean combining a simple command with JS? Like just hiding a group in combination with calling a function?
Copy link to clipboard
Copied
Lilybiri,
The reason I prefer to use Javascript is that the features offered by Captivate offer a fragmented suite of facilities, such as:
These are just four of the different ways to control Captivate, I find it awkward and complicated to split the control of the project between these different features.
Even when using these features they have their limitations, such as not being able to use variables in many commands. I see no benefit in using these features and then utilising Javascript to fill in the gaps when Captivate cannot offer a solution.
I would rather have one single location to control the flow and operation of the project. The only way to do this is to control everything from a single external library of Javascript functions.
Using external Javascript enables me to do simple and useful tasks quickly, such as:
1) Global Search and Replace on a variable name.
2) REM out lines of code to help locate errors.
3) View the overall flow of the project.
4) Type comments and notes in the Javascript to help document the logic.
When I work with Captivate I prefer to use as few features as possible, such as using SmartShapes as Buttons and Clickboxes, rather than using a combination of all three. So using Javascript as the main way of controlling Captivate fits with my way of working.
I hope that explains why I would prefer to use Javascript.
Thank you
Peter
Copy link to clipboard
Copied
It has not much sense to answer, just see that you never even tried to udnerstand how actions are working in Captivate at all. JavaScript is also event-driven. There are events included in Captivate, but with CpExtra (for HTML5) or EventHandler widgets I can create many more events. CpExtra moreover allows lot more extensions of the actions functionality
Just like in any programming language you can combine commands that alswya have to be done with loops, conditions etc... Bothc advanced and schared actions are created in the same dialog box, it is the way of saving them and defining parameters that make shared actions more flexible, the same way you can create functions in a programmng language to resuse over and over again. One of the big advantages of shared actions over advanced actions is that they have descriptions, are documented and appear as aeets in the Library (which can be used as external Library in any other project).
You talk only about the advantages of JS, never about the disadvantages. Most clients can manage to understand an advanced/shared action and are able to edit them. Can you do the same with JS? How much time do you spend on debugging?
Just FYI I programmed in many languages, probably even before you were born, before the first PC and Mac appeared. I appreciated the simplicity of the point-and-click advanced actions, and use JS in combination when I have to add functionlities that are not possible with CP nor with CpExtra.
There are some great JS experts around on this forum that are very helpful. They never forced me to defend the advanced/shared actions.
WHy do you group objects if you cannot use those groups as I can in actions? That is the main reason why I group a lot, although with the release of multistate objects already not as much as in prevuos versions
Copy link to clipboard
Copied
CpExtra's @syntax and/or #syntax might be a solution for this issue:
http://www.infosemantics.com.au/adobe-captivate-widgets/cpextra/help/basic-concepts/at-syntax
Copy link to clipboard
Copied
It can easily be done - check with David at TLC media.
Copy link to clipboard
Copied
Thank you all,
I spent a few hours hard coding!
Would still love to hear from anyone with a solution.
Cheers.
Peter
Copy link to clipboard
Copied
You are correct that there are no groups when the file is published. Captivate just executes script to hide all of the individual objects the same as what your script is doing.
I use a script that resets the slide to all objects original visibility state and then shows the objects with the specific naming convention.
Your script could be modified slightly to get all of the items on a slide and check if the GroupName is in the name of the element.
Since jQuery is available you can just do this:
hideGroup('doctor');
function hideGroup( which )
{
$("*[id*="+ which +"]:visible").each(function()
{
cp.hide( $(this).attr( "id" ));
});
}
This will hide all objects with "doctor" in the name.
Copy link to clipboard
Copied
TLC.
Big thank you!
That code is just so useful.
I have added it into my library of external Javascript and I'm sure I can use it in other projects.
Much appreciated.
Peter
Copy link to clipboard
Copied
You could also create an array of all of the item you show and use that function to show and hide.
How are you showing the group items to begin with?
Copy link to clipboard
Copied
Hmmm.. and when I want to hide an id that begins with CirkellineC - only when I mouseclick on a button which ID begins with ButtonC - I tried this:
$('[id^="ButtonC"]').mousedown(function(){
hideGroup('CirkelineC');
function hideGroup( which )
{
$("*[id^="+ which +"]").each(function()
{
cp.hide( $(this).attr( "id" ));
});}
I can't get it to work.
/Jacob
Copy link to clipboard
Copied
Grouped objects in Captivate are not actually grouped in the output code. They only really exist in the interface at Edit time. Your code needs to specify all of the objects in the group and hide them explicitly.
Copy link to clipboard
Copied
Hi Ian,
I'm aware og that. Every objects have the same id^
Copy link to clipboard
Copied
Where is the JS being executed, is it in an external file? Just wondering because you are attaching an event listener. Have you tried looking in the console to seee if there are any errors?
Copy link to clipboard
Copied
Hi again,
The JS lib is just the CP js's.
I use $('[id^="ButtonA"]' depending on which device the learner usses (cpInfoMobileOS). This part works (but not included in this issue solving).
What should I look for in the console?
I have 20 (home build) multiple choice slides all with objects $('[id^="ButtonA"]'), $('[id^="ButtonB"]', $('[id^="ButtonC"]', and $('[id^="ButtonD"]'. And four buttons that should match the choices.
If $('[id^="ButtonA"]').mousedown(function(){
Then it should hide ID^=CirkelineA
I will then make a switch case
else
id^ButtonB
B, C, D and CirklineB, C, and D.
All this above is because I got some issues with cp states on Android and IOS. I got no reply when I asked the question below, so I look into another solution with the mess above.
/Jacob
Copy link to clipboard
Copied
You could use this, adding an if staement for each of the buttons and groups:
var btn = document.activeElement.id;
if (btn === 'ButtonC')
{
hideGroup('CirkellineC');
}
function hideGroup( which )
{
$("*[id*="+ which +"]:visible").each(function()
{
cp.hide( $(this).attr( "id" ));
});
}
I would change the naming conventions of your buttons and groups to make the code more dynamic though. Since it's basically hard coded with the groups and button names with the if statement, why are you just not executing the captivate hide command?
Copy link to clipboard
Copied
Last time I tried to show and hide groups with JavaScript, here is what I did.
It is very similar to what you have done with some minor adjustments.
Would an approach like this work for you?
The function is placed as an onEnter action.
function hideGroup(gpCode) {
$("*[id*="+gpcode+"]").each(function() {
cp.hide($(this).attr("id"));
});
}
In my case, gpcode is a common tag I give to all items in my group.
So if I wanted to hide five boxes in a group, I might name them as follows...
box1_test
box2_test
box3_test
box4_test
box5_test
Then I can pass in "_test" as the gpcode when I call the function on my button.
hideGroup("_test");
Hopefully you find something useful out of this.
Copy link to clipboard
Copied
I made this for a menu a while ago.
Works like a charm.
$('[id^="Menu"]').each(function( index ){
if($( this ).css('visibility') ==='visible')cp.hide(this.id)
else cp.show(this.id);
});
But in the actual case my issue is that all objects are hidden from the beginning when I'm entering a slide and it should only show object1 if I click on button1 and let all other objects be hidden or just execute cp.show except for the mousedown object (or hide only for the clicked object, it is shown). If the student changes his mind and chooses button2, 3 or 4, it should then hide object1 and vice versa.
/Jacob
Copy link to clipboard
Copied
So then I would have two functions.
One to hide and one to show.
Button 1
showGroup("_grp1");
hideGroup("_grp2");
hideGroup("_grp3");
hideGroup("_grp4");
Button 2
showGroup("_grp2");
hideGroup("_grp1");
hideGroup("_grp3");
hideGroup("_grp4");
etc
Copy link to clipboard
Copied
Hmmm....
I think I got a bit confused of all this JS re-editing.
But here is a screenshot, where I made some renaming. I hope that could help me reaching the goal using mousedown(function() / click(function() when entering a slide.
/Jacob
Copy link to clipboard
Copied
So you are not using groups, this JS will work with your setup, execute this JS on slide enter:
var elemsShow = [];
window.cpAPIEventEmitter.addEventListener("CPAPI_SLIDEENTER", function(e)
{
for ( var i = 0; i < e.Data.si.length; i++ )
{
if ( e.Data.si[ i ].n.indexOf( 'Button') !== -1 )
{
document.getElementById(e.Data.si[ i ].n).addEventListener( 'click', showElem, false )
}
if ( e.Data.si[ i ].n.indexOf( 'checkmark') !== -1 )
{
elemsShow.push(e.Data.si[ i ].n);
}
}
});
function showElem( e )
{
var a = e.target.id.charAt( 0 );
for ( var i = 0; i < elemsShow.length; i++ )
{
if ( elemsShow[ i ].charAt(0).toLowerCase() === a )
{
cp.show(elemsShow[i]);
break;
}
}
}
Copy link to clipboard
Copied
Thanks so far!
It's shows the checkmarks, but does not hide them again when I click on the same or another. Do I need to add cp.hide(elemsHide[i]);
/Jacob
Copy link to clipboard
Copied
Change to this:
var elemsShow = [];
window.cpAPIEventEmitter.addEventListener("CPAPI_SLIDEENTER", function(e)
{
for ( var i = 0; i < e.Data.si.length; i++ )
{
if ( e.Data.si[ i ].n.indexOf( 'Button') !== -1 )
{
document.getElementById(e.Data.si[ i ].n).addEventListener( 'click', showElem, false )
}
if ( e.Data.si[ i ].n.indexOf( 'checkmark') !== -1 )
{
elemsShow.push(e.Data.si[ i ].n);
}
}
});
function showElem( e )
{
var a = e.target.id.charAt( 0 );
for ( var i = 0; i < elemsShow.length; i++ )
{
if ( elemsShow[ i ].charAt(0).toLowerCase() === a )
{
cp.show(elemsShow[i]);
}
else
{
cp.hide(elemsShow[i]);
}
}
}