Forum Moderators: open

Message Too Old, No Replies

Radio Button Disable/Enable Script

         

LinusIT

2:55 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



I have a page with 3 different sections of radio button choices - First 5 - Second 5 - Sack Type. Under Sack Type there are 3 options, if I select one particular option I need it to disable 2 options from the other 2 sections.

I have never written any Javascript before just now so I'm not surprised it doesn't work as intended.

Javascript Code:

<script language="javascript" type="text/javascript">
function chMd()
{
if(document.getElementById('attrib-3-3').checked = true) {
document.getElementById('attrib-8-45').disabled = true;
document.getElementById('attrib-8-44').disabled = true;
document.getElementById('attrib-9-49').disabled = true;
document.getElementById('attrib-9-50').disabled = true;
}
if(document.getElementById('attrib-3-3').checked = false) {
document.getElementById('attrib-8-45').enabled = true;
document.getElementById('attrib-8-44').enabled = true;
document.getElementById('attrib-9-49').enabled = true;
document.getElementById('attrib-9-50').enabled = true;
}

}

</script>


HTML Code:

<form name="cart_quantity" action="ten-packs-p-28.html?action=add_product&amp;number_of_uploads=0" method="post" enctype="multipart/form-data">
<div id="productAttributes">

<h4 class="optionName back">First 5</h4>
<div class="back">
<input type="radio" onclick="chMd()" name="id[8]" value="44" checked="checked" id="attrib-8-44" /><label class="attribsRadioButton zero" for="attrib-8-44">Five Soft</label><br />
<input type="radio" onclick="chMd()" name="id[8]" value="45" id="attrib-8-45" /><label class="attribsRadioButton zero" for="attrib-8-45">Five Stalky</label><br />
<input type="radio" onclick="chMd()" name="id[8]" value="46" id="attrib-8-46" /><label class="attribsRadioButton zero" for="attrib-8-46">Five Straw</label><br />
<input type="radio" onclick="chMd()" name="id[8]" value="47" id="attrib-8-47" /><label class="attribsRadioButton zero" for="attrib-8-47">Five Plastic Hay ( -&pound;2.50 )</label><br />
<input type="radio" onclick="chMd()" name="id[8]" value="48" id="attrib-8-48" /><label class="attribsRadioButton zero" for="attrib-8-48">Five Plastic Straw ( -&pound;2.50 )</label><br />
</div>
<h4 class="optionName back">Second 5</h4>
<div class="back">
<input type="radio" onclick="chMd()" name="id[9]" value="49" checked="checked" id="attrib-9-49" /><label class="attribsRadioButton zero" for="attrib-9-49">Five Soft</label><br />
<input type="radio" onclick="chMd()" name="id[9]" value="50" id="attrib-9-50" /><label class="attribsRadioButton zero" for="attrib-9-50">Five Stalky</label><br />
<input type="radio" onclick="chMd()" name="id[9]" value="51" id="attrib-9-51" /><label class="attribsRadioButton zero" for="attrib-9-51">Five Straw</label><br />
<input type="radio" onclick="chMd()" name="id[9]" value="52" id="attrib-9-52" /><label class="attribsRadioButton zero" for="attrib-9-52">Five Plastic Hay ( -&pound;2.50 )</label><br />
<input type="radio" onclick="chMd()" name="id[9]" value="53" id="attrib-9-53" /><label class="attribsRadioButton zero" for="attrib-9-53">Five Plastic Straw ( -&pound;2.50 )</label><br />
</div>
<h4 class="optionName back">Sack Type</h4>
<div class="back">
<input type="radio" onclick="chMd()" name="id[3]" value="3" id="attrib-3-3" /><label class="attribsRadioButton zero" for="attrib-3-3">Plastic</label><br />
<input type="radio" onclick="chMd()" name="id[3]" value="1" id="attrib-3-1" /><label class="attribsRadioButton zero" for="attrib-3-1">Hessian Sacks ( +&pound;2.00 )</label><br />
<input type="radio" onclick="chMd()" name="id[3]" value="2" checked="checked" id="attrib-3-2" /><label class="attribsRadioButton zero" for="attrib-3-2">Polyprop Sacks</label><br />
</div>
</div>
</form>


Unfortunately I have had to add onclick="chMd()" to every single input button, I have no way around this. If you click on radio button then it screws up and the only fix is F5.

Help please....

Fotiman

3:45 pm on Oct 6, 2010 (gmt 0)

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



The first thing I see is that you're using the assignment operator (=) where you intended to use the equality operator (==).

