You are here: Home / Documentation / How To's / How to give users an easy way to toggle a value on an object

How to give users an easy way to toggle a value on an object

by nguyen — published Apr 04, 2012 12:18 PM, last modified Aug 16, 2016 10:50 AM
e.g. to allow hiring supervisors to mark that they are interested (or not) in a given applicant

What We Want to Do

On our campus Intranet we are developing a form and workflow that lets students apply for an IT job.

The form is implemented with PloneFormGen and D2C (uwosh.pfg.d2c), which creates a fully fledged standalone content object from the values submitted using the form.  (Yes, Dorothy, this IS MAGIC!).  The workflow is designed by plone.app.workflowmanager (yes, yes, magic too).

A string field in the form is called "supervisor interested", and is meant to contain the user ID of the hiring supervisor who is interested in that particular job applicant.

We want to give the hiring supervisor a simple way of toggling that they (and only they) are interested in a particular job applicant.

Portal Actions on the Object

We created two actions in portal_actions -> object called "mark_interested" and "mark_not_interested".  The URLs for each invoke a Controller Python Script of the same name. 

string:mark_interested

and

string:mark_not_interested

The condition for displaying the actions are

python:object.Type() == 'IT Student Application Entry'  and hasattr(object, 'supervisor-interested') and getattr(object, 'supervisor-interested', None) == ''

and

python:object.Type() == 'IT Student Application Entry'  and object.getValue('supervisor-interested') == context.portal_membership.getAuthenticatedMember().getUserName()

The permission required is "Modify portal content" for both actions, and both actions have the "Visible" checkbox checked.

Use Controller Python Scripts

We need to redirect the browser back to the modified object once we're done marking that we are (or are no longer) interested.  A normal Script (Python) does not have the state variable bound by default, and we need state to set the next action.  A Controller Python Script (CPS) has the state variable bound by default.

The mark_interested CPS is created in the portal_skins/custom folder and its source code is:

userid = context.portal_membership.getAuthenticatedMember().getUserName()

field = context.getField('supervisor-interested')
oldValue = context.getValue('supervisor-interested') 
if oldValue.strip() == '':
  context.setValue('supervisor-interested', userid)
  context.reindexObject()

from Products.CMFPlone.utils import transaction_note
from Products.CMFPlone import PloneMessageFactory as _
transaction_note('%s indicated interest' %
                 (userid))
context.plone_utils.addPortalMessage(_(u'You marked that you are interested in this applicant.'))
state.setNextAction('redirect_to:string:%s' % context.absolute_url())
return state.set(context = context)
 

The mark_not_interested CPS has this source code:

userid = context.portal_membership.getAuthenticatedMember().getUserName()

field = context.getField('supervisor-interested')
oldValue = context.getValue('supervisor-interested') 
if oldValue.strip() == userid:
  context.setValue('supervisor-interested', '')
  context.reindexObject()

from Products.CMFPlone.utils import transaction_note
from Products.CMFPlone import PloneMessageFactory as _
transaction_note('%s removed interest' %
                 (userid))
context.plone_utils.addPortalMessage(_(u'You marked that you are no longer interested in this applicant.'))
state.setNextAction('redirect_to:string:%s' % context.absolute_url())
return state.set(context = context)
 

 

Navigation