javascript - aftersaverow - jqgrid inline editing save row
jqgrid valores de opción desplegable de selección incorrecta en el cuadro de edición (2)
La respuesta a su pregunta depende un poco de la fuente donde recibe la información que se muestra en "Estado para EE. UU." Y "Estado para el Reino Unido". Hay dos posibilidades admitidas por jqGrid: 1) el uso del parámetro de value
de editoptions 2) el uso de los parámetros dataUrl
y buildSelect
de las funciones de edición . La primera forma es la mejor en caso de edición local o en el caso de que la lista de opciones posibles sea estática. La segunda opción se utilizará en el caso, que la información sobre los estados, países y estados de algún país se obtendrá por solicitud AJAX de la base de datos. Describo la solución en el ejemplo del uso del parámetro de value
para no tener dependencias con los componentes del servidor. La mayoría de las partes de la implementación son las mismas en el caso del uso de dataUrl
y buildSelect
.
Hice el ejemplo en vivo que demuestra lo que necesitas.
El principal problema es que el value
de las editoptions
de editoptions
se usa solo una vez en el momento de la inicialización. Dentro de la función dataInit uno puede sobreescribir el value
, pero después del cambio del valor en el primer cuadro de selección / desplegable con países, el segundo cuadro de selección / desplegable con estados debe reconstruirse manualmente. Para hacerlo, hay que entender que el elemento HTML seleccionado tiene ID construido desde la fila id ''_'' y el nombre de la columna: rowId + "_State". Además, es importante que el value
de las editoptions
de editoptions
se restablezca al valor inicial, de modo que cualquier identificación de estado se pueda decodificar con el nombre del estado.
Aquí está el código del ejemplo :
var countries = { ''1'': ''US'', ''2'': ''UK'' };
var states = { ''1'': ''Alabama'', ''2'': ''California'', ''3'': ''Florida'', ''4'': ''Hawaii'', ''5'': ''London'', ''6'': ''Oxford'' };
var statesOfCountry = {
1: { ''1'': ''Alabama'', ''2'': ''California'', ''3'': ''Florida'', ''4'': ''Hawaii'' },
2: { ''5'': ''London'', ''6'': ''Oxford'' }
};
var mydata = [
{ id: ''0'', Country: ''1'', State: ''1'', Name: "Louise Fletcher" },
{ id: ''1'', Country: ''1'', State: ''3'', Name: "Jim Morrison" },
{ id: ''2'', Country: ''2'', State: ''5'', Name: "Sherlock Holmes" },
{ id: ''3'', Country: ''2'', State: ''6'', Name: "Oscar Wilde" }
];
var lastSel = -1;
var grid = jQuery("#list");
var resetStatesValues = function () {
grid.setColProp(''State'', { editoptions: { value: states} });
};
grid.jqGrid({
data: mydata,
datatype: ''local'',
colModel: [
{ name: ''Name'', width: 200 },
{ name: ''Country'', width: 100, editable: true, formatter: ''select'',
edittype: ''select'', editoptions: {
value: countries,
dataInit: function (elem) {
var v = $(elem).val();
// to have short list of options which corresponds to the country
// from the row we have to change temporary the column property
grid.setColProp(''State'', { editoptions: { value: statesOfCountry[v]} });
},
dataEvents: [
{
type: ''change'',
fn: function(e) {
// To be able to save the results of the current selection
// the value of the column property must contain at least
// the current selected ''State''. So we have to reset
// the column property to the following
//grid.setColProp(''State'', { editoptions:{value: statesOfCountry[v]} });
//grid.setColProp(''State'', { editoptions: { value: states} });
resetStatesValues();
// build ''State'' options based on the selected ''Country'' value
var v = parseInt($(e.target).val(), 10);
var sc = statesOfCountry[v];
var newOptions = '''';
for (var stateId in sc) {
if (sc.hasOwnProperty(stateId)) {
newOptions += ''<option role="option" value="'' +
stateId + ''">'' +
states[stateId] + ''</option>'';
}
}
// populate the new
if ($(e.target).is(''.FormElement'')) {
// form editing
var form = $(e.target).closest(''form.FormGrid'');
$("select#State.FormElement", form[0]).html(newOptions);
} else {
// inline editing
var row = $(e.target).closest(''tr.jqgrow'');
var rowId = row.attr(''id'');
$("select#" + rowId + "_State", row[0]).html(newOptions);
}
}
}
]
}
},
{
name: ''State'', width: 100, editable: true, formatter: ''select'',
edittype: ''select'', editoptions: { value: states }
}
],
onSelectRow: function (id) {
if (id && id !== lastSel) {
if (lastSel != -1) {
resetStatesValues();
grid.restoreRow(lastSel);
}
lastSel = id;
}
},
ondblClickRow: function (id, ri, ci) {
if (id && id !== lastSel) {
grid.restoreRow(lastSel);
lastSel = id;
}
resetStatesValues();
grid.editRow(id, true, null, null, ''clientArray'', null,
function (rowid, response) { // aftersavefunc
grid.setColProp(''State'', { editoptions: { value: states} });
});
return;
},
editurl: ''clientArray'',
sortname: ''Name'',
height: ''100%'',
viewrecords: true,
rownumbers: true,
sortorder: "desc",
pager: ''#pager'',
caption: "Demonstrate dependend select/dropdown lists (edit on double-click)"
}).jqGrid(''navGrid'',''#pager'',
{ edit: true, add: true, del: false, search: false, refresh: false },
{ // edit options
recreateForm:true,
onClose:function() {
resetStatesValues();
}
},
{ // add options
recreateForm:true,
onClose:function() {
resetStatesValues();
}
});
ACTUALIZADO : actualicé el código anterior para que funcione en caso de edición de formulario también. Puedes verlo en vivo aquí . Debido a que jqGrid no es compatible con la edición local para la edición de formularios, no pude probar el código. Sin embargo, espero haber aprovechado al máximo los cambios requeridos.
ACTUALIZADO 2 : amplié el código anterior para apoyar
- Edición en línea, edición de formularios, barra de herramientas de búsqueda y búsqueda avanzada
- Los botones de navegación anterior o siguiente en el formulario de edición
- Mejora el soporte del teclado en selects (el problema con la actualización refrescante dependiente en algunos navegadores es fijo)
La nueva versión de la demo está aquí . El código modificado de la demostración que se encuentra a continuación:
var countries = { ''1'': ''US'', ''2'': ''UK'' },
//allCountries = {'''': ''All'', ''1'': ''US'', ''2'': ''UK''},
// we use string form of allCountries to have control on the order of items
allCountries = '':All;1:US;2:UK'',
states = { ''1'': ''Alabama'', ''2'': ''California'', ''3'': ''Florida'', ''4'': ''Hawaii'', ''5'': ''London'', ''6'': ''Oxford'' },
allStates = '':All;1:Alabama;2:California;3:Florida;4:Hawaii;5:London;6:Oxford'',
statesOfUS = { ''1'': ''Alabama'', ''2'': ''California'', ''3'': ''Florida'', ''4'': ''Hawaii'' },
statesOfUK = { ''5'': ''London'', ''6'': ''Oxford'' },
// the next maps contries by ids to states
statesOfCountry = { '''': states, ''1'': statesOfUS, ''2'': statesOfUK },
mydata = [
{ id: ''0'', country: ''1'', state: ''1'', name: "Louise Fletcher" },
{ id: ''1'', country: ''1'', state: ''3'', name: "Jim Morrison" },
{ id: ''2'', country: ''2'', state: ''5'', name: "Sherlock Holmes" },
{ id: ''3'', country: ''2'', state: ''6'', name: "Oscar Wilde" }
],
lastSel = -1,
grid = $("#list"),
removeAllOption = function (elem) {
if (typeof elem === "object" && typeof elem.id === "string" && elem.id.substr(0, 3) !== "gs_") {
// in the searching bar
$(elem).find(''option[value=""]'').remove();
}
},
resetStatesValues = function () {
// set ''value'' property of the editoptions to initial state
grid.jqGrid(''setColProp'', ''state'', { editoptions: { value: states} });
},
setStateValues = function (countryId) {
// to have short list of options which corresponds to the country
// from the row we have to change temporary the column property
grid.jqGrid(''setColProp'', ''state'', { editoptions: { value: statesOfCountry[countryId]} });
},
changeStateSelect = function (countryId, countryElem) {
// build ''state'' options based on the selected ''country'' value
var stateId, stateSelect, parentWidth, $row,
$countryElem = $(countryElem),
sc = statesOfCountry[countryId],
isInSearchToolbar = $countryElem.parent().parent().parent().hasClass(''ui-search-toolbar''),
//$(countryElem).parent().parent().hasClass(''ui-th-column'')
newOptions = isInSearchToolbar ? ''<option value="">All</option>'' : '''';
for (stateId in sc) {
if (sc.hasOwnProperty(stateId)) {
newOptions += ''<option role="option" value="'' + stateId + ''">'' +
states[stateId] + ''</option>'';
}
}
setStateValues(countryId);
// populate the subset of contries
if (isInSearchToolbar) {
// searching toolbar
$row = $countryElem.closest(''tr.ui-search-toolbar'');
stateSelect = $row.find(">th.ui-th-column select#gs_state");
parentWidth = stateSelect.parent().width();
stateSelect.html(newOptions).css({width: parentWidth});
} else if ($countryElem.is(''.FormElement'')) {
// form editing
$countryElem.closest(''form.FormGrid'').find("select#state.FormElement").html(newOptions);
} else {
// inline editing
$row = $countryElem.closest(''tr.jqgrow'');
$("select#" + $.jgrid.jqID($row.attr(''id'')) + "_state").html(newOptions);
}
},
editGridRowOptions = {
recreateForm: true,
onclickPgButtons: function (whichButton, $form, rowid) {
var $row = $(''#'' + $.jgrid.jqID(rowid)), countryId;
if (whichButton === ''next'') {
$row = $row.next();
} else if (whichButton === ''prev'') {
$row = $row.prev();
}
if ($row.length > 0) {
countryId = grid.jqGrid(''getCell'', $row.attr(''id''), ''country'');
changeStateSelect(countryId, $("#country")[0]);
}
},
onClose: function () {
resetStatesValues();
}
};
grid.jqGrid({
data: mydata,
datatype: ''local'',
colModel: [
{ name: ''name'', width: 200, editable: true },
{ name: ''country'', width: 100, editable: true, formatter: ''select'', stype: ''select'', edittype: ''select'',
searchoptions: {
value: allCountries,
dataInit: function (elem) { removeAllOption(elem); },
dataEvents: [
{ type: ''change'', fn: function (e) { changeStateSelect($(e.target).val(), e.target); } },
{ type: ''keyup'', fn: function (e) { $(e.target).trigger(''change''); } }
]
},
editoptions: {
value: countries,
dataInit: function (elem) { setStateValues($(elem).val()); },
dataEvents: [
{ type: ''change'', fn: function (e) { changeStateSelect($(e.target).val(), e.target); } },
{ type: ''keyup'', fn: function (e) { $(e.target).trigger(''change''); } }
]
}},
{ name: ''state'', width: 100, formatter: ''select'', stype: ''select'',
editable: true, edittype: ''select'', editoptions: { value: states },
searchoptions: { value: allStates, dataInit: function (elem) { removeAllOption(elem); } } }
],
onSelectRow: function (id) {
if (id && id !== lastSel) {
if (lastSel !== -1) {
$(this).jqGrid(''restoreRow'', lastSel);
resetStatesValues();
}
lastSel = id;
}
},
ondblClickRow: function (id) {
if (id && id !== lastSel) {
$(this).jqGrid(''restoreRow'', lastSel);
lastSel = id;
}
resetStatesValues();
$(this).jqGrid(''editRow'', id, {
keys: true,
aftersavefunc: function () {
resetStatesValues();
},
afterrestorefunc: function () {
resetStatesValues();
}
});
return;
},
editurl: ''clientArray'',
sortname: ''name'',
ignoreCase: true,
height: ''100%'',
viewrecords: true,
rownumbers: true,
sortorder: "desc",
pager: ''#pager'',
caption: "Demonstrate dependend select/dropdown lists (inline editing on double-click)"
});
grid.jqGrid(''navGrid'', ''#pager'', { del: false }, editGridRowOptions, editGridRowOptions);
grid.jqGrid(''filterToolbar'', {stringResult: true, searchOnEnter: true, defaultSearch : "cn"});
ACTUALIZADO 3 : la última versión del código de la demostración que encontrará aquí .
Estoy usando la edición de formulario. Hay dos cuadros de selección en el formulario. Un cuadro de selección es el país, otro cuadro de selección es el estado. El cuadro de selección de estado depende del país seleccionado y se completará dinámicamente. Por ejemplo:
País:
EE. UU. (Valor de opción = 1)
Reino Unido (valor de opción = 2)
Estado para EE. UU .:
Alabama (valor de la opción = 1)
California (valor de la opción = 2)
Florida (valor de la opción = 3)
Hawaii (valor de la opción = 4)
Estado para el Reino Unido:
Londres (valor de la opción = 5)
Oxford (valor de la opción = 6)
Como puede ver arriba, la ID de estado para Reino Unido comienza con 5. Cuando edito un registro que contenía Country id=2 (UK)
e State id=6 (Oxford)
, el formulario de edición se mostrará correctamente: País es Reino Unido y Estado es Oxford. Pero si se abre el cuadro de selección de estado, el texto de la opción es correcto (muestra London Oxford) pero el valor de la opción comenzará desde 0. Lo que debería ser correcto es que el valor de la opción debería comenzar desde 5.
Si selecciona y cambia el cuadro desplegable del país a EE. UU., Luego vuelve a cambiar a Reino Unido, el valor de la opción se completará correctamente (comienza desde 5).
Mi pregunta es, ¿cómo podemos llenar el cuadro de selección para el estado con el valor de opción correcto según el país en el cuadro de edición cuando se carga el formulario de edición?
Estoy usando la edición de formulario. Hay tres cuadros de selección en el formulario. Un cuadro de selección es el país, un cuadro de selección es la ciudad, otro cuadro de selección es la calle. El cuadro de selección de ciudad depende del país seleccionado y se poblará dinámicamente. El cuadro de selección de calles depende de la ciudad seleccionada y se poblará dinámicamente. Guardo Country, City, Street en MySQL. Si elijo un país, ¿cómo puedo cambiar el cuadro de selección de ciudad de la tabla MySQL?