2012-05-24 27 views
7

Primero, ya leí la pregunta "jQuery Grid Recommendations" pero no responde a mi pregunta.Recomendaciones editables de jQuery Grid con REST API

tengo una pequeña REST API with MongoDB Backend simplemente:

obtener toda equipamientos:

GET /equipements HTTP/1.1 
{{_id:key1, name:Test Document 1, plateforme:prod}, {_id:key2, name:Test Document 2, plateforme:prod}, ...} 

Obtén equipement con la clave: key1

GET /equipements/key1 HTTP/1.1 
{"_id": "key1", "name": "Test Document 1", "plateforme": "prod"} 

Añadir nueva equipamientos de

PUT /equipements HTTP/1.1 {"_id": "key8", "name": "Test Document 3", "plateforme": "prod"} 
HTTP/1.0 200 OK 

Ahora, necesito encontrar una manera fácil de permitir que el usuario lambda agregar/ver/del equipos. Entonces, creo que una interfaz web con una interfaz de usuario jQuery es la mejor. I tried con Sencha Rest Proxy pero no sé javascript y no puedo adaptar el ejemplo.

¿Cómo arreglo mi javascript para mi back-end REST?

Y/O

Me puede recomendar una alternativa más sencilla a Sencha Resto proxy? (que trabaja con mi backend REST) ​​

Respuesta: jqGrid

Y/O

Lo jQuery cuadrícula me recomiendan? (que trabaja con mi backend REST) ​​

Respuesta: jqGrid

Pregunta final: ¿Por qué mis células no se pueden editar con doble clic?

Apéndices

el lado del servidor (EDIT: Agregar Mensaje méthode)

#!/usr/bin/python 
import json 
import bottle 
from bottle import static_file, route, run, request, abort, response 
import simplejson 
import pymongo 
from pymongo import Connection 
import datetime 



class MongoEncoder(simplejson.JSONEncoder): 
    def default(self, obj): 
       # convert all iterables to lists 
     if hasattr(obj, '__iter__'): 
      return list(obj) 
     # convert cursors to lists 
     elif isinstance(obj, pymongo.cursor.Cursor): 
      return list(obj) 
     # convert ObjectId to string 
     elif isinstance(obj, pymongo.objectid.ObjectId): 
      return unicode(obj) 
     # dereference DBRef 
     elif isinstance(obj, pymongo.dbref.DBRef): 
      return db.dereference(obj) 
     # convert dates to strings 
     elif isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) or isinstance(obj, datetime.time): 
      return unicode(obj) 
     return simplejson.JSONEncoder.default(self, obj) 



connection = Connection('localhost', 27017) 
db = connection.mydatabase 

@route('/static/<filename:path>') 
def send_static(filename): 
    return static_file(filename, root='/home/igs/restlite/static') 

@route('/') 
def send_static(): 
    return static_file('index.html',root='/home/igs/restlite/static/') 

@route('/equipements', method='PUT') 
def put_equipement(): 
    data = request.body.readline() 
    if not data: 
     abort(400, 'No data received') 
    entity = json.loads(data) 
    if not entity.has_key('_id'): 
     abort(400,'No _id specified') 
    try: 
     db['equipements'].save(entity) 
    except ValidationError as ve: 
     abort(400, str(ve)) 

@route('/equipements', method='POST') 
def post_equipement(): 
    data = request.forms 

    if not data: 
     abort(400, 'No data received') 
    entity = {} 
    for k,v in data.items(): 
     entity[k]=v 

    if not entity.has_key('_id'): 
     abort(400,'No _id specified') 
    try: 
     db['equipements'].save(entity) 
    except ValidationError as ve: 
     abort(400, str(ve)) 


@route('/equipements/:id', methodd='GET') 
def get_equipement(id): 
    entity = db['equipements'].find_one({'_id':id}) 
    if not entity: 
     abort(404, 'No equipement with id %s' % id) 
    return entity 

