Package: axf
AXF is a collection of ToscaWidgets2 widgets with resources loading
based on theAXEL Loaderto perform
resources loading so that it is possible to replace resources and load
widgets from ajax requests.Installingaxf can be installed from pypi:easy_install axfor:pip install axfshould just work for most of the usersLayoutsAXF provides a TW2 layout for bootstrap, which is available asaxf.bootstrap.BootstrapFormLayout, to make your forms use
bootstrap3 just have their layout inherit from it:from axf.bootstrap import BootstrapFormLayout

class BootstrapRegistrationForm(Form):
    class child(BootstrapFormLayout):
        text = TextField(label=l_('Text'))

    submit = SubmitButton(value=l_('Register'), css_class='btn btn-default')Using WidgetsTo start using AXF widgets you must add axel to your pages so that
widgets can load their resources:<script src="https://raw.github.com/amol-/axel/master/src/axel.js"></script>The AXEL loader is used instead of standard ToscaWidgets2 resources
injection to make possible to load the forms where they are used throughjQuery.load, as resources loading and injection is performed by
AXEL not response manipulation to append the resources to head or body
is required.If you want to load and submit forms through ajax requests in TurboGears
consider usingtgext.ajaxformsReplacing resources required by the widgets can be performed using
the AXEL loader. Most widgets will depend on jQuery and will load it
from the jquery cdn, if your website uses jQuery and you want to use
a different version of it you can easily replace it using:axel.register('jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');Just place your registerbeforedisplaying the widget and your version
of the library will be used.Each widget will list its resources with the name used to register them
in AXEL, so that you can replace them.AjaxAutoCompleteFieldaxf.widgets.ajax_autocomplete_field.AjaxAutocompleteFieldis field that provides
autocompletion based on select2 backed by a json based api. Each entry has to provide
atextwhich is displayed to the user and anidwhich is submitted with the form.textandidcan coincide for plain text autocompletion.The field requires two parametersdatasourceandinverse_datasourceare respectively
the api to retrieve list of data available for the text written by the user and to retrieve
the text corresponding to an already selected entry (for example in case of validation error
or editing existing data)EXAMPLE:city    = AjaxAutocompleteField(label=l_('City'), validator=validators.Validator(required=True),
                                placeholder=l_('Select City'),
                                datasource=lurl('/ajax/get_cities'),
                                inverse_datasource=lurl('/ajax/city_from_id'))resourcesjquery - jquery libraryselect2 - select2 libraryselect2-style - select2 stylesheetdatasource apiThe API is required to accept a term to search as input, to return a list of{text: "value", id: "id"}entries and a marker to indicate if more data is available:@expose('json')
def get_cities(self, term='', **kw):
    return dict(more=False, results=[dict(text=c[1], id=c[0]) for c in cities_dict.items()])datasource_inverse apiThe API is required to accept an id as argument in the form/apiname/IDand return thetextandidof the corresponding entry:@expose('json')
def city_from_id(self, city_id=None, **kw):
    return dict(text=cities_dict.get(city_id), id=city_id)AjaxSingleSelectFieldaxf.widgets.ajax_single_select.AjaxSingleSelectFieldis a field that loads its data
from a datasource api whenever another field changes. This can be used to implement cascading
single select fields, where options available depend on another selection.The field requires two parametersdatasourcewhich is the api to call to request
for the data available on the value of the other field andoneventwhich is
a tuple with a selector and a javascript event (currently ignored) which specifies
which field should trigger data update. Whenever the  field specified by the selector changes
the single select field is reloaded asking to the datasource for the data.EXAMPLE:category = forms.SingleSelectField(label=l_('Category'), options=Deferred(get_categories),
                                   validator=validators.Validator(required=True))
subcategory = AjaxSingleSelectField(label=l_('Sub Category'), onevent=('#category', 'change'), prompt_text=None,
                                    validator=validators.Validator(required=True),
                                    datasource=lurl('/ajax/get_subcategories'))resourcesjquery - jquery librarydatasource apiThe API is required to accept the current value of the field linked byoneventoption
and return a list of options for theAjaxSingleSelectFieldin the form{name: "name", value: "value"}:@expose('json')
def get_subcategories(self, selected=None, **kw):
    if not selected:
        return dict(options=[])
    return dict(options=[dict(name=c['name'], value=c['id']) for c in subcategories.get(selected, [])])AjaxCascadingFieldaxf.widgets.ajax_cascading_field.AjaxCascadingFieldis a field that loads its data
from a datasource api whenever another field changes. This can be used to implement input fields,
where value depend on another selection.The field requires three parametersdatasourcewhich is the api to call to request
for the data available on the value of the other field,oneventwhich is
a tuple with a selector and a javascript event (currently ignored) which specifies
which field should trigger data update andtypewhich is the type of the input.
Whenever the  field specified by the selector changes the input field is
reloaded asking to the datasourcefor the data.EXAMPLE:category = forms.SingleSelectField(label=l_('Category'), options=Deferred(get_categories),
                                   validator=validators.Validator(required=True))
category_description = AjaxCascadingField(label=l_('Category Description'),
                                          onevent=('#category', 'change'),
                                          prompt_text=None,
                                          validator=validators.Validator(required=True),
                                          datasource=lurl('/ajax/get_category_description'),
                                          type='textarea')resourcesjquery - jquery librarydatasource apiThe API is required to accept the current value of the field linked byoneventoption
and return the value for theAjaxCascadingFieldin the form{value: "value"}:@expose('json')
def get_category_description(self, selected=None, **kw):
    if not selected:
        return dict(value='')
    return dict(value=category[selected].get('description'))WysiHtml5TextAreaaxf.widgets.wysihtml5_text_area.WysiHtml5TextAreais a Text Area with wysiwyg editorWysiHtml5TextArea requires the same parameter of tw2 TextArea, when you render the result
html you must declare CSS rules for alignment:.wysiwyg-text-align-right {
  text-align: right;
}

.wysiwyg-text-align-center {
  text-align: center;
}

.wysiwyg-text-align-left {
  text-align: left;
}WysiHtml5 DocumentationEXAMPLE:description = WysiHtml5TextArea(label=l_('Description'), validator=Validator(required=True), rows=8)resourcesjquery - jquery librarywysihtml5 - WYSIHTML5 librarywysihtml5ParserRules - WYSIHTML5 parserwysihtml5_text_area.css - WYSIHTML5 style