Hiding dexterity field according user property - plone

While adding dexterity object, I have two fields in which we like to display only one field according to user property which is saved in members data.
Schema definition is somewhat like:
class IMyApplication(form.schema):
fieldA = schema.textline(...)
fieldB = schema.textline(...)
I would like to show one fields out of these two field to user according to their user property.
Many thanks in advance for guide/link/advise .

First please consider the example for a custom add/edit form in the DX-docu
Then you are able to hide a field in the updateWidgets method of the form.
Example Code (not tested):
from plone.dexterity.browser.add import DefaultAddForm
from z3c.form import interfaces
class AddForm(DefaultAddForm):
def updateWidgets(self):
super(AddForm, self).updateWidgets()
if my_condition:
self.widgets['myfield'].mode = interfaces.HIDDEN_MODE
Since you have to do the same in the add and edit form, you could create a mixin class with your customization.

Related

Entity reference field and dependent dropdown

I have a content type with an entity reference field referencing to a custom entity. I need to use a select box because an autocomplete widget is not suitable in my case. However, I cannot load all the entities at once as selectable values because they are too many (72000+ the form won't even load). So I default the entity reference select box to a limited number of values using a views filter and then hide it by default. Then I use an ajax dependent dropdown to show and populate the entity reference select box with filtered down values (I'm using a module that implements hook_form_alter).
My problem is that the form won't validate because now I can select entity reference values which are not the default ones in the select box. So I guess I should control in some way the validation rules of the entity reference field. Is there an easy way to do this? Which hook should I use?
Set the entity reference field to autocomplete and take it out of the process entirely in your form alter with $form['field_entity_ref']['#access'] = FALSE. This should fix the validation problem. (of course, "field_entity_ref" is what I'm calling your actual reference field.
Add your own validation to the form, if that is still necessary.
Finally, implement hook_node_presave() to manually put the value of your custom ajax drop down box.
So if your custom ajax select box was named my_custom_ref, then it would look something like this:
function mymodule_node_presave($node) {
if (isset($node->my_custom_ref)) {
$node->field_entity_ref[$node->language][0]['target_id'] = $node->my_custom_ref;
}
}

Hide field without content for Dexterity content type

I created a content type with Dexterity, and after adding one item,
on the front page the fields without content are still displayed in the details page.
I want to hide those fields and their title, what should I do?
You can customize the view of Dexterity types using a display form.
This is a z3c.form form, so we can use the .updateWidgets() method to set the widget availability dynamically to hide some of them:
import z3c.form
from plone.directives import dexterity
class MyCustomView(dexterity.DisplayForm):
grok.context(IMyContentType)
grok.require('zope2.View')
def updateWidgets(self):
super(MyCustomView, self).updateWidgets()
for widget in self.widgets.values():
if not widget.value:
widget.mode = z3c.form.interfaces.HIDDEN_MODE

Is it possible for a behavior to specify a custom subform for fields which it adds

I'm trying to create a behavior which adds 2 new fields to content types to which it is applied, but I'd like those fields to have a custom subform on the add/edit forms for content types it is added to. Is there any straightforward way to do this as part of the behavior?
You can use a fieldset inside your schema
from plone.directives import form
....
class IMyBehaviorSchema(form.Schema):
form.fieldset('myfieldset', label=u"My Behavior fieldset",
fields=['firstfieldname', 'secondfieldname'])
to display your additional fields with Plone form tabbing enabled. See Dexterity manual for further information

How to create "Available field" properties in my own property?

I have created a class inherit from StateManagedCollection.
It has got a few class as Columns like GridView.
But I can not select which filed I want to select from.
It should look like the picture below in design.
But mine is the one below:
I have written the property as below:
[Description("A collection of ToolBarItem's ")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Editor(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty)]
public virtual Items Items
{
}
Can anyone help me out?
GridView columns collection uses a custom UI Type editor to show this interface. The in-built ASP.NET CollectionEditor will not show the required UI. Further in your case, CollectionEditor may not work if the collection's item type is a abstract class.
Solution is to build your own custom UI Type editor - basic steps are
Inherit from System.Drawing.Design.UITypeEditor.
Override GetEditStyle method to inform the property browser that you will launch modal form.
Override the EditValue method to launch your custom UI form.
Build the custom UI Form.
See a couple examples here (see sample for TagTypeEditor) and here.

Dynamically add different user controls

I'm working on a website that will allow instructors to report on the academic progress of students in their classes. I've got the website set up two primary pages: one with a user control that displays the classes (a GridView of basic class info with a child GridView in a template field that displays student names and checkboxes to select them -- called MiniStudents), and another with a user control that displays the selected students -- called FullStudents.
Although improbable, it's possible that an instructor could have the same student in two separate classes. I've already accounted for this in the current page setup -- the combination of student ID and class ID (class IDs change each quarter, for those thinking this will be an issue) form a unique key within the database. Recently, one of my users asked if I could break records out by classes on the page, so that instructors would be able easily recognize which class they're operating in.
So, my question is this: is it possible for me to dynamically add a column to the end of the class user control that would allow me to switch out MiniStudents for FullStudents?
If I've left out any important details or if anyone wants/needs code, please let me know.
Try this:
//Under page_load
string path;
if(condition) path = "~/MiniStudents.ascx";
else path = "~/FullStudents.ascx";
Control userControl = this.LoadControl(path);
panel1.Controls.Add(userControl);
And if you have specific properties that you want to set before the usercontrol gets rendered then make them inherit a custom usercontrol class:
public class CustomControl : UserControl
public class MiniStudents : CustomControl
public class FullStudents : CustomControl
So then you can do this:
CustomControl userControl = (CustomControl)this.LoadControl(path);
userControl.UserId = userId;
I hope this helps!
You could add both, and hide one or the other.
You could use a multiview control to control which control is visible. Though I would be concerned about your viewstate size if you are loading all these controls simulantously. It sounds like there could be a lot of data and markup on the page.

Resources