I've just recently learned about:
Form.error_css_class
Form.required_css_class
Docs: https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.Form.error_css_class
So by defining 'error_css_class' and 'required_css_class' in forms
class MyForm(forms.Form):
error_css_class = 'error'
required_css_class = 'required'
name = forms.CharField(...)
I can do:
<div class="field-wrapper {{ form.name.css_classes }}">
...
</div>
This will output:
<div class="field-wrapper required">
...
</div>
However I want to add additional classes to the field, e.g I would like to add 'text name' css class for the "name" field. And reading the docs, I think its possible.
https://docs.djangoproject.com/en/dev/ref/forms/api/#django.forms.BoundField.css_classes
After reading the above I tried to do
self.fields['name'].css_classes('name text')
That doesn't work. I get
'CharField' object has no attribute 'css_classes'
I also tried
name = forms.CharField(css_classes='name text')
TypeError
__init__() got an unexpected keyword argument 'css_classes'
I know I can add extra attr to field widget
self.fields['name'].widget.attrs['class'] = 'name text'
But I want to add css classes to field wrapper.
I could write a custom templatetag... to check field name/type and return appropriate css classes... but if there is something builtin .. I would love to keep my templates clean :-).
Also hardcoding css classes per field is not an option .. as the form fields are dynamic.
Any help will be appreciated.
I figured out how to do it using a custom BoundField
from django.forms import forms
class CustomBoundField(forms.BoundField):
def css_classes(self, extra_classes=None):
# logic for determining css_classes has been omitted
extra_classes = ['name', 'text']
return super(CustomBoundField, self).css_classes(extra_classes=extra_classes)
In my forms, I overide getitem
def __getitem__(self, name):
try:
field = self.fields[name]
except KeyError:
raise KeyError('Key %r not found in Form' % name)
return CustomBoundField(self, field, name)
Related
I'm using react-jsonschema-form 1.2.1 to build a form based on a JsonSchema (v7). I want to automatically trim leading and trailing white spaces from certain text box input fields when a user presses submit on the form. Since the form is completely rendered by the <Form> element of the react-jsonschema-form module, I don't know how I can do this with JavaScript code.
Does react-jsonschema-form have trim capabilities?
Thanks in advance!
There a few different ways to do this, none as simple as flag to trim all string data though.
You can define a custom widget and use the uiSchema to designate specific fields to use this widget. This widget can then trim the value before using the native onChange function to notify the form that its value was changed, refer to: https://react-jsonschema-form.readthedocs.io/en/latest/advanced-customization/#custom-widget-components
You can define your own TextWidget (reserved name, refer to: https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/components/widgets/TextWidget.js => https://github.com/mozilla-services/react-jsonschema-form/blob/master/src/components/widgets/BaseInput.js) and then use this TextWidget to replace all string-type fields:
const myWidgetOverrides = { TextWidget };
render() {
return (
<Form schema={schema}
widgets={this.myWidgetOverrides}
/>
);
}
You can override the validate function inside a new class component that extends the React JSONSchema Form class:
class TrimmedStringForm extends Form {
validate(formData, schema) {
formData = trimAllStrings(formData);
return super.validate(formData, schema);
}
}
or define your own validation function (refer to:
https://react-jsonschema-form.readthedocs.io/en/latest/validation/#custom-validation) to trim all/specific string-type fields from formData before it is passed into the submit function.
When using ui:widget the field will not change the formData of the form, unlike when not using ui:widget any change in the field will be seen in the formData when the form is submitted.
Shall I change the formData of the form manually when the field text changes? if so, is there an example to do so?
Steps to Reproduce
Create the class that represent the custom UI, and use the following for render:
return (
<div >
{this.props.children}
</div>
)
Add to the schema.properties "City": {type: "string", title:"City"}
Add to the schema.properties "City": { "ui:widget": DefaultInput, classNames: "col-md-4"}
Where City is the name of the custom component.
and DefaultInput is the class that represent the custom ui of field.
Expected behavior
To see the value of the custom text field when submit the form:
onSubmit = ({formData}) => console.log(formData);
What I see is:
{City: undefined}
Any idea?
if you use custom 'ui:widgets' you have to use the json-schema-form onChange method when any item's value gets changed and after that you can get changed value from form.
In a project I'm working on we've defined a simple z3c.form, it looks like this.
class IImportCandidateForm(Interface):
csv_file = NamedFile(title=_(u'CSV file'))
class ImportForm(form.Form):
fields = field.Fields(IImportForm)
ignoreContext = True
def updateWidget(self):
super(ImportForm, self).updateWidget()
... snip ...
#button.buttonAndHandler(u'Import')
def handleImport(self, action):
data, errors = self.extractData()
if errors:
self.status = self.formErrorMessage
return
file = data["csv_file"].data
Is there a way to associate a custom css file with this form without first wrapping it in a custom page template with the form?
No, there isn't. Unless you use a form wrapper, the form's template renders only the form and not the entire page.
In you are using this form in a custom view, you have a class style added to the body class (something like template-yourviewname). So you can add you CSS rules to a main CSS resource, loaded in every page, but prefix every rule with .template-yourviewname.
I would like to integrate a date picker in a form. So I created a custom DateTimePickerView like this :
App.DateTimePickerView = Em.View.extend
templateName: 'datetimepicker'
didInsertElement: ->
self = this
onChangeDate = (ev) ->
self.set "value", moment.utc(ev.date).format("dd/MM/yyyy hh:mm")
#$('.datetimepicker').datetimepicker(language: 'fr', format: 'dd/mm/yyyy hh:ii').on "changeDate", onChangeDate
Here is the template :
<script type="text/x-handlebars" data-template-name="datetimepicker" >
<input type="text" class="datetimepicker" readonly>
</script>
In my form I want to bind this component to an attribute of my model (I am using the RestAdapter) :
<script type="text/x-handlebars" id="post/_edit">
<p>{{view Ember.TextField valueBinding='title'}}</p>
<p>{{view App.DateTimePickerView valueBinding='date'}}</p>
</script>
Everything works fine in apparence : the DateTimePicker is well displayed and the value is set inside the input.
But there is a problem in the effective binding : when I send the form, the post param "date" (corresponding to the attribute) is null.
When I look inside the generated html code I can see the following :
<p>
<input id="ember393" class="ember-view ember-text-field" type="text" value="Event 1">
</p>
<div id="ember403" class="ember-view">
<input type="text" class="datetimepicker" readonly="">
</div>
I am not an expert in the global ember structure, but I guess that the id element is important for the binding. In that case, for my component, the ember id is put to the container of my component and not to the input containing the value. So I guess the problem is here.
So what could be the correct way to make it work ?
I just created a working jsfiddle here ; we can see that the modifications in the title field are taken into account but not the modifications in the DateTimePickerView component.
I guess the problem lies in the fact that you where trying to listen on an event fired from the datetimepicker which is not captured, and thus the model value not set.
To make things more solid you should get the datetimepicker current date value in your doneEditing function, just before saving the model back to the store.
Let me show in code what I mean:
window.App.EventController = Ember.ObjectController.extend(
...
doneEditing: ->
// relevant code line
#get("model").set("date_begin", $('.datetimepicker').data('date'))
#set "isEditing", false
#get("store").commit()
...
)
And here your (working) jsfiddle.
Hope it helps
Edit
After reading your comment I've modified the input field inside your datetimepicker template. Please see here an updated jsfiddle that also initializes the input field of the datetimepicker on edit begin when calling edit.
...
edit: ->
#set "isEditing", true
startDate = #get("model").get("date_begin")
#$(".datetimepicker").data({date: startDate}).datetimepicker("update")
...
You are now safe to remove the onDateChange function and do init and save inside your edit and doneEditing respectively, applying format or whatever.
Edit 2
Reading your last comment, this is how you register customEvents for example in your App.DateTimePickerView:
...
customEvents: {
changedate: "changeDate"
}
...
this way Ember will be aware of your custom events. You can register whatever events you want but notice that the keyname is lowercased and the value must have the event name to listen to camelcased. For more infos on custom events see here.
Please see here for another update jsfiddle with the changeDate custom event registered.
I have finally resolved this problem making some controls when using the moment.js library.
Everything was working fine with the binding process of the custom datetimepickerview.
Here is a working jsfiddle : here
The relevant code is here :
window.App.DateTimePickerView = Ember.View.extend(
templateName: 'datetimepicker'
didInsertElement: ->
#this test is important and was the problem
if #.get 'value'
#$('input').val moment.utc(#.get 'value').format('LLL')
onChangeDate = (ev) =>
date = moment.utc(ev.date).format('LLL')
#.set "value", date
#$('.datetimepicker').datetimepicker(format: 'dd/MM/yyyy', pickTime: false).on "changeDate", onChangeDate
)
In a asp.net C# webapp I'm using the CKEditor 3.6.2 and I'm facing the following problem:
In my stylesheet I have a CSS class to use in tables and I'm trying to bring this class already filled in the "Table properties", "Advanced" tab and the "Stylesheet Classes" field.
I want to bring this field filled with the string "blue_table", which is the name of my CSS class. I'm working with the source of the "table" plugin. I have figured out how to change the value of fields like width and height, but the one I want is the "Stylesheet Classes" field.
Do any of you know to to set a default value for this field?
You don't have to edit the ckeditor.js file to customise the editor. You can add the following either to config.js and use it site wide or on any page where you're using CKEditor (inside a script tag as below, after the editor fields you're using).
<script type="text/javascript">
CKEDITOR.on( 'dialogDefinition', function( ev ) {
// Take the dialog name and its definition from the event data.
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
// Check if the definition is from the dialog we're
// interested on (the Table dialog).
if ( dialogName == 'table' ) {
// Set the tab
var advTab = dialogDefinition.getContents( 'advanced');
// Grab the field
var stylesField = advTab.get('advCSSClasses');
// Set the default value
stylesField['default'] = 'blue_table';
}
});
</script>
This is modified from the CKEditor documentation. The hardest part is working out the IDs and names for all the fields used in the dialogs.
Finally I found the answer. This property is in the dialogadvtab, in the property "advCSSClasses". The thing is that this plugin is inside the core js, I mean the ckeditor.js.
I had to do this :
children :
[
{
id : 'advCSSClasses',
att : 'class',
type : 'text',
label : lang.cssClasses,
'default' : 'blue_table',
setup : setupAdvParams,
commit : commitAdvParams
}
]
The "problem" now is that I had to do it in the ckeditor.js, which is not a good practice. The problem is solved, but not int the best way.