I have a requirement to build a "Search" form for a travel company. This search form will be used for searching different travel components such as Flights, Hotels, Cars etc.
Most of the fields in the form are common (such as travel dates, origin and destination cities etc) for all components but will also contain some component specific fields (such as Business/First/Economy Class & Nonstop Flight Indicators for Flight Search).
Even though most of the fields are common, they need to be displayed with component-specific labels...for example: "travel dates" would say "check-in & check-out dates" on Hotel search form where as they would say "departure & return dates" on Flight search form.
What is the best approach to design a search form which would display field with component-specific labels and also provides a way to map/associate fields to components (common fields to all component types and component-specific fields to corresponding component)? Is there something similar to Data Annotations for achieving this behavior?
So Within "Form A", field 1 has a certain display label
A "Form" has many fields and each field has a display label that changes by form.
A Form has one or more fields
Not all forms need to have all fields (that is some forms may have fewer fields than the set of all fields).
So if you can imagine a set of tables in a database (the data from these tables can be cached in memory if need be) that represent this data then at the time of rendering a specific form, you'll get the set of fields and their display labels. It's easy enough to then bind the display labels to the appropriate components.
This is the best way to do it rather than rely on reflection.
The basic data structure would be a Dictionary that uses the form's name (or some other identifier) as the key. The "value" part of the Disctionary will be another dictionary that uses the control id/name as the key and the value will be the display label.
so something like:
Dictionary<string, Dictionary<string, string>>
Or you could have a "custom" dictionary for the latter like so
public class
ControlDisplayLabelDictionary :
Dictionary {
}
And then you could populate the whole structure like so:
var formControlLabels = new Dictionary<string,
ControlDisplayLabelDictionary>();
var cdForFormA = new ControlDisplayLabelDictionary();
cdForFormA.Add("Control1", "Travel Dates");
cdForFormA.Add("Control2", "Some Label control2 on FormA");
cdForFormA.Add("Control3", "Some Label control3 on FormA");
formControlLabels.Add("Form A", cdForFormA);
var cdForFormB = new ControlDisplayLabelDictionary();
cdForFormA.Add("Control1", "Booking Dates");
cdForFormA.Add("Control2", "Some Label control2 on FormB");
cdForFormA.Add("Control3", "Some Label control3 on FormB");
formControlLabels.Add("Form B", cdForFormA);
Of course, when the data comes from a database the actual population code will differ but the idea remains the same. Now you could choose the cache this structure in memory but I wouldn't do that unless there is a performance issues since the database will actually cache this "data" in memory anyway and it is very unlikely that the database engine will hit the hard disks after the first time. Provided of course you have enough memory on your database server box.
Related
I have an issue related to the data filtering. I have a Google Drive table to store data, and I want to show one field of this data source in a dropdown to make a filter by this field (Country).
The problem is that this dropdown filter it's only showing the countries that appears on the current page of the list. For example, if in the first page appears one country (Thailand) on the dropdown I'll only see Thailand.
If we move to the second page of the list we have another two countries (Spain and Portugal) and then the dropdown will only show Spain and Portugal.
What I really want is a dropdown which shows all the countries, no matter if they aren't on the current page, but I don't know how to fix it.
This the the configuration of the Country Selector:
In the help, it's said we should use #datasource.model.fields.COUNTRY.possibleValues,
but if I use this paramater as Options, nothing is displayed in the selector.
I have spend a lot of hours trying to fix this issue and I don't find the solution, and I would like to check with you if it's an issue or I'm doing something wrong...
Could you help me?
You are using the same datasource for your dropdown and table and by #distinct()#sort() you are filtering items that are already loaded to browser (opposed to the whole dataset stored in database).
You need to have a separate datasource for your dropdown. There are at least three techniques to do this:
Possible values
You can predefine allowed values for your Country field and use them to populate drop down options both in create form and table filtering #datasource.model.fields.Country.possibleValues as you mentioned in question:
Create model for countries
By introducing dedicated related model for countries you can get the following benefits:
normalized data (you will not store the same country multiple times)
you'll be able to keep your countries list clean (with current approach there is possibility to have the same country with different spellings like 'US', 'USA', 'United State', etc)
app users when they create new records will be able to choose the country they need from dropdown (opposed to error prone typing it every time for all new records).
your dropdown bindings will be as simple as these:
// for names
#datasources.Countries.items..Names
// for options
#datasources.Countries.items.._key
// for value
#datasource.query.filters.Country._key._equals
Create Calculated Model
With Calculated Model you'll be able to squeeze unique country values from your table. You server query script can look similar to this:
function getUniqueCountries_() {
var consumptions = app.models.Consumption.newQuery().run();
var countries = [];
consumptions.reduce(function (allCountries, consumption) {
if (!allCountries[consumption.Country]) {
var country = app.models.CountryCalc.newRecord();
country.Name = consumption.Country;
countries.push(country);
allCountries[consumption.Country] = true;
}
}, {});
return countries;
}
However with growth of your Consumption table it can give you significant performance overhead. In this case I would rather look into direction of Cloud SQL and Calculated SQL model.
Note:
I gave a pretty broad answer that also covers similar situations when number of field options can be unlimited (opposed to limited countries number).
I am trying to make form builder in android. I have a real problem at designing database. In this application User first drags the required fields to the screen and change the labels of fields. The fields Contains:
CheckBox
RadioButton
TeXtBox
PlainText
This is my mockup:
I have real problem in designing database.I need a help to accomplish it.
Any Links to the tutorials or ER Diagrams will be really appreciated.
In this application user will drag his required fields to the screen as shown in mock up. Suppose when user drags on checkbox icon then the Editable Checkbox label and editable options will appear in the screen. Then Form builder names the label according to his requirements and options also. In this way he first builds the form .
That's what I created in 10 minutes, hope it helps.
TB_FieldType //field type
UUID_Type,
Type_Name, (Checkbox, RadioButton, Textbox, PlainText, Password, DropdownSelect...)
TB_FieldRule //Table field rule
UUID_Rule,
Rule (numeric only, not null...)
TB_UserTable //Save user designed thrir own table
UUID_Table,
Table_Name, (Designed table name)
TB_UserTable_Field //Designed table field detail
UUID_TableField,
UUID_Table,
UUID_Type,
UUID_GroupID, (can be null if field is single type*)
UUID_Rule,
Field_Name, (Display name)
Field_Length,
TB_Group //(for field(s) in multi type*, like RadioButton, DropwodnSelect... )
UUID,
GroupID,
GroupData,
I would create a table for storing the field definitions with fields like this:
survey_id (reference to the survey which the field belongs to)
field_id (unique id of the field)
field_type (checkbox, radio, plain etc.)
field_label
field_data (additional information if required, e.g. selection options for radio - dependent on type)
field_index (defines the order of fields)
... any additional field you may need
From this data, you can dynamically build your GUI.
And you will need another table for storing the answers (if it is in scope of your app):
field_id (reference to the former table)
value (entered by the user)
...user_id, timestamp etc. according to your needs
I have a behavior that defines two fields: year and week (of the year).
This behavior is reused for several content types, and only in one of them I need to make sure that this fields are not repeated in any other instance of the same content type, i.e. two objects of this content type can not share the same year and week (is fine to share the same year or the same week).
As this restriction is only meant for this specific content type I tried with an zope.interface.invariant but for some reason I can not get access to the fields defined in the behavior.
A simplified version of the Content type would be:
class IMyContentType(form.Schema)
title = schema.TextLine(title="My title",
description="My description",
required=True,
)
#invariant
def check_year_and_week(data):
data.week
How can I get the value (if any) from within check_year_and_week invariant?
You can't. Invariants have access to values for other fields in the same interface, but not fields from other interfaces.
You can use a widget manager validator instead: http://developer.plone.org/reference_manuals/active/schema-driven-forms/customising-form-behaviour/validation.html#widget-manager-validators
Or do the validation in your form's action handler: http://developer.plone.org/reference_manuals/active/schema-driven-forms/customising-form-behaviour/validation.html#validating-in-action-handlers
A behavior is nothing but an adapter; if you're not getting the fields on the invariant you probably need adapt your content type before trying to access the extra fields.
Say for example I am printing name tags for thousands of content nodes in one content type called “Attendee.” Each of these nodes specifies a single "Attendee" for an event, (and their respective name tag). Say these attendees also needed name tags printed out for their “friends” who are attending with them. That is no problem—these “friends” obviously need their own node with the same fields to get their own name tag, so I distinguish that they are a “Friend of an Attendee” with a simple checkbox.
Now here’s the sorting order / grouping problem: When rendering the view, I need these “friends of attendees” to appear “right after” the attendee they are going with. Is there a way for me to maybe create a new autocomplete text field to link these together and then have them output next to each other?
p.s. I am technically using the Views PDF module, but it has the basic Views functions, so if it's possible with Views, it will probably be possible with this module.
In order to group these together, you have to have some way of linking friends to the attendees. You can do this by adding an entity reference field to the content type. See https://drupal.org/project/entityreference
here are the steps:
from admin/structure/types select "manage fields" on your content type
on the "manage fields" tab, click in "Add new field", and type in a label name. say "friend of"
for "type", select "Entity Reference", and for now, choose "Autocomplete" for your widget
click save
in the field edit tab:
select Target Type: Node
under Entity Selection, set Mode: Simple
set Target bundles: ( your attendees type )
click save
go to admin/config/development/performance and clear all caches
You should now see an autocomplete field when you edit an attendee that you can use to set the friend relationship
Things normally get a bit complicated now, as you have to tell views about the relationship between attendees and their friends. If you want to keep this dead easy, you can set the primary attendees as their own "friend" ( who they are going with ) so that you can group them together easily with their companions, without having to worry about contexts, relationships, or any other fancy stuff.
I have created a Drupal website with a new page for registration purposes. I would like to have a checkbox list of my provided services (for example back-up user files), with the corresponding prices next to each service.
When multiple checkboxes are checked, the values (in this case, the prices) need to sum up to a total amount. This amount then should be displayed on the page.
How can I sum the amounts associated with the checkboxes?
You have the checkbox value attribute to attach the price amount to a checkbox?
While submitting/processing use js/php logic to add the selected checkboxes.
Update:
options array should be like this
array('return_value1' => t('Display Value 1'), 'return_value2' => t('Display Value 2'))
Look into the Computed Field module.
Computed Field is a very powerful CCK field module that lets you add a
custom "computed fields" to your content types. These computed fields
are populated with values that you define via PHP code. You may draw
on anything available to Drupal, including other fields, the current
user, database tables, you name it. (Feeling the power yet? :) ) You
can also choose whether to store your computed field values in the
database with other content fields, or have them "calculated" on the
fly during node views. (Although you should note that Views use
requires database stored values.) This field is literally the Swiss
Army knife of CCK fields. So start cooking up your PHP based values!