Wtforms - How FieldList receives input from frontend - frontend

I am curious how FieldList of wtforms works, I did some experiment with the front end using javascript.
So basically I have a multiple repeatable fields, and there is a button to dynamically add new field and changes its id, name, for following the wtforms convention (e.g. transaction-item-0-something for first field, transaction-item-1-something for second field, etc).
One experiment that I did was putting same id and name same for 2 of field list (e.g. transaction-item-0-something for 1st field, transaction-item-0-something for 2nd field). and wtforms only took the first input value (is expected).
Second experiment was the one that bugs me, I deliberately changed some of the number so it would skip some number (transaction-item-0-something for 1st field, transaction-item-2-something for 2nd field), and it worked fine, wtforms received both of the input.
So this makes me wondering, do id and name not need to be ordered? if so how the wtforms handle the received input then, is just getting the all the ids of item which contains transaction-item-x-something? and just loop through it but also check if the registered id is in there?

Actually, I just dug through the source code and found out the order does not matter, as long as it is a number (.isdigit()), it will loop through all the received data and then put it inside a set which is like python keys in dictionary, so duplicate value will be removed.
Which means html will send every <input> regardless of its id or name is same and let the backend handles it

Related

Is it possible to display dict.values() under the wx.ComboBox but transmit dict.keys() to Bind event?

I'm working on a GUI based on wxpython and have the following question regarding wx.Combobox feature:
Is it possible to display dict.values() in the drop down list and select one of the displayed item but in Bind event send dict.key for this item somehow? I want to present possible options for selection in a user friendly way - example is below.
I think it should be possible with the dictionary but don't know how to realize that.
I'm parsing all Sections from INI file with configparser to a list:
sections= ['123ABC456','123DEF456','123GHI456','123JKL456','123MNO456']
and assign it to Combobox:
self.combo_sections = wx.ComboBox(panel, choices=sections)
self.combo_sections.Bind(wx.EVT_COMBOBOX, self.on_combo_sections)
self.on_combo_sections function is parsing section's options.
What i need is to convert list items to a readable format:
['ABC','DEF','GHI','JKL','MNO']
And display these values under combobox drop down list. Since initial Section's values are essential for further work - based on section name, configparser gets section's options, how can i send original values instead of formatted ones but still display formatted ones under the drop down?
Thanks in advance for any inputs!
wxComboBox supports associating the so called "client data" with each of its items, so you can use this and store the sections value as this client data, then you will be able to get them back whenever you have an index of combobox item.
Alternatively, just keep your own array in combobox items order and store the sections in it -- this is more or less how "client data" is implemented internally anyhow.
The main advantage of using built-in client data support is that it is kept in sync even if the items are added/inserted/deleted to/from the control, but if your combobox doesn't change after creation, using your own data structure should be simpler.

How to ensure that in flask WTForms, a form field is only tested for validity after it has been filled in?

I am trying to create a search form for a website where you can find movie reviews. As such, the user should be able to search for their movie by entering either the movie title or the imdb id or the year of release. However, the user should also not be allowed to search with a blank form.
class SearchForm(FlaskForm):
movie_title = StringField('Movie Title', validators=None)
imdb_id = StringField('IMDB_ID', validators=[Length(min=9,max=9)])
year = IntegerField('Year of Release', validators=[Length(min=4,max=4)])
submit = SubmitField('Search')
This is my current form.
However, due the length validtors in place for imdb_id and year, the user is unable to submit the form if they leave the beforementioned two fields empty as an empty field does not meet the minimum length of 9 and 4 respectively. Is there anyway to work around this such that a form is only validated if it is filled in?
You need to provide a method which checks all the appropriate fields and ensures that at least one has content. Then you can check the prerequisite in the form validation method.
class SearchForm(FlaskForm):
# ....
def any_fields_filled(self):
return any(self.movie_title.data, self.imdb_id.data, self.year.data)
def validate(self):
return self.any_fields_filled()
Then you need to mark the fields as Optional, e.g.:
imdb_id = StringField('IMDB_ID', validators=[Optional(), Length(min=9,max=9)])
If you find yourself needing to consult any_fields_filled() as part of one of the validators you declare on an individual field, you can either use a method instead (validate_field_name()) or you can use the If() validator in the WTForms-Components library.

Limit autocomplete binding after specific number of character been typed

With the jQuery autocomplete, there are properties I can set to only initiate populating the list when a specific number of characters are typed by the user. This helps to reduce the number of items in the list, when ServerFiltering is enabled.
https://docs.telerik.com/aspnet-mvc/helpers/autocomplete/overview
eg.
.Filter("startswith")
.MinLength(3)
However, I don't see anything similar in the Angular component, unless I'm missing something. There is the filterchange event
https://www.telerik.com/kendo-angular-ui/components/dropdowns/autocomplete/filtering/
This assumes that the list has already been populated and data binding has occurred, so that the list can be filtered.
How can I only bind the list when some minimum number of characters has been typed, as in the case with the jQuery widget using ServerBinding?
You can initially data-bind the AutoComplete to an empty array or a collection of preset initial data items, and call the data service to obtain data from the server only after the user has typed a certain number of characters, e.g.:
DOCS
Modified example

