Comments (25)
The usecase you describe does not exist. You can only filter select fields individually.
Your right this could be an interesting feature....
To develop this you must develop the template yourself. Then override the edit_template property.
from flask-appbuilder.
I might give it bash. A concrete example is some-one needs to add a new item to a store. They first select an item group say fruits, then select an actual item which then gives a drop down list of apple, banana etc. They then add quantity price etc and submit.
Currently one of the ways to do this is to overload the repr_ of an model to be '%s -%s' %(self.group,self.name) so that a user can manually add the filter in the select2 text box by typing the group, essentially duplicating inputs but still not having to scroll down a long list.
Once you have cascading filters based on inputs you can start doing really fancy stuff like forcing users to only select items that are part of a particular hierarchy all on one simple form.
from flask-appbuilder.
Yes, this is a recurring problem/feature when developing a web app.
One way to do it: when the user selects a 'master' combo the form reloads (or submits to a specific endpoint) the server populates the slave combos and renders the form again.
Another way: when the user selects a 'master' combo fires something like jQuery.getJSON() to a specific endpoint the server returns Json data for the slave combo(s).
What would be the best way to define an API for this feature? regarding of course the current API for ModelView or extending Model from SqlAlchemy. Any ideas ?
from flask-appbuilder.
Option A: Clean less flexible relies on metadata look ups to determine fk and many to many etc.
add_form_cascade_query=[('field_name',['parent1_field_name','parent2_field_name'])]
Option B: Flexible, similar to existing query API
add_form_query_cascade = [('field_name', 'parent field'
SQLAModel,
[['column of related object',FilterObject,'parent field's object's column name']]
)]
Here you should be able to specify multiple field names and a field name multiple times.
from flask-appbuilder.
good suggestions, need some time to think about it
from flask-appbuilder.
I just had a bit of a rethink about this API and the API for filters in general. I came up with the following: Each filter is simply function that accepts a query and then returns a query.
Eg: lambda query: query.join(Mod).filter(Mod.id==55)
Then the api for the cascading filter could just be a function that accepts the current state of the form and a query object and returns a query object.
Eg: lambda query,item: query.join(SomeMod).filter(SomMOd.name=item.som_mod.name)
This api could then technically apply to all filters and user just needs understand the principal of one API.
from flask-appbuilder.
My last comment feels kinda retarded seeing that the basefilter works this way.
from flask-appbuilder.
It's not retarded at all, actually it could be a good idea (it would make a 'cleaner' API).
But it would not be possible (or easy) to implement a solution for searching on lists so dynamic like it is today.
Also, I would like to support other kind of data engines (NoSQL) in the future, this solution makes an abstraction layer that make it possible.
Never feel bad to propose, question or brainstorm, even if you get it wrong. Actually your comments made me think about supporting model joins, and question about the API in general.
from flask-appbuilder.
I don't have much to add, but would enjoy this feature as well. For my purposes, here's the work-around I did.
Table A has two columns that are a composite Foreign key to two columns in Table B. When adding an entry to Table A, the two foreign columns are treated independently by Flask-AppBuilder (using somewhat tricky relationships in the model.py definition) so can select
("X,only-works-with-Y") instead of ("Y,only-works-with-Y"). But when you do the insert, the db foreign key rejects what doesn't work so at least you know -- hopefully the end user knows what combination are valid. Not ideal but functional.
from flask-appbuilder.
I noticed their was some work already done on this.
I have taken another stab at this and realized there would need to be some larger changes. Namely select2 fields would get all their data via ajax.
The filled in form is serialized and passed to the ajax request so that it can be used in the query.
This means the cascade filter can be added. Plus a user can overload the ajax request method and do whatever they want with it.
I will make a pull request when I done.
from flask-appbuilder.
Careful with turning all select2 to ajax, search widget uses it. This is a tricky one...
from flask-appbuilder.
Yes it is turning out to be rather tricky. I have the base set up, But now trying to make sure all those self.add_form.refresh calls don't reset the dynamically set form choices not allowing the form.validate() to succeed. Plus ensuring all the existing base filters work. While trying to continue working only through the datamodel and filters api to ensure everything else works for other db's.
from flask-appbuilder.
If you need any help, don't hesitate.
from flask-appbuilder.
Sorry for taking long. I have this feature for the standard ModelViews. But the search widgets are still a problem. What is the best approach to fixing this is?
If you want you can see the changes in my fork.
https://github.com/philliproso/Flask-AppBuilder/tree/ajax_select_2
from flask-appbuilder.
No problem
Lot of work here, with some major changes. I need to carefully look at this...
from flask-appbuilder.
Looking back, I think it is best to simply show an example of how to create this feature using a custom widget, an additional form field, overloading the pre_add method and the add and edit template.
This would have minimum impact on the existing code base. Currently what I have done in my fork is a bit too disruptive. However I think long term all select 2's should be moved to ajax style requests, and the filters module could probably do with some simplification.
from flask-appbuilder.
Looks great could you write a little tutorial on the docs about this?
from flask-appbuilder.
I will create an example and make a pull request just for the example
from flask-appbuilder.
Great, Thanks.
from flask-appbuilder.
This talks about it here
But I am not sure if compatible with Flask-AppBuilder
from flask-appbuilder.
And with a little of ajax? You have to expose /filtrarplantilla/
(haven't test it in appbuilder, but works with Flask)
function filtrarPlantillaTipus(element) {
var tipus = element.options[element.selectedIndex].value
var llista = document.getElementById("VMTemplate")
$.ajax({
type: "GET",
//~ dataType: "json",
url:"/filtraPlantilla/" + tipus,
success: function(templates)
{
if (templates.length >0) {
var contingut='<option value="">Seleccioneu una entre '+templates.length+' plantilles trobades</option>';
} else {
var contingut='<option value="">Cap plantilla coincident</option>';
}
for (var i=0; i<templates.length; i++) {
contingut=contingut+'<option value="'+templates[i]['id']+'" >'+templates[i]['name']+'</option>';
}
llista.innerHTML=contingut;
}
});
And then in your template:
<tr>
<td>Tipus de plantilla:</td>
<td><select name="VMTemplateType" onchange="filtrarPlantillaTipus(this);">
<option value="">Seleccioneu tipus de plantilla:</option>
<option value="VIMET">vimet</option>
<option value="MEVES">Meves</option>
<option value="PUBLIQUES">Públiques</option>
</select>
</td>
<tr>
<td>Plantilla:</td>
<td><select id="VMTemplate" name="VMTemplate" onchange="selectChange(this);">
<option value="">Seleccioneu plantilla base:</option>
</td>
<tr>
from flask-appbuilder.
Hi again,
One option will be to override the add.html template to add your own javascript code and find what is the id for the html select block. For example:
<select class="my_select2 form-control" data-placeholder="Select Value" id="template_base" name="template_base" style="width:250px"></select>
That in your example will be dummy_city2 or something like that.
But you should call filtrarPlantillaTipus on the first select (location) so I think the only way will be to create your own select widget that calls that function onchange.
This is only an idea.
from flask-appbuilder.
Hi Jvinolas,
I have overriden add.html in my views.py:
class MyGeneralView(ModelView):
datamodel = SQLAInterface(MyDataBase)
add_template = 'add_contacts.html'
Then in my templates/add_contacts.html:
{% extends "appbuilder/general/model/add.html" %}
{% block add_form %}
{{ super() }}
"""
Welcome
This Text is before the add form widget
"""{% endblock %}
But trying to work out how to do what you suggested.
BTW is your syntax above correct? tr don't seem to have closing tags?
And how to expose /filtrarplantilla/? I do have Flask-Restless so maybe in init.py:
api_manager = APIManager(app, flask_sqlalchemy_db=db)
api_manager.create_api(Countries, methods=['GET', 'POST', 'DELETE', 'PUT'])
create one more for localhost:8080/api/filtrarplantilla/
api_manager.create_api(xxx?, methods=['GET', 'POST', 'DELETE', 'PUT'])
And where to place that statement:
select class="my_select2 form-control" data-placeholder="Select Value" id="template_base" name="template_base" style="width:250px">
from flask-appbuilder.
http://devzone.co.in/simple-example-of-dependable-dropdowns-cascading-dropdowns-using-angularjs/
Also, doesn't seem to work above angularJS > 1.0.8 when current stable release is 1.3.15.
in views.py:
class MgntServerGeneralView(ModelView):
datamodel = SQLAInterface(MyTable)
add_template = 'testDropDown.html'
/templates/testDropDown.html:
<title>Cascading Dropdowns in AngularJs :devzone.co.in </title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> <script> function CountryCntrl($scope) { $scope.countries = { 'India': { 'Maharashtra': ['Pune', 'Mumbai', 'Nagpur', 'Akola'], 'Madhya Pradesh': ['Indore', 'Bhopal', 'Jabalpur'], 'Rajasthan': ['Jaipur', 'Ajmer', 'Jodhpur'] }, 'USA': { 'Alabama': ['Montgomery', 'Birmingham'], 'California': ['Sacramento', 'Fremont'], 'Illinois': ['Springfield', 'Chicago'] }, 'Australia': { 'New South Wales': ['Sydney'], 'Victoria': ['Melbourne'] } }; } </script> <div ng-controller="CountryCntrl">
<div>
Region:
<select id="country" ng-model="states" ng-options="country for (country, states) in countries">
<option value=''>Select</option>
</select>
</div>
<div>
Cities: <select id="state" ng-disabled="!states" ng-model="cities" ng-options="state for (state,city) in states"><option value=''>Select</option></select>
</div>
</div>
</body>
in app.js:
function CountryCntrl($scope) {
$scope.countries = {
'India': {
'Maharashtra': ['Pune', 'Mumbai', 'Nagpur', 'Akola'],
'Madhya Pradesh': ['Indore', 'Bhopal', 'Jabalpur'],
'Rajasthan': ['Jaipur', 'Ajmer', 'Jodhpur']
},
'USA': {
'Alabama': ['Montgomery', 'Birmingham'],
'California': ['Sacramento', 'Fremont'],
'Illinois': ['Springfield', 'Chicago']
},
'Australia': {
'New South Wales': ['Sydney'],
'Victoria': ['Melbourne']
}
};
}
But this doesn't tie in with Flask-AppBuilder SQLAlchemy with look and feel and database.
from flask-appbuilder.
So is it a challenge to implement in Flask-AppBuilder? Or is it quite straight forward to add, say AngularJS logic to the front end by overriding select widget?
from flask-appbuilder.
Related Issues (20)
- ModuleNotFoundError in `flask fab create-app` with python 3.12 HOT 3
- Just released WTForms 3.1.0 break FAB widgets (including just released 4.3.8)
- Issue: FAB cannot read tables with primary key columns with spaces HOT 2
- get 404 response when using example api code HOT 3
- it's possible to change the table name for user/role/permission tables? HOT 2
- Unable to retrive more pages from ModelRestApi HOT 1
- Is it possible to add both AUTH_DB and AUTH_OAUTH at a time ? HOT 1
- Order of Lists in Multiview HOT 3
- Make Google OAuth login work for users created using `create-user`
- flask fab create-app returns error HOT 3
- When redefining created and changed by fks to change the custom view, they get nullified HOT 2
- Actual way for Keycloak integration
- Can we add optimistic locking in user land?
- actions on child/related views (multiple childs exist) not working properly HOT 2
- TypeError occured on front-end when using the 'extra_classes=readonly' argument for the Select2Widget HOT 1
- Cannot use anonymous user with LDAP
- user_registration error
- Add support for marshmallow-sqlalchemy 1.0.0
- Support Personal Access Tokens in addition to AUTH_TYPE HOT 1
- [Request] Implement compatibility for Flask 3.0.2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from flask-appbuilder.