wiki:DeveloperGuidelines/Popup

Version 1 (modified by Fran Boon, 16 years ago) ( diff )

--

Popups for Form reference data

When adding items, the opened window should be a popup, Submit should close that window & pre-populate the main form with the result.

ToDo:

  • Make work for nested popups (currently all share the name 'popupWin')
  • Don't lose existing populated fields in main form (Read into JS & re-populate?)

We use Progressive Enhancement to allow non-Javascript browsers to access via a new tab (with manual refresh of parent window & then manual selection of new item).

Model should include a comment like this:

db.table.field.comment=DIV(A(T('Add Contact'),_class='popup',_href=URL(r=request,c='pr',f='person',args='create',vars=dict(format='plain')),_target='top'),A(SPAN("[Help]"),_class="tooltip",_title=T("Contact|The Person to contact for this.")))

We use jQuery to catch the click for the class=popup (in static/scripts/S3.js):

$('a.popup').click(function(){
    var url=$(this).attr('href');
    var caller=$(this).parents('tr').attr('id').replace(/__row/,'');
    openPopup(url.replace(/format=plain/,'format=popup')+'&caller='+caller);
    return false;
});

This triggers the popup defined in the same file:

var popupWin = null;
function openPopup(url) {
	if ( !popupWin || popupWin.closed ) {
		popupWin = window.open( url, "popupWin", "width=640,height=480" );
	} else popupWin.focus();
}

There is a special format=popup added to the RESTlike CRUD controller in __db.py:

elif representation=="popup":
    form=crud.create(table,onvalidation=onvalidation)
    response.view='popup.html'
    return dict(module_name=module_name,form=form,module=module,resource=resource,main=main,caller=request.vars.caller)

This uses it's own view: views/popup.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
{{if session.s3.debug:}}
  {{include 'sahana_scripts_debug.html'}}
  {{include 'sahana_styles_debug.html'}}
{{else:}}
  {{include 'sahana_scripts_min.html'}}
  <link href="/{{=request.application}}/static/styles/S3/sahana.min.css" rel="stylesheet" type="text/css" media="screen" charset="utf-8" />
{{pass}}
<script type="text/javascript">
$(function() {
    // bind form and provide a simple callback function 
    $('form').ajaxForm(function() {
        // refresh lookup list in parent window
        // FIXME: How to get it to keep the rest of the form fields? (Read them in & re-populate?)
        self.opener.location.reload(true);
        // find which ID we need to make active
        {{field='%s_%s_%s' % (module,resource,main)}}
        value=$('input#{{=field}}').val();
        $.getJSON("{{=URL(r=request,c=module,f=resource,args=['search'],vars=dict(format='json',field=main,filter='='))}}"+"&value="+value,
        function(data){
            // set the caller's lookup list to the new ID
            self.opener.$('select#{{=caller}}').val(data[0].id);
            // close the popup
            self.close();
        });
    }); 
});
</script>
</head>
<body>
<div id="popup" class="clearfix">
 {{include 'key.html'}}
 <div class='form-container'>
  {{=form}}
 </div>
</div>
</body>
</html>

DeveloperGuidelines

Note: See TracWiki for help on using the wiki.