Eclipse Scout go through fields in form data - forms

I would like to go through all fields in form data.
I know that in form I could do something like this :
// Go through all fields with IFormFieldVisitor
box.visitFields(new IFormFieldVisitor() {
#Override
public boolean visitField(IFormField field, int level, int fieldIndex) {
if (field instanceof MyClass) {
...
}
return true;
}
}, 0);
but form data doesn't have this options. How to do this in form data.

You can obtain them using
AbstractFormData.getFields to obtain the top-level fields. If you need nested fields as well, have a look at the more complex AbstractFormData.getAllFieldsRec().
AbstractFormData.getAllProperties to obtain properties that you have defined by annotating the getters and setters with #FormData
That was the simple case.
Now, if you are using the Scout Extension mechanism to add new elements to an existing form (and it's formdata), you will have to take those contributions into account.
If you need to do this, you can refer to the source code of the AbstractForm.importFormData to see how Scout implements this.

Related

How to store a unique value into a Panel (GWT)?

This is simple question but there's No answer found on the Internet.
Ok, some widgets such as CheckBox have a method called myCHeckBox.setFormValue(text); so I take advantage of this method to store the unique ID into a CheckBox so that later on I just myCHeckBox.getFormValue(); to retrieve back the unique value.
However, there's no setFormValue on GWT Panel?
So if we want to store a unique value into a Panel (for example, FlowPanel, VerticalPanel)?
Then Which method can i use to do that?
The way I see it what you are really trying is to extend the purpose of the Panel. I cannot see why you would want a unique identifier, as the object of the Panel is as unique as it guess but that's not the point here.
Since you want to extend the Panel do just that. Extend the corresponding class and give it a unique value, implement the corresponding getters and setters and then you are set. It is as simple as that
class AbsolutePanelUnq extends AbsolutePanel
{
private int uniqueId;
public getUniqueId(){
return uniqueId;
}
public setUniqueId(int uniqueId)
{
this.uniqueId = uniqueId;
}
}
Then create the object and do whatever you need.
Best way I can suggest:
Public class myPanel extends Panel {
private myUniqueValue;
//Getter setter for myUniqueValue
}

Should a method be 'fired' from within a property?

My application uses the MVVM pattern. My TextBox is bound to a property of my ViewModel (type string).
When ever the content of the TextBox changed via the user typing, I want to perform some validation.
So, currently, my code is
<TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}" />
and my ViewModel has this property and field:
private string _xmlContentAsString;
public string XmlContentAsString
{
get { return _xmlContentAsString; }
set
{
if (_xmlContentAsString == value)
return;
_xmlContentAsString = value;
PerformValidiationLogic(value);//This is where I am unsure
}
}
Now, this works but, and I don't know why, I don't like this! It some how feels 'hacked' to include the method in the property.
Can some one please tell me if this is the correct approach when using the MVVM pattern?
There's different type of validations.
For simplistic validating string lengths or allowed characters etc you can use DataAnnotations and put the validation in attributes on your properties. You'll need to include
using System.ComponentModel.DataAnnotations;
then for example to keep string to 9 characters:
[StringLength(9)]
public string StringValue
{
get
{
return stringValue;
}
set
{
this.stringValue = value;
}
}
Then there is validation that is a bit more complex and is effectively enforcing your business logic.
There seem to be many views on how to do this. Ideally it should belong on the model, so that the validation can be reused, but obviously called via the viewmodel.
Personally I will put method calls in the property setters occasionally, to me thats the whole reason for having the ability to create setters and getters - otherwise there's very little point in having anything other than auto properties.
But if it's complex or asynchronous then you can hit issues.
I'd be very careful doing it with UpdateSourceTrigger=PropertyChanged, as that means you'll be firing it every character.
In your example, you perform validation logic on the value, but what would be the result of the validation if it fails? Typically you would want to notify the user of a validation failure. If that is the case, then I suggest IDataErrorInfo (examples can be found here:
http://codeblitz.wordpress.com/2009/05/08/wpf-validation-made-easy-with-idataerrorinfo/).
If you plan on overriding the value without notifying the user, then validating in the setter is acceptable (though still not a fan for more personal reasons).
In my opinion thats the correct approach. I would write a base class for your ViewModel that contains a method that sets the property, call PropertyChanged and validate if some validation rule is attached to that property.
For example:
public abstract class ValidableViewModel
{
private List<ValidationRule> _validationRules;
public ValidableViewModel()
{
_validationRules = new List<ValidationRule>();
}
protected virtual void SetValue<T, T2>(Expression<Func<T>> expression,
ref T2 backend, T2 value)
{
if (EqualityComparer<T2>.Default.Equals(backend, value))
return;
backend = value;
OnPropertyChanged(expression);
Validate(expression.Name, value);
}
protected void Validate(string propertyName, object value)
{
foreach(var validationRule in _validationRules)
{
if(validationRule.PropertyName == propertyName)
validationRule.Execute(value);
}
}
}
The code is not complete, there is missing a lot. But it could be a start ;-)
I personally don't advise putting so much logic in your property. I would use a command bound to an event, ie the lostfocus event of the textbox, and perform your validation there.
I would use something like this:
<TextBox Text="{Binding XmlContentAsString, UpdateSourceTrigger=PropertyChanged}">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="LostFocus">
<interactivity:InvokeCommandAction Command="{Binding LostFocusCommand, Mode=OneWay}"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</TextBox>
then have a command in your view model that is LostFocusCommand wiht your validation logic.
I use mvvm-light and can give a more detailed example for that. (you will need to include the blend interactivity declaration at the top of your xaml)

