Páginas

martes, 28 de junio de 2011

Web2py ejemplo sencillo donde vincularemos python con javascript

En este pequeño ejemplo vamos a mostrar como pasar variables python hacia el código javascript, fijaos bien que las variables python dentro del javascript tienen '   ' ,comillas simples, ejemplo '{{variable}}'.

en la controladora.............................

def index():  

    var1 = 'hola'  # la pasaremos como parametro de la función mostrar()
    var2 = 'hola2'  # la pasaremos directamente dentro de dicha función  
 
    return dict(var1=var1, var2=var2)

en la vista...............................................................

index.html

{{extend 'layout.html'}}

{{=var1}}<br/>
{{=var2}}<br/>
{{lista = ['hola','hola2']}}

<input type="button" value='prueba' onclick="mostrar('{{=var1}}')"/>

<script type="text/javascript">

function mostrar(variable)

    var Lista = []
    alert(variable);
    var mivarjs='{{=var2}}';
    alert(mivarjs);
    {{for i in lista:}}
        Lista.push('{{=i}}');
     {{pass}} 
     alert(Lista);
  
}
</script>



miércoles, 12 de enero de 2011

Web2py ejemplo ajax upload hecho por michele.comitini

Esta ejemplo permite a los usuarios (sin autenticación) asociar imágenes a los usuarios registrados (primero tenes que registrar algunos usuarios). La lista es actualizada sin recargar toda la página.

Referencia: http://www.web2pyslices.com/main/slices/take_slice/114

Primero crear dentro de la carpeta static/js el archivo ajaxupload.js

Despues descargar este plugin:
Copiar y pegar contenido del plugin en el archivo ajaxupload.js

en el modelo................

db.define_table('user_pictures',
                Field('user', db.auth_user, unique=True, represent=lambda id: '%s %s ' %( db.auth_user(id).first_name, db.auth_user(id).last_name)),
                Field('picture', 'upload', requires=IS_IMAGE()))
               
db.user_pictures.user.requires=IS_IN_DB(db,'auth_user.id', '%(first_name)s %(last_name)s', zero=T('Escoge uno'))


default.py.............................................

def index():
        return dict()
   
def user_picture_list():
    rows = db(db.user_pictures.id>0).select()
    return dict(rows=rows)

def user_picture_form():
    form = SQLFORM(db.user_pictures)
    if form.accepts(request.vars):
       response.flash='Thanks for filling the form'
       return XML('ajax("%s",[],"pic_list");' % URL('user_picture_list.load'))
    elif form.errors:
        response.flash='Fill the form correctly'
    else:
        response.flash='Please, fill the form'

    return dict(form=form)


en las vistas................................................


default/index.html
{{response.files.append(URL(r=request,c='static',f='js/ajaxupload.js'))}}
{{extend 'layout.html'}}

<div class='ez-wr'>

    <h2>Esta lista crecera a medida que se carguen las imágenes</h2>

  <div class='ez-box' id='pic_list'>
    {{=LOAD('default', 'user_picture_list.load', ajax=False)}}
  </div>
</div>
<div class='ez-wr'>
  <p>
    Cargue una nueva imagen  </p>
  <div class='ez-box'>
    {{=LOAD('default','user_picture_form.load', ajax=False)}}
  </div>
</div>

default/user_picture_form.load     //fijaos que la terminacion es (.load) no (.html) y tampoco se le pone {{extend 'layout.html'}}


{{=form}}
<script type='text/javascript'>
  //<!--
    jQuery('document').ready(function() {
        jQuery('form').ajaxForm({dataType: 'script',
                 url: "{{=URL('user_picture_form')}}"
                 });
});
                     //-->
</script>

default/user_picture_list.load    //fijaos que la terminacion es (.load) no (.html) y tampoco se le pone {{extend 'layout.html'}}


<div class='ez-wr'>
     {{for r in rows:}}
     <div class="ez-wr">
       <div class="ez-fl ez-negmr ez-50">
     {{user = db.auth_user(r.user)}}
     {{="%s %s" % (user.first_name,user.last_name)}}
       </div>
       <div class="ez-last ez-oh">
     {{=IMG(_src=URL(f='download',args=[r.picture]))}}
       </div>
     </div>
     {{pass}}
   </div>

lunes, 10 de enero de 2011

Web2py ejemplo sobre selección dinámica y auto-completar.

En este ejemplo vamos a utilizar los ayudantes FORM, SELECT, OPTION etc... donde mostraremos de forma dinámica los meses en un combo-box, también haremos una búsqueda de esos mismo meses a medida que vamos escribiendo.

Más Información: http://www.latinuxpress.com/books/drafts/web2py/caps/capz10.html#auto-completar

default.py.....................................

def index():
    lista = ['Enero' , 'Febrero' , 'Marzo' , 'Abril' , 'Mayo' , 'Junio', 'Julio','Agosto' , 'Septiembre' , 'Octubre' , 'Noviembre' , 'Diciembre']

    form=FORM(LABEL('Selecione un mes: '),SELECT([OPTION(texto, _value=texto) for texto in lista],_name='combo'),BR(),LABEL('Escribir el nombre de un mes:'),INPUT(_name='month',_id='month'))

    return dict(lista=lista,form=form)

