Question

I am writing a Backbone app in CoffeeScript. I am also using Select2 for dropdowns. Some dropdowns support users entering new dropdown options. I can do that generally. But...

My problem is that I want to dynamically apply select2 for user created options by looping through model fields in my Backbone view.

Perhaps the code can explain what I'm doing better. (I hope)

# this is taken from the render method of my view
#
# Apply select2 widget for fields accepting user-created options
field_options = null
for field in @model.fields
    if field.fieldType == 'hidden' and field.show and field.options?
        field_options = field.options
        @$('input[name=' + field.name + ']').select2
            width: 'resolve'
            data: field_options
            createSearchChoice: (term) ->
                id: String(field_options.length + 1)
                text: term

This code works if only one field is to accept user-created options. If there are two fields, then the field_options.length is always the same length (that of only one of the fields).

I know I have a scoping issue, but don't understand how to correct it.

Please help! I'm stuck

Was it helpful?

Solution

The problem with your scoping is that your select2 function is holding a reference to field_options variable, field_options is used inside the loop but when the loops end the select2 function still holds a reference to it, which actually mean it gets the value of the last assignment that field_options received. it is complicated, because this a javascript mistake.

The best thing you can do it just transform this to a function, functions, unlike {}, has their own scope.

I think that a much more cleaner approach is this:

setSelect2 = (field) ->
  @$('input[name=' + field.name + ']').select2
    width: 'resolve'
    data: field.options
    createSearchChoice: (term) ->
      id: String(field.options.length + 1)
      text: term 

setSelect2 field for field in @model.fields when field.fieldType == 'hidden' and field.show and field.options?

This way the function capture the field variable (because function has it's own scope) and it will not be changed in the next loop

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top