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
This is an excellent work!!!!so far no luck to run it, I have a default controller and many tables using IS_IN_DB, do I have to list all of them in validate_popup, and create_popup functions ( all tables referencing different tables); OPTION_WTH_ADD_LINK is unrecognized. In your example product is used as a table name and as a controller, please clarify. I have c= default, table name = x, a field in x is y, and y is referencing table name k and field name m in k, please can you walk me through this.
Make sure that the model and controllers have imported properly the widgetAddLink module (steps 5 and 7).
Is there a file with the name "widgetAddLink.py" in your folder "modules"?
Can you post a piece of the code of the model, including the lines that you import the module and the lines that calling the validator IS_IN_DB and the widget OPTIONS_WITH_ADD_LINK?
Hi i tried to put this in my program. But its not recognizing OPTION_WITH_ADD_LINK it appear this message "NameError: name 'OPTIONS_WITH_ADD_LINK' is not defined".
The other problem i have in one of my tables i have person who has occupation, organization, specialty these are IS_IN_DB i have to put a create and validate one function for each tables?
The last question is this support a pop up inside other popup, like categoryType -> category -> product. So in product i add my widget and also in categoryType. so when i click the link it should appear a popup and inside this another so i can insert the a new category and/or a new categoryType?
I hope you can help me with this. And if you have a little example how to do this could you give it to me, i wold appreciate thsi a lot. Well thanks a lot. Bye Take care.
Sorry. I found some bugs and fix them.
Changes:
- The new step 2 was included.
- The step 5 (now 6) was fixed.
for someone who has sophie's problems. The option
exec('import applications.%s.modules.widgetAddLink as popup' % request.application)
should be after the imports and the database creation.
show more comments0
dbb 15 years ago
0
renatocaliari 15 years ago
0
sophie 15 years ago
0
renatocaliari 15 years ago
0
iacastillop 15 years ago