def month_selector():

    months = ['Enero' , 'Febrero' , 'Marzo' , 'Abril' , 'Mayo' , 'Junio' , 'Julio' , 'Agosto' , 'Septiembre' , 'Octubre' , 'Noviembre' , 'Diciembre']

    month_start = request.vars.month.capitalize()
    selected = [m for m in months if m.startswith(month_start)]
    return DIV(*[DIV(k,
                                 _onclick="jQuery('#month').val('%s')" % k,
                                 _onmouseover="this.style.backgroundColor='PaleGreen'",
                                 _onmouseout="this.style.backgroundColor='white'",
                                 _onmouseup="jQuery('.suggestions').hide()",
                                 ) for k in selected])

default/index.html.............................
{{extend 'layout.html'}}


<style>
#suggestions { position: relative; }
.suggestions { background: white;  }
.suggestions DIV { padding: 2px 4px 2px 4px; }
</style>

{{=form}}


<div id='suggestions'> </div>

<script>
jQuery("#month").keyup(function(){
      ajax('month_selector', ['month'], 'suggestions')});
</script>



viernes, 31 de diciembre de 2010

Web2py ejemplo de paginación

Vamos a paginar una tabla en la vista cada 10 elementos.

en el modelo...................

#recuerde llenar la tabla

db.define_table('persona',
     Field('fecha','datetime'),
     Field('nombre'),
     Field('apellido'),
     Field('profesion'))

en la controladora.............................

def index():
   if len(request.args):
       page=int(request.args[0])
   else:
       page=0

   items_per_page=10   # cantidad de elementos por los cuales hacer la paginación

   limitby=(page*items_per_page,(page+1)*items_per_page+1)    
     
   lista = db(db.persona.id > 0).select(orderby = ~db.persona.fecha,limitby=limitby)
   return dict(lista=lista,page=page,items_per_page=items_per_page)

en la vista...............................................................

index.html

{{extend 'layout.html'}}
<table>
<tr>

<td>Fecha </td>
<td>Nombre</td>
<td>Apellido</td>
<td>Profesion</td>

</tr>
<tr>
{{for i,row in enumerate(lista):}}
{{if i==items_per_page: break}}
<td> {{=row.fecha}}</td>
<td> {{=row.nombre}}</td>  
<td> {{=row.apellido}}</td> 
<td> {{=row.profesion}}</td>

</tr> 
{{pass}}
</table>

<br/>
{{if page:}}
<a href="{{=URL(args=[page-1])}}">anterior</a>
{{pass}}


{{if len(lista)>items_per_page:}}
<a href="{{=URL(args=[page+1])}}">siguiente</a>
{{pass}}

miércoles, 29 de diciembre de 2010

Web2py un ejemplo donde usaremos la función LOAD



Vamos a tratar de comentar los comentarios. Tendremos muchos comentarios padres y cada comentario padre tendrá muchos subcomentarios hijos. Cuando se crea un comentario padre automáticamente se crea un formulario para los subcomentarios, cada hijo sabrá quien es su padre y todo esto ocurrirá en una misma página (algo parecido a lo que hace el facebook).

Este ejemplo funciona satisfactoriamente gracias a la cooperación de Alan Etkin:

en el modelo..........................................

db.define_table('comment',
   Field('body',label='Comentario'))
  
db.define_table('comment2',
   Field('body',label='Comentario'),
   Field('idcomentario',db.comment))  
  
db.comment.body.requires=IS_NOT_EMPTY()
db.comment2.body.requires=IS_NOT_EMPTY()
db.comment2.idcomentario.writable = db.comment2.idcomentario.readable = False



en la controladora........................................

def index():  

    form = SQLFORM(db.comment,fields=['body'])   
    if form.accepts(request.vars,session):
        response.flash='su comentario ha sido posteado'
        
        
    lista = db(db.comment.id>0).select(orderby = ~db.comment.id)
    
    return dict(form=form,lista=lista)
               

def post():   
    id1=request.args[0]
    comentario=db(db.comment.id==request.args[0]).select()[0]
    form = SQLFORM(db.comment2,fields=['body'])
    form.vars.idcomentario=comentario.id
 
    if form.accepts(request.vars,session):
         response.flash='su comentario ha sido posteado'
    elif request.post_vars.has_key('body'):     # Alan Etkin aporte
          if len(request.post_vars['body']) >0:
             response.flash='su comentario ha sido posteado'
             db.comment2.insert(body = request.post_vars['body'],idcomentario = id1)
            
   
    
    comments=db(db.comment2.idcomentario==comentario.id).select()

    return dict(form=form,comments=comments)


en la vista.....................................................

default/index.html

{{extend 'layout.html'}}

<h2>Postea un comentario:</h2>
<div>
{{=form}}
</div>
{{if len(lista):}}
{{for elem in lista:}}
     <h3>{{=elem.body}}</h3>
    <div>{{=LOAD('default','post.load',args=[elem.id],ajax=True)}}</div>
 {{pass}}
{{else:}}
    <h2>No hay comentarios</h2>
{{pass}}



