Forum Moderators: open

Message Too Old, No Replies

Need some help with adding these attributes in the javascript itself.

         

nlraley

8:49 pm on Dec 16, 2009 (gmt 0)

10+ Year Member



I am creating a web page and I am trying to get the web page to validate; however, after editing my page to include a pull up and down menu, it no longer validates b/c of an attribute in my HTML that the javascript is calling.

The piece of html I am having issues with is:
<a href="#" rel="toggle[MyAccount]" data-openimage="ManageMyAccountGrey.png" data-closedimage="ManageMyAccountBlue.png"><img src="ManageMyAccountGrey.png" alt="none"></a>

<div id="MyAccount">
The cat (Felis catus), also known as the domestic cat or house cat to distinguish it from other felines, is a small carnivorous species of crepuscular mammal that is often valued by humans for its companionship and its ability to hunt vermin. It has been associated with humans for at least 9,500 years. A skilled predator, the cat is known to hunt over 1,000 species for food. It can be trained to obey simple commands.
</div>
<b></b>
<a href="#" rel="toggle[HelpAndSupport]" data-openimage="HelpAndSupportGrey.png" data-closedimage="HelpAndSupportBlue.png"><img src="HelpAndSupportGrey.png" alt="none" ></a>

<div id="HelpAndSupport">
The dog (Canis lupus familiaris) is a domesticated subspecies of the wolf, a mammal of the Canidae family of the order Carnivora. The term encompasses both feral and pet varieties and is also sometimes used to describe wild canids of other subspecies or species. The domestic dog has been one of the most widely kept working and companion animals in human history, as well as being a food source in some cultures.
</div>

