Python Django: Pass json from view to javascript in template - javascript

I am new to django.
From my findings, I tried this way, but didn't work.
<script type="text/javascript" >
var data = {{json}}
</script>
I am trying to use data table from this website, http://www.datatables.net/manual/data.
<script type="text/javascript" class="init">
var temp = '{{campaignList|escapejs}}'; // should be a list, but becomes a string
alert(typeof temp)
$(document).ready( function () {
$('#campaigns').DataTable({
data: temp,
columns: [
{ data: 'id' },
{ data: 'name' },
{ data: 'date' },
]
});
} );
</script>
When I check the type before passing into datatable, the type becomes string.
I also tried {{campaignList|escapejs}} without quote, but didn't work.
Any suggestion? Thanks.

If campaignList is a json string, pass it to safe filter to prevent escape:
var data = {{ campaignList|safe }};

Related

getting a specific value from JSON.parse() javascript

Hello I am trying to figure out how to get the "changes" value from
{ data: { sequenceStart: 1613141716565, symbol: 'KCS-BTC', changes: { asks: [Array], bids: [] }, sequenceEnd: 1613141716565 }, subject: 'trade.l2update', topic: '/market/level2:KCS-BTC', type: 'message' }
The data is stored in let data = JSON.parse(msg)
I have tried console.log(data.data.changes) but get undefined, im lost because console.log(data.data) seems to get me part way there but not when I add .changes?
Can you check my code below.
I think your msg is not formated correctly , you can compare with my code
<body >
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
var msg = '{"data": { "sequenceStart": "1613141716565", "symbol": "KCS-BTC", "changes": { "asks":[["0","0","1613141798456"]],"bids":[]}, "sequenceEnd": 1613141716565 }, "subject": "trade.l2update", "topic": "/market/level2:KCS-BTC", "type": "message" }';
var data = JSON.parse(msg);
console.log(data.data.changes);
var msg1 = '{"sequenceStart":1613141798456,"symbol":"KCS-BTC","changes":{"asks":[["0","0","1613141798456"]],"bids":[]},"sequenceEnd":1613141798456}';
var data1 = JSON.parse(msg1);
console.log(data1.changes);
});
</script>
</body>

handlebars and JSON data coming from a fetch

