Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] InputOptions for Select and Radio have an implicitly defined object sort #812

Closed
nickraphael opened this issue Jan 11, 2018 · 10 comments
Assignees
Labels
type: bug If the bug is not reproducible, ask for clarifications, and close after a week if no news are given type: feature

Comments

@nickraphael
Copy link

So I have a list of things coming back from a database. Lets say they have an id and a name. The id is from the database.
{ id: 4, name: "nick" }
{ id: 10, name: "dave" }
{ id: 2, name: "zac" }

I'm setting the inputOptions parameter but it seems to only accept a string array. I use the id as the index and the value is the name. But now the select will order my list by the database id. Is there a way to separate the id from the ordering? The ideal would be setting inputOptions to an array of objcts with an id and value. It could then order by the array and retain the id for the select value.

Hope that made sense?

@acupofjose
Copy link

"If input parameter is set to 'select' or 'radio', you can provide options. Object keys will represent options values, object values will represent options text values."

So do something like this:

inputOptions: {
  4: "nick",
  10: "dave",
  2: "zac"
}

(See https://jsfiddle.net/ad3quksn/320/)

@nickraphael
Copy link
Author

You fiddler orders the select as Zac, Nick Dave. I assume because thats the number order (2,4,10). But I want it in the order I created the inputOptions (nick, dave, zac).

@acupofjose acupofjose reopened this Jan 11, 2018
@acupofjose
Copy link

acupofjose commented Jan 11, 2018

@nickraphael I apologize, misunderstood the issue. As I explore it more, it looks like this will actually need a PR to fix. Thanks for the report!

It looks like the JS engine will automatically sort object keys. Example

Code in source sweetalert2.js#L1121-L1133

My suggestion would be to have a specific object structure and to accept an array of object instead:

inputOptions: [
  {id: 4, value: 'option1'},
  {id: 6, value: 'option2'},
  {id: 5, value: 'option3'}
]

Changing name of issue for clarity.

@acupofjose acupofjose changed the title How can I set the id of select options? [Bug] InputOptions for Select and Radio have an implicitly defined object sort Jan 11, 2018
@acupofjose acupofjose added type: bug If the bug is not reproducible, ask for clarifications, and close after a week if no news are given type: feature labels Jan 11, 2018
@limonte
Copy link
Member

limonte commented Jan 11, 2018

Let's not fix the issue of JS engine in this tiny UI plugin :)

My suggestion is to add some spaces to inputOptions keys before passing it to swal(): https://jsfiddle.net/ad3quksn/324/

SweetAlert2 will autotrim the result value for you, so you will get the expected value and select will keep the order of items.

@zenflow
Copy link
Member

zenflow commented Jan 11, 2018

From Node.js REPL:

> {3: 3, 2: 2, 1: 1}
{ '1': 1, '2': 2, '3': 3 }

Interesting JS quirk I did not know about!

@limonte We can't fix this issue with JS, but we could work around it by accepting alternate formats: array of objects ({ id, text }) or array of strings (for when the id and the text are the same).

The other advantage of this is that arrays are easier to manipulate than objects.

This shouldn't be hard to accomplish, or add much complexity. I can submit a PR if this sounds acceptable @limonte. (I know I have a lot of pending PRs, but they're coming!)

@limonte
Copy link
Member

limonte commented Jan 12, 2018

This shouldn't be hard to accomplish, or add much complexity. I can submit a PR if this sounds acceptable @limonte.

I think you underestimating the complexity of this change. How to match which key will represent the key, which will represent the value? What will happen with key duplicates? What if some key isn't present - null or undefined?

This is out of scope of SweetAlert2. I hope our users are able to write a one-liner to provide the data in the expected format, e.g. the array from this issue can be easily converted to object:

https://jsfiddle.net/ad3quksn/325/

@limonte limonte closed this as completed Jan 12, 2018
@toverux
Copy link
Member

toverux commented Jan 12, 2018

I quite agree.
(By the way, the keys order in the objects is in fact unspecified and are left to the implementation).

However... we could eventually support Map which is an adapted data structure for that type of use cases.

inputOptions: new Map([
    [1 , "Linus Torvalds"],
    [2, "Richard Stallman"]
]),

Map is an iterable, is standard, preserves insertion order, and is already documented. It also probably requires less lines of code for us (than a custom array+objects structure) and has a compact declaration syntax.

@limonte
Copy link
Member

limonte commented Jan 12, 2018

However... we could eventually support Map which is an adapted data structure for that type of use cases.

Maps are cool because they will take care of key dups out of the box:

Maps are supported by IE11 and easy to add, I'll do that!

@limonte limonte reopened this Jan 12, 2018
@zenflow
Copy link
Member

zenflow commented Jan 13, 2018

What will happen with key duplicates? What if some key isn't present - null or undefined?

I would have said "It shouldn't really matter, whether the duplicates are removed or an error is thrown, or neither. Garbage in, garbage out." I didn't understand the first (not quoted) question/concern.

But I agree using Map is much better.

@limonte
Copy link
Member

limonte commented Jan 28, 2018

@nickraphael Maps support has been added 🎉

Here's the jsfiddle with your data: https://jsfiddle.net/ad3quksn/348/

const items = [ 
  { id: 4, name: "nick" },
  { id: 10, name: "dave" },
  { id: 2, name: "zac" },
]

const inputOptions = new Map
items.forEach(item => inputOptions.set(item.id, item.name))

swal({
  input: 'select',
  inputOptions,
  inputValue: 10
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug If the bug is not reproducible, ask for clarifications, and close after a week if no news are given type: feature
Projects
None yet
Development

No branches or pull requests

5 participants