How can we set second picklist value dynamically with string value is know in CRM Dynamics 4.0

I have two pick-list in Car details entity. I'm setting the Model (cir_model) Picklist value with from the input parameter (that is CrmNumber) of Custom Workflow activity and it's working as expected, and the second pick-list Marque (cir_marque) will be set logically using the Model pick-list.
Logic should be if Model is set to 'Ac Ace' then Marque should be set to 'Ac'. Take value 'Ac' using Split() from the string 'Ac Ace'.
Normally in C# this can be done easily but in CRM 4.0 how this can be achieve (How I'll set 'Ac' to Marque)
public static DependencyProperty modelProperty = DependencyProperty.Register("model",
typeof(int), typeof(CreateCardetails));
[CrmInput("Model")]
public int model
{
get
{
return (int)base.GetValue(modelProperty);
}
set
{
base.SetValue(modelProperty, value);
}
}
public static DependencyProperty ContactProperty =
DependencyProperty.Register("Contact", typeof(Lookup), typeof(CreateCardetails));
[CrmInput("Contact ID")]
[CrmReferenceTarget("contact")]
public Lookup Contact
{
get
{
return (Lookup)base.GetValue(ContactProperty);
}
set
{
base.SetValue(ContactProperty, value);
}
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext
executionContext)
{
//Create an car details record which will be linked to the contact record
DynamicEntity cardetails = new DynamicEntity("cir_cardetails");
cardetails["cir_carsdetailsid"] = Contact;
//Setting the picklist value of Model
Picklist modelPickList = new Picklist();
modelPickList.Value = model.Value;
cardetails.Properties.Add(new PicklistProperty("cir_model",modelPickList));
/*
Here the logic should be done for setting Marque (cir_model) value
Picklist marquePickList = new Picklist();
marquePickList.Value = ???
cardetails.Properties.Add(new PicklistProperty("cir_marque",marquePickList));
*/
//Creating the car details record
Guid carkey = crmService.Create(cardetails);
}
How we can set the Marque value logically, I have left the code blank for this like below
/*
Here the logic should be done for setting Marque (cir_marque) value
Picklist marquePickList = new Picklist();
marquePickList.Value = ???
cardetails.Properties.Add(new PicklistProperty("cir_marque",marquePickList));
*/
Please arrange to help me out on this, all suggestions are welcome.
There is no language CRM 4.0, in CRM 4.0 you code in c#. The only thing that change is the way you work with new types.
In Workflow you don't work with controls, you work with entities and the related attributes. So you "just" need to get the attribute cir_model, do a subtring and find the available options in Marque and set the corrected value. Check this sample from SDK.
You can use JavaScript or C# (Plug-In, Workflow) to accomplish this. There are some considerations to think of when choosing which approach to use.
If you want the user to be able to see the result in real time (when they select) then you can use JavaScript.
If you don't care for the user to see the result, or there is data coming in from an outside source (not the user form), then think about using a plugin.
I don't think you should have to use a WF to do this, plugins are just as easy to write and will happen instantaneously instead of waiting for the async process to complete.

Spring MVC custom editor and select-options bad performance

