Solved

Optgroup toggle

Posted on 2010-11-29
10
2,431 Views
Last Modified: 2012-05-10
Hi, im using this code from jQuery UI MultiSelect Widget and it uses this option called optgroupToggle that separates a list by Groups my problem is that i would like to have groups and also independent <option> in the code below you can see that it has 2 groups like this

<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>
<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window


What i need is to also have <option> that are not in the group:

<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

<option value="option">Independent Option</option>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window


but it automatically groups in Group One even if it's outside the <optgroup> Label any help to do this would be great.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery MultiSelect Widget Demo</title>
<link rel="stylesheet" type="text/css" href="../jquery.multiselect.css" />
<link rel="stylesheet" type="text/css" href="assets/style.css" />
<link rel="stylesheet" type="text/css" href="assets/prettify.css" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/ui-lightness/jquery-ui.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script type="text/javascript" src="../src/jquery.multiselect.js"></script>
<script type="text/javascript" src="assets/prettify.js"></script>
<script type="text/javascript">
$(function(){

	var $callback = $("#callback");
	
	$("select").multiselect({
		optgrouptoggle: function(event, ui){
			var values = $.map(ui.inputs, function(checkbox){
				return checkbox.value;
			}).join(", ");
		
		}
	});

});
</script>
</head>
<body onload="prettyPrint();">


<select multiple="multiple" size="5">
<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>
<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>
</select>


</body>
</html>

Open in new window

0
Comment
Question by:jd_18286
  • 5
  • 4
10 Comments
 
LVL 82

Expert Comment

by:leakim971
ID: 34235581
What about :

<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

  <optgroup style="display:none">
	  <option value="option">Independent Option</option>
  </optgroup>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window


Or :


<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

  <optgroup label="">
	  <option value="option">Independent Option</option>
  </optgroup>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window


Or :

<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

  <optgroup style="---------------">
	  <option value="option">Independent Option</option>
  </optgroup>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window

0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 34248562
the way the widget works is it assumes anything between one optgroup and the next optgroup tag belongs in the first optgroup - disregarding what your actual html markup may be (i.e. option tags outside any optgroup.

there is a work-around for this, but you will have to hack the widget's js a little:

1) first, add some class to the <option> tags that should be outside any <optgroup>. for example let's add 'nooptgroup' class to them, so that your <select> loks like this:
<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

<option value="option" class="nooptgroup">Independent Option</option>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>

Open in new window


2) now for some js hacking. open jquery.multiselect.js and find the part that sets widget's default options. in ver 1.6 this begins on line 27.
now add this line into the options:
skipOptgroupClass: 'nooptgroup' // if this is NOT the last line in optios, add a comma at the end

Open in new window

(adding the above will allow you to define skipOptgroupClass option in the widget init code, passing it whatever class you gave your stand-alone <option> tags)

3) now find  el.find('option').each(function(i){ code block  (line 88 in ver 1.6) and add
isNoOptgroup = $this.is('.'+o.skipOptgroupClass),

Open in new window

line after the line beginning with isDisabled

4) about 20 lines down (line 113 in ver 1.6) find the line
html.push('<label for="'+inputID+'" class="'+labelClasses.join(' ')+ '"><input id="'+inputID+'" name="multiselect_'+id+'" type="'+(o.multiple ? "checkbox" : "radio")+'" value="'+value+'" title="'+title+'"');

Open in new window

and change it to:
html.push('<label for="'+inputID+'" class="'+labelClasses.join(' ')+ '"><input id="'+inputID+'" name="multiselect_'+id+'" type="'+(o.multiple ? "checkbox" : "radio")+'" value="'+value+'" title="'+title+'"'+(isNoOptgroup ? 'class="'+o.skipOptgroupClass+'"' : ''));

Open in new window

(we have just added a bit of code at the end of the original line)

5) finally, find _bindEvents function definition and inside it find the line
$inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible');

Open in new window

(line 220 in ver 1.6) and change it to
$inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible').not('.'+self.options.skipOptgroupClass);

Open in new window


done!

let me know if you get  lost in all these changes and i will post the complete edited js code for the widget.

Azadi
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 34248589
PS:
you will notice that the 'independent' option looks exactly like all other options in the widget.
only by clicking on the group header you will see that that option does not get selected.

you may have to add some CSS for the nooptgroup class to make it look a bit different from other options so that users can visually distinguish 'independent' options from 'grouped' options...

Azadi
0
 

Author Comment

by:jd_18286
ID: 34253476
i followed all the steps correctly but for some reason it dosent work it keeps grouping it in GROUP ONE  i attach u my jquery.multiselect.js  with the changes made in line:

Line: 28
Line: 90
Line: 113

and in HTML it's like this:

<select id="test-2" multiple="multiple" size="5">
<optgroup label="Group One">
	<option value="option1">Option 1</option>
	<option value="option2">Option 2</option>
	<option value="option3">Option 3</option>
</optgroup>

<option value="option" class="nooptgroup">Independent Option</option>

<optgroup label="Group Two">
	<option value="option4">Option 4</option>
	<option value="option5">Option 5</option>
	<option value="option6">Option 6</option>
	<option value="option7">Option 7</option>
</optgroup>
</select>

Open in new window


 jquery.multiselect.js Screen Shot OF HTML
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 34253655
line 220 in your jquery.multiselect.js is different from mine.
mine is
$inputs = $this.parent().nextUntil('li.ui-multiselect-optgroup-label').find('input:visible').not('.'+self.options.skipOptgroupClass);

Open in new window


the .not() part at the end is what makes the widget not select the class="nooptgroup" options when clicking on group header.

Azadi
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:jd_18286
ID: 34253684
ok that did the trick any CSS u can recommend me to distinguish 'independent' options from 'grouped' options?
0
 
LVL 27

Accepted Solution

by:
azadisaryev earned 500 total points
ID: 34253797
up to you. but to make it possible to define css for 'independent' options you need to make another little change to jquery.multiselect.js:

find on lines 108-110 this code:
if( isDisabled ){
  labelClasses.push('ui-state-disabled');
}

Open in new window


and add this line after it:
if(isNoOptgroup) labelClasses.push(o.skipOptgroupClass+"_label");

Open in new window


this will add a 'nooptgroup_label' class to the <label> elements surrounding your 'independent' options/checkboxes

now you can define style for .nooptgroup_label class in your css. for example, you can set a large line-hight property to increase the vertical distance between them and make them stand out from the rest of the options.
<style type="text/css">
.nooptgroup_label {text-indent:1em; line-height:2em;}
</style>

Open in new window


Azadi
0
 

Author Comment

by:jd_18286
ID: 34253883
ohh thanks so much your a life saver i was wondering if you could help me out in something more i would be glad to give u more points for ur help i attached an image of how it looks and it really looks great i  want to make Option 3 like a parent and the Independent Option a child when i click in the child the parent will also be selected is that possible? Screen Shot
0
 
LVL 27

Expert Comment

by:azadisaryev
ID: 34253916
hmm... i think that is possible, but i will have to tinker with the js code figure out the best way to do it.
i am at work now, so can't spend much time on this. will post tonight.

Azadi
0
 

Author Comment

by:jd_18286
ID: 34253978
i found the idea in this site IDEA if u check out the Socks Finder in the Colour Field if u click on Plain it selects all the child check-boxes or if u select a Child it selects also the parent checkbox that in this case is Plain any way i think its using the same script im using hope u can help me out with this and tx
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

What is a Lightbox? A Lightbox is the effect you see when you click, for example, an image and the screen fades out and up pops the same image but in its full size dimensions. There are lots of Lightbox effects for jQuery. Problem is they are a…
How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now