Issue
I´m querying data from my db and save it in a list. On my .html template i have 2 select2 fields, which are both in a form. In one i want to add the data in the select2 field using flask and ajax. Any help is appreciated!!
Here is my code i´ve done so far.
app.py
@application.route("/autocomplete",methods=["POST","GET"])
def autocomplete():
#getting topic names
q1="MATCH (n:Topic) RETURN n"
nodes=neo4j_session.run(q1)
node_result = nodes.data()
node_raw=list()
for d in node_result:
for key in d:
node_raw.append(d[key])
nodes=list()
for i in node_raw:
nodes.append(i['Name'])
return return json.dumps(nodes)
@application.route('/index', methods=["POST","GET"])
def index():
if request.method == "POST":
df=pd.DataFrame()
nodes=autocomplete()
topic=request.form.get("topic")
return render_template("dashboard.html",nodes=nodes)
return render_template("dash.html")
dashboard.html
<form method="get|post" name ="myform" autocomplete="on">
<select name="topic" ></select>
<select name="relationship"></select>
<br>
<br>
<button id="frmbtn" type="submit" class="btn btn-primary" >Show Result</button>
</form>
select2call:
(function() {
const content2= {{ nodes|tojson|safe}}
$('select[name="topic"]').select2({
data: content2,
width: '25%',
multiple: true, //if multiple should be selected, set true
placeholder: 'Select a Department'
});
$('form[name="myform"]').bind(function(evt) {
//evt.preventDefault();
$.ajax({
method: 'POST',
url: '/index',
data:$(this).serialize(),
success:function(){
}
})
});
});
})({{ url_for('.index') | tojson }});
Solution
The following example shows you how to add data to your select2 field using neo4j.
To provide the data for the select field using AJAX, you need a list of objects that have the properties id and text. This list is a property called results within a parent object. Later, the ids are assigned to the respective value attribute of the option element and the text is embedded.
{
"results": [
{ "id": 1, "text": "one" },
{ "id": 2, "text": "two" }
]
}
For this purpose, a database request is made in the example, in which the id and the name of the node are requested, whose name contains the sent string. The id is assigned the alias id, the name the alias text. The result is then sorted by the name property.
def work(tx, qs):
return tx.run(
'MATCH (n:Topic) '
'WHERE toLower(n.name) CONTAINS toLower($qs) '
'RETURN id(n) AS id, n.name AS text '
'ORDER BY n.name',
qs=qs
).data()
Afterwards, the data obtained from the database is converted to dicts and sent back to the client in JSON format, with the list present as a nested results property.
If the user now sends the form to the server, all nodes whose ids are contained in the sent list are queried. Their names are extracted and returned again as a list of dicts of a nested structure in JSON format
def work(tx, ids):
return tx.run(
'MATCH (n:Topic) '
'WHERE id(n) IN $ids '
'RETURN n.name AS name '
'ORDER BY n.name',
ids=ids
).data()
The received result is displayed on the page.
Flask (app.py)
from flask import (
Flask,
g,
jsonify,
render_template,
request
)
from neo4j import (
GraphDatabase
)
url = 'bolt://localhost:7687'
username = 'neo4j'
password = 'test'
app = Flask(__name__)
driver = GraphDatabase.driver(url, auth=(username, password))
def get_db():
if not hasattr(g, 'neo4j_db'):
g.neo4j_db = driver.session()
return g.neo4j_db
@app.teardown_appcontext
def close_db(error):
if hasattr(g, 'neo4j_db'):
g.neo4j_db.close()
@app.route('/')
def index():
return render_template('index.html')
@app.route('/topics')
def get_topics():
def work(tx, qs):
return tx.run(
'MATCH (n:Topic) '
'WHERE toLower(n.name) CONTAINS toLower($qs) '
'RETURN id(n) AS id, n.name AS text '
'ORDER BY n.name',
qs=qs
).data()
db = get_db()
data = db.read_transaction(work, request.args.get('q', ''))
return jsonify(results=data)
@app.post('/data')
def data():
def work(tx, ids):
return tx.run(
'MATCH (n:Topic) '
'WHERE id(n) IN $ids '
'RETURN n.name AS name '
'ORDER BY n.name',
ids=ids
).data()
db = get_db()
data = db.read_transaction(work, request.form.getlist('topics', type=int))
return jsonify(results=data)
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Index</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
</head>
<body>
<form name="my-form" method="post">
<select name="topics"></select>
<button type="submit">Submit</button>
</form>
<output name="result"></output>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
<script type="text/javascript">
(function(topicsUrl, dataUrl) {
$(document).ready(function() {
$('select[name="topics"]').select2({
ajax: {
url: topicsUrl,
dataType: 'json'
},
width: '25%',
multiple: true,
placeholder: 'Enter another topic'
});
$('form[name="my-form"]').submit(function(event) {
event.preventDefault();
$.ajax({
method: 'POST',
url: dataUrl,
data: $(this).serialize()
}).done(function(data) {
$('output[name="result"]').html(JSON.stringify(data.results));
});
});
});
})(
{{ url_for('get_topics') | tojson }},
{{ url_for('.data') | tojson }}
);
</script>
</body>
</html>
Answered By - Detlef
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.