|
Introduction
This script aims to extend the functionality of the standard <select> field in web pages. Sometimes, we need to order elements in a list. Such functionality extension may be useful, for example, in CMS when you need an interface to order and reorder some elements.
Background
I started to work on a new CMS project for my client and searched for a script to reorder <select> elements. I found many scripts, but none of them does what I expect and what I need. As you know, the difference between programmers and normal people is that when programmers need something, they sit and script. So I wrote this script...
Why use THIS script?
- First of all, this script supports the
multiple="multiple" attribute of the sorted <select> field. You can move up, down, to top, or to bottom even a complex multiple selection. Read more in "About multiple selections";
- Another advantage of this script is that it does not copy values of the
<select> in to a hidden field, but submit the whole field as an array to the server. Note that the name of the <select> field must contain [] at the end. For example, if the name of the field should be "files", use: name="files[]";
- Some browsers support different colors, fonts, styles and background colors for different elements of the
<select> field - MSIE and Firefox. This script supports not only reordering texts and values, but also reorders the layout of the <select> field by changing colors, background colors, ID and class name attributes of the moved elements;
- Also, when using
viceversa() and listsort() functions, the script remembers which element is selected and which is not;
- At last, the script is tested under MSIE, Netscape 6 and 7, Opera 6 and 7, and Firefox 0.8.# and 0.9.#.
Functions
There are six basic functions to order elements:
top(object);
Moves selected items in the <select> field to the top;
up(object);
Moves selected items in the <select> field one step upper;
down(object);
Moves selected items in the <select> field one step lower;
bottom(object);
Moves selected items in the <select> field to the bottom;
- NEW!
viceversa(object, onlyselected);
Reorders all or only selected items in the <select> field in backorder;
- NEW!
swap(object);
Swaps the first and the last selected items in the <select> field;
listsort(object, criteria, parameter, parameter);
Sorts all items in the <select> field by a criteria.
Also, there are additional functions:
selectall(object);
Selects all items in the <select> field before submitting the <form>;
selectnone(object);
Unselects all items in the <select> field;
mousewheel(object);
Moves selected items in the <select> field up or down by scrolling the mouse wheel.
additem(object, value, text, index, id, className, color, backgroundColor, selected);
Adds a new item with specified parameters to the existing <select> field;
removeitem(object, index);
Removes item from the <select> field;
Calling the functions
You can create buttons for each function using this code: <input type="button" value="Top" onclick="top(object);"
title="Move to top" />
Or you can use any page object with the onclick="function();" event. Don't use the <button> tag to create such buttons, because in some browsers, this type of buttons submits the form! Also, if using <img>, don't use the onclick="function();" event inside the image, but put the image in to an anchor tag: <a href="#" onclick="top(object); return false;">
<img src="..." border="0" />
</a>
Never use href="javascript:". Later, I plan to submit an article on "Why we have never used href="javascript:"".
Another good idea is to use the mouse wheel to call the script. Unfortunately, it may be done only under the MSIE browser because of the onmousewheel="" event: <select ... onmousewheel="mousewheel(this);">
If you use server side, you need to submit all elements in the <select> field. This is because we added the selectall(); function which can be used with the onsubmit="" event. <form ... onsubmit="selectall('object'); return true;">
NEW! The new added function selectnone(); may be used with the ondblclick="" event. This way it is possible to unselect elements: <select ... ondblclick="selectnone(this);">
Function parameters
Note that when calling any function of the script, as a first parameter, you have to set the <select> object. It means you have to send an instance to the object or just send the ID of the object: f(object);
f("id");
The listsort(object, by, numeric, caseSensitive); function accepts four parameters, but the last three are optional.
- Required,
object is an instance to the <select> field object or its ID;
- Optional,
by - integer. Sets the sort criteria. Acceptable values:
- Optional,
numeric - boolean. If true, sorts by numeric values. For example, 2 is before 10;
- Optional,
caseSensitive - boolean. If true, sorts by case sensitive values. For example, a is before Z;
The additem(object, text, value, index, id, className, color, backgroundColor, selected); function accepts nine parameters, but only the first and the second are required.
- Required,
object is an instance to the <select> field object or its ID;
- Required,
text - string. Sets the text of the new element;
- Optional,
value - string or integer. Sets the value of the new element;
- Optional,
index - integer. If set, determines in which position to add the new element. If not set or wrong, the new element is added at the end of the field. Index starts from 0 (zero) - the first element;
- Optional,
id - string or integer. Sets the ID of the new element. Be careful not to duplicate some ID!
- Optional,
className - string. Sets the CSS class of the new element;
- Optional,
color - string may be color name or HTML color value. Sets the color of the new element. See the known bugs!
- Optional,
backgroundColor - string may be color name or HTML color value. Sets the background color of the new element. See the known bugs!
- Optional,
selected - boolean. If true, the new added element will be selected by default.
The removeitem(object, index); function accepts two parameters, and only the first is required.
- Required,
object is an instance to the <select> field object or its ID;
- Optional,
index - integer or boolean:
- If set as integer, determines which element to remove where 0 (zero) is the first element;
- If set as negative integer, the last element is removed;
- If set as positive integer greater than the element's amount, the last element is removed;
- If set as boolean
False, the last element is removed;
- If not set or else, the last element is removed;
- If set as boolean
True, the selected element(s) is(are) removed. Note: if more than one element is selected, all selected elements will be removed.
The viceversa(object, onlyselected); from version 1.3, this function accepts two parameters, and only the first is required.
- Required,
object is an instance to the <select> field object or its ID;
- Optional,
onlyselected - boolean:
- If set as true, only selected items are reordered in backorder (also if selection is not continuous). If only two elements are selected, works like the
swap function;
- If set as false or not set, all elements are reordered in backorder;
About multiple selections
Multiple selection means that users can select more than one element of the <select> field. To enable multiple selection, add multiple="multiple" and size="#" attributes.
Two types of multiple selections exist:
- Simple (continuous) multiple selection may be done by pressing and holding down the Shift key while clicking to select. All elements between the first and the last clicked are selected;
- Complex multiple selections may be done by pressing and holding down the Ctrl key while clicking to select. Only clicked elements are selected.
When moving up or down a complex multiple selection, two script behaviors are possible:
- Default. When the upper or lower selected element goes to the top or bottom, the unselected elements inside the complex multiple selection moves to the opposite direction to decrement the space between selected elements until the complex selection looks like a simple one; or
- When the upper or lower selected element goes to the top or bottom, it unselects and starts moving to the opposite direction until only one element is selected. So, the first of the selection goes last, and the last goes first;
If you need the second behavior, edit line 12 of up() and down() functions as follows:
if (sel[i] != 0 && !obj[sel[i]-1].selected) {
if (sel[i] != 0) {
if (sel[i] != obj.length-1 && !obj[sel[i]+1].selected) {
if (sel[i] != obj.length-1) {
The code
To use the script:
- Add inside the
<head> section of your web page, a link to load the script file: <script type="text/javascript" src="sort.js"></script>
Use the right location of the file in the src attribute, better relative;
- Create a
form in your web page and add an onsubmit event to it: <form method="post" action="..." onsubmit="selectall('order');">
...
</form>
The selectall() function parameter is the ID attribute of the <select> field. Better use POST method, because of limitations of the GET method!
- Add a
<select> field to your form: <select name="order[]" size="5" multiple="multiple"
id="order" onmousewheel="mousewheel(this);">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
- Optionally add the
onmousewheel event to the <select> field;
- Add some buttons for ordering functions. Not necessary for all functions - for example, you can add only
up() and down() functions: <input type="button" value="Move Up" onclick="up('order');"
title="Move up" />
<input type="button" value="Move Down" onclick="down('order');"
title="Move down" />
where the function parameter is the ID attribute of the <select> field.
- Debug to ensure everything is right. That's it!
Server side
Your server side script will receive an array variable containing the ordered values. For example, try this PHP code:
or ASP: <%
For Each item In Request.Form()("order[]")
Response.Write item & "<br />"
Next
%>
Example
Known bugs
A few bugs caused by some browsers' limitations:
- Only MSIE and Firefox support formatting of elements;
- Also, in other browsers, sort by color or background color doesn't work;
- Only MSIE supports the
onmousewheel event;
History
- Version 1.1 [November 21, 2004]
- Added function
selectnone();
- Added function
additem();
- Added function
removeitem();
- Some minor bug fixes.
- Version 1.2 [September 8, 2005]
- Bug fixed when adding element to the
<SELECT> with selected elements;
- Bug fixed in all functions when working with in element's text.
- Version 1.3 [November 7, 2005]
- Added function
swap();
- Advanced function
viceversa(); now supports only selected parameter;
- Some minor bug fixes.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 25 (Total in Forum: 25) (Refresh) | FirstPrevNext |
|
|
 |
|
|
The parameters on this article say that addItem takes parameters additem(object, value, text, index,...
But the code actually takes parameters additem(object, text, value, index,...
value and text are in the opposite order. Otherwise a great script.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
sorting algorithm is very very slow with the multiple select boxes which has too many items
Ahmet BÜTÜN http://www.ahmetbutun.net
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
It's a great script to use. I'm using it in ColdFusion. It works fine as a stand alone page but when I use it to call up through AJAX. The up and down functions are not working at all. The error states "selected is null or not an object. The swap, top and bottom buttons worked fine. Have you worked in ColdFusion and AJAX before? If so, did you use this script on ColdFusion? I would like to know.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello, this is a very nice script that solves many problems I may have faced in case I'd solve the sorting thing server-side. So, congratulations!
I wonder, if it is possible to click on an item and edit it? I use your script to sort and save menu items on one of my sites and I'd appreciate the option of editing the items' text.
Leon
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Because in last week I have received a dozen of requests for version 1.3 (which is also available here after registration) I have uploaded it on my host @ http://www.babailiica.com/js/sorter/
Also I plan to release the 1.4 version with a few new bugfixes and more new features. I`ll include the remove function in core script. Hope this will happen in January 2007, now I`m verry busy.
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
|
Hi This is an excellent script, suits to my requirement and I want to know whtether is there any format to save all the changes made to <select> box? If available please help me
Thanks
http://www.hotscripts.com/PHP/Scripts_and_Programs/Miscellaneous/osCommerce_Addons/index.html
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Ususaly I have an integer field named list_id in my database and when I select data from some table I use ORDER BY list_id ASC, id ASC
When You want to save the new order of the elements - just loop for each element in the select field and update it!
<?php if (isset ($_POST["order"])) { foreach ($_POST["order"] as $key=>$value) { //type here MySQL query to update record with ID = $value to LIST_ID = $key } } ?>
But this is not a good solution for bigger tables in databases! I`m searching for a better solution from time to time, but seems this is the best.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
If you add a product and you click to up or down in a big list. The focus go to the first element of the list...
Vezz
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hi,
I found your js and I tried to use the listSort function . I use the Struts Framework to display elements like "select". With the version of this framework that I use, I can't define the ID. So I pass the object "document.myForm.groupSelect" as the first argument where groupSelect is the nname of the select object. My problem is FireFox said that the method listsort(document.myForm.groupSelect, 1, false, false) is not defined.
My jsp contains the following lines :
<script type=text/javascript language="JavaScript" src="<%request.getcontextPath()%>/static/js/sort.js> ... <script type=text/javascript language="JavaScript"> listsort(document.myForm.groupSelect, 1, false, false); </script>
Do you have any idea about what's wrong ?
Thanks, Christian
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hey man,
great script, thanks for making it public... just one tip, you might include a compressed .js file with no spaces or comments...it might save some kb's especially for people browsing from countries with slow internet like South Africa!
Thanks again nelwa www.nellen.co.za
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
It is very happy for sharing the code...Keep it up
Sreenivasulu Palavarapu Infinite Computer Solutions, Bangalore.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'll be modifying this terrific code to add a 'swap' function to switch to entries. If/when I get it done I'll pass it along.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Well if you describe more about what this function have to do, I`ll try to add it. I think it can be done to work proper only if two (not more, not less) elements are selected! If you have any other ideas - please e-mail me or post here.
I also think about AJAX loading of elements - what do you think abot this? Not sure hot exactly to implement it- only text and values can be loaded by XML or all the data - selections, colors, backgrounds...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I have updated the script and the article. It is submited and coming soon... But it is now available at the demo URL[^]
I have added a function to swap the first and the last elements of the selection.
Also the viceversa function was advanced a bit and now supports second optional argument- onlyselected which works like the swap function when only two elements are selected!
The AJAX elements load - next month
BABA...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
If used from an ASPX page, does the reordered list post back in a way that the new order can be determined in the code behind? Do you know if it affects the viewstate?
Thanks.
Zeke
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
The reordered list is posted back via the Request.Form object. If you specify the name of the listbox, Request.Form("ListBoxName") returns a comma-delimited string. You split that into an array, loop through and bind the listbox to the array, or iterate through the array to do what you need to do. The one problem with this is that you only get the Value of the selected items back, not the Text, so you need to be aware of this if you have different values.
You also need to make sure to call the selectall(); function when the form is posted. If you don't do this, you won't get the complete list back from Request.Form. I modified the selectall() function to always return true so that the form would always submit after I added it to the OnSubmit event.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Did anyone get this to work? I have been trying but seem unable to find the data in the forms collection! I am firing the selectall event but nothing seems to get submitted!
Definitely a PEBCAK! (Problem Exists Between Keyboard And Chair) www.FruitBatInShades.com
-- modified at 8:11 Tuesday 25th April, 2006
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I'm using a listbox named lstArrange and a button called btnSave.
For the button, I used the following code:
btnSave.Attributes("onclick") = "selectall('" & lstArrange.ClientID & "');"
I use the following code to retrieve the list values of the sorted items:
Dim asList() As String = Split(Request.Form(lstArrange.UniqueID), ",")
Two things to check: 1) Because of the javascript sorting, you can't just examine lstArrange. It is still in the unsorted order because that is how .NET created it. You must pull out the values from the form directly, not via the normal .NET object/property way. 2) Have you verified that the selectall is assigned to the button's onclick attribute by looking at the page's html source?
HTH.
Zeke
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks for replying ZekeLA. I have sorted it all out now I don't put client side script into the html code (search for behavior.js) so that method will not work for me. I do now have a working control though
Definitely a PEBCAK! (Problem Exists Between Keyboard And Chair) www.FruitBatInShades.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Nicely done It would be nice to have a function for removing (deleting) items from the list as well.
davej
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
| | |