default/post.load  // fijaos que la terminacion es (.load) no (.html) y tampoco se le pone {{extend 'layout.html'}}


{{if len(comments):}}
{{for comment in comments:}}
   <h5>{{=comment.body}}</h5>
{{pass}}
{{else:}}
{{pass}}

{{=form}}

Web2py un ejemplo interesante hecho por mdipierro

Hay veces en las cuales usted tiene dos tablas (ejemplo "cliente", 'dirección') que están unidos entre sí por una referencia y desea crear un único formulario que permite introducir información acerca de un cliente y su dirección por defecto. Asi es como se hace.

Referencia: http://www.web2pyslices.com/main/slices/take_slice/102

en el modelo

db.define_table('client',
     Field('name'))
db.define_table('address',
    Field('client',db.client,writable=False,readable=False),
    Field('street'),Field('city'))

en la controladora

def register():
    form=SQLFORM.factory(db.client,db.address)
    if form.accepts(request.vars):
        id = db.client.insert(**db.client._filter_fields(form.vars))
        form.vars.client=id
        id = db.address.insert(**db.address._filter_fields(form.vars))
        response.flash='Thanks for filling the form'
    return dict(form=form)

Personalizando el menú de la app Welcome en Web2Py - Parte 1

Una de las cosas más interesantes de web2py es su gran versatilidad y sencillez, esto reduce sensiblemente la curva de aprendizaje en comparación con otros frameworks.
En este post -dividido en dos partes- aprenderemos a personalizar el menú por defecto que viene en la app "Welcome" de Web2Py.
En esta primera parte veremos como programar diferentes opciones del menú, en la segunda veremos como modificar la apariencia del menu en la vista.
El fichero en cuestión que modificarás será el siguiente: tu-app/models/menu.py, el cual luce de la siguiente manera:
# -*- coding: utf-8 -*-

#########################################################################
## Customize your APP title, subtitle and menus here
#########################################################################

response.title = request.application
response.subtitle = T('customize me!')
response.meta.author = 'you'
response.meta.description = 'describe your app'
response.meta.keywords = 'bla bla bla'

##########################################
## this is the main application menu
## add/remove items as required
##########################################

response.menu = [
(T('Index'), False, URL(request.application,'default','index'), [])
]

##########################################
## this is here to provide shortcuts
## during development. remove in production
##
## mind that plugins may also affect menu
##########################################

response.menu+=[
(T('Edit'), False, URL('admin', 'default', 'design/%s' % request.application),
[
(T('Controller'), False,
URL('admin', 'default', 'edit/%s/controllers/%s.py' \
% (request.application,request.controller=='appadmin' and
'default' or request.controller))),
(T('View'), False,
URL('admin', 'default', 'edit/%s/views/%s' \
% (request.application,response.view))),
(T('Layout'), False,
URL('admin', 'default', 'edit/%s/views/layout.html' \
% request.application)),
(T('Stylesheet'), False,
URL('admin', 'default', 'edit/%s/static/base.css' \
% request.application)),
(T('DB Model'), False,
URL('admin', 'default', 'edit/%s/models/db.py' \
% request.application)),
(T('Menu Model'), False,
URL('admin', 'default', 'edit/%s/models/menu.py' \
% request.application)),
(T('Database'), False,
URL(request.application, 'appadmin', 'index')),
]
),
]

La línea que nos interesa es la siguiente:

response.menu = [
(T('Index'), False, URL(request.application,'default','index'), [])
]
Aqui tenemos el primer item del menú que viene por defecto y vamos a pasar a describir su contenido. "Index" es lo que aparece visiblemente en el menú. El parámetro "False" es un misterio, aunque seguramente mediante la práctica se puede aprender su utilidad (porque no encontré documentación al respecto). Luego el siguinte parámetro "URL" muy fácil de entender: pasamos la aplicación en cuestion (si dejamos vacios se usa la app presente), el controlador (si dejamos vacio usará "default.py")y la función en cuestión, en este caso index.
Como el primer item de nuestro menú es index, no existen submenús, pero qué si queremos tener un submenú aquí? Muy fácil, creamos una nueva tupla dentro de los corchetes que quedaron vacios, como un parámetro más y podríamos continuar así recursivamente.

Sin embargo tenemos más código, que significa? Significa que cada vez que agregamos un item al menú debemos agregalo de la siguiente manera:

response.menu+=[...] #Entre corchetes va el siguiente menú.

En este caso, el nuevo item es "Edit":

response.menu+=[
(T('Edit'), False, URL('admin', 'default', 'design/%s' % request.application),...

en "URL" debemos seguir los pasos descriptos anteriormente y borrar lo que aparece aqui.
Lo mismo debemos hacer con los siguientes subitems que vienen dentro de la linea. Con simple copie y pegue y sustituyendo nombres y controladores podemos armar sin mas complicaciones nuestros menúes. Es más, con un poco de práctica y experiencia podrías crear varios menúes diferentes. Pero eso es letra para otro post.

Practiquen y prueben. Hagan sus preguntas en los comentarios si algo no quedó claro (seguramente :P ...)y trataremos de responder lo antes posible.