Primefaces SelectOneMenu, selection on filter

A user of one of my applications has observed a strange behaviour of the selectOneMenu of Primefaces when using filters.
I have a mask with some fields, some of them are selectOneMenues. I deliver values via a map of Strings and use a filter on them, so the user can search for specific values, in this case currencies.
I have set a default value for this field (as the value in the object behind this field).
So, imagine the following case:
User opens the mask - default value is set on the selectOneMenues
User klicks the arrow on the field and opens the list of available values
he types in some characters and a result is returned (he finds various values with it)
when this happens, in the field, the first value from the result list is set automatically
when the user now selects a random entry, it is set and everything is fine
if the user instead decides he want's the default value back he could either click somewhere on the mask and the value is resetted -> works fine
or he could decide to click on the original value, which was set as default before, in this case the selected value doesn't change but stays the first result from the filter
when now saving the entity behind the form, the original default value is saved
I assume that this happens because when the first result from the filter is set, it just set in the frontend and not in the entity behind the form/ the backend.
Is this a known bug? Do you have any idea how to fix it with a reasonable amount of effort?
I will try to convince my customer to accept this behavior, but I think it's a bit strange, although I admit this is a scenario that's not likely to happen, often. Nevertheless, they found it =)
I am using Primefaces version 5.3.11 (elite version or something like that)

Repeated fileDownload control each displays the same list of files?

I'm creating a student assignment submission application using xpages (8.5.3 FP3 UP1). The details are:
Student can do any number of submission. For each submission, a unique SubmitID will be created. For now,
a. The Form (Submit) - 2 fields only (SubmitID, SoftCopy-RTF type)
b. The View (Submit) - 2 column only (SubmitID, AttachmentNames)
c. Examples of SubmitID are: submit1, submit2
For each submission, student must select what course/subject that submission is for (eg: Maths, Physics etc). Therefore I've already created another form for the teacher to create the list of subject
a. The Form (Subject) - 1 field only (SubjectName)
b. The View (Subject) - 1 column only (SubjectName)
c. Say for now 2 subject has been created - Maths & Physics
I've created 2 xpage:
a. Submit.xsp - to create new submission (using form - Submit)
b. SubmitView.xsp - to display the list of submission (using view - Submit)
For Submit.xsp, here's where my problem begins:
a. The controls in here are as follows: SubmitID EditBox, Repeat Control(inside is a CheckBox, a fileUpload, and a fileDownload)
b. The repeat is based on the list of subject available. The CheckBox title will be each of the SubjectName. In the OnChange event of the fileUpload control, each time after a file is browsed, the checkbox will get checked and this worked.
c. The fileUpload should only update the accompanying fileDownload but instead the attachment that I just uploaded is reflected to every other fileDownload control. I'm doing full refresh on the fileUpload OnChange because that's the only way for the fileDownload to be updated. What is wrong here and what should I do to get the result that I wanted? Saving the document and opening it later in both read-only or edit mode is fine although each subject still display the same list of uploaded files. Both fileUpload and fileDownload are binded to the SoftCopy field.
Unless I'm not correctly interpreting your description, you're binding multiple upload / download controls to the same item ("SoftCopy"). Because these controls are always bound to an item, not to each other, a download control will show any attachments stored within the source item, regardless of how they got there. To limit display of attachments in a download control to those sent via a specific upload control, they must be stored in an item unique to that pair.
For example, if each pair were bound to a subject-specific item, such as "SoftCopy_Maths" or "SoftCopy_Physics", then each download would only display attachments stored within that specific item. You don't know what subjects will be defined, so you can't define these fields on the form, but that's okay... you don't need to. NSF has no schema, so a field need not be defined on a form for a control to be bound to it; the item will be created when the document is saved, even if the form does not define it. Strictly speaking, even the form itself need not exist.
We typically bind controls to items using dot syntax, e.g. #{currentDocument.SoftCopy}, but array syntax is equally valid, e.g. #{currentDocument["SoftCopy"]}. So if you wrap these controls in something that establishes the dynamic item name as a variable or property, you can use array syntax to target that dynamic item. Two of the best ways to do this are data contexts and custom controls.
For instance, you could surround the contents of the repeat in a panel, and define a panel-specific dataContext that associates the variable attachmentItemName with the concatenation of the item name prefix and the specific subject. Your upload and download controls can then be bound to #{currentDocument[attachmentItemName]}.
Alternatively, you can move the same content to a custom control that accepts the data source and item name as properties, in which case your value binding might look like #{compositeData.dataSource[compositeData.attachmentItemName]}.
Apart from very minor differences in runtime performance, either approach is equally valid.

Resources