This is the particular part in the script that is calling for the open-image attribute that is defined in the HTML:
$allcontrols.each(function(){ //loop though each control link
this._divids=this.getAttribute('rel').replace(/(^\w+)¦(\s+)/g, "").replace(/[\[\]']/g, "") //cache value 'div1,div2,etc' within identifier[div1,div2,etc]
if (this.getElementsByTagName('img').length==1 && ac.divholders[this._divids]){ //if control is an image link that toggles a single DIV (must be one to one to update status image)
animatedcollapse.preloadimage(this.getAttribute('data-openimage'), this.getAttribute('data-closedimage')) //preload control images (if defined)
$togglerimage=$(this).find('img').eq(0).data('srcs', {open:this.getAttribute('data-openimage'), closed:this.getAttribute('data-closedimage')}) //remember open and closed images' paths
ac.divholders[this._divids].$togglerimage=$(this).find('img').eq(0) //save reference to toggler image (to be updated inside slideengine()
ac.divholders[this._divids].$togglerimage.attr('src', (ac.divholders[this._divids].$divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}
$(this).click(function(){ //assign click behavior to each control link
var relattr=this.getAttribute('rel')
var divids=(this._divids=="")? [] : this._divids.split(',') //convert 'div1,div2,etc' to array
if (divids.length>0){
animatedcollapse[/expand/i.test(relattr)? 'show' : /collapse/i.test(relattr)? 'hide' : 'toggle'](divids) //call corresponding public function
return false
}
}) //end control.click
})// end control.each

My question is how can I assign this attribute for MyAccount and HelpAndSupport in the javascript itself so that I don't have to assign it in my HTML so the HTML validates once again?

Any ideas? Thanks in advance!

Any suggestions?

[edited by: nlraley at 8:52 pm (utc) on Dec. 16, 2009]

nlraley

8:50 pm on Dec 16, 2009 (gmt 0)

10+ Year Member



Sorry about the formatting, it jumbled it all up on me when I posted it in the code brackets...

rocknbil

10:50 pm on Dec 16, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Edit: Ignore the rantings below, addressed in your other thread [webmasterworld.com]. Well, except for the <b></b> and href="#" . . .

What is/are the specific error(s)? If it's the Javascript itself with an XHTML doctype, use the CDATA elements . . . . .

Any ideas?

This is the particular part in the script that is calling for the open-image attribute that is defined in the HTML:

So that is directly inline with the HTML? Not getting it . . . it should be surrounded by <script> tags and could be moved to the head or an external file.

Remove --> <b></b>

Unrelated, maybe, but this is bad . . .

<a href="#" rel="toggle[MyAccount]" ....

Renders your content inaccessible without JS. Put a link to the non-javascript content.

<a href="support.html" rel="toggle[MyAccount]" .....

The onclick event handler should return false so it doesn't navigate to the page if JS is enabled.

nlraley

2:15 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Well basically the javascript calls on the this.GetAttribute to grab the values for data-openimage and data-closedimage, which itself is defined in the html tag here:
<a href="#" rel="toggle[HelpAndSupport]" data-openimage="HelpAndSupportGrey.png" data-closedimage="HelpAndSupportBlue.png">

When checking for validation after adding this bit of code function into my html page it no longer validates on the two lines where I call the data-open and data-closedimage properties in my href tags. I get a :
Line 91, Column 52: Attribute "DATA-OPENIMAGE" is not a valid attribute
…="toggle[MyAccount]" data-openimage="ManageMyAccountGrey.png" data-closedimage

I am assuming b/c it does not validate b/c as they pointed out in the other post that data-closedimage is not a valid property call in Strict HTML that I am using for the page.

It was recommended that I remove the property call; however, as noted it breaks the functionality of the javascript that is calling for that attribute for my MyAccount and HelpAndSupport.

They further recommended that I add the properties to the javascript itself; however, I am not quite sure how exactly I would go about assigning the properties for these 2 values.

Fotiman

2:20 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Quickest way would be to add id's to the links that you need to modify, and then get those links and assign the other properties. For example, instead of this:

<a href="#" rel="toggle[MyAccount]" data-openimage="ManageMyAccountGrey.png" data-closedimage="ManageMyAccountBlue.png">

You would have this:

<a href="#" rel="toggle[MyAccount]" id="manageMyAccount">

Then add some script to assign the additional properties:


$('#manageMyAccount').data-openimage = 'ManageMyAccountGrey.png"';

(and similar for the other elements and properties).

nlraley

2:26 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Ah, so that's the format. Wasn't sure the exact format to do that in the script itself.

I'll give it a try, Thanks!

nlraley

2:34 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Okay, I've added:
$('#MyAccount').data-openimage = 'ManageMyAccountGrey.png"';
$('#MyAccount').data-closedimage = 'ManageMyAccountBlue.png"';
$('#HelpAndSupport').data-openimage = 'HelpAndSupportGrey.png"';
$('#HelpAndSupport').data-closedimage = 'HelpAndSupportBlue.png"';

Setting the data-closed and data-open images. However, I have lost the functionality of the script itself now. The images now load; however, the script doesn't open and close the menus like it was supposed to do.

Any ideas?

Fotiman

2:59 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Note, you have elements with id's MyAccount and HelpAndSupport already. You'll want to use different id values for those links so as not to conflict with those existing element ids. That's why in my example I used "manageMyAccount" instead of just "MyAccount".

nlraley

3:16 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



I had tried it both ways and it still didn't call on the animation or anything. They were both maximized on load and clicking the links didn't start any animation. Do I need to change how they are called in the script itself?

Fotiman

3:24 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Try this instead:

document.getElementById('manageMyAccount').data-openimage = 'ManageMyAccountGrey.png"';

Or this:

$('#manageMyAccount').get(0).data-openimage = 'ManageMyAccountGrey.png"';

Is seems that jQuery might not be returning the actual DOM node but rather an array of nodes.

nlraley

3:49 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Seems like it should be working but it must not be passing those values in all the other function calls or something as it still isn't working.

Here is the full code I have so far with the added attributes like you have said:


//** Animated Collapsible DIV v2.0- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.
//** May 24th, 08'- Script rewritten and updated to 2.0.
//** June 4th, 08'- Version 2.01: Bug fix to work with jquery 1.2.6 (which changed the way attr() behaves).
//** March 5th, 09'- Version 2.2, which adds the following:
//1) ontoggle($, divobj, state) event that fires each time a DIV is expanded/collapsed, including when the page 1st loads
//2) Ability to expand a DIV via a URL parameter string, ie: index.htm?expanddiv=jason or index.htm?expanddiv=jason,kelly

//** March 9th, 09'- Version 2.2.1: Optimized ontoggle event handler slightly.
//** July 3rd, 09'- Version 2.4, which adds the following:
//1) You can now insert rel="expand[divid] ¦ collapse[divid] ¦ toggle[divid]" inside arbitrary links to act as DIV togglers
//2) For image toggler links, you can insert the attributes "data-openimage" and "data-closedimage" to update its image based on the DIV state

$('#manageMyAccount').get(0).data-openimage = 'ManageMyAccountGrey.png"';
$('#manageMyAccount').get(0).data-closedimage = 'ManageMyAccountBlue.png"';

$('#manageHelpAndSupport').get(0).data-openimage = 'ManageHelpAndSupportGrey.png"';
$('#manageHelpAndSupport').get(0).data-closedimage = 'ManageHelpAndSupportBlue.png"';

var animatedcollapse={
divholders: {}, //structure: {div.id, div.attrs, div.$divref, div.$togglerimage}
divgroups: {}, //structure: {groupname.count, groupname.lastactivedivid}
lastactiveingroup: {}, //structure: {lastactivediv.id}
preloadimages: [],

show:function(divids){ //public method
if (typeof divids=="object"){
for (var i=0; i<divids.length; i++)
this.showhide(divids[i], "show")
}
else
this.showhide(divids, "show")
},

hide:function(divids){ //public method
if (typeof divids=="object"){
for (var i=0; i<divids.length; i++)
this.showhide(divids[i], "hide")
}
else
this.showhide(divids, "hide")
},

toggle:function(divid){ //public method
if (typeof divid=="object")
divid=divid[0]
this.showhide(divid, "toggle")
},

addDiv:function(divid, attrstring){ //public function
this.divholders[divid]=({id: divid, $divref: null, attrs: attrstring})
this.divholders[divid].getAttr=function(name){ //assign getAttr() function to each divholder object
var attr=new RegExp(name+"=([^,]+)", "i") //get name/value config pair (ie: width=400px,)
return (attr.test(this.attrs) && parseInt(RegExp.$1)!=0)? RegExp.$1 : null //return value portion (string), or 0 (false) if none found
}
this.currentid=divid //keep track of current div object being manipulated (in the event of chaining)
return this
},

showhide:function(divid, action){
var $divref=this.divholders[divid].$divref //reference collapsible DIV
if (this.divholders[divid] && $divref.length==1){ //if DIV exists
var targetgroup=this.divgroups[$divref.attr('groupname')] //find out which group DIV belongs to (if any)
if ($divref.attr('groupname') && targetgroup.count>1 && (action=="show" ¦¦ action=="toggle" && $divref.css('display')=='none')){ //If current DIV belongs to a group
if (targetgroup.lastactivedivid && targetgroup.lastactivedivid!=divid) //if last active DIV is set
this.slideengine(targetgroup.lastactivedivid, 'hide') //hide last active DIV within group first
this.slideengine(divid, 'show')
targetgroup.lastactivedivid=divid //remember last active DIV
}
else{
this.slideengine(divid, action)
}
}
},

slideengine:function(divid, action){
var $divref=this.divholders[divid].$divref
var $togglerimage=this.divholders[divid].$togglerimage
if (this.divholders[divid] && $divref.length==1){ //if this DIV exists
var animateSetting={height: action}
if ($divref.attr('fade'))
animateSetting.opacity=action
$divref.animate(animateSetting, $divref.attr('speed')? parseInt($divref.attr('speed')) : 500, function(){
if ($togglerimage){
$togglerimage.attr('src', ($divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}
if (animatedcollapse.ontoggle){
try{
animatedcollapse.ontoggle(jQuery, $divref.get(0), $divref.css('display'))
}
catch(e){
alert("An error exists inside your \"ontoggle\" function:\n\n"+e+"\n\nAborting execution of function.")
}
}
})
return false
}
},

generatemap:function(){
var map={}
for (var i=0; i<arguments.length; i++){
if (arguments[i][1]!=null){ //do not generate name/value pair if value is null
map[arguments[i][0]]=arguments[i][1]
}
}
return map
},

init:function(){
var ac=this
jQuery(document).ready(function($){
animatedcollapse.ontoggle=animatedcollapse.ontoggle ¦¦ null
var urlparamopenids=animatedcollapse.urlparamselect() //Get div ids that should be expanded based on the url (['div1','div2',etc])
var persistopenids=ac.getCookie('acopendivids') //Get list of div ids that should be expanded due to persistence ('div1,div2,etc')
var groupswithpersist=ac.getCookie('acgroupswithpersist') //Get list of group names that have 1 or more divs with "persist" attribute defined
if (persistopenids!=null) //if cookie isn't null (is null if first time page loads, and cookie hasnt been set yet)
persistopenids=(persistopenids=='nada')? [] : persistopenids.split(',') //if no divs are persisted, set to empty array, else, array of div ids
groupswithpersist=(groupswithpersist==null ¦¦ groupswithpersist=='nada')? [] : groupswithpersist.split(',') //Get list of groups with divs that are persisted
jQuery.each(ac.divholders, function(){ //loop through each collapsible DIV object
this.$divref=$('#'+this.id)
if ((this.getAttr('persist') ¦¦ jQuery.inArray(this.getAttr('group'), groupswithpersist)!=-1) && persistopenids!=null){ //if this div carries a user "persist" setting, or belong to a group with at least one div that does
var cssdisplay=(jQuery.inArray(this.id, persistopenids)!=-1)? 'block' : 'none'
}
else{
var cssdisplay=this.getAttr('hide')? 'none' : null
}
if (urlparamopenids[0]=="all" ¦¦ jQuery.inArray(this.id, urlparamopenids)!=-1){ //if url parameter string contains the single array element "all", or this div's ID
cssdisplay='block' //set div to "block", overriding any other setting
}
else if (urlparamopenids[0]=="none"){
cssdisplay='none' //set div to "none", overriding any other setting
}
this.$divref.css(ac.generatemap(['height', this.getAttr('height')], ['display', cssdisplay]))
this.$divref.attr(ac.generatemap(['groupname', this.getAttr('group')], ['fade', this.getAttr('fade')], ['speed', this.getAttr('speed')]))
if (this.getAttr('group')){ //if this DIV has the "group" attr defined
var targetgroup=ac.divgroups[this.getAttr('group')] ¦¦ (ac.divgroups[this.getAttr('group')]={}) //Get settings for this group, or if it no settings exist yet, create blank object to store them in
targetgroup.count=(targetgroup.count¦¦0)+1 //count # of DIVs within this group
if (jQuery.inArray(this.id, urlparamopenids)!=-1){ //if url parameter string contains this div's ID
targetgroup.lastactivedivid=this.id //remember this DIV as the last "active" DIV (this DIV will be expanded). Overrides other settings
targetgroup.overridepersist=1 //Indicate to override persisted div that would have been expanded
}
if (!targetgroup.lastactivedivid && this.$divref.css('display')!='none' ¦¦ cssdisplay=="block" && typeof targetgroup.overridepersist=="undefined") //if this DIV was open by default or should be open due to persistence
targetgroup.lastactivedivid=this.id //remember this DIV as the last "active" DIV (this DIV will be expanded)
this.$divref.css({display:'none'}) //hide any DIV that's part of said group for now
}
}) //end divholders.each
jQuery.each(ac.divgroups, function(){ //loop through each group
if (this.lastactivedivid && urlparamopenids[0]!="none") //show last "active" DIV within each group (one that should be expanded), unless url param="none"
ac.divholders[this.lastactivedivid].$divref.show()
})
if (animatedcollapse.ontoggle){
jQuery.each(ac.divholders, function(){ //loop through each collapsible DIV object and fire ontoggle event
animatedcollapse.ontoggle(jQuery, this.$divref.get(0), this.$divref.css('display'))
})
}
//Parse page for links containing rel attribute
var $allcontrols=$('a[rel]').filter('[rel^="collapse[quote], [rel^="expand[quote], [rel^="toggle[quote]') //get all elements on page with rel="collapse[]", "expand[]" and "toggle[]"
$allcontrols.each(function(){ //loop though each control link
this._divids=this.getAttribute('rel').replace(/(^\w+)¦(\s+)/g, "").replace(/[\[\]']/g, "") //cache value 'div1,div2,etc' within identifier[div1,div2,etc]
if (this.getElementsByTagName('img').length==1 && ac.divholders[this._divids]){ //if control is an image link that toggles a single DIV (must be one to one to update status image)
animatedcollapse.preloadimage(this.getAttribute('data-openimage'), this.getAttribute('data-closedimage')) //preload control images (if defined)
$togglerimage=$(this).find('img').eq(0).data('srcs', {open:this.getAttribute('data-openimage'), closed:this.getAttribute('data-closedimage')}) //remember open and closed images' paths
ac.divholders[this._divids].$togglerimage=$(this).find('img').eq(0) //save reference to toggler image (to be updated inside slideengine()
ac.divholders[this._divids].$togglerimage.attr('src', (ac.divholders[this._divids].$divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}
$(this).click(function(){ //assign click behavior to each control link
var relattr=this.getAttribute('rel')
var divids=(this._divids=="")? [] : this._divids.split(',') //convert 'div1,div2,etc' to array
if (divids.length>0){
animatedcollapse[/expand/i.test(relattr)? 'show' : /collapse/i.test(relattr)? 'hide' : 'toggle'](divids) //call corresponding public function
return false
}
}) //end control.click
})// end control.each

$(window).bind('unload', function(){
ac.uninit()
})
}) //end doc.ready()
},

uninit:function(){
var opendivids='', groupswithpersist=''
jQuery.each(this.divholders, function(){
if (this.$divref.css('display')!='none'){
opendivids+=this.id+',' //store ids of DIVs that are expanded when page unloads: 'div1,div2,etc'
}
if (this.getAttr('group') && this.getAttr('persist'))
groupswithpersist+=this.getAttr('group')+',' //store groups with which at least one DIV has persistance enabled: 'group1,group2,etc'
})
opendivids=(opendivids=='')? 'nada' : opendivids.replace(/,$/, '')
groupswithpersist=(groupswithpersist=='')? 'nada' : groupswithpersist.replace(/,$/, '')
this.setCookie('acopendivids', opendivids)
this.setCookie('acgroupswithpersist', groupswithpersist)
},

getCookie:function(Name){
var re=new RegExp(Name+"=[^;]*", "i"); //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return null
},

setCookie:function(name, value, days){
if (typeof days!="undefined"){ //if set persistent cookie
var expireDate = new Date()
expireDate.setDate(expireDate.getDate()+days)
document.cookie = name+"="+value+"; path=/; expires="+expireDate.toGMTString()
}
else //else if this is a session only cookie
document.cookie = name+"="+value+"; path=/"
},

urlparamselect:function(){
window.location.search.match(/expanddiv=([\w\-_,]+)/i) //search for expanddiv=divid or divid1,divid2,etc
return (RegExp.$1!="")? RegExp.$1.split(",") : []
},

preloadimage:function(){
var preloadimages=this.preloadimages
for (var i=0; i<arguments.length; i++){
if (arguments[i] && arguments[i].length>0){
preloadimages[preloadimages.length]=new Image()
preloadimages[preloadimages.length-1].src=arguments[i]
}
}
}

}

Fotiman

4:01 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ah, perhaps this is called before those elements exist on the page. Try moving these lines:
$('#manageMyAccount').get(0).data-openimage = 'ManageMyAccountGrey.png"';
$('#manageMyAccount').get(0).data-closedimage = 'ManageMyAccountBlue.png"';

$('#manageHelpAndSupport').get(0).data-openimage = 'ManageHelpAndSupportGrey.png"';
$('#manageHelpAndSupport').get(0).data-closedimage = 'ManageHelpAndSupportBlue.png"';

to the first items after this line:
jQuery(document).ready(function($){

nlraley

4:10 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



I think that is getting to the right track but it's still not working after that. I think it has something to do with them being stored as an array like you mentioned earlier.

The:
jQuery.each(ac.divholders, function(){ //loop through each collapsible DIV object
this.$divref=$('#'+this.id)
if ((this.getAttr('persist') ¦¦ jQuery.inArray(this.getAttr('group'), groupswithpersist)!=-1) && persistopenids!=null){ //if this div carries a user "persist" setting, or belong to a group with at least one div that does
var cssdisplay=(jQuery.inArray(this.id, persistopenids)!=-1)? 'block' : 'none'
}
Part is probably where it is calling the div and assigning them the attributes, just not entirely sure how to get it all to work when I assign the attributes into the javascript itself instead of the html.

I'd really like to get this up and running but I might just say to hell with it, as the script does work with the attribute being called in the html, even though it isn't the right way to do it which is driving me nuts.

nlraley

4:14 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Oh wait a second, I wander if it is in the script declaration of my html document in this:
<script type="text/javascript">

animatedcollapse.addDiv('MyAccount', 'fade=0,speed=400,group=AccountDiv')
animatedcollapse.addDiv('HelpAndSupport', 'fade=0,speed=400,group=AccountDiv,persist=1,hide=1')

animatedcollapse.ontoggle=function($, divobj, state){ //fires each time a DIV is expanded/contracted
//$: Access to jQuery
//divobj: DOM reference to DIV being expanded/ collapsed. Use "divobj.id" to get its ID
//state: "block" or "none", depending on state
}

animatedcollapse.init()

</script>

nlraley

4:28 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Okay, let me step back a few steps.

If I take out the attribute being called in the html tag that I had at the start of this, I obtain the full functionality of the script, it just doesn't show the images.

This loads the page with the first div, MyAccount, expanded and the 2nd one is minimized. If I click on the 2nd, HelpAndSupport, the first one minimizes and the 2nd one opens up. This works as intended.

Now, what I was wanting, was when one was currently open, it would display the grey image and the one that was minimized would be the blue variation. They would change upon the other one being opened up.

With it being set up this way the images are not even loading.

So if I can backtrack and get the image swapping functionality, preferably on the click event, and not break the javascript, that is what my ultimate goal is.

Any suggestions on how to go about doing this? Or do you think I should just use the mouseover feature?

Fotiman

5:16 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ok, I think I see what's happening. :)
The call to animatedcollapse.init() happens first. In that method, it does this:

jQuery(document).ready(function($){
...
}

Which is where it looks for the 'data-openimage' and 'data-closedimage' attributes. So you need to have them defined BEFORE that gets executed. However, the real problem is that this method is using the 'getAttribute' method, which doesn't recognize the attribute that we added by doing node.attribute = ''. So, give this a try. I think this works.


jQuery(document).ready(function($){
var btn, n, toggleButtons = {
'manageMyAccount': {
open: 'ManageMyAccountGrey.png',
closed: 'ManageMyAccountBlue.png'
},
'manageHelpAndSupport': {
open: 'ManageHelpAndSupportGrey.png',
closed: 'ManageHelpAndSupportBlue.png'
}
}
for (btn in toggleButtons) {
n = document.getElementById(btn);
n.setAttribute('data-openimage', toggleButtons[btn].open);
n.setAttribute('data-openclosed', toggleButtons[btn].closed);
}
});
animatedcollapse.init();

Essentially, I'm using the setAttribute method instead of using the dot notation to assign the value, and I'm creating a nice data structure that makes it easier to automate.

Fotiman

5:40 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ok, one last time... there was a typo in my example. 'data-openclosed' should have been 'data-closedimage':


jQuery(document).ready(function($){
var btn, n, toggleButtons = {
'manageMyAccount': {
open: 'ManageMyAccountGrey.png',
closed: 'ManageMyAccountBlue.png'
},
'manageHelpAndSupport': {
open: 'ManageHelpAndSupportGrey.png',
closed: 'ManageHelpAndSupportBlue.png'
}
}
for (btn in toggleButtons) {
n = document.getElementById(btn);
n.setAttribute('data-openimage', toggleButtons[btn].open);
n.setAttribute('data-closedimage', toggleButtons[btn].closed);
}
});
animatedcollapse.init();

nlraley

5:52 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Okay, I'm starting to understand what you are saying with this; however, it still isn't functioning with the code.

This appears to be where they are grabbing the open and closed image properties from the html:

if (this.getElementsByTagName('img').length==1 && ac.divholders[this._divids]){ //if control is an image link that toggles a single DIV (must be one to one to update status image)
animatedcollapse.preloadimage(this.getAttribute('data-openimage'), this.getAttribute('data-closedimage')) //preload control images (if defined)
$togglerimage=$(this).find('img').eq(0).data('srcs', {open:this.getAttribute('data-openimage'), closed:this.getAttribute('data-closedimage')}) //remember open and closed images' paths
ac.divholders[this._divids].$togglerimage=$(this).find('img').eq(0) //save reference to toggler image (to be updated inside slideengine()
ac.divholders[this._divids].$togglerimage.attr('src', (ac.divholders[this._divids].$divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}

So if I am understanding you right after digging through this I simply need to define my variables for btn, n, and toggleButtons for manageMyAccount and HelpAndSupport.

Then the for loop you have should assign the attributes for data-openimage and data-closedimage, I renamed openclosed to closedimage b/c that is the property that they are calling.

I see and understand this. I have added everything below the var declaration to the jQuery.ready function and this "should" work from everything that I can tell. But it is not.

I think the reason is this:

Where it is calling the data-open and data-closed images in the script I pasted at the beginning of this reply, it isn't calling the ManageMyAccount b/c the div it is working with in the HTML is actually the MyAccount. Would I not need to rename those to take out the Manage in front of them to be setting the attributes for the divs correctly?

Fotiman

6:23 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Note, I tried this locally, and it is working for me, exactly as I have it posted (in my last post).


So if I am understanding you right after digging through this I simply need to define my variables for btn, n, and toggleButtons for manageMyAccount and HelpAndSupport.

The only values that you would define are those in toggleButtons (not btn, or n as those values are derived).

I see and understand this. I have added everything below the var declaration to the jQuery.ready function and this "should" work from everything that I can tell. But it is not.

Note, the entire block of code as I pasted it should go above the call to animatedcollapse.init(). That is, this is a NEW jQuery.ready, NOT using the jQuery.ready that is defined inside the init method.


Where it is calling the data-open and data-closed images in the script I pasted at the beginning of this reply, it isn't calling the ManageMyAccount b/c the div it is working with in the HTML is actually the MyAccount. Would I not need to rename those to take out the Manage in front of them to be setting the attributes for the divs correctly?

The code, as you had it, should remain unchanged, EXCEPT for the addition of the code block I listed. So you should have something like this:


animatedcollapse.addDiv('MyAccount', 'fade=0,speed=400,group=AccountDiv')
animatedcollapse.addDiv('HelpAndSupport', 'fade=0,speed=400,group=AccountDiv,persist=1,hide=1')
animatedcollapse.ontoggle=function($, divobj, state){ //fires each time a DIV is expanded/contracted
//$: Access to jQuery
//divobj: DOM reference to DIV being expanded/ collapsed. Use "divobj.id" to get its ID
//state: "block" or "none", depending on state
}
jQuery(document).ready(function($){
var btn, n, toggleButtons = {
'manageMyAccount': {
open: 'web.gif',
closed: 'warning.gif'
},
'manageHelpAndSupport': {
open: 'web.gif',
closed: 'warning.gif'
}
}
for (btn in toggleButtons) {
n = document.getElementById(btn);
n.setAttribute('data-openimage', toggleButtons[btn].open);
n.setAttribute('data-closedimage', toggleButtons[btn].closed);
}
});
animatedcollapse.init();

Your markup then looks like this:

<a href="#" rel="toggle[MyAccount]" id="manageMyAccount"><img src="ManageMyAccountGrey.png" ></a>
<div id="MyAccount">...</div>

The toggle relation is where the link gets associated with the block to toggle.

nlraley

7:17 pm on Dec 17, 2009 (gmt 0)

10+ Year Member


Okay, I broke the html out so I have less factors running that could influence the appearance.

Here is there shortened HTML
[quote]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="test5.css">
<link rel="stylesheet" type="text/css" href="topmenu.css">
<link rel="stylesheet" type="text/css" href="header.css">
<link rel="stylesheet" type="text/css" href="body.css">
<link rel="stylesheet" type="text/css" href="accountselector.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="animatedcollapse.js">

/***********************************************
* Animated Collapsible DIV v2.4- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for this script and 100s more
***********************************************/

</script>

<script type="text/javascript">

animatedcollapse.addDiv('MyAccount', 'fade=0,speed=400,group=AccountDiv')
animatedcollapse.addDiv('HelpAndSupport', 'fade=0,speed=400,group=AccountDiv,persist=1,hide=1')
animatedcollapse.ontoggle=function($, divobj, state){ //fires each time a DIV is expanded/contracted
//$: Access to jQuery
//divobj: DOM reference to DIV being expanded/ collapsed. Use "divobj.id" to get its ID
//state: "block" or "none", depending on state
}
jQuery(document).ready(function($){
var btn, n, toggleButtons = {
'manageMyAccount': {
open: 'ManageMyAccountGrey.png',
closed: 'ManageMyAccountBlue.png'
},
'manageHelpAndSupport': {
open: 'HelpAndSupportGrey.png',
closed: 'HelpAndSupportBlue.png'
}
}
for (btn in toggleButtons) {
n = document.getElementById(btn);
n.setAttribute('data-openimage', toggleButtons[btn].open);
n.setAttribute('data-closedimage', toggleButtons[btn].closed);
}

});
animatedcollapse.init();

</script>
<title></title>
</head>
<body>
<div id= "headerwrapper-right">
<a href="#" rel="toggle[MyAccount]" id = "manageMyAccount"><img src="ManageMyAccountGrey.png" alt="none"></a>

<div id="MyAccount">
The cat (Felis catus), also known as the domestic cat or house cat to distinguish it from other felines, is a small carnivorous species of crepuscular mammal that is often valued by humans for its companionship and its ability to hunt vermin. It has been associated with humans for at least 9,500 years. A skilled predator, the cat is known to hunt over 1,000 species for food. It can be trained to obey simple commands.
</div>
<b></b>
<a href="#" rel="toggle[HelpAndSupport]" id = "manageHelpAndSupport"><img src="HelpAndSupportGrey.png" alt="none" ></a>

<div id="HelpAndSupport">
The dog (Canis lupus familiaris) is a domesticated subspecies of the wolf, a mammal of the Canidae family of the order Carnivora. The term encompasses both feral and pet varieties and is also sometimes used to describe wild canids of other subspecies or species. The domestic dog has been one of the most widely kept working and companion animals in human history, as well as being a food source in some cultures.
</div>
</div>
</body>
</html>[/quote]

The script calls call for your standard jquery javascript file as well as one called animatedcollapse.
AnimatedCollapse is here:
[quote]//** Animated Collapsible DIV v2.0- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.
//** May 24th, 08'- Script rewritten and updated to 2.0.
//** June 4th, 08'- Version 2.01: Bug fix to work with jquery 1.2.6 (which changed the way attr() behaves).
//** March 5th, 09'- Version 2.2, which adds the following:
//1) ontoggle($, divobj, state) event that fires each time a DIV is expanded/collapsed, including when the page 1st loads
//2) Ability to expand a DIV via a URL parameter string, ie: index.htm?expanddiv=jason or index.htm?expanddiv=jason,kelly

//** March 9th, 09'- Version 2.2.1: Optimized ontoggle event handler slightly.
//** July 3rd, 09'- Version 2.4, which adds the following:
//1) You can now insert rel="expand[divid] ¦ collapse[divid] ¦ toggle[divid]" inside arbitrary links to act as DIV togglers
//2) For image toggler links, you can insert the attributes "data-openimage" and "data-closedimage" to update its image based on the DIV state

var animatedcollapse={
divholders: {}, //structure: {div.id, div.attrs, div.$divref, div.$togglerimage}
divgroups: {}, //structure: {groupname.count, groupname.lastactivedivid}
lastactiveingroup: {}, //structure: {lastactivediv.id}
preloadimages: [],

show:function(divids){ //public method
if (typeof divids=="object"){
for (var i=0; i<divids.length; i++)
this.showhide(divids[i], "show")
}
else
this.showhide(divids, "show")
},

hide:function(divids){ //public method
if (typeof divids=="object"){
for (var i=0; i<divids.length; i++)
this.showhide(divids[i], "hide")
}
else
this.showhide(divids, "hide")
},

toggle:function(divid){ //public method
if (typeof divid=="object")
divid=divid[0]
this.showhide(divid, "toggle")
},

addDiv:function(divid, attrstring){ //public function
this.divholders[divid]=({id: divid, $divref: null, attrs: attrstring})
this.divholders[divid].getAttr=function(name){ //assign getAttr() function to each divholder object
var attr=new RegExp(name+"=([^,]+)", "i") //get name/value config pair (ie: width=400px,)
return (attr.test(this.attrs) && parseInt(RegExp.$1)!=0)? RegExp.$1 : null //return value portion (string), or 0 (false) if none found
}
this.currentid=divid //keep track of current div object being manipulated (in the event of chaining)
return this
},

showhide:function(divid, action){
var $divref=this.divholders[divid].$divref //reference collapsible DIV
if (this.divholders[divid] && $divref.length==1){ //if DIV exists
var targetgroup=this.divgroups[$divref.attr('groupname')] //find out which group DIV belongs to (if any)
if ($divref.attr('groupname') && targetgroup.count>1 && (action=="show" ¦¦ action=="toggle" && $divref.css('display')=='none')){ //If current DIV belongs to a group
if (targetgroup.lastactivedivid && targetgroup.lastactivedivid!=divid) //if last active DIV is set
this.slideengine(targetgroup.lastactivedivid, 'hide') //hide last active DIV within group first
this.slideengine(divid, 'show')
targetgroup.lastactivedivid=divid //remember last active DIV
}
else{
this.slideengine(divid, action)
}
}
},

slideengine:function(divid, action){
var $divref=this.divholders[divid].$divref
var $togglerimage=this.divholders[divid].$togglerimage
if (this.divholders[divid] && $divref.length==1){ //if this DIV exists
var animateSetting={height: action}
if ($divref.attr('fade'))
animateSetting.opacity=action
$divref.animate(animateSetting, $divref.attr('speed')? parseInt($divref.attr('speed')) : 500, function(){
if ($togglerimage){
$togglerimage.attr('src', ($divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}
if (animatedcollapse.ontoggle){
try{
animatedcollapse.ontoggle(jQuery, $divref.get(0), $divref.css('display'))
}
catch(e){
alert("An error exists inside your \"ontoggle\" function:\n\n"+e+"\n\nAborting execution of function.")
}
}
})
return false
}
},

generatemap:function(){
var map={}
for (var i=0; i<arguments.length; i++){
if (arguments[i][1]!=null){ //do not generate name/value pair if value is null
map[arguments[i][0]]=arguments[i][1]
}
}
return map
},

init:function(){
var ac=this
animatedcollapse.init();
jQuery(document).ready(function($){
animatedcollapse.init();
animatedcollapse.ontoggle=animatedcollapse.ontoggle ¦¦ null
var urlparamopenids=animatedcollapse.urlparamselect() //Get div ids that should be expanded based on the url (['div1','div2',etc])
var persistopenids=ac.getCookie('acopendivids') //Get list of div ids that should be expanded due to persistence ('div1,div2,etc')
var groupswithpersist=ac.getCookie('acgroupswithpersist') //Get list of group names that have 1 or more divs with "persist" attribute defined
if (persistopenids!=null) //if cookie isn't null (is null if first time page loads, and cookie hasnt been set yet)
persistopenids=(persistopenids=='nada')? [] : persistopenids.split(',') //if no divs are persisted, set to empty array, else, array of div ids
groupswithpersist=(groupswithpersist==null ¦¦ groupswithpersist=='nada')? [] : groupswithpersist.split(',') //Get list of groups with divs that are persisted
jQuery.each(ac.divholders, function(){ //loop through each collapsible DIV object
this.$divref=$('#'+this.id)
if ((this.getAttr('persist') ¦¦ jQuery.inArray(this.getAttr('group'), groupswithpersist)!=-1) && persistopenids!=null){ //if this div carries a user "persist" setting, or belong to a group with at least one div that does
var cssdisplay=(jQuery.inArray(this.id, persistopenids)!=-1)? 'block' : 'none'
}
else{
var cssdisplay=this.getAttr('hide')? 'none' : null
}
if (urlparamopenids[0]=="all" ¦¦ jQuery.inArray(this.id, urlparamopenids)!=-1){ //if url parameter string contains the single array element "all", or this div's ID
cssdisplay='block' //set div to "block", overriding any other setting
}
else if (urlparamopenids[0]=="none"){
cssdisplay='none' //set div to "none", overriding any other setting
}
this.$divref.css(ac.generatemap(['height', this.getAttr('height')], ['display', cssdisplay]))
this.$divref.attr(ac.generatemap(['groupname', this.getAttr('group')], ['fade', this.getAttr('fade')], ['speed', this.getAttr('speed')]))
if (this.getAttr('group')){ //if this DIV has the "group" attr defined
var targetgroup=ac.divgroups[this.getAttr('group')] ¦¦ (ac.divgroups[this.getAttr('group')]={}) //Get settings for this group, or if it no settings exist yet, create blank object to store them in
targetgroup.count=(targetgroup.count¦¦0)+1 //count # of DIVs within this group
if (jQuery.inArray(this.id, urlparamopenids)!=-1){ //if url parameter string contains this div's ID
targetgroup.lastactivedivid=this.id //remember this DIV as the last "active" DIV (this DIV will be expanded). Overrides other settings
targetgroup.overridepersist=1 //Indicate to override persisted div that would have been expanded
}
if (!targetgroup.lastactivedivid && this.$divref.css('display')!='none' ¦¦ cssdisplay=="block" && typeof targetgroup.overridepersist=="undefined") //if this DIV was open by default or should be open due to persistence
targetgroup.lastactivedivid=this.id //remember this DIV as the last "active" DIV (this DIV will be expanded)
this.$divref.css({display:'none'}) //hide any DIV that's part of said group for now
}
}) //end divholders.each
jQuery.each(ac.divgroups, function(){ //loop through each group
if (this.lastactivedivid && urlparamopenids[0]!="none") //show last "active" DIV within each group (one that should be expanded), unless url param="none"
ac.divholders[this.lastactivedivid].$divref.show()
})
if (animatedcollapse.ontoggle){
jQuery.each(ac.divholders, function(){ //loop through each collapsible DIV object and fire ontoggle event
animatedcollapse.ontoggle(jQuery, this.$divref.get(0), this.$divref.css('display'))
})
}
//Parse page for links containing rel attribute
var $allcontrols=$('a[rel]').filter('[rel^="collapse[quote], [rel^="expand[quote], [rel^="toggle[quote]') //get all elements on page with rel="collapse[]", "expand[]" and "toggle[]"
$allcontrols.each(function(){ //loop though each control link
this._divids=this.getAttribute('rel').replace(/(^\w+)¦(\s+)/g, "").replace(/[\[\]']/g, "") //cache value 'div1,div2,etc' within identifier[div1,div2,etc]
if (this.getElementsByTagName('img').length==1 && ac.divholders[this._divids]){ //if control is an image link that toggles a single DIV (must be one to one to update status image)
animatedcollapse.preloadimage(this.getAttribute('data-openimage'), this.getAttribute('data-closedimage')) //preload control images (if defined)
$togglerimage=$(this).find('img').eq(0).data('srcs', {open:this.getAttribute('data-openimage'), closed:this.getAttribute('data-closedimage')}) //remember open and closed images' paths
ac.divholders[this._divids].$togglerimage=$(this).find('img').eq(0) //save reference to toggler image (to be updated inside slideengine()
ac.divholders[this._divids].$togglerimage.attr('src', (ac.divholders[this._divids].$divref.css('display')=="none")? $togglerimage.data('srcs').closed : $togglerimage.data('srcs').open)
}
$(this).click(function(){ //assign click behavior to each control link
var relattr=this.getAttribute('rel')
var divids=(this._divids=="")? [] : this._divids.split(',') //convert 'div1,div2,etc' to array
if (divids.length>0){
animatedcollapse[/expand/i.test(relattr)? 'show' : /collapse/i.test(relattr)? 'hide' : 'toggle'](divids) //call corresponding public function
return false
}
}) //end control.click
})// end control.each

$(window).bind('unload', function(){
ac.uninit()
})
}) //end doc.ready()
},

uninit:function(){
var opendivids='', groupswithpersist=''
jQuery.each(this.divholders, function(){
if (this.$divref.css('display')!='none'){
opendivids+=this.id+',' //store ids of DIVs that are expanded when page unloads: 'div1,div2,etc'
}
if (this.getAttr('group') && this.getAttr('persist'))
groupswithpersist+=this.getAttr('group')+',' //store groups with which at least one DIV has persistance enabled: 'group1,group2,etc'
})
opendivids=(opendivids=='')? 'nada' : opendivids.replace(/,$/, '')
groupswithpersist=(groupswithpersist=='')? 'nada' : groupswithpersist.replace(/,$/, '')
this.setCookie('acopendivids', opendivids)
this.setCookie('acgroupswithpersist', groupswithpersist)
},

getCookie:function(Name){
var re=new RegExp(Name+"=[^;]*", "i"); //construct RE to search for target name/value pair
if (document.cookie.match(re)) //if cookie found
return document.cookie.match(re)[0].split("=")[1] //return its value
return null
},

setCookie:function(name, value, days){
if (typeof days!="undefined"){ //if set persistent cookie
var expireDate = new Date()
expireDate.setDate(expireDate.getDate()+days)
document.cookie = name+"="+value+"; path=/; expires="+expireDate.toGMTString()
}
else //else if this is a session only cookie
document.cookie = name+"="+value+"; path=/"
},

urlparamselect:function(){
window.location.search.match(/expanddiv=([\w\-_,]+)/i) //search for expanddiv=divid or divid1,divid2,etc
return (RegExp.$1!="")? RegExp.$1.split(",") : []
},

preloadimage:function(){
var preloadimages=this.preloadimages
for (var i=0; i<arguments.length; i++){
if (arguments[i] && arguments[i].length>0){
preloadimages[preloadimages.length]=new Image()
preloadimages[preloadimages.length-1].src=arguments[i]
}
}
}

}[/quote]

This, as I have it here, is not working for me.

[1][[b]edited by[/b]: nlraley at 7:29 pm (utc) on Dec. 17, 2009][/1]

nlraley

7:27 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



The only thing I can think is that the attributes I am setting are getting overwritten when it is calling the animatedcollapse script. Although that doesn't explain why the divs aren't expanding or collapsing.

Fotiman

7:35 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not sure what to tell you. I took your HTML code exactly as above except I commented out all of the CSS lines (as I don't have those files). I copied the animatedcollapse.js code from www.dynamicdrive.com. And it works for me in Firefox, IE7, and Chrome.

nlraley

7:38 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Rofl, nevermind. Somewhere in trying out the other ways of doing it I had broken the actual code for the animated collapse. That explains alot of things.

Thanks for the help!

Fotiman

7:54 pm on Dec 17, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Oh good, glad you got it sorted. :)

nlraley

8:06 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



Would have never caught it if I hadn't reloaded the original and found out it was broke too.

And there I was wandering why in the world everything added up to that it should work, you saying it worked, and having it not work on my end, was driving me nuts.

Really appreciate all the help, now to see if I validate again.

nlraley

8:07 pm on Dec 17, 2009 (gmt 0)

10+ Year Member



And great, I'm validated and running full force again. Thanks!