I have the code below and have 2 separate issues, so please bear with me on this:
Issue 1 [fetch ?]:
The data displayed doesn't change when the JSON change. Sounds like it's a cache issue as I can't see any HTTP request beside the original one. How can I force the JSON file to be downloaded again each time?
Issue 2 [handlebars ?]: with $(document.body).append(html); in the loop, it keeps re-writing the instead of editing the values. How can I change this?
Here is the code:
javascript.js:
async function fetch_json() {
try {
var resp = await fetch('http://localhost:8000/data.json', {mode: 'cors'});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
html page:
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}}
Name : {{name}} Value : {{value}} <br>
{{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{ "name" : "john doe", "value" : "developer" },{ "name" : "bob boby", "value" : "developer2" }];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
//$(document.body).append(html);
})
}, 1000);
var template = document.getElementById('handlebars-demo').innerHTML;
Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$(document.body).append(html);
</script>
any help would be the most appreciated, thank you!
You should create a DOM element to hold the HTML you are generating. I've created <div id="content"></div> in the example.
You can use $().html() to overwrite the HTML each time instead of appending.
$('#content') selects the DOM element with id=content and then overwrite the HTML inside .html(string) with string.
A common approch to cache busting is to attach a timestamp to the url as a url query param, which I have done by concatenating nocache='+new Date().getTime().
In normal use in production a unique identifier is usually generated per version for each resource after building.
// for demo purposes, overwrite value property with username property
jsonify = x => x.json().then(x => x.map(x => ({ ...x,
value: x.username
})));
async function fetch_json() {
try {
// append timestamp to prevent caching
var resp = await fetch('https://jsonplaceholder.typicode.com/users?nocache=' + new Date().getTime(), {
mode: 'cors'
});
var jsonObj = await jsonify(resp);
return jsonObj;
} catch (error) {
// all errors will be captured here for anything in the try block
console.log('Request failed', error);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.6/handlebars.js" integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8=" crossorigin="anonymous"></script>
<div id="content"></div>
<script id="handlebars-demo" type="text/x-handlebars-template">
<div>
{{#each this}} Name : {{name}} Value : {{value}} <br> {{/each}}
</div>
</script>
<script type="text/javascript">
var test_data = [{
"name": "john doe",
"value": "developer"
}, {
"name": "bob boby",
"value": "developer2"
}];
setInterval(function() {
test_data = fetch_json()
.then(function(result) {
html = templateScript(result);
$('#content').html(html);
})
}, 2000);
var template = document.getElementById('handlebars-demo').innerHTML;
//Compile the template data into a function
var templateScript = Handlebars.compile(template);
var html = templateScript(test_data);
$('#content').html(html);
</script>

setting the value of select by partially specifying the first parameter value

I have 2 select2 controls, both has same data loaded into them
I know that $("#basic").val("44||four||another||data4").trigger("change") will set as "invalid"
I need to set "invalid" just by setting the value as 44.
Likewise when I specify 22 it must specify the selected as "bug"
Note that it should entirely match the first parameter of id string separated by ||, ie when $("#basic").val("44").trigger("change") should not select 444.
<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>
<select id="advanced">
</select>
<select id="basic">
</select>
<script>
var data = [
{
id: "11||first||another||data1",
text: 'enhancement'
},
{
id: "22||second||another||data2",
text: 'bug'
},
{
id: "33||third||another||data3",
text: 'duplicate'
},
{
id: "444||fourfour||another||data44",
text: 'Junk'
},
{
id: "44||four||another||data4",
text: 'invalid'
},
{
id: "55||five||another||data5",
text: 'wontfix'
}
];
$("#advanced").select2({
data: data
})
$("#basic").select2({
data: data
})
$("#basic").val("44").trigger("change")
</script>
</body>
</html>
you could create a selectValue function that wraps your change. That way you'd be able to select an option based on any value of the key.
selectValue = function (value) {
let id = data.find(item => {
let ids = item.id.split("||")
if(ids && ids.indexOf(value) !== -1)
return true
})
// you need this check in case no id was found
if(id) {
id = id.id
$("#basic").val(id).trigger("change")
}
}
//usage
selectValue("44")
If data isn't a global variable make sure to add it as a function argument
selectValue = function (data, value) {
let id = data.find(item => {
let ids = item.id.split("||")
if(ids && ids.indexOf(value) !== -1)
return true
})
// you need this check in case no id was found
if(id) {
$("#basic").val(id.id).trigger("change")
}
}
//usage
selectValue(data, "44")
Also this assumes that another part of your key was just a placeholder. All parts of your id would need to be unique from each other for this to work.
Using attributeStartsWith selector
var data = [{"id":"11||first||another||data1","text":"enhancement"},{"id":"22||second||another||data2","text":"bug"},{"id":"33||third||another||data3","text":"duplicate"},{"id":"444||fourfour||another||data44","text":"Junk"},{"id":"44||four||another||data4","text":"invalid"},{"id":"55||five||another||data5","text":"wontfix"}];
$("#advanced").select2({
data: data
})
$("#basic").select2({
data: data
})
$("#basic option[value^=44]").prop('selected', true).trigger("change")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>
<select id="advanced"></select>
<select id="basic"></select>

Navigating a json file to create desired array for jquery autocomplete

I am programming an autocomplete function for a search bar that features names of places in Norway.
I collect the data from a REST api URL provided by a third party.
Example with input "st" and two results:
{
"sokStatus":{
"ok":"true",
"melding":""
},
"totaltAntallTreff":"81280",
"stedsnavn":[
{
"ssrId":"23149",
"navnetype":"By",
"kommunenavn":"Larvik",
"fylkesnavn":"Vestfold",
"stedsnavn":"Stavern",
"aust":"214841.84",
"nord":"6550500.29",
"skrivemaatestatus":"Godkjent",
"spraak":"NO",
"skrivemaatenavn":"Stavern",
"epsgKode":"25833"
},
{
"ssrId":"506202",
"navnetype":"By",
"kommunenavn":"Stord",
"fylkesnavn":"Hordaland",
"stedsnavn":"Stord",
"aust":"-32194.93",
"nord":"6665261.05",
"skrivemaatestatus":"Godkjent",
"spraak":"NO",
"skrivemaatenavn":"Stord",
"epsgKode":"25833"
}
]
}
I want to have the autocomplete array contain the "stedsnavn" features from all the returned results in the json file. so for the above example it would be [Stavern, Stord].
I built my code based off a template/tutorial i found online. When I run it now the autocomplete suggestion is the "totaltAntallTreff" feature so for the json above it would suggest 81280.
Edit: What I really need to know is how to properly query the json where I now only have response(data). I have tried several methods ($.map, $.each) but whenever I modify my code it ends up giving no autocomplete suggestions.
See my code below
$(function () {
var getData = function (request, response) {
$.getJSON(
"https://ws.geonorge.no/SKWS3Index/ssr/json/sok?antPerSide=5&eksakteForst=false&navn=" + request.term + "*",
function (data) {
(response(data));
});
};
var selectItem = function (event, ui) {
$("#myText").val(ui.item.value);
return false;
}
$("#myText").autocomplete({
source: getData,
select: selectItem,
minLength: 1,
change: function() {
$("#myText").val("").css("display", 2);
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery-ui.css" />
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.0/themes/base/jquery.ui.autocomplete.css" />
<script src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script>
<div id="menu-container">
<input type="text" id="myText" />
</div>
Given the JSON structure provided, you could get the result with the following:
let json_data = {
"sokStatus": {
"ok": "true",
"melding": ""
},
"totaltAntallTreff": "81280",
"stedsnavn": [{
"ssrId": "23149",
"navnetype": "By",
"kommunenavn": "Larvik",
"fylkesnavn": "Vestfold",
"stedsnavn": "Stavern",
"aust": "214841.84",
"nord": "6550500.29",
"skrivemaatestatus": "Godkjent",
"spraak": "NO",
"skrivemaatenavn": "Stavern",
"epsgKode": "25833"
},
{
"ssrId": "506202",
"navnetype": "By",
"kommunenavn": "Stord",
"fylkesnavn": "Hordaland",
"stedsnavn": "Stord",
"aust": "-32194.93",
"nord": "6665261.05",
"skrivemaatestatus": "Godkjent",
"spraak": "NO",
"skrivemaatenavn": "Stord",
"epsgKode": "25833"
}
]
}
let values = json_data.stedsnavn.map(item => item.skrivemaatenavn);
values.forEach(value => {
$("#list").append(`<li>${value}</li>`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="list"><ul>
As to what json_data.stedsnavn.map(item => item.skrivemaatenavn); is doing:
json_data.stedsnavn.map(item => item.skrivemaatenavn);
// Get the "stedsnavn" key from the data, an array
// Map each object in the array to
// its "skrivemaatenavn" key

Load db data into javascript file

I am using Laravel 5.5 and I am trying to work with ag-grid and want to load my data that is coming from my db directly into the Javascript file.
My Migration looks like the following:
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
My Frontend looks like the following:
example.js
// specify the columns
var columnDefs = [
{headerName: "Name", field: "name"},
{headerName: "Created_At", field: "created_at"},
{headerName: "Updated_At", field: "updated_at"}
];
// specify the data
var rowData = [
{name: "TODO 1", created_at: "01.01.2018", updated_at: "05.11.2016"},
{name: "TODO 1", created_at: "01.01.2018", updated_at: "05.11.2016"} // here I would like to replace this dummy data with my db data
];
// let the grid know which columns and what data to use
var gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
onGridReady: function () {
gridOptions.api.sizeColumnsToFit();
}
};
// used in our jasmine test
function selectAllRows() {
gridOptions.api.selectAll();
}
// wait for the document to be loaded, otherwise ag-Grid will not find the div in the document.
document.addEventListener("DOMContentLoaded", function () {
// lookup the container we want the Grid to use
var eGridDiv = document.querySelector('#myGrid');
// create the grid passing in the div to use together with the columns & data we want to use
new agGrid.Grid(eGridDiv, gridOptions);
});
home.blade.php
<html>
<head>
<script src="https://www.ag-grid.com/dist/ag-grid/ag-grid.js"></script>
<script src="example.js"></script>
</head>
<body>
<h1>Ag-Grid Example</h1>
<div id="myGrid" style="height: 115px;width:500px" class="ag-fresh"></div>
<!-- Own Scripts -->
<script src="{{ asset('js/example.js') }}"></script>
</body>
</html>
Any suggestions how to insert my data that I load from the database into the the variable rowData in my example.js file?
I appreciate your replies!
If you're getting the data as a collection, you can just pass the data like this:
<script>
var app = {{ $collection }};
</script>
If it's an array, you can use #json directive:
<script>
var app = #json($array);
</script>
You also could use one of the available packages or put the data into a hidden input HTML element to be able to use this data in JS.

Categories