Reputation: 13486
I have these two JSON maps:
{
"1000006": "Alternate Business Phone",
"1000008": "Alternate Home Phone",
"1000001": "Business Phone",
"1000003": "Clinic Phone",
"3": "Facsimile",
"1000007": "Home Phone",
"1000004": "Lab Phone",
"4": "Pager",
"1000002": "Secure Msg Phone"
}
and
{
"6": "Business Email",
"1000005": "Deliver To Email",
"7": "Personal Email"
}
Which are key-value maps alphabetized by value. I am using these two to change the contents of a drop-down menu based on another drop-down's selected item. Pics to illustrate:
Phone selected:
Email selected:
But, as you can see in the image, the order of the list items is not being preserved.
My Javascript handling the list items is this:
var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
function changePhoneEmailItems()
{
var selectedItem = document.getElementById("addNewCategory").value;
var options;
if('1' === selectedItem) {
options = options_1;
} else {
options = options_2;
}
var list = document.getElementById("addNewUsageType");
list.options.length=0;
for(var i in options) {
list.add(new Option(options[i], i));
}
}
According to this StackOverflow answer, I need to change the data structure I'm using because JSON is, by definition, unordered.
I tried changing the JSON to a new Map
:
var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
var options_1_map = new Map(options_1);
console.log(options_1_map);
But it threw an error:
TypeError: options_1 is not iterable
How do I change the JSON object to preserve the original order?
NOTE: My JSON is coming from a Spring controller which is "wrapping" the map in JSON to send to the view. But I am able to modify the controller if there is a more sensible way to transfer the map from the controller to the view.
EDIT: For good measure, the controller code that is generating the JSON is:
for(int i = 1; i <= 2; i++) {
JsonObject json = new JsonObject();
HashMap<String, String> CDCONTMETHTP = (HashMap<String, String>)model.get("CDCONTMETHTP_" + i);
for(Entry<String, String> option : CDCONTMETHTP.entrySet()) {
json.addProperty(option.getKey(), option.getValue());
}
model.put("options_" + i, json);
}
Which I am able to modify if need be.
Upvotes: 3
Views: 1513
Reputation: 13486
David's answer worked, but not without modifying the for loop that iterated through the elements. I have posted the full solution here:
var options_1 = {"1000006":"Alternate Business Phone","1000008":"Alternate Home Phone","1000001":"Business Phone","1000003":"Clinic Phone","3":"Facsimile","1000007":"Home Phone","1000004":"Lab Phone","4":"Pager","1000002":"Secure Msg Phone"};
var options_2 = {"6":"Business Email","1000005":"Deliver To Email","7":"Personal Email"};
function changePhoneEmailItems()
{
var selectedItem = document.getElementById("addNewCategory").value;
var options;
if('1' === selectedItem) {
options = options_1;
} else {
options = options_2;
}
var list = document.getElementById("addNewUsageType");
list.options.length=0;
Object.keys(options).forEach(function(i) {
list.add(new Option(options[i].value, options[i].key))
});
}
Upvotes: 0
Reputation: 4147
Your JSON maps are key-value pairs and there is no way to preserve the ordering of keys. You can convert your JSON maps to Array
s, which will preserve the order.
Instead of this JSON:
{
"6": "Business Email",
"1000005": "Deliver To Email",
"7": "Personal Email"
}
Send this JSON:
[
{"id": 6, "text": "Business Email"},
{"id": 1000005, "text": "Deliver To Email"},
{"id": 7, "text": "Personal Email"}
]
Upvotes: 7