?
Solved

Duplicate <SELECT> just one time

Posted on 2012-09-12
11
Medium Priority
?
371 Views
Last Modified: 2012-09-13
I have huge forms that use SELECTs with identical data (size list) for stock list. The html is reaching 4 mb. Each SELECT have a preselected value when the page loads.

I want to duplicate the data with javascript but only when a select is clicked/onfocus to prevent unnecessary duplication for SELECTs where user have not selected a new OPTION. Also, for each SELECT the duplication should be done only once in case of multiple click/onfocus on the same SELECT.

I've tried like this:

Have a hidden SELECT with all the values
<select style="display:none;" id="sizeOptions">
<option id="1">Text1</option>
...
<option id="200">Text200</option>
</select>

Open in new window


Have visible SELECTs that contain only the preselected value and a "0" value
<select class="sizeList" id="sizeList1">
<option id="0">-- empty --</option>
<option id="25" selected="selected">Text25</option>
</select>
<select class="sizeList" id="sizeList2">
<option id="0">-- empty --</option>
<option id="43" selected="selected">Text43</option>
</select>

Open in new window


I have tried with

function popSize(id) {
id.innerHTML = id.innerHTML+document.getElementById("sizeOptions").innerHTML
;}
...
<select onfocus="popSize(this);" id="sizeList">
<option id="0">-- empty --</option>
<option id="25" selected="selected">Text25</option>
</select>

Open in new window


2 things happen. Naturally, the SELECT grows on every onFocus. But worse, the SELECTED attribute is not respected, which is potentially catastrofic.

I'm using Firefox 15.0.1


I took a look at jQuery but I cant get that to work either.
0
Comment
Question by:Alfahane
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 54

Expert Comment

by:Scott Fell, EE MVE
ID: 38394157
Are you trying to do a chained select where the selection of one effects the outcome of the other?  http://www.appelsiini.net/2010/jquery-chained-selects.  This jquery add on allows this by making the class= of the 2nd select the same value of the first.
<select id="mark">
  <option value="">--</option>
  <option value="bmw">BMW</option>
  <option value="audi">Audi</option>
</select>
<select id="series">
  <option value="">--</option>
  <option value="series-3" class="bmw">3 series</option>
  <option value="series-5" class="bmw">5 series</option>
  <option value="series-6" class="bmw">6 series</option>
  <option value="a3" class="audi">A3</option>
  <option value="a4" class="audi">A4</option>
  <option value="a5" class="audi">A5</option>
</select>

<script src=jquery.js></script>
<script>$("#series").chained("#mark"); </script>

Open in new window

On another note, if your html is 4 megs, that sounds kind of high.  Besides possibly splitting up your form to multiple pages, some small changes might help like minifying your html.
<select style="display:none;" id="sizeOptions"><option id="1">Text1</option><option id="200">Text200</option></select>

Open in new window

0
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38394305
The problem with this approach is that the click / focus events don't allow you to select the selected value so it shows in the select box.
There are two options.
1 just popuplate all selects when the page loads
2. Do it on the mouseover event
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var lastval = 0;
$(function() {
// Populate from master on page load
  $('select.empty').each(function() {
    var val = $(this).val();
    $(this).html($('#master').html());
    $(this).val(val);
  });
});
</script>
<style type="text/css">
</style>
</head>
<body>
<a>Test</a>
<select name="master" id="master" style="display: none">
  <option value="0">--empty--</option>
  <option value="1">Text1</option>
  <option value="2">Text2</option>
  <option value="3">Text3</option>
  <option value="4">Text4</option>
  <option value="5">Text5</option>
  <option value="6">Text6</option>
</select>
<select class="empty" name="field1">
  <option value="0">--empty--</option>
  <option value="5" selected="selected">Text5</option>
</select>
<select class="empty" name="field2">
  <option value="0">--empty--</option>
  <option value="6" selected="selected">Text6</option>
</select>
<select class="empty" name="field3">
  <option value="0">--empty--</option>
  <option value="3" selected="selected">Text3</option>
</select>

</body>
</html>

Open in new window

Mouseover solution
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var lastval = 0;
$(function() {
  $('select.empty').mouseover(function() {
    var val = $(this).val();
    $(this).html($('#master').html());
    $(this).val(val);
  });
});
</script>
<style type="text/css">
</style>
</head>
<body>
<a>Test</a>
<select name="master" id="master" style="display: auto">
  <option value="0">--empty--</option>
  <option value="1" selected="selected">Text1</option>
  <option value="2">Text2</option>
  <option value="3">Text3</option>
  <option value="4">Text4</option>
  <option value="5">Text5</option>
  <option value="6">Text6</option>
</select>
<select class="empty" name="field1" id="test">
  <option value="0">--empty--</option>
  <option value="5" selected="selected">Text5</option>
</select>
<select class="empty" name="field2">
  <option value="0">--empty--</option>
  <option value="6" selected="selected">Text6</option>
</select>
<select class="empty" name="field3">
  <option value="0">--empty--</option>
  <option value="3" selected="selected">Text3</option>
</select>

</body>
</html>

Open in new window

0
 
LVL 9

Expert Comment

by:Sar1973
ID: 38394325
You could develop a simple function which evaluates the outerHTML (checking how many SELECT you have) and then launch an innerHTML if necessary, under the condition on document.getElementById("sizeOptions").value (or document.getElementById("sizeOptions").options[document.getElementById("sizeOptions").selectedIndex].text).
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:Alfahane
ID: 38394353
No, not chained. The selects are independent of eachother.

The hidden SELECT was just my idea of have a source with all options.