@route('/equipements', methodd='GET') 
def get_equipements(): 
    entity = db['equipements'].find({}) 
    if not entity: 
     abort(404, 'No equipement') 
    response.content_type = 'application/json' 
    entries = [entry for entry in entity] 
    return MongoEncoder().encode(entries) 

run(host='0.0.0.0', port=80) 

EDIT: jqGrid:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>Rest Proxy Example</title> 
    <link rel="stylesheet" type="text/css" href="/static/css/ui.jqgrid.css" /> 
    <link rel="stylesheet" type="text/css" href="/static/css/jquery-ui-1.8.20.custom.css" /> 

    <script type="text/javascript" src="/static/js/jquery.js"></script> 
    <script type="text/javascript" src="/static/js/jquery.jqGrid.min.js"></script> 
    <script type="text/javascript" src="/static/js/grid.locale-fr.js"></script> 
    <script type="text/javascript"> 
     jQuery(document).ready(function(){ 
      var lastsel; 

jQuery("#list2").jqGrid({ 
    url:'equipements', 
    datatype: "json", 
    colNames:['Id','Name', 'Plateforme'], 
    colModel:[ 
     {name:'_id',index:'_id', width:50, editable:true}, 
     {name:'name',index:'_id', width:300, editable:true}, 
     {name:'plateforme',index:'total', width:200,align:"right", editable:true}, 
    ], 
    rowNum:30, 
    rowList:[10,20,30], 
    pager:'pager2', 
    sortname: '_id', 
    viewrecords: true, 
    width: 600, 
    height: "100%", 
    sortorder: "desc", 
    onSelectRow: function(_id){ 
     if(_id && _id!==lastsel){ 
      jQuery('#liste2').jqGrid('restoreRow',lastsel); 
      jQuery('#liste2').jqGrid('editRow',_id,true); 
      lastsel=_id; 
     } 
    }, 
    jsonReader: { 
     repeatitems: false, 
     id: "_id", 
     root: function (obj) { return obj; }, 
     records: function (obj) { return obj.length; }, 
     page: function (obj) { return 1; }, 
     total: function (obj) { return 1; } 
    }, 
    editurl:'equipements', 
    caption:"Equipements" 
}); 
jQuery("#list2").jqGrid('navGrid','#pager2',{edit:true,add:true,del:true}); 
}); 
    </script> 
</head> 
<body> 
    <table id="list2"></table> 
    <div id="pager2"></div> 
    <br /> 

</body> 
</html> 
+0

"No sé javascript" - Eso tendrá que cambiar si está tratando de crear una interfaz para un cliente REST. Tómese el tiempo para aprender JavaScript; al final será rentable y no es un lenguaje muy difícil. – RustyTheBoyRobot

+0

Es solo para el equipo interno y no es mi trabajo escribir web frontend. Un día, aprenderé javascript. Pero ahora, tengo muchas cosas más importantes. – Yohann

Respuesta

7

Usted puede utilizar jqGrid para comunicarse con su servicio Restfull. jqGrid admite modos de edición en árbol: edición de celda, edición en línea y edición de forma. Además, la edición en línea se puede inicializar de diferentes maneras. Por ejemplo, puede llamar al método editRow dentro de la devolución de llamada onSelectRow o ondblClickRow o usar navGrid para agregar el botón "Eliminar" en la barra de herramientas navigator y inlineNav para agregar los botones "Agregar" y "Editar". Otra forma será usar formatter: "actions" para incluir botones de "edición" en una columna de la grilla. Puede encontrar todas las formas en the official jqGrid demo. Más detalles técnicos de implementación que puedes encontrar en the answer.

Encuentro personalmente importante que usted entienda otro aspecto importante del uso de los servicios RESTfull en el front-end web. El problema es que la API RESTfull estándar no tiene ninguna interfaz estándar para clasificar, paginar y filtrar los datos. Intento explicar el problema a continuación. Después de eso, espero que quede claro mi recomendación de ampliar la API RESTfull estándar actual con métodos adicionales que tienen parámetros adicionales y que proporcionan funcionalidad de clasificación, paginación y filtrado.

