Yii-AjaxDropDown

Yii dropdown widget with AJAX data

  • 所有者: bizley/Yii-AjaxDropDown
  • 平台:
  • 许可证: GNU General Public License v2.0
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

Yii-AjaxDropDown

Yii 1.1 dropdown widget with AJAX data

AjaxDropDown allows to use dropdown menu to select one or more values in your form. Dropdown data is sent using the AJAX post method.

This widget is designed to be used with Bootstrap CSS although the option to switch it off is given ('bootstrap' => false). In case you don't want to use Bootstrap make sure to set the proper event for the AJAX data collecting ('triggerEvent').

The widget was not tested with Yiistrap, YiiBooster or any other Yii Bootstrap 3rd party library.

How it works

The widget collects AJAX data and displays it as the list where every element can be clicked to select that value for the model attribute. The number of results per page is controlled by the source controller action. After first page the widget collects new page data only when the 'next' button is clicked and that target page has not been collected already. In any other case the data is present all the time and browsing through the already loaded pages takes no server time. The idea behind the input text field next to the dropdown button is to give the option to filter the source data before displaying it in the widget but there are no requirements for this so feel free to add any logic here you like.

Screenshots

All the examples here are using Bootstrap 3.3.1.
Default view:

Dropdown list visible: (option 'dropup' is available as well)

Extra button:

Records selected:

How to install

Copy the AjaxDropDown folder to your /protected/extensions Yii folder. Then add the following inside your form view:

<?php $this->widget('ext.AjaxDropDown.AjaxDropDown', array(
  'model' => $model,
  'attribute' => 'attribute',
  'source' => $this->createUrl('controller/action'),
)); ?>

Where $model is your CModel object, 'attribute' is object's attribute and data source URL is 'controller/action'.
This is just a basic widget configuration. You can find all the options described in the AjaxDropDown.php.

Full widget structure with possible options

<div id="[WIDGET_ID]" class="ajaxDropDownWidget {mainClass}" {style="{mainStyle}"}>
    <div class="ajaxDropDown {groupClass}" {style="{groupStyle}"}>
        <input type="text" name="ajaxDropDownInput" value="" class="{inputClass}" {style="{inputStyle}"}>
        <input type="hidden" value="[SELECTED_ID]" name="[ATTRIBUTE_NAME]" class="singleResult">
        <div class="{buttonsClass}" {style="{buttonsStyle}"}>
            {<button type="button" {extraButtonHtmlOptions}>{extraButtonLabel}</button>}
            <button data-page="[DATA_PAGE]" data-toggle="dropdown" type="button" class="ajaxDropDownToggle {buttonClass}" {style="{buttonStyle}"}>
                {buttonLabel}
            </button>
            <button type="button" class="ajaxDropDownSingleRemove {removeSingleClass}" {style="{removeSingleStyle}"}>
                {removeSingleLabel}
            </button>
            <ul role="menu" class="ajaxDropDownMenu {resultsClass}" {style="{resultsStyle}"}>
                <li class="dropdown-header {headerClass}" {style="{headerStyle}"}>
                    {pagerBegin}
                        <span class="ajaxDropDownPageNumber">[CURRENT_PAGE_NUMBER]</span>/<span class="ajaxDropDownTotalPages">[TOTAL_PAGES_NUMBER]</span>
                    {pagerEnd}{local.allRecords, local.recordsContaining}
                </li>
                <li class="divider"></li>
                <li class="ajaxDropDownLoading {loadingClass}" {style="{loadingStyle}"}>{progressBar}</li>
                <li class="dropdown-header {errorClass}" {style="{errorStyle}"}>{local.error}</li>
                <li class="dropdown-header {noRecordsClass}" {style="{noRecordsStyle}"}>{local.noRecords}</li>
                <li class="ajaxDropDownPages ajaxDropDownPage[PAGE_NUMBER] ajaxDropDownRecord[RECORD_ID] {recordClass}" {style="{recordStyle}"}>
                    <a data-id="[RECORD_ID]" class="ajaxDropDownResult" href="#">{markBegin}[RECORD_VALUE]{markEnd}</a>
                </li>
                <li class="divider ajaxDropDownInfo"></li>
                <li class="ajaxDropDownInfo {switchClass}" {style="{switchStyle}"}>
                    <a class="ajaxDropDownPrev {previousClass}" {style="{previousStyle}"} href="#">
                        {previousBegin}{local.previous}{previousEnd}
                    </a>
                    <a class="ajaxDropDownNext {nextClass}" {style="{nextStyle}"} href="#">
                        {nextBegin}{local.next}{nextEnd}
                    </a>
                </li>
            </ul>
        </div>
    </div>
    <ul class="ajaxDropDownResults {selectedClass}" {style="{selectedStyle}"}>
        <li class="ajaxDropDownSelected[SELECTED_ID] {resultClass}" {style="{resultStyle}"}>
            <a class="ajaxDropDownRemove {removeClass}" {style="{removeStyle}"} href="#" data-id="[SELECTED_ID]">
                {removeLabel}
            </a>{additionalCode}{markBegin}[SELECTED_VALUE]{markEnd}<input type="hidden" value="[SELECTED_ID]" name="[ATTRIBUTE_NAME]">
        </li>
    </ul>
