Link to home
Start Free TrialLog in
Avatar of john_yourspace
john_yourspace

asked on

UL to Select

Hi guys,

I am trying to convert the following list to a <select>so it can be submitted as part of a form

The structure can not change on the ul list as this is how the css is styled correctly( I didnt do it )

This is the general idea of what I need is

http://v2.easy-designs.net/articles/replaceSelect2/

I just need the js to match the below css structure.


Thanks for all your help

John





<ul>
                    	<li><a href="#" title="1">1</a>
                        	<ul>
                            	<li><a href="#" title="1">1</a></li>
                                <li><a href="#" title="2">2</a></li>
                                <li><a href="#" title="3">3</a></li>
                                <li><a href="#" title="4">4</a></li>
                            </ul>
                        </li>
                    </ul>

Open in new window

Avatar of Kiran Sonawane
Kiran Sonawane
Flag of India image

Check this
Test Page http://jsfiddle.net/h75Cy/

<html>
<head>
<meta http-equiv="Content-Language" content="en-gb">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Kiran Test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>

<script>
$(document).ready(function(){
  var select = $('<select></select>');
  $("ul li ul li").each(function(){
    select.append('<option value="' + $(this).text() + '">' + $(this).text() + '</option>');
  });
  $("p#output").append(select);
});

</script>
</head>

<body>
<form>
  <ul>
    <li><a href="#" title="1">1</a>
        <ul>
            <li><a href="#" title="1">1</a></li>
              <li><a href="#" title="2">2</a></li>
              <li><a href="#" title="3">3</a></li>
              <li><a href="#" title="4">4</a></li>
          </ul>
      </li>
  </ul>
  
  <p id="output"></p>
</form>
</body>

</html>

Open in new window

Avatar of john_yourspace
john_yourspace

ASKER

Hi sonawanekiran,


This displays the select box, but there are new things to note


One: there can be more then one select box on the page,

Two:the select box must be hidden( I can do this with css left - 100000px)

Three: When a user select an option from the UL it needs to update the UL to show the correct selected item / update the drop down so the correct value is submitted


Basically this UL is a complete replacement for the select but I still need the value sent to my form

NOTE: I can create a select box and just use the JS to render the CSS for the drop down this may be the easiest solution
This is my attempt at what I am on about

http://jsfiddle.net/h75Cy/3/
When I click any of the numbers on the list nothing happens?
what exactly do you want to do when you click on those numbers?
Ok,  I ll explain again,


A designer has made me a page with a form in it, he has used the following code

<ul>
                    	<li><a href="#" title="1">1</a>
                        	<ul>
                            	<li><a href="#" title="1">1</a></li>
                                <li><a href="#" title="2">2</a></li>
                                <li><a href="#" title="3">3</a></li>
                                <li><a href="#" title="4">4</a></li>
                            </ul>
                        </li>
                    </ul>

Open in new window


I now need to send this data to my form, so in this ul drop down I need to be able to extract the data on my form side if that makes sense.

Ie convert the above list to a drop down for a my form?


Something like this?

http://jsfiddle.net/Ygxt5/5/
Here is another fiddle that keeps both lists in synch with each other (code is documented as well)

http://jsfiddle.net/Ygxt5/13/
Ok I have updated that file with exactly what I have

http://jsfiddle.net/Ygxt5/14/

As you can the css makes the ul act like a select, I just need to be able to gather this data on the post

Hope that makes sense sorry for the confusion