El problema es muy fácil de entender si tiene un gran conjunto de datos. No tiene sentido mostrar en la cuadrícula, por ejemplo, 10000 filas de datos a la vez. El usuario no puede ver los datos en la pantalla sin scolling o paginación de datos. Además, por las mismas razones tiene sentido implementar ordenando e incluso filtrando de los datos. Por lo tanto, es mucho más práctico mostrar solo una página de datos al principio y darle al usuario alguna interfaz para buscar los datos. En la norma pager de jqGrid que se parece a

enter image description here

el usuario puede ir a la "siguiente", "Última" página "Anterior" o "primero" o elija el tamaño de página:

enter image description here

, además, el usuario puede especificar la página deseada mediante entrada directa de la nueva página y pulsando Enter de :

enter image description here

De la misma manera que el usuario puede hacer clic en el encabezado de cualquier columna para ordenar los datos de la cuadrícula de la columna:

enter image description here

Otro elemento de la interfaz de usuario muy importante (importante desde el punto usuarios de vista) podría ser alguna interfaz de filtrado como here por ejemplo o una interfaz de búsqueda como here.

Le doy un ejemplo de jqGrid, pero el problema me parece común. Quiero enfatizar que el servicio RESTfull no le brinda una interfaz estándar para ordenar, paginar y filtrar los datos.

En caso de utilizar jqGrid, la URL RESTfull obtendrá de manera predeterminada parámetros adicionales. Es: page, rows que especifican el número de página y el tamaño de página que se solicitó desde el servicio, sidx y sord parámetros que especifican la columna de ordenación y la dirección de clasificación y _search y filters (el último es en the format) que permite el apoyo filtración. Se puede cambiar el nombre de los parámetros si es necesario utilizando la opción prmNames de jqGrid.

Te recomiendo que leas the answer sobre la pregunta acerca de la codificación de la URL. Creo que la parte _search=false&rows=20&page=1&sidx=&sord=asc no pertenece al recurso y, por lo tanto, es mejor enviar la información como parámetros y no como parte de la URL.

Lo que principalmente quería expresar en mi respuesta es que el uso de la API RESTfull clásica pura no es suficiente para implementar una buena interfaz de usuario. Deberá ampliar la interfaz con los parámetros adicionales utilizados para buscar, clasificar y filtrar, o no podrá crear una GUI web fácil de usar y fácil de usar.

+0

Gracias por esta larga respuesta. Poco no responde a mi pregunta: de hecho, no es posible usar jQGrid con mi back end de REST. jQGrid usa un formato jsojn específico: '{total: xxx, página: yyy, registros: zzz, filas: [ {nombre1:" Fila01 ", nombre2:" Fila 11 ", nombre3:" Fila 12 ", nombre4:" Fila 13 ", nombre5:" Fila 14 "}, ...' – Yohann

+0

@Yohann: ¡No! jqGrid puede leer casi * cualquier * formato JSON, solo debe usar el correspondiente [jsonReader] (http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data). No describe su formato de datos actual detallado, pero supongo que el siguiente 'jsonReader' funcionará en su caso:' jsonReader: {repeatitems: falso, id: "_id", raíz: función (obj) {return obj; }, records: function (obj) {return obj.length; }, página: función (obj) {return 1; }, total: function (obj) {return 1; }} ' – Oleg

+0

@Yohann: El formato estándar de datos de entrada parece un poco extraño, pero si envía desde la matriz de cadenas de servidores en lugar de las propiedades * con nombre, puede reducir el tamaño de los datos transferidos entre el servidor y el cliente. Además, requiere que el usuario especifique el id * único * 'de cada fila porque el id se utilizará como 'id' de' '- rowid. – Oleg