</div>

Names in curly brackets are options and can be set as widget parameters. Names in square brackets are automatically set widget data.

AJAX data source

Below is the structure required by this widget:

array(
    'data' => array(
        array(
            'id' => RECORD_ID,
            'mark' => RECORD_EMPHASIS,
            'value' => RECORD_VALUE
        ),
        ...
    ),
    'page' => CURRENT_PAGE_NUMBER,
    'total' => TOTAL_PAGES_NUMBER
)

Where:
RECORD_ID is the record identificator,
RECORD_EMPHASIS is the 0, 1 flag wheter this record value should be surrounded with {markBegin} and {markEnd},
RECORD_VALUE is the record actual value,
CURRENT_PAGE_NUMBER is the actual page number (starting from 1),
TOTAL_PAGES_NUMBER is the number of all available pages.

This should be JSON encoded. You can find the example in the example_data_source.php.

Preselected and post-validate data with PHP

In case you want to display some records as already selected or simply just want to keep the selected data after validation you need to prepare the 'data' parameter which is the array almost identical to the source one.

array(
    array(
        'id' => RECORD_ID,
        'mark' => RECORD_EMPHASIS,
        'value' => RECORD_VALUE
    ),
    ...
)

This time the array shouldn't be encoded. Keep this structure even in case of single result.

You can find the form controller example in example_controller.php.

Preselected and post-validate data with JavaScript

You can manipulate selected results by triggering the following events on AjaxDropDown object:

add
Add one or more results. In case the 'singleMode' is true only the last added result will be displayed.

jQuery({id or class of AjaxDropDown field}).trigger('add', [result1, result2, ...]);

With every result data being object with id, value, mark and additional properties (only id is required):

{id:1, value:"xxx", mark:0, additional:"xxx"}

removeOne
Remove one or more results.

jQuery({id or class of AjaxDropDown field}).trigger('removeOne', [id1, id2, ...]);

removeAll
Remove all results.

jQuery({id or class of AjaxDropDown field}).trigger('removeAll');

By default events (except 'removeAll') are calling callback methods onRemove and onSelect. You can change it by setting 'jsEventsCallback' to false.

Available extra options

Drop up
Set 'dropup' => true to trigger dropdown menu above to button.

Additional button
Set 'extraButtonLabel' and/or 'extraButtonOptions' to add extra button between input text field and dropdown trigger button.

Additional code
Set 'additionalCode' if you want to add an extra code between link removing the selected result and selected result label. You can use {ID} and {VALUE} tags to get these automatically replaced with selected data. You can replace this general option for only one row by setting 'additional' array element in 'data' parameter.

Single mode
Set 'singleMode' to true if you want only one result to be selectable at once. This option renders selected result inside the filter field - if you want it to be displayed underneath the field set 'singleModeBottom' to true.

Callbacks
Pass any JavaScript function as a string to 'onSelect' and 'onRemove' parameters to call them when selecting or removing the results from the list. In first case available variables are id (ID of the result), label (its label) and selection (list of all selected results). In second case only id and selection are available.

主要指标

概览
名称与所有者bizley/Yii-AjaxDropDown
主编程语言PHP
编程语言PHP (语言数: 2)
平台
许可证GNU General Public License v2.0
所有者活动
创建于2015-01-17 11:44:00
推送于2016-02-29 18:36:49
最后一次提交2016-02-29 19:34:52
发布数8
最新版本名称1.3.2 (发布于 )
第一版名称v1.1.1 (发布于 )
用户参与
星数3
关注者数1
派生数1
提交数40
已启用问题?
问题数1
打开的问题数0
拉请求数0
打开的拉请求数0
关闭的拉请求数0
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?