Im using custom editor in Spring MVC to map string valuest to my domain objects. Simple case: User object refers to Company (User.company -> Company). In User form I register data binder:
protected void initBinder(WebDataBinder binder) throws Exception {
binder.registerCustomEditor(Company.class, new CompanyEditor(appService));
}
Editor is defined as folows:
class CompanyEditor extends PropertyEditorSupport {
private AppService appService;
public CompanyEditor(AppService appService) {
this.appService = appService;
}
public void setAsText(String text) {
Company company = appService.getCompany(text);
setValue(company);
}
public String getAsText() {
Company company = (Company) this.getValue();
if (company != null)
return company.getId();
return null;
}
}
When I use dropdown in my form
<form:select path="company">
<form:options items="${companies}" itemLabel="name" itemValue="id"/>
</form:select>
I experience severe performance problems because (to check if company is selected, I suppose) fires setAsText and getAsText for each option, which makes it to run a SQL query for each company.
I thought that setAsText is used when I commit form to make application know how to translate compnany id to Company (persisted) object. Why should it fire it in dropdowns. Any ideas how to fix it?
If your form backing object is stored as session attribute(i.e. you have something like #SessionAttributes("command") in your controller), so you can try to modify your setAsText(String text) method
public void setAsText(String text) {
Company currentCompany = (Company) this.getValue();
if ((currentCompany != null) && (currentCompany.getId().equals(text)))
return;
Company company = appService.getCompany(text);
setValue(company);
}
but I think that Spring 3.1 #Cacheable abstraction was introduced exactly for the such kind of things and is preferable
see examples in documentation
#Cacheable("books")
public Book findBook(ISBN isbn) {...}
P.S. Consider using new Converter SPI instead of Property Editors.
In general, it's possible to implement a generic converter for your look-up entities, so it will automatically convert entities from text using id if they have some specific attribute, for example, in one of my projects all #Entity types are being automatically converted using a global ConditionalGenericConverter implementation, so I neither register custom property editors during binding nor implement specific converters for types which are simple #Entity classes with #Id annotated primary keys.
Also it's very convenient when Spring automatically converts textual object ids to the actual entities when they are specified as #RequestParam annotated controller method arguments.

Wicket - Wrapped collection Model "transformation"

I have a domain object which has a collection of primitive values, which represent the primary keys of another domain object ("Person").
I have a Wicket component that takes IModel<List<Person>>, and allows you to view, remove, and add Persons to the list.
I would like to write a wrapper which implements IModel<List<Person>>, but which is backed by a PropertyModel<List<Long>> from the original domain object.
View-only is easy (Scala syntax for brevity):
class PersonModel(wrappedModel: IModel[List[Long]]) extends LoadableDetachableModel[List[Person]] {
#SpringBean dao: PersonDao =_
def load: List[Person] = {
// Returns a collection of Persons for each id
wrappedModel.getObject().map { id: Long =>
dao.getPerson(id)
}
}
}
But how might I write this to allow for adding and removing from the original List of Longs?
Or is a Model not the best place to do this translation?
Thanks!
You can do something like this:
class PersonModel extends Model<List<Person>> {
private transient List<Person> cache;
private IModel<List<String>> idModel;
public PersonModel( IModel<List<String>> idModel ) {
this.idModel = idModel;
}
public List<Person> getObject() {
if ( cache == null ) {
cache = convertIdsToPersons( idModel.getObject() );
return cache;
}
public void setObject( List<Person> ob ) {
cache = null;
idModel.setObject( convertPersonsToIds( ob ) );
}
}
This isn't very good code but it shows the general idea. One thing you need to consider is how this whole thing will be serialised between requests, you might be better off extending LoadableDetachableModel instead.
Another thing is the cache: it's there to avoid having to convert the list every time getObject() is called within a request. You may or may not need it in practice (depends on a lot of factors, including the speed of the conversion), but if you use it, it means that if something else is modifying the underlying collection, the changes may not be picked up by this model.
I'm not quite sure I understand your question and I don't understand the syntax of Scala.
But, to remove an entity from a list, you can provide a link that simply removes it using your dao. You must be using a repeater to populate your Person list so each repeater entry will have its own Model which can be passed to the deletion link.
Take a look at this Wicket example that uses a link with a repeater to select a contact. You just need to adapt it to delete your Person instead of selecting it.
As for modifying the original list of Longs, you can use the ListView.removeLink() method to get a link component that removes an entry from the backing list.