PDA

View Full Version : Switch Content Script II



nathalie123
11-23-2005, 11:19 AM
Hi There,

In the great Swith content script part 2 the content is automaticly expanded when you visit te page.... That whas not the case in part 1.. only part 1 is not compatible with Opera..

Does anyone know what to change in the script that it on load not automatically expands te content but that you really have to click top open the content as in part one!

Thanks.....

jscheuer1
11-24-2005, 10:01 AM
To really get this script working like that in the three browsers it is designed for, a few changes need to be made.

First do a global search and replace on this:

search for:

"none" : ""

replace with:

"none" : document.body.filters? "block" : "table-cell"

Make sure you get them both (there's only two but, be sure).

Next add in this code just after the credit, so it looks like so (additions red):


/***********************************************
* Switch Content script II- Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
if(document.getElementById)
document.write('<style type="text/css">\
.switchcontent{\
display:none;\
}\
</style>')

Finally, add this line into the function do_onload(), as shown (red again):


function do_onload(){
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && get_cookie(window.location.pathname)!="" && ccollect.length>0)
revivecontent()
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
sweeptoggle('contract')
}

Note: This breaks the persistence feature so, until someone figures out how to update it, you should not try to use it.

guvenck
11-26-2005, 09:40 AM
Thanks for your help, that was something I also was wondering...
But, after applying your patch above, the look changed in my browser, Firefox. Before the patch, both IE and FF were displaying the same output, but after the patch, the switchcontent part gone narrow for a few pixels. Here I send you two screenshots attached:

What do you think this might happen?

jscheuer1
11-26-2005, 01:47 PM
Sounds like you may have missed this part of the instructions:


First do a global search and replace on this:

search for:

"none" : ""

replace with:

"none" : document.body.filters? "block" : "table-cell"

Make sure you get them both (there's only two but, be sure).

If that isn't the problem I'd need to see your code, so either:

.

or:

Post your code here, put code tags:




code goes here



around your code in messages here so that it appears as it was when you copied it from your page.

holden
11-27-2005, 04:44 AM
Dear jscheuer1,

Thanks so much for this script. I would also prefer that everything is collapsed when the page loads. I have updated the script with your edits and have run into a problem simular to nathalie123's.

It works perfectly in IE, but the table is distored in FF and Opera when it loads collapsed (as I want it) but then when you expand it, it becomes even more distorted. It worked perfectly in every browser before I made the edits you suggested.

Perhaps I did something wrong?

Here is a link to the page i'm working on:
http://encorelessons.com/switch.html

Any help would be greatly appreciated.

Thanks so much,
Holden

jscheuer1
11-27-2005, 06:22 AM
holden,

You haven't followed the original demo's example markup. In that, each block of content to be expanded was contained within a single table-cell (a <td>) element. You have chosen to use a table row (the <tr>) element. And, for some reason, this also prevents the sweeptoggle function from locating the expand/contract symbol correctly, I'll worry about that later, in another post, if I get to it. The bigger problem is the layout of the content. To fix that, all you need to do is change it in the script where we put:

table-cell

to

table-row

Do this in both places. That will accurately reflect the type of display property these elements should have now that you've changed them from td's (from the demo) to tr's in your markup.

One sure way to get it working 100% is to follow the demo's example markup and to set 'var enablepersist="off"', as I advised originally.

jscheuer1
11-27-2005, 06:38 AM
holden,

The problem with the sweeptoggle not finding the + and - images is another omission on your part from the demo, each place that you have:


<img src="images/minus.gif" onClick="expandcontent(this, 'ca')" />

It needs to be:


<img class="showstate" src="images/minus.gif" onClick="expandcontent(this, 'ca')" />

Make the change to table-row from my previous post, add in these class names that you have omitted and set:

var enablepersist="off"

And you will be in business.

Added Later: I notice that the 'Contract Locations | Expand Locations' part is off center in IE. If you remove the width attribute from its cell, it will line up and not be adversely affected in other browsers. Take out the red part:


<td width="218" colspan="5" align="center"><a href="javascript:sweeptoggle('contract')" class="switch">Contract Locations</a> | <a href="javascript:sweeptoggle('expand')" class="switch">Expand Locations</a></td>

jscheuer1
11-27-2005, 09:14 AM
OK, folks, I solved the persistence problem with this script when converted to having an initial state of all items closed. I've also added language that allows one to use a <tr>, a <td> or an ordinary block level element as the containers for the expandable content. I've even enabled persistence with Opera, something even the original did not have. There still will be problems in some browsers if your expandable content container is a table (a table may be OK), a li or a ul tag, or an inline element, or a block level container that you have changed to use a different style of display than is its native display style. It is still best to follow the demo HTML template for this script, it is just that this version is more forgiving than my previous one, which assumed strict adherence to the demo markup. Here is the entire modified script, changes are too extensive to go into piecemeal:


<script type="text/javascript">

/***********************************************
* Switch Content script II- Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
* Modified by jscheuer1 in http://www.dynamicdrive.com/forums to
* initially be closed and allow for persistence in Opera
***********************************************/
if(document.getElementById)
document.write('<style type="text/css">\
.switchcontent{\
display:none;\
}\
</style>')

var enablepersist="on" //Enable saving state of content structure using session cookies? (on/off)
var memoryduration="7" //persistence in # of days

var contractsymbol='images/minus.gif' //Path to image to represent contract state.
var expandsymbol='images/plus.gif' //Path to image to represent expand state.

/////No need to edit beyond here //////////////////////////

function getElementbyClass(rootobj, classname){
var temparray=new Array()
var inc=0
var rootlength=rootobj.length
for (i=0; i<rootlength; i++){
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}

function sweeptoggle(ec, operaFlag){
var inc=0
while (ccollect[inc]){
var el=ccollect[inc]
el.style.display=(ec=="contract")? "none" : document.body.filters? "block" : el.tagName=="TR"? "table-row" : el.tagName=="TD"? "table-cell" : "block"
inc++
}
revivestatus()
if (window.opera&&!operaFlag)
saveswitchstate();
}

function expandcontent(curobj, cid){
if (ccollect.length>0){
var el=document.getElementById(cid)
el.style.display=(document.getElementById(cid).style.display!="none")? "none" : document.body.filters? "block" : el.tagName=="TR"? "table-row" : el.tagName=="TD"? "table-cell" : "block"
curobj.src=(document.getElementById(cid).style.display=="none")? expandsymbol : contractsymbol
}
if (window.opera)
saveswitchstate();
}

function revivecontent(){
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
for (i=0; i<selectedComponents.length-1; i++){
var el=document.getElementById(selectedComponents[i])
el.style.display=document.body.filters? "block" : el.tagName=="TR"? "table-row" : el.tagName=="TD"? "table-cell" : "block"
}
}

function revivestatus(){
var inc=0
while (statecollect[inc]){
if (ccollect[inc].style.display=="none")
statecollect[inc].src=expandsymbol
else
statecollect[inc].src=contractsymbol
inc++
}
}

function get_cookie(Name) {
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}

function getselectedItem(){
if (get_cookie(window.location.pathname) != ""){
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}

function saveswitchstate(){
var inc=0, selectedItem=""
while (ccollect[inc]){
if (ccollect[inc].style.display!=="none")
selectedItem+=ccollect[inc].id+"|"
inc++
}
if (get_cookie(window.location.pathname)!=selectedItem){ //only update cookie if current states differ from cookie's
var expireDate = new Date()
expireDate.setDate(expireDate.getDate()+parseInt(memoryduration))
document.cookie = window.location.pathname+"="+selectedItem+";path=/;expires=" + expireDate.toGMTString()
}
}

function do_onload(){
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
sweeptoggle('contract', 1)
if (enablepersist=="on" && get_cookie(window.location.pathname)!="" && ccollect.length>0)
revivecontent()
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
}

if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload

if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate

</script>

guvenck
11-27-2005, 11:21 AM
Hi jscheuer,

I would like to report that the updated code fixed my problem. It looks good in both FF and IE. Don't know about Opera. Thanks a lot for your help.

holden
11-27-2005, 03:54 PM
John,

Wow! Thanks so much for your fast and thorough response. It's working perfectly now. It's just the code I was looking for.

Have a great Sunday :)

Holden

ddadmin
11-28-2005, 09:29 AM
Wow great work jscheuer1, thanks for putting the time into this. I'll have to review it sometime to see if any of the changes should be added to the formal version.

jscheuer1
11-29-2005, 05:59 AM
Thanks dd! The code can be tightened up a little more though. I created some new variables to handle Mozilla's and Opera's need to have specific display modes specified, rather than simply 'none' or 'block' as IE seems to prefer. These variables, though local, could be exploited inside the functions where they are created to shorten the code a bit more than I at first realized.

Also, I am now thinking a function might be created to return the display mode for non-IE browsers, and called each time it is needed rather than repeating the code three times as is now the case. That would also make it more wieldy to add in other display mode types.

jscheuer1
11-29-2005, 10:46 AM
OK, I found another way entirely of dealing with the display style. Originally, I had added a document.write stylesheet to set the display to none for all expandable/contractable content. But, that meant that in some browsers I had to determine the proper display style for a given element when the time came to expand it. I have gotten around that by still having the document.write stylesheet but, once I set the styles of the elements to whatever style they need to be using their style property, I disable the document.write stylesheet. This allows any element to assume its default display style or even one set for it in the page's hard coded stylesheet when it is expanded, simply by using the scripts original method of setting style.display='' for expanded. Browsers that don't support this type of shenanigans but that do support getElementById (if there are any) should still be able to run the script with just a slight lag onload before all content is contracted. This is very good because it uses only a test to see if the method is supported, rather than any browser sniffing. Here is the updated script:


<script type="text/javascript">

/***********************************************
* Switch Content script II- Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use. Last updated April 2nd, 2005.
* Visit http://www.dynamicdrive.com/ for full source code
* Modified by jscheuer1 in http://www.dynamicdrive.com/forums to
* initially be closed and allow for persistence in Opera
***********************************************/

var initialstate=0 //0 for contracted, 1 for expanded
var enablepersist="on" //Enable saving state of content structure using session cookies? (on/off)
var memoryduration="7" //persistence in # of days

var contractsymbol='minus.gif' //Path to image to represent contract state.
var expandsymbol='plus.gif' //Path to image to represent expand state.

/////No need to edit beyond here //////////////////////////

if(!initialstate){
if(document.getElementById)
document.write('<style id="styletest" type="text/css">\
#nothing {\
}\
</style>')

if(typeof document.getElementById('styletest').disabled=='boolean')
document.write('<style id="added" type="text/css">\
.switchcontent{\
display:none;\
}\
</style>')
}

function getElementbyClass(rootobj, classname){
var temparray=new Array()
var inc=0
var rootlength=rootobj.length
for (i=0; i<rootlength; i++){
if (rootobj[i].className==classname)
temparray[inc++]=rootobj[i]
}
return temparray
}


function sweeptoggle(ec, operaFlag){
var inc=0
while (ccollect[inc]){
ccollect[inc].style.display=ec=="contract"? "none" : ""
inc++
}
revivestatus()
if (enablepersist=="on"&&window.opera&&!operaFlag)
saveswitchstate();
}

function expandcontent(curobj, cid){
if (ccollect.length>0){
var el=document.getElementById(cid)
el.style.display=el.style.display!="none"? "none" : ""
curobj.src=(el.style.display=="none")? expandsymbol : contractsymbol
}
if (enablepersist=="on"&&window.opera)
saveswitchstate();
}

function revivecontent(){
selectedItem=getselectedItem()
selectedComponents=selectedItem.split("|")
for (i=0; i<selectedComponents.length-1; i++){
document.getElementById(selectedComponents[i]).style.display=initialstate? "none" : ""
}
}

function revivestatus(){
var inc=0
while (statecollect[inc]){
if (ccollect[inc].style.display=="none")
statecollect[inc].src=expandsymbol
else
statecollect[inc].src=contractsymbol
inc++
}
}

function get_cookie(Name) {
var search = Name + "="
var returnvalue = "";
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(search)
if (offset != -1) {
offset += search.length
end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
returnvalue=unescape(document.cookie.substring(offset, end))
}
}
return returnvalue;
}

function getselectedItem(){
if (get_cookie(window.location.pathname) != ""){
selectedItem=get_cookie(window.location.pathname)
return selectedItem
}
else
return ""
}

function saveswitchstate(){
var inc=0, selectedItem=""
while (ccollect[inc]){
if (!initialstate&&ccollect[inc].style.display!=="none"||initialstate&&ccollect[inc].style.display=="none")
selectedItem+=ccollect[inc].id+"|"
inc++
}
if (get_cookie(window.location.pathname)!=selectedItem){ //only update cookie if current states differ from cookie's
var expireDate = new Date()
expireDate.setDate(expireDate.getDate()+parseInt(memoryduration))
document.cookie = window.location.pathname+"="+selectedItem+";path=/;expires=" + expireDate.toGMTString()
}
}

function do_onload(){
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "switchcontent")
statecollect=getElementbyClass(alltags, "showstate")
if(!initialstate){
sweeptoggle('contract', 1)
document.getElementById('added').disabled=true
}
if (enablepersist=="on" && get_cookie(window.location.pathname)!="" && ccollect.length>0)
revivecontent()
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
}

if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload

if (enablepersist=="on" && document.getElementById)
window.onunload=saveswitchstate

</script>

DennisA
02-26-2006, 01:42 PM
Hi, John.

I've been using this script for several months as I found it to be an excellect solution for StoreSense eCommerce systems that needed selectable view/hide content for customers.

Last year StoreSense was bought by eBay and changed to ProStores, and since upgrading to ProStores a couple months ago, the script fails on MSIE with a 'ccollect is undefined' error. However, it works just fine in Mozilla and Opera.

Whether the ProStores upgrade has any bearing is unknown, but I thought I'd at least mention that slice of history since it seemed to be a bit too coincidental.

I have modified the script with your latest change, but unfortunately, I continue to get the same results.

For reference, here is a URL where I have the script running:

http://store.closeoutstock.com/prostores/servlet/Categories?category=Camera

Any ideas on how this can be resolved would be greatly appreciated.

Thanks!

DennisA
02-26-2006, 02:17 PM
I found the problem right after posting my initial message.

The cause was due to a flash file that was preventing the page from completing its page load. This apparently caused MSIE to consider the script incomplete, even tho all related JS and HTML code had been properly downloaded to the browser.

Thanks.