The form consists of product variants where every variant has it's own row with its own select for color and size:
variant 1 |SELECT, size (with current preselected) | SELECT, color (with current preselected)  | change amount | ...
variant 2 |SELECT, size (with current preselected)  | SELECT, color (with current preselected) | change amount | ...
....

Open in new window


There are up to about 250 variants per product. That's, up to 250 selects with sizes, and 250 selects with colors. For example all SELECTs with colors are _identical_ except for the SELECTS's attributes [name] and [id] and which option is pre-selected (althought a variant can have same color as other variants so it _can_ have the same option selected).

Sometimes a size or color for a product variant changes (for example One Size becomes Small/Medium). I dont want to create new variants when this happens because that "breaks" the history of a variant. These changes dont happen often and that's why in most cases loading full selects is unneccessary. So instead of creating 250 color selects server side and waste time while the html is loading I want to save time by using javascript. I've manually edited the final HTML and I get from 4MB to about 0.8MB if I can find a way to reuse the data in the hidden select.

The reason why it's on one page is that when a delivery is made to the warehouse the administrator updates the stock amounts grouped by products (=that exists in many variants) and in these situations having all variants on the same page gives a much better overview.
0
 

Author Comment

by:Alfahane
ID: 38394401
julianH - Great stuff! But there is a problem. When I use your exact code (exact HTML with your examples) it works fine except for that after I click on the select (focus), just view it with out changing anything the selected option changes to "--- empty ---" by itself. And on unFocus it stays on "--- empty---".
0
 

Author Comment

by:Alfahane
ID: 38394414
julianH - I ment the mouseOver.

The onLoad works perfect. But that mean that it would populate all selects regardless of it getting used on not.
0
 
LVL 54

Expert Comment

by:Scott Fell, EE MVE
ID: 38394415
I don't think you need the hidden select.    What I think you want to do is place your variants in an array. http://www.w3schools.com/js/js_obj_array.asp Then generate your selects from the array as a function.

The way I handle multiple variants of on data type such as size where you could have (mens small, mens medium, mens large, women's small...., dress size 10, dress size 12, shoe size 7, shoe size 8, hat size 10..) is to have a separate table of size types (mens shirts, women's dresses, mens shoes etc) each with an id.   Then a size table with (id, typeid, size).  Now there are a lot of options from here but you could either store the size type id with the product, or have another table that matches product id's with size type id's.

Then in your js, you have a giant array of all sizes that includes the (id, sizetypeid, size).  In your form, you would then generate your <select></select> pulling only the sizetypeid associated with that product.

Personally, I would still generate the arrays server side. What happens if something changes?  Using the array/function, they only have to be written once.  You could also simply generate an outside xml or json page of meta data that either gets created on the fly or each time  you update your color type or size type.  Then use the xml or json to populate your select.
0
 
LVL 60

Accepted Solution

by:
Julian Hansen earned 2000 total points
ID: 38394518
With the OnLoad solution - I would not worry about the fact that all boxes are populated - it is client side memory after page download so yes the page will be big but not excessively so and you will have saved on the download speed.

The mouseover one is easily fixed - change the binding to live like so
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var lastval = 0;
$(function() {
  $('select.empty').live('mouseover', function() {
   // you can combine some of the following into a single line - for clarity I have not done so
    var val = $(this).val();
    $(this).html($('#master').html());
    $(this).val(val);
    $(this).removeClass('empty');
  });
});
</script>
<style type="text/css">
</style>
</head>
<body>
<a>Test</a>
<select name="master" id="master" style="display: none">
  <option value="0">--empty--</option>
  <option value="1">Text1</option>
  <option value="2">Text2</option>
  <option value="3">Text3</option>
  <option value="4">Text4</option>
  <option value="5">Text5</option>
  <option value="6">Text6</option>
</select>
<select class="empty" name="field1">
  <option value="0">--empty--</option>
  <option value="5" selected="selected">Text5</option>
</select>
<select class="empty" name="field2">
  <option value="0">--empty--</option>
  <option value="6" selected="selected">Text6</option>
</select>
<select class="empty" name="field3">
  <option value="0">--empty--</option>
  <option value="3" selected="selected">Text3</option>
</select>

</body>
</html>

Open in new window

0
 

Author Comment

by:Alfahane
ID: 38396234
julianH - Thank you! This works perfectly. And on FF, IE, Chrome and Opera. Many thanks!


Regarding onload. The scrolling of the page is noticably slower when the HTML gets big. Even on fast computers. I'm not sure what reason. I just thought that minimizing the document, even when content is created by javascript, is good. Maybe I'm wrong. Maybe it's more about the amount of selects rather than total amount of options. Also, I've noticed that Norton Internet Security (used across the organization) dont like huge forms. It seams to validate them and in the process temporarily lock the browser.
0
 

Author Closing Comment

by:Alfahane
ID: 38396239
Low weight solution. Excellent!
0
 
LVL 60

Expert Comment

by:Julian Hansen
ID: 38396267
You are welcome - thanks for the points
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When it comes to write a Context Sensitive Help (an online help that is obtained from a specific point in state of software to provide help with that state) ,  first we need to make the file that contains all topics, which are given exclusive IDs. …
Finding original email is quite difficult due to their duplicates. From this article, you will come to know why multiple duplicates of same emails appear and how to delete duplicate emails from Outlook securely and instantly while vital emails remai…
In this tutorial viewers will learn how to embed videos in a webpage using HTML5. Ensure your DOCTYPE declaration is set to HTML5: "<!DOCTYPE html>": Use the <video> tag to insert a video. Define the src as the URL of your video; this is similar to …
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

839 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