Поиск на панели инструментов jqGrid с автозаполнением по данным json - PullRequest
2 голосов
/ 18 мая 2011

Я нашел очень хорошую демонстрацию Олега (http://www.ok -soft-gmbh.com / jqGrid / FillToolbarSearchFilter.htm), которая показывает «поиск на панели инструментов jqGrid с автозаполнением с использованием локальных данных», но у меня не получается заставить его работатьJSON через AJAX.Есть ли веская причина, по которой функция автозаполнения не будет работать, даже если я заставлю сетку быть локальной после загрузки?

$(document).ready(function() {

    var mygrid = $("#mylist"),
    mygetUniqueNames = function(columnName) {
        var texts = mygrid.jqGrid('getCol',columnName), uniqueTexts = [],
            textsLength = texts.length, text, textsMap = {}, i;
        for (i=0;i<textsLength;i++) {
            text = texts[i];
            if (text !== undefined && textsMap[text] === undefined) {
                // to test whether the texts is unique we place it in the map.
                textsMap[text] = true;
                uniqueTexts.push(text);
            }
        }
        return uniqueTexts;
    };





    mygrid.jqGrid({
            url:'autocompleteTest.php',
            datatype: "json",
            colNames:['name', 'City','stateCd'],
            colModel:[                      
                    {name:'name',index:'name',width:225, search: true},
                    {name:'City',index:'City',width:125},
                    {name:'stateCd',index:'stateCd',width:75},
                  ],

         rowNum: 100,
        loadonce : true,
         sortname: 'name',
        sortorder: 'desc',
         sortable: true,
        viewrecords: true,
        rownumbers: true,
        sortorder: "desc",
        ignoreCase: true,
        pager: '#mypager',
        height: "auto",
        caption: "How to use filterToolbar better with data from server"
    }).jqGrid('navGrid','#mypager',
              {edit:false, add:false, del:false, search:false, refresh:false});

    mygrid.jqGrid('setColProp', 'name',
            {
                searchoptions: {
                    sopt:['bw'],
                    dataInit: function(elem) {
                        $(elem).autocomplete({
                            source:mygetUniqueNames('name'),
                            delay:0,
                            minLength:0
                        });
                    }
                }
            });

    mygrid.jqGrid('filterToolbar',
            {stringResult:true, searchOnEnter:true, defaultSearch:"bw"});

    });

1 Ответ

3 голосов
/ 21 мая 2011

Сложно привести пример в случае использования удаленного source параметра jQuery UI Autocomplete. Основная проблема в том, что ваш вопрос касается jqGrid, который является чистым JavaScript решением. Если бы мы обсуждали серверную часть решения, у нас было бы слишком много вариантов. Многие пользователи используют разные языки: Java, C #, VB, PHP и так далее. Например, я лично предпочитаю C #. Затем нам нужно будет выбрать технологию, которую мы используем: ASP.NET MVC, WCF, веб-сервис ASPX и так далее. Например, я бы выбрал WCF. Затем мы должны определить технологию доступа к базе данных, например, Entity Framework, LINQ to SQL, SqlDataReader, SqlDataAdapter и так далее. Позвольте мне выбрать Entity Framework и предоставить вам соответствующий пример кода, но он вам не очень поможет, если вы используете, например, PHP и MySQL.

Поэтому я просто опишу, какой интерфейс должен иметь сервер для удаленного source параметра jQuery UI Autocomplete без кода .

В моем примере вы должны заменить параметр source на URL вашего сервера следующим образом:

dataInit: function(elem) {
    $(elem).autocomplete({
        source:'yourSearchUrl.php',
        minLength:2
    });
}

Если пользователь вводит два символа (значение может быть изменено с помощью опции minLength), например, 'ab', автозаполнение выполнит HTTP-запрос GET с параметром term=ab:

yourSearchUrl.php?term=ab

ваш сервер должен ответить данными JSON в том же формате, что и для локального источника. Я использовал формат строкового массива в моем предыдущем примере. Другой поддерживаемый формат - массив объектов с меткой / значением / обоими свойствами, такими как

[
    {
        "id": "Dromas ardeola",
        "label": "Crab-Plover",
        "value": "Crab-Plover"
    },
    {
        "id": "Larus sabini",
        "label": "Sabine`s Gull",
        "value": "Sabine`s Gull"
    },
    {
        "id": "Vanellus gregarius",
        "label": "Sociable Lapwing",
        "value": "Sociable Lapwing"
    },
    {
        "id": "Oenanthe isabellina",
        "label": "Isabelline Wheatear",
        "value": "Isabelline Wheatear"
    }
]

прочитайте документацию для получения дополнительной информации.

Если вам нужно реализовать более сложный сценарий и отправить некоторые дополнительные данные на сервер или преобразовать ответ сервера любым способом, вы можете использовать пользовательскую функцию обратного вызова источника. В этом случае вы должны использовать source: function(request, response) {/*your implementation*/}, где request будет объектом, обладающим свойством term (request.term). Внутри вашей реализации вы должны сделать ajax-запрос к серверу вручную. response будет функцией обратного вызова, которую вы должны вызывать после того, как ваш пользовательский запрос ajax будет завершен (внутри обработчика событий success). Функция response должна вызываться с параметром, который должен быть массивом в том же формате, который возвращает mygetUniqueNames. Я рекомендую вам изучить исходный код jQuery Autocomplete demo .

Чтобы предоставить уникальные данные из одного столбца таблицы, вы должны просто использовать SELECT DISTINCT оператор SQL, который поддерживается в большинстве баз данных.

Я надеюсь, что мое описание поможет вам.

ОБНОВЛЕНО : Если у вас есть локальный источник, решение вы можете найти в моем старом ответе , который вы уже используете. Вам просто нужно вызвать filterToolbar после заполнения исходного массива . Поскольку вы загружаете данные с сервера, вам следует переместить вызов filterToolbar внутри loadComplete . Вы используете опцию loadonce:true jqGrid, которая переключает datatype с 'json' на 'local' после первой загрузки данных. Таким образом, вы можете включить в обработчик событий loadComplete вашей сетки код, подобный следующему:

var grid = $('#list');
grid({
    url:'autocompleteTest.php',
    datatype: 'json',
    loadonce: true,
    // ... other parameters
    loadComplete: function(data) {
        if (grid.getGridParam('datatype') === 'json') {
            // build the set 'source' parameter of the autocomplete
            grid.jqGrid('setColProp', 'name', {
                searchoptions: {
                    sopt:['bw'],
                    dataInit: function(elem) {
                        $(elem).autocomplete({
                            source:mygetUniqueNames('name'),
                            delay:0,
                            minLength:0
                        });
                    }
                }
            });
            mygrid.jqGrid('filterToolbar',
                          {stringResult:true,searchOnEnter:true,
                           defaultSearch:"bw"});
        }
    }
});

Если вам потребуется перезагрузить данные с сервера (измените datatype на 'json' и позвоните grid.trigger('reloadGrid')), вам придется изменить приведенный выше код, чтобы сначала уничтожить виджет autocomplete с помощью $('#gs_name').autocomplete('destroy'), а затем создайте его еще раз с тем же кодом, что и внутри dataInit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...