if(document.getElementById('attrib-3-3').checked = true) {

should be:

if(document.getElementById('attrib-3-3').checked == true) {

or even better, since the property itself will evaluate to either true or false, you could just do this:

if(document.getElementById('attrib-3-3').checked) {

Then this bit:

if(document.getElementById('attrib-3-3').checked = false) {

could be changed to:

if(!document.getElementById('attrib-3-3').checked) {

(notice the addition of the ! preceding the condition, which negates it)
However, this is just the opposite of the check that was performed in the "if" condition, so just replace that entire line with an "else":

else {

Next, there is no "enabled" property. Instead, you want to set "disabled" = false;
So this:

document.getElementById('attrib-8-45').enabled = true;
document.getElementById('attrib-8-44').enabled = true;
document.getElementById('attrib-9-49').enabled = true;
document.getElementById('attrib-9-50').enabled = true;

becomes this:

document.getElementById('attrib-8-45').disabled = false;
document.getElementById('attrib-8-44').disabled = false;
document.getElementById('attrib-9-49').disabled = false;
document.getElementById('attrib-9-50').disabled = false;


Lastly:

Unfortunately I have had to add onclick="chMd()" to every single input button

Actually, a much better approach is to assign event listeners from JavaScript instead of including them in your markup. This promotes a cleaner separation of content and behavior layers. In addition, because events "bubble up", you could potentially add only a single event listener to a shared ancestor of all the input elements, like the form.

Hope this helps.

Fotiman

4:01 pm on Oct 6, 2010 (gmt 0)

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



Also, remove the language attribute from your script tag. It's invalid and not needed. Also, the logic here is really that you're setting the disabled property to match the checked property of one radio button, so here's how I might have done it:

<script type="text/javascript">
function chMd() {
var get = document.getElementById;
(get('attrib-8-45')).disabled = (get('attrib-8-44')).disabled = (get('attrib-9-49')).disabled = (get('attrib-9-50')).disabled = ((get('attrib-3-3')).checked);
}
</script>

LinusIT

4:48 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



Thanks very much for the comprehensive reply :)

I've used the code from your later post and it's worked a treat.

I have another issue now though, say the visitor selects attrib-8-45 and attrib-9-49 then selects attrib-3-3 thus disabling the already selected options, they remain selected and I'm concerned they may not notice this and the form would process anyway.

Is there any way of effectively clearing those elements as well as disabling them?

Lastly, your last paragraph about event listeners from JavaScript sounds a much better idea than assigning an onclick function to everything. If you don't mind could you help me out with this as well please.

Fotiman

5:40 pm on Oct 6, 2010 (gmt 0)

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



Disabled form elements don't get submitted by browsers so you should be fine to leave them.

As for the event listener, are you using any frameworks like jQuery, YUI, Prototype, mootools, etc.? These might be overkill if you're looking to attach only 1 event listener, but they can be very powerful if you think you might use them more in the future.

For now I'll assume you are not using a framework.

window.onload = function () {
var productAttributes = document.getElementById('productAttributes');
productAttributes.onclick = chMd;
}

The above example uses event "handlers" vs. event "listeners", which is functionally equivalent to using inline event handler attributes. The down side to event handlers is that you can have only 1 handler, and if your page has JavaScript that tries to set window.onload in more than one place, the last one defined will be the one that executes. Event "listeners", on the other hand, allow any number of listeners to be attached to an event. However, it's a bit more complicated to get a cross-browser method for attaching event listeners. There are many different ways to achieve this, but a basic example looks like this:


var addEvent = function (el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
};

The method above provides a cross-browser way to attach event listeners. It is not the most efficient method, as each time it is called it will perform checks to see which version is supported. It does, however, give a fairly clear picture of what it's trying to do. So instead of the event handler, you would do:

addEvent(window, 'load', function () {
var productAttributes = document.getElementById('productAttributes');
addEvent(productAttributes, 'click', chMd);
});


Follow?

LinusIT

5:49 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



Follow? I wish :)

I am not using any framework although I have seen ways of doing of what I want using Jquery which I would have used if I understood how to use it correctly.

Let's see how well I understand. So the Function chMD would remain but I would add your 2 other sections of code you've posted?

Assuming I'm correct in understanding, would I be able to then get rid of the onclick event for each radio button?

Sorry if my lack of knowledge becomes annoying, I appreciate your help greatly.

Fotiman

6:00 pm on Oct 6, 2010 (gmt 0)

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



Correct. :)

LinusIT

6:14 pm on Oct 6, 2010 (gmt 0)

10+ Year Member



That is cool, you always teach me new stuff Fotiman, thanks.

One last question, if I added a validator that prompted the user that a selection must be made, using the scenario I made early where they selected the values that were afterwards disabled would it recognise that nothing was selected?

I suppose it depends on what validator I use, then again a "checked" but disabled element should be ignored.

Fotiman

6:36 pm on Oct 6, 2010 (gmt 0)

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



Yeah, it really depends on what the validator code is attempting to do.

LinusIT

4:01 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



I have been expanding on what you helped with yesterday but come across a stumbling block.

Here's the code as of now:

function chMd()
{
var get = document.getElementById; (get('attrib-2-4')).disabled = (get('attrib-2-5')).disabled = (get('attrib-2-6')).disabled = (get('attrib-3-9')).disabled = (get('attrib-3-10')).disabled = (get('attrib-3-11')).disabled = ((get('attrib-1-2')).checked);
var get = document.getElementById; (get('attrib-2-7')).disabled = (get('attrib-2-8')).disabled = (get('attrib-3-12')).disabled = (get('attrib-3-13')).disabled = ((get('attrib-1-1')).checked);
var get = document.getElementById; (get('attrib-4-14')).disabled = (get('attrib-4-15')).disabled = (get('attrib-4-16')).disabled = ((get('attrib-1-2')).checked);
var get = document.getElementById; (get('attrib-4-17')).disabled = (get('attrib-4-18')).disabled = ((get('attrib-1-1')).checked);


The problem I'm having is that the first two lines are working great but the other two aren't. At a first guess I'd say it's because the 3rd var line is trying to do similar things to the 1st var line on the
= ((get('attrib-1-1')).checked);


Also is there anyway to get this to work on the status of two buttons? What I mean is, if attrib-1-1 or attrib-1-3 are checked then disable the other radio buttons included on that var line. Something like this at the end
= ((get('attrib-1-1')).checked) OR = ((get('attrib-1-1')).checked);


The reason I have done four seperate var lines (I wish I knew what they should be called) is because I have a dynamic page which brings up certain radio buttons depending on the page content. So for one page attrib-2-4, 2-5, 2-6 etc will always show and for another page attrib-4-14, 4-15, 4-16 etc will always show.

My only clue at present to solve this is to combine 1st & 3rd lines and 2nd & 4th. I'm wondering whether this would cause an error as some of the IDs won't exist.

Fotiman

5:22 pm on Oct 7, 2010 (gmt 0)

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



You only need to do "var get = document.getElementById;" once. This is just declaring a variable "get" that will be a shortcut to document.getElementById. So I'd start by doing this:


function chMd()
{
var get = document.getElementById;
(get('attrib-2-4')).disabled = (get('attrib-2-5')).disabled = (get('attrib-2-6')).disabled = (get('attrib-3-9')).disabled = (get('attrib-3-10')).disabled = (get('attrib-3-11')).disabled = ((get('attrib-1-2')).checked);
(get('attrib-2-7')).disabled = (get('attrib-2-8')).disabled = (get('attrib-3-12')).disabled = (get('attrib-3-13')).disabled = ((get('attrib-1-1')).checked);
(get('attrib-4-14')).disabled = (get('attrib-4-15')).disabled = (get('attrib-4-16')).disabled = ((get('attrib-1-2')).checked);
(get('attrib-4-17')).disabled = (get('attrib-4-18')).disabled = ((get('attrib-1-1')).checked);
}


And the OR operator is ||, so you could do:

... = ((get('attrib-1-1')).checked || (get('attrib-1-3')).checked);


Now, if you page is dynamic and some of those values are not included on the page, then the code will error because it will attempt to do document.getElementById('attrib-x-y'), which will return null, and then it tries to set the "checked" property on the null object (ERROR). If it's possible that the items won't exist on the page, you need to add further checks:

For example:


function chMd()
{
var get = document.getElementById,
attrib-2-4 = (get('attrib-2-4') || {}),
attrib-2-5 = (get('attrib-2-5') || {}),
...
attrib-1-2 = (get('attrib-2-5') || {checked:false};
attrib-2-4.disabled = attrib-2-5.disabled = ... = attrib-1-2.checked;
...
}

In other words, try to get each element and assign it to a variable. If the get returns null (the element with that id was not found), then the || case will execute, resulting in the variable being assigned an object literal ({}). It's valid to assign new properties to an object, as in:

var myObj = {};
myObj.disabled = false; // Perfectly valid

However, we have to make sure that the checkbox we're dependent on has a valid value for the "checked" property, which is why I assigned that variable a default "checked" property:

attrib-1-2 = (get('attrib-2-5') || {checked:false};

In other words, it will do document.getElementById('attrib-2-5') and if that returns null, attrib-1-2 will be an object with a "checked" property set to false, so that when we try to access the checked property in our assignment, we aren't getting an undefined value. Alternatively, you could check to make sure attrib-1-2 was not null before doing the assignment.

LinusIT

7:03 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



I understand the first two parts you posted but not the later (checking part).

I have rewritten the code in the way you've said where I only specify "var" once and using the | | operator. This has worked a treat, thanks.

function chMd()
{
//first page
var get = document.getElementById; (get('attrib-2-4')).disabled = (get('attrib-2-5')).disabled = (get('attrib-2-6')).disabled = ((get('attrib-1-2')).checked);
(get('attrib-2-7')).disabled = (get('attrib-2-8')).disabled = ((get('attrib-1-1')).checked || (get('attrib-1-3')).checked);
(get('attrib-3-9')).disabled = (get('attrib-3-10')).disabled = (get('attrib-3-11')).disabled = ((get('attrib-5-20')).checked);
(get('attrib-3-12')).disabled = (get('attrib-3-13')).disabled = ((get('attrib-5-19')).checked || (get('attrib-5-21')).checked);
//second page
(get('attrib-4-17')).disabled = (get('attrib-4-18')).disabled = ((get('attrib-1-1')).checked || (get('attrib-1-3')).checked);
(get('attrib-4-14')).disabled = (get('attrib-4-15')).disabled = (get('attrib-4-16')).disabled = ((get('attrib-1-2')).checked);
}


The part I'm really stuck on now is the checking part, I have read it several times but it goes over my head.

The code above is for a dynamic page and will only be used in two instances. I have put comments in showing the seperation. The first page works fine but the second page doesn't, your post explains why perfectly.

For example, attrib-2-4, 2-5, 2-6 and so on will only appear on one page and on the other page attrib 4-17, 4-18 etc will appear.

Could you help with the checking part please? Just getting me started would be great.

LinusIT

7:09 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



I've had another thought.

If certain radio button groups were disabled by default and only enabled once the user has chosen one of the first radio buttons that would be much better.

At present they can select an option, then choose one of the others which then disables it, leaving it still checked although disabled, some people may not know/notice the difference.

Is it easy to disable radio button groups? If so then I can change the above code to enable the options instead of disabling the others.

Fotiman

7:46 pm on Oct 7, 2010 (gmt 0)

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



The reason page 1 works is because that code is listed first. It will execute:
(get('attrib-2-7')).disabled = ...
but when it gets to:
(get('attrib-4-17')).disabled = ...
It will error and stop processing because get('attrib-4-17') will return null, so when you attempt to set the disabled property, it is trying to do "set the property 'disabled' of object null", which will cause a runtime error.

With page 2, the error will happen earlier in the code, when you attempt to set (get('attrib-2-7')).disabled = ...
It will error on the first item, thus your page 2 code never gets executed.

My suggested fix for this was basically to store a reference to the DOM object in a variable, and in the cases where that element is not included on the page, store an object literal instead. This way, you never try to set a property on a null object.

LinusIT

7:53 pm on Oct 7, 2010 (gmt 0)

10+ Year Member



I understand where the problem is and why it's happening but I don't have the foggiest of where to start with writing that into the code.

Can I do something like:

if attrib2-8 exists then ..... else if attrib-4-18 exists then ......

I'm very new to javascript coding and only learn by looking/reading other code.

LinusIT

6:40 pm on Oct 11, 2010 (gmt 0)

10+ Year Member



I have tried to get my head around the checking of elements but have got nowhere and have now run into another problem.

Apart from the element checking it was working fine, for the first page anyway. But I have recently added some lightbox code to the page and this stops what we've done completely.

Here's the code I've added for lightbox images

<script language="javascript" type="text/javascript"><!--
/*
Slimbox v1.67 - The ultimate lightweight Lightbox clone
(c) 2007-2008 Christophe Beyls <http://www.digitalia.be>
MIT-style license.
*/
var Slimbox;(function(){var E=window,n=Browser.Engine.trident4,t,g,F=-1,v,D,u,x,L,r,m={},s=new Image(),J=new Image(),H,a,h,p,I,e,G,c,z,K,w,i,d,B;E.addEvent("domready",function(){$(document.body).adopt($$(H=new Element("div",{id:"lbOverlay"}),a=new Element("div",{id:"lbCenter"}),G=new Element("div",{id:"lbBottomContainer"})).setStyle("display","none"));h=new Element("div",{id:"lbImage"}).injectInside(a).adopt(p=new Element("div"),I=new Element("a",{id:"lbPrevLink",href:"#",title:"Previous",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/prevlabel.gif) no-repeat 0 top"}}).addEvent("click",A),e=new Element("a",{id:"lbNextLink",href:"#",title:"Next",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/nextlabel.gif) no-repeat 100% top"}}).addEvent("click",f));c=new Element("div",{id:"lbBottom"}).injectInside(G).adopt(new Element("a",{id:"lbCloseLink",href:"#",title:"Close",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/closelabel.gif) no-repeat center"}}).addEvent("click",C),z=new Element("div",{id:"lbCaption"}),K=new Element("div",{id:"lbNumber"}),new Element("div",{styles:{clear:"both"}}))});Slimbox={open:function(O,N,M){t=$extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeTransition:false,initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},M||{});w=new Fx.Tween(H,{property:"opacity",duration:t.overlayFadeDuration});i=new Fx.Morph(a,$extend({duration:t.resizeDuration,link:"chain"},t.resizeTransition?{transition:t.resizeTransition}:{}));d=new Fx.Tween(h,{property:"opacity",duration:t.imageFadeDuration,onComplete:j});B=new Fx.Tween(c,{property:"margin-top",duration:t.captionAnimationDuration});if(typeof O=="string"){O=[[O,N]];N=0}x=E.getScrollTop()+(E.getHeight()/2);L=t.initialWidth;r=t.initialHeight;a.setStyles({top:Math.max(0,x-(r/2)),width:L,height:r,marginLeft:-L/2,display:""});u=n||(H.currentStyle&&(H.currentStyle.position!="fixed"));if(u){H.style.position="absolute"}w.set(0).start(t.overlayOpacity);y();l(1);g=O;t.loop=t.loop&&(g.length>1);return b(N)}};Element.implement({slimbox:function(M,N){$$(this).slimbox(M,N);return this}});Elements.implement({slimbox:function(M,P,O){P=P||function(Q){return[Q.href,Q.title]};O=O||function(){return true};var N=this;N.removeEvents("click").addEvent("click",function(){var Q=N.filter(O,this);return Slimbox.open(Q.map(P),Q.indexOf(this),M)});return N}});function y(){var M=E.getScroll(),N=E.getSize();$$(a,G).setStyle("left",M.x+(N.x/2));if(u){H.setStyles({left:M.x,top:M.y,width:N.x,height:N.y})}}function l(M){["object",n?"select":"embed"].forEach(function(O){Array.forEach(document.getElementsByTagName(O),function(P){if(M){P._slimbox=P.style.visibility}P.style.visibility=M?"hidden":P._slimbox})});H.style.display=M?"":"none";var N=M?"addEvent":"removeEvent";E[N]("scroll",y)[N]("resize",y);document[N]("keydown",o)}function o(N){var M=N.code;return t.closeKeys.contains(M)?C():t.nextKeys.contains(M)?f():t.previousKeys.contains(M)?A():false}function A(){return b(v)}function f(){return b(D)}function b(M){if(M>=0){F=M;v=(F||(t.loop?g.length:0))-1;D=((F+1)%g.length)||(t.loop?0:-1);q();a.className="lbLoading";m=new Image();m.onload=k;m.src=g[M][0]}return false}function k(){a.className="";d.set(0);h.setStyles({backgroundImage:"url("+m.src+")",display:""});p.setStyle("width",m.width);$$(p,I,e).setStyle("height",m.height);z.set("html",g[F][1]||"");K.set("html",(((g.length>1)&&t.counterText)||"").replace(/{x}/,F+1).replace(/{y}/,g.length));if(v>=0){s.src=g[v][0]}if(D>=0){J.src=g[D][0]}L=h.offsetWidth;r=h.offsetHeight;var N=Math.max(0,x-(r/2)),M;if(a.clientHeight!=r){i.start({height:r,top:N})}if(a.clientWidth!=L){i.start({width:L,marginLeft:-L/2})}M=function(){G.setStyles({width:L,top:N+r,marginLeft:-L/2,visibility:"hidden",display:""});d.start(1)};if(i.check(M)){M()}}function j(){if(v>=0){I.style.display=""}if(D>=0){e.style.display=""}B.set(-c.offsetHeight).start(0);G.style.visibility=""}function q(){m.onload=$empty;m.src=s.src=J.src="";i.cancel();d.cancel();B.cancel();$$(I,e,h,G).setStyle("display","none")}function C(){if(F>=0){q();F=v=D=-1;a.style.display="none";w.cancel().chain(l).start(0)}return false}})();

/* Zen Lightbox v1.5 2008-12-18 */

Slimbox.scanPage = function() {
$$(document.links).filter(function(el) {
return el.rel && el.rel.test(/^lightbox/i);
}).slimbox({overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeTransition:false,initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]}, null, function(el) {
return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
});
};
window.addEvent("domready", Slimbox.scanPage);
//--></script>


Do I either need to have one or the other, or can I modify the radio button code to work along with the lightbox stuff.

Fotiman

1:21 pm on Oct 12, 2010 (gmt 0)

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



Slimbox requires a framework like mootools or jQuery. I suspect that the "addEvent" method is already defined, thus the one we created is not needed.

LinusIT

7:33 pm on Oct 12, 2010 (gmt 0)

10+ Year Member



I have removed the addEvent code that we created and tested, the slimbox stuff still works but the radio buttons don't work.

I have found this in the generated HTML

<script type="text/javascript" src="includes/templates/premium1c/jscript/zen_lightbox_mootools_custom.js"></script>


Are there any solutions to my problems or do I need to choice between control or fancy image functions?

Thanks for your replies

Fotiman

8:44 pm on Oct 12, 2010 (gmt 0)

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



Ok, mootools defines an addEvent method for each element, so after removing the addEvent function that I defined earlier, do this:


window.addEvent('load', function () {
var productAttributes = document.getElementById('productAttributes');
productAttributes.addEvent('click', chMd);
});


As long as mootools is included before this code, it should work.

LinusIT

8:25 am on Oct 13, 2010 (gmt 0)

10+ Year Member



I have done as you've suggested but it's still not working. I'm thinking I've messed up somewhere. Here's all the Javascript code in the head section of the page:

<script type="text/javascript" src="includes/modules/pages/product_info/jscript_textarea_counter.js"></script>
<script type="text/javascript">
var addEvent = function (el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
};

function chMd()
{
var get = document.getElementById; (get('attrib-2-4')).disabled = (get('attrib-2-5')).disabled = (get('attrib-2-6')).disabled = ((get('attrib-1-2')).checked);
(get('attrib-2-7')).disabled = (get('attrib-2-8')).disabled = ((get('attrib-1-1')).checked || (get('attrib-1-3')).checked);
(get('attrib-3-9')).disabled = (get('attrib-3-10')).disabled = (get('attrib-3-11')).disabled = ((get('attrib-5-20')).checked);
(get('attrib-3-12')).disabled = (get('attrib-3-13')).disabled = ((get('attrib-5-19')).checked || (get('attrib-5-21')).checked);
(get('attrib-4-17')).disabled = (get('attrib-4-18')).disabled = ((get('attrib-1-1')).checked || (get('attrib-1-3')).checked);
(get('attrib-4-14')).disabled = (get('attrib-4-15')).disabled = (get('attrib-4-16')).disabled = ((get('attrib-1-2')).checked);
}
</script>
<script language="javascript" type="text/javascript"><!--
function popupWindow(url) {
window.open(url,'popupWindow','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=100,height=100,screenX=150,screenY=150,top=150,left=150')
}
function popupWindowPrice(url) {
window.open(url,'popupWindow','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,copyhistory=no,width=600,height=400,screenX=150,screenY=150,top=150,left=150')
}
//--></script>
<script type="text/javascript" src="includes/templates/premium1c/jscript/zen_lightbox_mootools_custom.js"></script>
<script type="text/javascript">
window.addEvent('load', function () {
var productAttributes = document.getElementById('productAttributes');
productAttributes.addEvent('click', chMd);
});
</script>
<script language="javascript" type="text/javascript"><!--
/*
Slimbox v1.67 - The ultimate lightweight Lightbox clone
(c) 2007-2008 Christophe Beyls <http://www.digitalia.be>
MIT-style license.
*/
var Slimbox;(function(){var E=window,n=Browser.Engine.trident4,t,g,F=-1,v,D,u,x,L,r,m={},s=new Image(),J=new Image(),H,a,h,p,I,e,G,c,z,K,w,i,d,B;E.addEvent("domready",function(){$(document.body).adopt($$(H=new Element("div",{id:"lbOverlay"}),a=new Element("div",{id:"lbCenter"}),G=new Element("div",{id:"lbBottomContainer"})).setStyle("display","none"));h=new Element("div",{id:"lbImage"}).injectInside(a).adopt(p=new Element("div"),I=new Element("a",{id:"lbPrevLink",href:"#",title:"Previous",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/prevlabel.gif) no-repeat 0 top"}}).addEvent("click",A),e=new Element("a",{id:"lbNextLink",href:"#",title:"Next",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/nextlabel.gif) no-repeat 100% top"}}).addEvent("click",f));c=new Element("div",{id:"lbBottom"}).injectInside(G).adopt(new Element("a",{id:"lbCloseLink",href:"#",title:"Close",styles:{"background":"transparent url(includes/templates/premium1c/buttons/english/zen_lightbox/closelabel.gif) no-repeat center"}}).addEvent("click",C),z=new Element("div",{id:"lbCaption"}),K=new Element("div",{id:"lbNumber"}),new Element("div",{styles:{clear:"both"}}))});Slimbox={open:function(O,N,M){t=$extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeTransition:false,initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},M||{});w=new Fx.Tween(H,{property:"opacity",duration:t.overlayFadeDuration});i=new Fx.Morph(a,$extend({duration:t.resizeDuration,link:"chain"},t.resizeTransition?{transition:t.resizeTransition}:{}));d=new Fx.Tween(h,{property:"opacity",duration:t.imageFadeDuration,onComplete:j});B=new Fx.Tween(c,{property:"margin-top",duration:t.captionAnimationDuration});if(typeof O=="string"){O=[[O,N]];N=0}x=E.getScrollTop()+(E.getHeight()/2);L=t.initialWidth;r=t.initialHeight;a.setStyles({top:Math.max(0,x-(r/2)),width:L,height:r,marginLeft:-L/2,display:""});u=n||(H.currentStyle&&(H.currentStyle.position!="fixed"));if(u){H.style.position="absolute"}w.set(0).start(t.overlayOpacity);y();l(1);g=O;t.loop=t.loop&&(g.length>1);return b(N)}};Element.implement({slimbox:function(M,N){$$(this).slimbox(M,N);return this}});Elements.implement({slimbox:function(M,P,O){P=P||function(Q){return[Q.href,Q.title]};O=O||function(){return true};var N=this;N.removeEvents("click").addEvent("click",function(){var Q=N.filter(O,this);return Slimbox.open(Q.map(P),Q.indexOf(this),M)});return N}});function y(){var M=E.getScroll(),N=E.getSize();$$(a,G).setStyle("left",M.x+(N.x/2));if(u){H.setStyles({left:M.x,top:M.y,width:N.x,height:N.y})}}function l(M){["object",n?"select":"embed"].forEach(function(O){Array.forEach(document.getElementsByTagName(O),function(P){if(M){P._slimbox=P.style.visibility}P.style.visibility=M?"hidden":P._slimbox})});H.style.display=M?"":"none";var N=M?"addEvent":"removeEvent";E[N]("scroll",y)[N]("resize",y);document[N]("keydown",o)}function o(N){var M=N.code;return t.closeKeys.contains(M)?C():t.nextKeys.contains(M)?f():t.previousKeys.contains(M)?A():false}function A(){return b(v)}function f(){return b(D)}function b(M){if(M>=0){F=M;v=(F||(t.loop?g.length:0))-1;D=((F+1)%g.length)||(t.loop?0:-1);q();a.className="lbLoading";m=new Image();m.onload=k;m.src=g[M][0]}return false}function k(){a.className="";d.set(0);h.setStyles({backgroundImage:"url("+m.src+")",display:""});p.setStyle("width",m.width);$$(p,I,e).setStyle("height",m.height);z.set("html",g[F][1]||"");K.set("html",(((g.length>1)&&t.counterText)||"").replace(/{x}/,F+1).replace(/{y}/,g.length));if(v>=0){s.src=g[v][0]}if(D>=0){J.src=g[D][0]}L=h.offsetWidth;r=h.offsetHeight;var N=Math.max(0,x-(r/2)),M;if(a.clientHeight!=r){i.start({height:r,top:N})}if(a.clientWidth!=L){i.start({width:L,marginLeft:-L/2})}M=function(){G.setStyles({width:L,top:N+r,marginLeft:-L/2,visibility:"hidden",display:""});d.start(1)};if(i.check(M)){M()}}function j(){if(v>=0){I.style.display=""}if(D>=0){e.style.display=""}B.set(-c.offsetHeight).start(0);G.style.visibility=""}function q(){m.onload=$empty;m.src=s.src=J.src="";i.cancel();d.cancel();B.cancel();$$(I,e,h,G).setStyle("display","none")}function C(){if(F>=0){q();F=v=D=-1;a.style.display="none";w.cancel().chain(l).start(0)}return false}})();

/* Zen Lightbox v1.5 2008-12-18 */

Slimbox.scanPage = function() {
$$(document.links).filter(function(el) {
return el.rel && el.rel.test(/^lightbox/i);
}).slimbox({overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeTransition:false,initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]}, null, function(el) {
return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel));
});
};
window.addEvent("domready", Slimbox.scanPage);
//--></script>


Was I supposed to put all of the code for the buttons below the mootools section?

Thanks

Fotiman

1:43 pm on Oct 13, 2010 (gmt 0)

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



You were supposed to remove the addEvent function that we created, and make sure the mootools code appeared BEFORE your code. Try this:


<script type="text/javascript" src="includes/templates/premium1c/jscript/zen_lightbox_mootools_custom.js"></script>
<script type="text/javascript" src="includes/modules/pages/product_info/jscript_textarea_counter.js"></script>
<script type="text/javascript">
function popupWindow(url) {
window.open(url, 'popupWindow',
'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=yes,copyhistory=no,width=100,height=100,screenX=150,screenY=150,top=150,left=150');
}
function popupWindowPrice(url) {
window.open(url, 'popupWindow',
'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,copyhistory=no,width=600,height=400,screenX=150,screenY=150,top=150,left=150')
}
</script>
<script type="text/javascript">
function chMd() {
// Identify what page we are on
if ( PAGE1CONDITION ){ // page 1
($('attrib-2-4')).disabled = ($('attrib-2-5')).disabled = ($('attrib-2-6')).disabled = (($('attrib-1-2')).checked);
($('attrib-2-7')).disabled = ($('attrib-2-8')).disabled = (($('attrib-1-1')).checked || ($('attrib-1-3')).checked);
($('attrib-3-9')).disabled = ($('attrib-3-10')).disabled = ($('attrib-3-11')).disabled = (($('attrib-5-20')).checked);
($('attrib-3-12')).disabled = ($('attrib-3-13')).disabled = (($('attrib-5-19')).checked || ($('attrib-5-21')).checked);
}
else { // page 2
($('attrib-4-17')).disabled = ($('attrib-4-18')).disabled = (($('attrib-1-1')).checked || ($('attrib-1-3')).checked);
($('attrib-4-14')).disabled = ($('attrib-4-15')).disabled = ($('attrib-4-16')).disabled = (($('attrib-1-2')).checked);
}
}
window.addEvent('load', function () {
var productAttributes = document.getElementById('productAttributes');
productAttributes.addEvent('click', chMd);
});
</script>
<script type="text/javascript">
/*
Slimbox v1.67 - The ultimate lightweight Lightbox clone
(c) 2007-2008 Christophe Beyls <http://www.digitalia.be>
MIT-style license.
*/
// OMITTED FOR EXAMPLE PURPOSE ONLY
// ...
window.addEvent("domready", Slimbox.scanPage);
</script>


In this example, you now just need to replace PAGE1CONDITION with the proper conditions that will identify each page. For example, if page 1 will never have attrib-4-7, you could do:

if (!($('attrib-4-7'))) { // page 1

Also, I omitted the bulk of the Slimbox code to keep this post shorter. You would need to include that code.

LinusIT

9:04 am on Oct 15, 2010 (gmt 0)

10+ Year Member



Have done exactly what you've said and it's working now but only in Firefox, the radio button control doesn't work in IE.

Any clues?

Fotiman

11:56 am on Oct 15, 2010 (gmt 0)

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



I would try throwing some alert messages in just to see what's happening. For example:

window.addEvent('load', function () {
var productAttributes = document.getElementById('productAttributes');
alert('Adding click handler...');
productAttributes.addEvent('click', chMd);
});

function chMd() {
alert('Entering chMd...');
// Identify what page we are on
if ( PAGE1CONDITION ){ // page 1
alert('Page 1...');
($('attrib-2-4')).disabled = ($('attrib-2-5')).disabled = ($('attrib-2-6')).disabled = (($('attrib-1-2')).checked);
($('attrib-2-7')).disabled = ($('attrib-2-8')).disabled = (($('attrib-1-1')).checked || ($('attrib-1-3')).checked);
($('attrib-3-9')).disabled = ($('attrib-3-10')).disabled = ($('attrib-3-11')).disabled = (($('attrib-5-20')).checked);
($('attrib-3-12')).disabled = ($('attrib-3-13')).disabled = (($('attrib-5-19')).checked || ($('attrib-5-21')).checked);
}
else { // page 2
alert('Page 2...');
($('attrib-4-17')).disabled = ($('attrib-4-18')).disabled = (($('attrib-1-1')).checked || ($('attrib-1-3')).checked);
($('attrib-4-14')).disabled = ($('attrib-4-15')).disabled = ($('attrib-4-16')).disabled = (($('attrib-1-2')).checked);
}
}

LinusIT

1:28 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



In Firefox on page load it says "Adding Click Handler.." and when selecting a radio button it says "Entering chMD". In IE on page load it says "Adding Click Handler.." but when clicking on a radio button nothing comes up.

Also, in IE on the bottom left it says there is an error, when clicking on the icon it comes up with:

Object doesn't support this property or method, Line 22 char 1. This is line 22

productAttributes.addEvent('click', chMd);

Fotiman

1:57 pm on Oct 15, 2010 (gmt 0)

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



Ok, I thought that mootools was adding an addEvent method to all DOM elements (per [mootools.net...] but I'm not really all that familiar with mootools, and apparently that's not the case.

You could maybe try doing this instead:

productAttributes.onclick = chMd;

I'm not really a fan of attaching event handlers like that, but it might get you past this point.

LinusIT

6:33 pm on Oct 15, 2010 (gmt 0)

10+ Year Member



It is now working in Firefox and IE. The radio buttons are controlled and the slimbox effect work great.

Thank you very much