Многоуровневое аккордеонное действие jQuery в форме выбора списка - PullRequest
2 голосов
/ 02 января 2011

У меня есть виджет шаблона HTML и класс Python, когда он вызывается, в основном создает список «выбор» на основе значения, которое было выбрано. Поэтому, когда виджет загружается в первый раз, stl_template выглядит так:

<select name="country"> 
 <option name="uk">United Kingdom</option>
 <option name="fr">France</option>
 ... 
</select>

тогда, если пользователь выберет Великобритания, при следующей отправке виджет будет перезагружен, а выбранное имя будет изменено на 'регион':

<select name="region"> 
 <option name="uk#south-east">South East</option>
 <option name="uk#south-west">South West</option>
 ... 
</select>

и снова пользователь, например, выбирает «Юго-Восток» и отправляет форму, затем загружает все графства.

<select name="county"> 
 <option name="uk#south-east#surrey">Surrey</option>
 <option name="uk#south-east#west-sussex">West Sussex</option>
 ... 
</select>

Вот код Python, который делает это возможным, я использую библиотеку itools [http://git.hforge.org]:

class RegionSelect(Widget):

"""
We return Country/Region/County list for non javascript enabled browsers
"""

template = make_stl_template("""
<dd>
    <select id="${county}" name="${county}">
        <option stl:repeat="option options" value="${option/name}"
                selected="${option/name}">
        ${option/value}
        </option>
    </select>
</dd>
""")

@classmethod
def options(cls):
    context = get_context()
    country = context.get_form_value('country') or get_host_prefix(context) # returns a string like 'uk'
    region = context.get_form_value('region') # returns a string like 'uk#south-east'

    iana_root_zone = country or region
    if iana_root_zone:
        if region:
            # get the country_code
            iana_root_zone, region = region.rsplit('#', 1)
            options = getCounties().get_options(iana_root_zone, region)
            has_empty_value = 'Select your county'
        else:
            options = getRegions().get_options(iana_root_zone)
            # {'name': 'uk#south-east', 'value': u'South East', 'name': 'uk#south-west', 'value': u'South West'}
            has_empty_value = 'Select your region'
    else:
        options = getCountries().get_options()
        # {'name': 'uk', 'value': u'United Kingdom', 'name': 'fr', 'value': u'France'}
        has_empty_value = 'Select your country/region/county'

    if cls.has_empty_option:
        options.insert(0,
            {'name': '', 'value': has_empty_value, 'selected': True})
    return options

@classmethod
def county(self):
    context = get_context()
    host_prefix = get_host_prefix(context)
    country = context.get_form_value('country')
    region = context.get_form_value('region')
    county = context.get_form_value('county')
    if host_prefix and region or country and region or region:
        return 'county'
    elif host_prefix or country or host_prefix and country:
        return 'region'
    else:
        return 'country'

Это прекрасно работает, но я хотел бы написать javascript об этой функции и иметь некоторые идеи о том, как сделать это только с одним списком выбора, а не иметь несколько для каждой страны, региона, округа? 1014 *

Я думал расширить файл класса stl_template, чтобы включить onchange, чтобы:

template = make_stl_template("""
<dd>
    <select id="${county}" name="${county}">
        <option stl:repeat="option options" value="${option/name}"
                selected="${option/name}
                onchange="javascript: get_regions('/;get_counties_str?${county}='+ this.value, '${county}')"">
        ${option/value}
        </option>
    </select>
</dd>
""")

в идеале было бы иметь один список выбора, затем, когда пользователь выбирает «страну», я получаю аккордеонное действие, которое загружает все «регионы», а затем, когда пользователь выбирает регион, все «графства» 'перечислены.

что-то вроде вложенного списка аккордеонов, но в форме выбора.

любой совет высоко ценится.

1 Ответ

0 голосов
/ 13 июня 2011

Я не думаю, что вы можете вкладывать теги select.Единственный допустимый дочерний элемент тега select - это тег option.

Вы можете подделать его так, чтобы он выглядел как вложенный (имея 3 выбора и используя JS и несколько прикольных стилей).Это было бы довольно неудобно и немного хакерски.

В качестве альтернативы, вы не могли бы использовать select (вместо использования тегов ul) и JavaScript для сбора ввода (путем привязки к событию click тегов li).Это не очень хорошо, так как семантически, это должно быть сделано с тегами выбора.

Лично у меня было бы три тега выбора.Прежде всего, покажите тот, в котором есть страны.Когда пользователь выбирает страну, динамически генерируйте еще один выбор с соответствующими регионами в нем и отображайте.Когда пользователь выбирает регион, динамически генерирует другой выбор с соответствующими округами в нем и показывает.

Если вы действительно хотите, чтобы он был вложенным и согласованным, я бы не использовал select (вместо этого используя теги ul или, возможно, divs)).

...