Tło
Odebrałem trochę niekompletnej pracy od innego programisty, która obejmuje wyświetlanie wyników wyszukiwania. Jego podejście polegało na renderowaniu wyników w tabeli HTML za pomocą wbudowanego JavaScript i jQuery w następujący sposób.
Próbuję dokończyć pracę, ale wolałbym pisać mniej kodu i używać jqGrid, ponieważ zawiera funkcje sortowania i uporządkowania kodu. Uzyskanie wyników przez jqGrid jest łatwe, ale umieszczenie przycisków opcji w pustej kolumnie jest trudniejsze niż się spodziewałem.
Wersja jqGrid w aplikacji to 3.7.2. Siatka musi mieć przyciski opcji po lewej stronie, aby wybór był zgodny z resztą aplikacji.
Gdzie utknąłem
Wydaje się, że nie ma sposobu na posiadanie niezwiązanej kolumny w jqGrid. Oznacza to, że każda kolumna wydaje się potrzebować pola w danych źródłowych. Jeśli nie masz fikcyjnego pola, dane wierszy i nagłówki kolumn staną się niewyrównane.
Natknąłem się na przykład (patrz Edycja wierszy -> Edycja niestandardowa), który zwraca JSON z fikcyjnym polem w danych, a następnie modyfikuje dane siatki, aby wstawić przyciski.
Wolę nie umieszczać tam fikcyjnych danych, ponieważ czuje to brudne :) Chciałbym, aby mój JSON zawierał tylko dane potrzebne do reprezentowania wyników wyszukiwania. Pomyślałem więc, że lepiej byłoby zamiast tego dodać atrapę pola w kodzie skryptu, aby zachować czystość kodu po stronie serwera.
Próbuję zmodyfikować dane zwrócone z wywołania AJAX przed renderowaniem przez jqGrid. Próbowałem podłączyć się do zdarzenia loadComplete
, ale kiedy modyfikuję dane, wydaje się, że jest to już renderowane.
Próbowałem również podłączyć się do zdarzenia success
w polu ajaxGridOptions
options
, ale wydaje się, że całkowicie zastępuje to zdarzenie, a jqGrid nie renderuje danych.
Jak mogę zmodyfikować dane zwrócone z wywołania usługi sieciowej przed ich wyrenderowaniem przez jqGrid?
3 odpowiedzi
Rozwiązanie w mojej poprzedniej odpowiedzi zepsuło sortowanie, więc wymyśliłem inne rozwiązanie.
Ponieważ jqGrid nie zapewnia podpięć do wygodnej modyfikacji danych, konieczne było cofnięcie poziomu i podpięcie do jQuery. Zamieniłem metodę $.ajax()
na własną. Najpierw sprawdza, czy operacja jest inicjowana przez jqGrid, a jeśli tak, dopełnia dane, wywołuje oryginalny program obsługi jqGrid success
, a następnie dodaje przyciski opcji do siatki. Sortowanie nadal działa, typ danych to nadal json i nie ma ręcznych wywołań addJSONData
i nadal jestem w stanie osiągnąć to, czego potrzebowałem z poprzedniego rozwiązania. Zasadniczo, zrobienie tego małego hacka jQuery pozwala mi obejść się bez robienia jakichkolwiek hacków jqGrid, które są znacznie bardziej kłopotliwe.
// Set up $.ajax() hook for modifying the data before jqGrid receives it
if (!this._ajaxOverridden) {
var oldAjax = $.ajax;
$.ajax = function (options) {
// Check whether this call is from jqGrid to our web service
if (options.url == config.eventSearchUrl && options.success) {
// Wrap the success event handler with our own handler that pads the data and creates the radio buttons
var oldSuccess = options.success;
options.success = function () {
thisEventSearchDialog._padData(arguments[0]);
oldSuccess.apply(this, arguments);
thisEventSearchDialog._createRadioButtons();
}
}
oldAjax(options);
};
this._ajaxOverridden = true;
}
Udało mi się wymyślić, jak to zrobić. Zamiast pozwalać jqGrid automatycznie ładować dane, trzeba ręcznie wykonać żądanie, a następnie załadować je za pomocą wywołania addJSONData
.
Mój jqGrid jest zdefiniowany w znaczniku w następujący sposób:
<fieldset>
<div style="display:none" class="searchResults">
<table id="eventSearchDialog-results">
</table>
<div id="eventSearchDialog-pager">
</div>
</div>
</fieldset>
Inicjuję siatkę następującym kodem:
// Initialize the grid
this._searchResults = this._dialog.find("#eventSearchDialog-results");
this._searchResults.jqGrid(
{
datatype: "local",
colNames: ['', 'Event Name', 'Event Type', 'Start Date', 'End Date', 'Location', 'Event Country', 'Sports'],
colModel: [
{ name: 'selector', index: 'selector', width: 30 },
{ name: 'EventName', index: 'EventName', formatter: jqgridCellFormatter, width: 150 },
{ name: 'EventType', index: 'EventType', formatter: jqgridCellFormatter, width: 120 },
{ name: 'StartDate', index: 'StartDate', formatter: jqgridCellFormatter, width: 100 },
{ name: 'EndDate', index: 'EndDate', formatter: jqgridCellFormatter, width: 100 },
{ name: 'Location', index: 'Location', formatter: jqgridCellFormatter, width: 100 },
{ name: 'EventCountry', index: 'EventCountry', formatter: jqgridCellFormatter, width: 100 },
{ name: 'Sports', index: 'Sports', formatter: jqgridCellFormatter }
],
rowNum: 10,
rowList: [10, 20, 30],
pager: this._dialog.find("#eventSearchDialog-pager"),
pginput: true,
sortname: 'EventName',
viewrecords: true,
sortorder: "asc",
hidegrid: false,
height: "auto",
shrinkToFit: true,
width: 630,
jsonReader:
{
page: "pageIndex",
total: "pageCount",
records: "recordCount",
root: "rows",
repeatitems: true
},
prmNames:
{
page: "pageIndex",
rows: "pageSize",
sort: "sortField",
order: "sortOrder"
}
}
);
// Set the data type to JSON, we don't do this in the options because it will cause a request to occur,
// but we do need it to be set to JSON so that the calls to addJSONData work later.
this._searchResults.jqGrid("setGridParam", { datatype: "json" });
Ładuję siatkę danymi z wywołania jQuery $.ajax()
, a w obsłudze zdarzeń success
dopełniam dane, a następnie ładuję je do jqGrid za pomocą addJSONData
.
Mój JSON wygląda tak:
{
"pageCount":1,
"pageIndex":1,
"recordCount":2,
"rows":
[
{"id":3, "cell":["Stevens Event 2", "Commonwealth Games", "03/05/2011", "16/05/2011", "sersdfweqr", "New Zealand", ["Archery"]]},
{"id":4, "cell":["Test - multiple sports", "Other", "01/05/2011", "30/06/2011", "Kobe", "Japan", ["Judo", "Karate", "Motor Sport", "Motorcycling", "Taekwondo"]]}
]
}
To jest mój program obsługi success
:
success: function (data, textStatus, xhr) {
// Pad data for our radio button column that has no corresponding field in the data
for (var counter = 0; counter < data.rows.length; counter++) {
data.rows[counter].cell.splice(0, 0, null);
}
thisEventSearchDialog._searchResults[0].addJSONData(data);
thisEventSearchDialog._createRadioButtons();
},
JqGrid zawierający kolumnę przycisków radiowych, dla których potrzebne były dane fikcyjne. Bez danych fikcyjnych dane wiersza nie pasują do nagłówków.
jqgridCellFormatter
, co jest bardzo ważne w Twoim przypadku. Jeśli używasz właściwości repeatitems: true
jsonReader
, dane dla każdej kolumny powinny być ciągami, a nie tablicą. Jak chcesz wyświetlić kolumnę Sports
? Dlaczego nie używasz standardowego programu formatującego date
dla kolumn StartDate
i StartDate
? Uważam, że użycie datatype:'local'
i ręczne wywołanie addJSONData
jest bardzo złym obejściem. Są lepsze rozwiązania.
addJSONData
i datatype:'local'
?
To jest stare pytanie i może nie dotyczyć wspomnianej wersji jqGrid (3.7.2), ale wydaje się, że jest z tym związane: Jak "wstępnie przetworzyć" odpowiedź ajax przed wyświetleniem w jqGrid i jeśli mam rację (około są powiązane), to poprawną odpowiedzią jest parametr/funkcja dataFilter
parametru ajaxGridOption
. U mnie zadziałało.
Podobne pytania
Powiązane pytania
Nowe pytania
jquery
jQuery to biblioteka JavaScript, rozważ także dodanie tagu JavaScript. jQuery to popularna biblioteka JavaScript działająca w różnych przeglądarkach, która ułatwia przechodzenie przez Document Object Model (DOM), obsługę zdarzeń, animacje i interakcje AJAX, minimalizując rozbieżności między przeglądarkami. Pytanie oznaczone tagiem jQuery powinno być powiązane z jQuery, więc jQuery powinno być używane przez dany kod i przynajmniej elementy związane z użyciem jQuery muszą znajdować się w pytaniu.
jsonReader
lub użyj tylko niestandardowego programu formatującego, aby wyświetlić dane w inny sposób. Czy mógłbyś zawrzeć w swoim pytaniu kod JavaScript, który definiuje jqGrid oraz pełne dane JSON zwrócone z serwera? Czy mógłbyś dodatkowo dokładnie opisać, jakie modyfikacje chcesz wprowadzić? Na przykładzie można znaleźć lepsze rozwiązanie.while($row = mysql_fetch_array($result,MYSQL_ASSOC)) { $responce->rows[$i]['id']=$row[id]; $responce->rows[$i]['cell']=array("",$row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]); $i++; }
Zwróć uwagę na""
dodany jako pierwsze pole.