J
Do you mind if I retrofit that into my second fiddle (http://jsfiddle.net/Ygxt5/13/)?  You have a lot of manual dom manipulation that I would much rather use jQuery as long as it yields the same result and you are OK with using jQuery.
Yea as long as it works and I don't need to alter the CSS too much,  as there is around 10 of these drop downs on a different forms

Thanks for all the help
Let me try and understand completely what you are looking for.  You would like the UL selection to result in the selection of the appropriate entry in a REAL select (which may or may not be hidden in the page)?

Also, there may be more than one UL on the page, right (more than one FAKE select type drop down)?
Exactly
Ok but are you starting with real selects in the first place and transforming those to UL?  Or are you starting with the UL stuff and wanting to generate a hidden select box dynamically that needs submitted.
I came up with something like this

http://jsfiddle.net/Ygxt5/27/

If you are transforming the selects, then I have to tweak the code.
Thank you so much Lo-Tan, I think this is exactly what I am looking for, A++,


Just one or two quick questions,

The page I am using this on is structured as follows

header (with drop down always on everypage) ie pick country or what ever

then I have a search with the same kinda of dropdown, but this will be in separate form

Do I just drop this code in an include with a document.ready around it?

And how does it know which form to drop the select into?


 
ASKER CERTIFIED SOLUTION
Avatar of Lo-Tan
Lo-Tan
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This fiddle actually shows which one is selected in the drop down:

http://jsfiddle.net/Ygxt5/28/
I almost have this thanks again for you patience,

Here is what I have now

This is dropdown.js
/**
 * This class manages the drop down belonging to a given set of
 * UL/LI items.  Whenever a new selection is made, the dropdown
 * managed by the instance of this class will be properly updated
 * and the list of items will be hidden from view.
 */
var SpecialDropdown = function(el, inputName, formId){
    this.form = jQuery("#" + formId);
    this.valueItem = jQuery(el);
    this.dropdownList = this.valueItem.siblings("ul");
    this.buildInputElement(inputName);
    this.bindListListeners();
    this.bindHoverFunctionality();
};

/**
 * The id of the form to inject the generated drop down into
 */
SpecialDropdown.prototype.formId = null;

/**
 * The root item that the user sees as being the value for the select
 */
SpecialDropdown.prototype.valueItem = null;

/**
 * The input element that is generated and managed by this component.  This is
 * where the value is stored whenever the user selects a new LI from the UL list.
 */
SpecialDropdown.prototype.inputElement = null;

/**
 * This is just a reference to the list of items for this drop down so that it
 * may be hidden/displayed as needed.
 */
SpecialDropdown.prototype.dropdownList = null;

/**
 * Constructs the input element that will hold the submittable value
 * and backs this UL/LI list in a form.
 */
SpecialDropdown.prototype.buildInputElement = function(inputName){
    this.form.append( jQuery("<span />").text(inputName + ": ") ); // temporary
    this.inputElement =
        jQuery("<input />").attr("type","text")
        .val(this.valueItem.attr("title"))
        .css({
        color: "blue"
            // Uncomment this to hide the drop downs from the user
            // ,display: "none"
        })
        .attr("name",inputName)
        .appendTo(this.form);
    this.form.append("<br />");
}
 
/**
 * Updates the value item on display, as well as the input element,
 * with the appropriate corresponding value.
 */
SpecialDropdown.prototype.setSelectedValue = function(value) {
    this.valueItem.text(value);
    this.inputElement.val(value);
}
    
/**
 * This method is invoked each time an item in the UL/LI list
 * is selected.
 */
SpecialDropdown.prototype.handleLIClick = function(evt) {
    var selectedAhref = jQuery(evt.target);
    selectedAhref.parent().siblings("li").children("a.selected-style").removeClass("selected-style");
    selectedAhref.addClass("selected-style");
    this.setSelectedValue(jQuery(evt.target).attr("title"));
    this.dropdownList.hide();
    return false;
};

/**
 * Wires all items in the UL/LI list (drop down list) to call the callback
 * so that styles can be applied to the selected item and so that the
 * backing input field can be updated.
 */
SpecialDropdown.prototype.bindListListeners = function() {
    this.dropdownList.find("li a").click(jQuery.proxy(this.handleLIClick, this));
};

/**
 * Binds mouse over and mouse exit events to properly hide and show the
 * list of choices that are in the UL
 */
SpecialDropdown.prototype.bindHoverFunctionality = function() {
    var ddList = this.dropdownList;
    var onMouseOver = function(){
        ddList.show(0);
    };
    var onMouseExit = function(){
        ddList.hide(0);
    };
    this.valueItem.parent().mouseenter(onMouseOver).mouseleave(onMouseExit);
    this.valueItem.click(function(){return false;});
};

Open in new window



My UL looks like this

<ul>
                    	<li><a href="#" id="locationParentUL" title="Galway">Galway</a>
                        	<ul>
                            	<li><a href="#" title="Galway">Galway</a></li>
                                <li><a href="#" title="Dublin">Dublin</a></li>
                                <li><a href="#" title="Cork">Cork</a></li>
                                <li><a href="#" title="Belfast">Belfast</a></li>
                            </ul>
                        </li>
                    </ul>
					<form id="frmLocation" name="frmLocation"/>

Open in new window



And in my footer I have

jQuery(document).ready(function(){
		new SpecialDropdown(jQuery("#locationParentUL"), "myInput", "frmLocation");
})

Open in new window



What am I doing wrong :(


I sorted it i had a form in a form duh :(
Excellent cannot thank you enough
You're welcome
Ok, I couldn't resist.  I cleaned up some of the code and also put in code that applies the selected-item class to the appropriate UL/LI as soon as you create the SpecialDropdown.  So even on the first expansion of the drop down, the right LI has the class applied.

Fiddle here >  http://jsfiddle.net/Ygxt5/30/

Code attached.

Cheers,
Lo-Tan
/**
 * This class manages the drop down belonging to a given set of
 * UL/LI items.  Whenever a new selection is made, the dropdown
 * managed by the instance of this class will be properly updated
 * and the list of items will be hidden from view.
 */
var SpecialDropdown = function(el, inputName, formElementId){
    this.formElement = jQuery("#" + formElementId);
    this.valueElement = jQuery(el);
    this.dropdownList = this.valueElement.siblings("ul");
    this.buildInputElement(inputName);
    this.bindListListeners();
    this.bindHoverFunctionality();
    this.setSelectedValue(this.valueElement.attr("title"));
};

/**
 * The form to inject the generated drop down into
 */
SpecialDropdown.prototype.formElement = null;

/**
 * The root item that the user sees as being the value for the select
 */
SpecialDropdown.prototype.valueElement = null;

/**
 * The input element that is generated and managed by this component.  This is
 * where the value is stored whenever the user selects a new LI from the UL list.
 */
SpecialDropdown.prototype.inputElement = null;

/**
 * This is just a reference to the list of items for this drop down so that it
 * may be hidden/displayed as needed.
 */
SpecialDropdown.prototype.dropdownList = null;

/**
 * Constructs the input element that will hold the submittable value
 * and backs this UL/LI list in a form.
 */
SpecialDropdown.prototype.buildInputElement = function(inputName){
    this.formElement.append( jQuery("<span />").text(inputName + ": ") ); // temporary
    this.inputElement = 
        jQuery("<input />").attr("type","text")
        //.val(this.valueElement.attr("title"))
        .css({
            color: "blue"
            // Uncomment this to hide the drop downs from the user
            // ,display: "none"
        })
        .attr("name",inputName)
        .appendTo(this.formElement);
    this.formElement.append("<br />");
}
 
/**
 * Updates the value item on display, as well as the input element,
 * with the appropriate corresponding value.
 */ 
SpecialDropdown.prototype.setSelectedValue = function(value) {
    this.valueElement.text(value);
    this.inputElement.val(value);
    // Highlight the appropriate element in the drop down list
    this.dropdownList.find("li > a.selected-style").removeClass("selected-style");
    this.dropdownList.find("li > a[title='" + value + "']").addClass("selected-style");
}
    
/**
 * This method is invoked each time an item in the UL/LI list
 * is selected.
 */
SpecialDropdown.prototype.handleLIClick = function(evt) {
    var selectedAhref = jQuery(evt.target);
    this.setSelectedValue(jQuery(evt.target).attr("title"));
    this.dropdownList.hide();
    return false;
};

/**
 * Wires all items in the UL/LI list (drop down list) to call the callback
 * so that styles can be applied to the selected item and so that the
 * backing input field can be updated.
 */
SpecialDropdown.prototype.bindListListeners = function() {
    this.dropdownList.find("li a").click(jQuery.proxy(this.handleLIClick, this));
};

/**
 * Binds mouse over and mouse exit events to properly hide and show the
 * list of choices that are in the UL
 */
SpecialDropdown.prototype.bindHoverFunctionality = function() {
    var ddList = this.dropdownList;
    var onMouseOver = function(){
        ddList.show(0);
    };
    var onMouseExit = function(){
        ddList.hide(0);
    };
    this.valueElement.parent().mouseenter(onMouseOver).mouseleave(onMouseExit);
    this.valueElement.click(function(){return false;});
};

Open in new window