Steps:
1) Put the jquery.jmpopups-0.5.1 in the static folder. It can be found at http://code.google.com/p/jmpopups/
2) Put the following lines into the web2py_ajax.html, BEFORE of the <script type="text/javascript"> tag:
<script src="{{=URL(r=request,c='static',f='jquery.jmpopups-0.5.1.js')}}" type="text/javascript"></script>
3) Put the following lines into the web2py_ajax.html, INSIDE the <script type="text/javascript"> tag:
$.setupJMPopups({
screenLockerBackground: "#003366",
screenLockerOpacity: "0.7"
});
function openAjaxPopup(name_popup, width, url) {
$.openPopupLayer({
name: name_popup,
width: width,
url: url
});
}
4) Put the module widgetAddLink.py in the modules folder. The contents of the file is below:
#!/usr/bin/env python
# coding: utf8
from gluon.html import *
from gluon.http import *
from gluon.validators import *
from gluon.sqlhtml import *
# request, response, session, cache, T, db(s)
# must be passed and cannot be imported!
class OPTIONS_WITH_ADD_LINK:
def __init__(self,**parameters):
self.parameters=parameters
def __del__(self): pass
def __call__(self,field,value):
"""
example::
db.main.product.widget = OPTIONS_WITH_ADD_LINK(T=T, r=request, c="product")
When the form is rendered it shows a dropbox and a "add" link
"""
# Create a SELECT object
select = OptionsWidget.widget(field,value)
# Get the parameters
request = self.parameters["r"]
a = request.application
c = self.parameters["c"]
T = self.parameters["T"]
f = self.parameters["f"] or None #new paremeter either None or the name of the field to use
requires = select.attributes["requires"]
# If is not the "IS_IN_DB" validator then can be that the line below fails
# because the requires can't have "ks" object
try:
# Get the field name from the foreign table from validator IS_IN_DB
if f is None:
field_name = requires.ks[0]
else:
field_name = f #use the one we specified (because there was no "ks" object)
except AttributeError:
return select
else:
# Get the id from the SELECT object that allows adding an option
select_id = select.attributes.get('_id', None)
id = "%(tablename)s_%(fieldname)s" % {"tablename":field._tablename,
"fieldname":field.name}
popup_id = "popup_%s" % id
width = 700
# Build the URL responsible for opening a popup window in the same screen
url= URL(r=request, c=c, f="create_popup",
vars=dict(title_name=field.name,field_name=field_name,
select_id=select_id))
# Create the script that add the "Add" link after the SELECT object
add_link = A(T("Add"),
_id="add_%s" % id,
_name="add_%s" % id,
_href="#",
_onclick=("openAjaxPopup('%(name)s',%(width)d,'%(url)s')"\
% {"id": id, "name":popup_id, "width":width, "url":url}),
_title="Add")
return DIV(select, " ", add_link)
def create_popup(request, table):
"""
Create a popup with a form to register a new record
"""
select_id = request.vars.select_id
form_name = "form_%(name)s" % {"name":select_id}
field_name = request.vars.field_name
url_ajax = URL(r=request,f='validate_popup',
vars=dict(form_name=form_name, select_id=select_id, field_name=field_name))
# Build the script responsible for submiting the form via ajax
script_submit = SCRIPT("""jQuery('#%(form)s').submit(function(){
jQuery.ajax({
type: "POST",
url: "%(url_ajax)s",
data: jQuery("#%(form)s").serialize(),
success: function(msg){jQuery('#message').html(msg);} });
return false;
});""" % {"form":form_name, "url_ajax":url_ajax} )
form = SQLFORM(table, _enctype=None, _id=form_name,_action=None, _method=None)
return dict(form=form,script_submit=script_submit,message=DIV(_id="message"))
def validate_popup(request, table):
"""
Validate the data from popup
"""
select_id = request.vars.select_id or None
field_name = request.vars.field_name or None
field_value = request.vars["%s" % field_name]
form = SQLFORM(table)
if form.accepts(request.vars,formname=None):
script = "$.closePopupLayer();"
if select_id:
script_add_option = """$("#%s").append("<option value='%s'>%s</option>");""" \
% (select_id, form.vars.id, field_value)
script_select_option = """$("#%s").val("%s");""" % (select_id, field_value)
return SCRIPT(script,script_add_option,script_select_option)
elif form.errors:
return DIV(TABLE(*[TR("%s %s" % (k,v)) for k, v in form.errors.items()]))
5) Put the popup.html in the views folder. The contents of the file is below:
<style type="text/css" media="screen">
.popup {background:#FFF; border:1px solid #333; padding:1px;}
.popup-header {height:24px; padding:7px; background:url("bgr_popup_header.jpg") repeat-x;}
.popup-header h2 {margin:0; padding:0; font-size:18px; float:left;}
.popup-header .close-link {float:right; font-size:11px;}
.popup-body {padding:10px;}
</style>
<div class="popup">
<div class="popup-header">
<h2>{{=T("Create a %(name)s", dict(name=request.vars.title_name)) }}</h2>
<a href="javascript:;" onclick="$.closePopupLayer()" title="Close" class="close-link">{{=T("Close")}}</a>
<br clear="both" />
</div>
<div class="popup-body">
{{=message}}
{{=form}}
{{=script_submit}}
</div>
</div>
6) Import the module in your model (maybe db.py):
exec('from applications.%s.modules.widgetAddLink import *' % request.application)
7) Add this widget to some field that uses the validator IS_IN_DB. Example:
db.main.product.requires = IS_IN_DB(db,db.product.id,db.product.name)
db.main.product.widget = OPTIONS_WITH_ADD_LINK(T=T, r=request, c="product")
Note: The OPTIONS_WITH_ADD_LINK requires three arguments:
a) T object (the object T is the language translator)
b) Request
c) and the name of the controller responsible for add a new register to the field in the left side
d) f (field) is optional.
8) Import the module in the controller specified above, in the widget configuration (e.g. product.py):
exec('import applications.%s.modules.widgetAddLink as popup' % request.application)
9) Add the following two methods into this controller:
def create_popup():
response.view='popup.html'
return popup.create_popup(request, db.tablename)
def validate_popup():
return popup.validate_popup(request, db.tablename)
Note: Replace db.tablename to the desired table. Example: db.product
Ready! This should work.
Issues known:
1) The record is added at the end of the list in the combo box. The widget does not reload the combo box object to sort it properly, just adds an item via jquery.
Comments (14)
- Login to post
order by: newest oldest upvoted downvoted
In fact, the script is send as expected.
The problem is that the validate_popup function does not get the name of the file that should have been uploaded (and my guess is that no file where uploaded by using the popup window....). I'll investigate more and keep you informed.
Hello,
This slice looks nice.
I still have some difficulties to make it working. The pop-up pops-up as wanted, but the submit button is inoperant.
If I add
In create_popup() I get on stdout :
Which looks ok, but still no submit url in the "form_card_file" form (as seen with firebug)....
Do you have any clue ?
Sophie,
It would needs some modification in this widget.
This is using the SQLFORM. What can i do if i want to add this link through the controller? I am creating the table in the controller, i think i have to put the widget here, but i dont know how. My controlles is this:
form=FORM(TABLE(
TD("Caracteristica"), TD(SELECT(_name="caracteristica",
*[OPTION(x.Caracteristica.nCaracteristica +' - '+ x.TipoCaracteristica.nTipoCaracteristica,_value=x.Caracteristica.id)
for x in db((db.Caracteristica.idTipoCaracteristica==db.TipoCaracteristica.id)&\
(db.Caracteristica.id.belongs(lista))).select(orderby=db.Caracteristica.nCaracteristica)])),
TD("Descripcion"),INPUT(_type='text',_name="descripcion"),
INPUT(_type='submit',_value='Submit')))
if form.accepts(request.vars, session):
if not form.vars.caracteristica=="":
db.CaracteristicaCientifico.insert(nCaracteristicaCientifico=form.vars.descripcion,
idCaracteristica=form.vars.caracteristica,idCientifico=session.idPrincipal)
redirect(URL(r=request, c='cientifico', f='insert', args=["db","CaracteristicaCientifico"]))
else:
form.errors.caracteristica ='Seleccionar un registro'
Thanks mr.freeze!
show more comments0
matclab 14 years ago
0
matclab 14 years ago
0
renatocaliari 14 years ago
0
sophie 14 years ago
0
renatocaliari 14 years ago