I included a Vue form component in one of my Django templates. Now, I would like to send a CSRF token along with the data, since Django views require a CSRF token. Is there any way I can include it in my Vue form?
Here is my component:
<template>
<form #submit.prevent="formSubmit()">
<input type="text" class="form-control" v-model="amount">
<br>
<input type="text" class="form-control" v-model="price">
<br>
<button class="btn btn-primary" style="width: 100%">BUY</button>
</form>
</template>
<script>
import axios from 'axios'
export default {
mounted() {
console.log('Component mounted.')
},
data() {
return {
name: '',
description: '',
output: ''
};
},
methods: {
formSubmit() {
let currentObj = this;
axios.post('MY_URL', {
price: this.price,
amount: this.amount,
})
.then(function (response) {
currentObj.output = response.data;
}.bind(this))
.catch(function (error) {
currentObj.output = error;
});
},
}
}
</script>
First, acquire the token from the csrftoken cookie:
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
...or from querying the document:
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value
Then, add the token value to your POST header:
axios.post('MY_URL', {
price: this.price,
amount: this.amount,
}, {
headers: {
'X-CSRFToken': csrftoken
}
})
In Sharepoint 2013, is it possible to drag and drop a file (.jpg , .pdf, .png) to a custom list as an attachment? If so, can this be achieved by using a script (JS, jquery)? So, if a user is reporting a bug (NewForm.aspx), and he has a screenshot of the error message saved as a .jpg, I would want him to be able to drop this file into a drop zone on the form.
Can this scenario work - I would be very grateful for your suggestions?
Here is my tested code.
<style type="text/css">
.droppable {
background: #08c;
color: #fff;
padding: 100px 0;
text-align: center;
}
.droppable.dragover {
background: #00CC71;
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
function makeDroppable(element, callback) {
var input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('id', 'dragdropContent');
input.setAttribute('multiple', true);
input.style.display = 'none';
input.addEventListener('change', triggerCallback);
element.appendChild(input);
element.addEventListener('dragover', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.add('dragover');
});
element.addEventListener('dragleave', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
});
element.addEventListener('drop', function (e) {
e.preventDefault();
e.stopPropagation();
element.classList.remove('dragover');
triggerCallback(e);
});
element.addEventListener('click', function () {
input.value = null;
input.click();
});
function triggerCallback(e) {
var files;
if (e.dataTransfer) {
files = e.dataTransfer.files;
} else if (e.target) {
files = e.target.files;
}
callback.call(null, files);
}
}
$(function () {
String.prototype.format = function () {
var args = [].slice.call(arguments);
return this.replace(/(\{\d+\})/g, function (a) {
return args[+(a.substr(1, a.length - 2)) || 0];
});
};
var element = document.querySelector('.droppable');
function callback(files) {
// Here, we simply log the Array of files to the console.
//console.log(files);
var fileName = files[0].name;
// Construct the endpoint. mydoc is document library name
var reader = new FileReader();
reader.file = files[0];
reader.onload = function (event) {
var arrayBuffer = event.target.result;
//var fileData = '';
//var byteArray = new Uint8Array(arrayBuffer);
//for (var i = 0; i < byteArray.byteLength; i++) {
// fileData += String.fromCharCode(byteArray[i]);
//}
var fileEndpoint = String.format(
"{0}/_api/web/lists/getByTitle('{1}')/RootFolder/files" +
"/add(overwrite=true, url='{2}')",
_spPageContextInfo.webAbsoluteUrl, 'mydoc', fileName);
//Add the file to the SharePoint folder.
$.ajax({
url: fileEndpoint,
type: "POST",
data: arrayBuffer,//fileData,
processData: false,
headers: {
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
"accept": "application/json;odata=verbose",
"content-length": arrayBuffer.byteLength,
//"IF-MATCH": itemMetadata.etag,
//"X-HTTP-Method": "MERGE"
},
success: function (data, b, c) {
alert('File upload succeeded.');
},
error: function (a, b, err) {
alert('Error: ' + err.responseText);
}
})
};
reader.onerror = function (e) {
alert(e.target.error);
}
var arrayBuffer = reader.readAsArrayBuffer(files[0]);
}
makeDroppable(element, callback);
})
</script>
<div class="droppable">
<p>Drag files here or click to upload</p>
</div>
Update:
This is the control in my test sample:
You could try to debug is any JS error in your page.
I am using ReactJs and Mocha and trying few unit tests. I have two mandatory form fields First Name and Last Name. I am trying to test the validation where if only one field is entered, the other field displays the missing value validation error.
Below code simulates the changes to the value and simulates the form submit.
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
The changed value is reflected in the event handlers on First Name. But, not in the test. So, both the fields display missing value validation failing my test.
What I could be doing wrong here?
Below are code:
//NameForm.jsx
'use strict';
var React=require('react')
var forms = require('newforms')
var NameForm = forms.Form.extend({
firstName: forms.CharField({maxLength: 100, label: "First name(s)"}),
lastName: forms.CharField({maxLength: 100, label: "Last name"}),
cleanFirstName(callback) {
callback(null)
},
render() {
return this.boundFields().map(bf => {
return <div className={'form-group ' + bf.status()}>
<label className="form-label" htmlFor={bf.name}>
<span className="form-label-bold">{bf.label}</span>
</label>
{bf.errors().messages().map(message => <span className="error-message">{message}</span>)}
<input className="form-control" id={bf.name} type="text" name={bf.name} onChange = {this.onChangeHandler}/>
</div>
})
}
, onChangeHandler: function(e){
console.log("onchnage on input is called ----- >> " + e.target.value)
}
})
module.exports = {
NameForm
}
Here is NamePage.jsx:
'use strict';
var React = require('react')
var {ErrorObject} = require('newforms')
var superagent = require('superagent-ls')
var {API_URL} = require('../../constants')
var {NameForm} = require('./NameForm')
var NamePage = React.createClass({
contextTypes: {
router: React.PropTypes.func.isRequired
},
propTypes: {
data: React.PropTypes.object,
errors: React.PropTypes.object
},
statics: {
title: 'Name',
willTransitionTo(transition, params, query, cb, req) {
if (req.method != 'POST') { return cb() }
superagent.post(`${API_URL}/form/NameForm`).send(req.body).withCredentials().end((err, res) => {
if (err || res.serverError) {
return cb(err || new Error(`Server error: ${res.body}`))
}
if (res.clientError) {
transition.redirect('name', {}, {}, {
data: req.body,
errors: res.body
})
}
else {
transition.redirect('summary')
}
cb()
})
}
},
getInitialState() {
return {
client: false,
form: new NameForm({
onChange: this.forceUpdate.bind(this),
data: this.props.data,
errors: this._getErrorObject()
})
}
},
componentDidMount() {
this.setState({client: true})
},
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
var errorObject = this._getErrorObject(nextProps.errors)
this.refs.nameForm.getForm().setErrors(errorObject)
}
},
_getErrorObject(errors) {
if (!errors) { errors = this.props.errors }
return errors ? ErrorObject.fromJSON(errors) : null
},
_onSubmit(e) {
e.preventDefault()
var form = this.state.form
form.validate(this.refs.form, (err, isValid) => {
if (isValid) {
this.context.router.transitionTo('name', {}, {}, {
method: 'POST',
body: form.data
})
}
})
},
render() {
return <div>
<h1 className="heading-large">Your name</h1>
<form action='name' method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
{this.state.form.render()}
<button type="submit" className="button">Next</button>
</form>
</div>
},
})
module.exports = NamePage
Here is NameTest.js :
//NameTest.js
var React = require('react')
var ReactAddons = require('react/addons')
var TestUtils = React.addons.TestUtils
var InputFieldItem = require('../../src/page/name/NamePage')
describe('Name page component', function(){
var renderedComponent;
before('render element', function() {
console.log("*** in before")
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
});
it('Only First Name entered should display one error message', function() {
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
var formElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'form').getDOMNode()
var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[0].getDOMNode()
var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[1].getDOMNode()
var buttonElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'button').getDOMNode()
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(renderedComponent, 'error-message')
console.log("First name value is :|"+ firstNameElement.value + "|")
expect (errorSpans.length).to.equal(1)
})
});
I not sure why the return is not being passed to the component template. It's listening and the value is found but its not working.
return result.resources; is not returning the data when result.resoures has an array of objects.
here is the autocomplete template auto-complete.hbs
<ul>
<li class='row input-group-lg'>
{{input type="text" value=searchText placeholder="Enter Street Address" class='col-md-6 col-md-offset-3 col-xs-12 street-address'}}
</li>
</ul>
<ul>
{{#each searchResults}}
<li>{{this.name}}</li>
{{/each}}
</ul>
here is auto-complete.js
import Ember from 'ember';
export default Ember.Component.extend({
searchText: null,
searchResults: function() {
var searchText = this.get('searchText');
if(!searchText) {
return;
}
Ember.$.ajax({
url: "http://dev.virtualearth.net/REST/v1/Locations",
dataType: "jsonp",
data: {
key: "",
q: searchText
},
jsonp: "jsonp"
}).then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
return result.resources;
}
}
});
}.property('searchText')
});
The code block
.then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
return result.resources;
}
}
will return from the promise and will not return the value for the computed property, which obviously means that you are not returning anything for the CP.
A possible work around can be
searchResults: function() {
var searchText = this.get('searchText');
var searchResults = Ember.ArrayProxy.create();
if(!searchText) {
return;
}
Ember.$.ajax({
url: "http://dev.virtualearth.net/REST/v1/Locations",
dataType: "jsonp",
data: {
key: "",
q: searchText
},
jsonp: "jsonp"
}).then(function(data) {
var result = data.resourceSets[0];
if (result) {
if (result.estimatedTotal > 0) {
searchResults.set('content',result.resources);
}
}
});
return searchResults;
}.property('searchText')
You can create an arrayproxy and return the arrayproxy for the CP. Upon completion of the promise, set the result as content to the arrayproxy, which will update the template.
I don't understand why, but Django has ceased including the csrf cookie in responses. I have the middleware enabled, have tried using RequestContext and am using render. I have even tried using the csrf_protect and requires_csrf_token decorators.
I am working on a dev server right now, and I can print the context after I use RequestContext, and it seems to include a csrf_token.
But when I look at the actual headers using Chrome's inspect element, the csrf_token isn't there, also when I use the console and type in "document.cookie" that does not have the csrf token.
HELP!
Here's an example view
#requires_csrf_token
def index(request):
context = RequestContext(request, {'foo':'bar'})
print context
return render(request, 'index.html', context)
The CSRF token seems to be in the context:
{u'csrf_token': <django.utils.functional.__proxy__ object at 0x1025ab990>}, ...
But it fails to make its way through...
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Cookie:__utma=96992031.468590559.1369255550.1369255550.1369255550.1; __utmb=96992031.17.10.1369255550; __utmc=96992031; __utmz=96992031.1369255550.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Host:127.0.0.1:8000
Referer:http://127.0.0.1:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31
UPDATE: Here is the template I'm using:
{% extends "base.html" %}
{% block hello %}
Basic Stock Event Charts
{% endblock %}
{% block content %}
<div id="leftsidebar">
<p>Use this tool to graph a time series data for a security. You can graph a security and
four other features such as volume, call option volume, or implied volatility. The tool will
zoom in on the date of interest to show the target audience the changes in the selected
vaiables preceeding the event. Because of large movement in variables before the announcement,
it may be helpful to use the minimum and maximum tools to zoom in on smaller movements ahead
of the event. </p>
<div class="ui-widget inline">
<label for="securities">1. Type in a ticker symbol</label>
<input id="securities">
</div>
<div class="inline"><input type="button" id="reload" value="Reset" class="hide" /></div>
<label for="datepicker">2. Pick your event date of interest.</label>
<input type="text" id="datepicker" disabled />
<label>3. Choose other series to graph.</label>
<p><strong>Primary Axis</strong></p>
Left Axis: <select id="series1" class="selectpicker span2" disabled><option value=""></option></select>
<div id="series1minmax" class="hide">
Min <input type="text" id="min1" class="input-mini" />
Max <input type="text" id="max1" class="input-mini" />
</div><input type="button" id="addaxes1" value="Graph" class="hide" />
<input type="button" id="removeaxes1" value="Remove" class="hide" /><br />
<br/>Right Axis: <select id="series2" class="selectpicker span2" disabled><option value=""></option>></select>
<div id="series2minmax" class="hide">
Min <input type="text" id="min2" class="input-mini" />
Max <input type="text" id="max2" class="input-mini" />
</div><input type="button" id="addaxes2" value="Graph" class="hide" />
<input type="button" id="removeaxes2" value="Remove" class="hide" /><br />
<input type="button" id="addextraaxis" value="Add Additional Axis" disabled/><br />
<div id="additional" class="hide">
<p><strong>Additional Axis</strong></p>
Left Axis: <select id="series3" class="selectpicker span2" disabled><option value=""></option></select>
<div id="series3minmax" class="hide">
Min <input type="text" id="min3" class="input-mini" />
Max <input type="text" id="max3" class="input-mini" />
</div><input type="button" id="addaxes3" value="Graph" class="hide" />
<input type="button" id="removeaxes3" value="Remove" class="hide" /><br />
<br/>Right Axis: <select id="series4" class="selectpicker span2" disabled><option value=""></option>></select>
<div id="series4minmax" class="hide">
Min <input type="text" id="min4" class="input-mini" />
Max <input type="text" id="max4" class="input-mini" />
</div><input type="button" id="addaxes4" value="Graph" class="hide" />
<input type="button" id="removeaxes4" value="Remove" class="hide" /><br />
</div>
</div>
<div id="rightsidebar">
<div id="container" class="hide"></div>
</div>
</div>
<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script src="http://code.highcharts.com/stock/highcharts-more.js"></script>
<script>
$(function() {
$("#removefromchart").click(function() {
var conceptName = $('#savedseries').find(":selected").remove();
});
$("#reload").click(function() {
location.reload();
})
$("#addextraaxis").click(function() {
$("#additional").removeClass("hide");
this.disabled = true
$("#addextraaxis").addClass("hide");
var chart = $("#container").highcharts();
chart.setSize(null, 650);
})
});
$(function() {
$("#series1").change(function() {
$("#addaxes1").removeClass("hide");
});
$("#series2").change(function() {
$("#addaxes2").removeClass("hide");
});
$("#series3").change(function() {
$("#addaxes3").removeClass("hide");
});
$("#series4").change(function() {
$("#addaxes4").removeClass("hide");
});
});
$(function() {
function setExtreme(isMin, axis, value) {
console.log("fired");
var chart = $('#container').highcharts();
if (isMin) {
console.log(value + " " + chart.yAxis[axis].getExtremes()["max"])
chart.yAxis[axis].setExtremes(value, chart.yAxis[axis].getExtremes()["max"]);
} else {
console.log(value + " " + chart.yAxis[axis].getExtremes()["min"])
chart.yAxis[axis].setExtremes(chart.yAxis[axis].getExtremes()["min"], value);
}
console.log(value);
}
function getAxisNumber(series) {
var indicies = {}
$.each(chart.yAxis, function(index, element) {
indicies[element.options.id] = index;
console.log(element.options.id);
});
return indicies[series]
}
$("#max1").change(function() {setExtreme(0, getAxisNumber("#series1"), this.value)});
$("#min1").change(function() {setExtreme(1, getAxisNumber("#series1"), this.value)});
$("#max2").change(function() {setExtreme(0, getAxisNumber("#series2"), this.value)});
$("#min2").change(function() {setExtreme(1, getAxisNumber("#series2"), this.value)});
$("#max3").change(function() {setExtreme(0, getAxisNumber("#series3"), this.value)});
$("#min3").change(function() {setExtreme(1, getAxisNumber("#series3"), this.value)});
$("#max4").change(function() {setExtreme(0, getAxisNumber("#series4"), this.value)});
$("#min4").change(function() {setExtreme(1, getAxisNumber("#series4"), this.value)});
});
$(function()
{
$("#removefromchart").click(function()
{
var conceptName = $('#savedseries').find(":selected").remove();
});
});
$(function() {
function addPlotLine(ts) {
var chart = $('#container').highcharts();
chart.xAxis[0].addPlotBand({
from: ts,
to: ((ts + 86400000) * 365),
color: 'rgba(68, 170, 213, 0.2)',
id: 'tsband'
});
chart.xAxis[0].addPlotLine({
value: ts,
color: 'rgb(255, 0, 0)',
width: 1,
id: 'tsline'
});
chart.xAxis[0].setExtremes(ts - (86400000 * 30), ts + 86400000)
}
function removeEventIfExists() {
var chart = $("#container").highcharts()
chart.xAxis[0].removePlotBand("tsband");
chart.xAxis[0].removePlotLine("tsline");
}
$("#datepicker").datepicker({
showButtonPanel: true, /*added by oussama*/
changeMonth: true, /*added by oussama*/
changeYear: true, /*added by oussama*/
dateFormat: 'yy-mm-dd',
onSelect: function (dateText, inst) {
utcDate = Date.UTC(dateText.split("-")[0], dateText.split("-")[1] - 1, dateText.split("-")[2]);
removeEventIfExists();
addPlotLine(utcDate);
$("#series1").removeAttr("disabled");
$("#series2").removeAttr("disabled");
$("#series3").removeAttr("disabled");
$("#series4").removeAttr("disabled");
$("#addextraaxis").removeAttr("disabled");
var ticker = $("#securities").val();
var date = $("#datepicker").val();
chart.setTitle({text: ticker + " around " + date});
}
});
});
$(function() {
function createChart() {
var chart = $('#container').highcharts();
var options = {chart: {
renderTo: 'container',
height: 450,
},
events: {
load: function(event) {
this.setExtremes();
}
},
rangeSelector: {
enabled: false,
},
exporting: {
enabled: false,
},
navigator: {
enabled: true,
series: { id: 'navigator' },
},
yAxis: [{
title: {
text: 'Price'
},
height: 150,
}],
},
chart = new Highcharts.StockChart(options);
return chart;
}
$("#securities").autocomplete({
source: "/api/get_securities/",
minLength: 1,
select: function(event, ui) {
var ticker = ui.item.label;
getSeries(ticker);
chart = createChart();
getTimeSeriesData(ticker + "|PX_LAST", 0);
$('#container').show();
$('#datepicker').removeAttr("disabled");
$('#reload').removeClass("hide");
chart.setTitle({text: ticker});
this.disabled = 'disabled';
},
});
});
$(function() {
function removeAxes(id) {
var chart = $('#container').highcharts();
chart.get(id).remove();
}
$("#removeaxes1").click(function() {
console.log("removeaxes1 clicked");
removeAxes("#series1");
$("#removeaxes1").addClass("hide");
$("#series1minmax").addClass("hide");
$("#series1minmax").removeClass("inline");
$("#series1").val("");
$("#min1").val("");
$("#max1").val("");
$("#series1").removeAttr("disabled");
});
$("#removeaxes2").click(function() {
console.log("removeaxes2 clicked");
removeAxes("#series2");
$("#removeaxes2").addClass("hide");
$("#series2minmax").addClass("hide");
$("#series2minmax").removeClass("inline");
$("#series2").val("");
$("#min2").val("");
$("#max2").val("");
$("#series2").removeAttr("disabled");
});
$("#removeaxes3").click(function() {
console.log("removeaxes3 clicked");
removeAxes("#series3");
$("#removeaxes3").addClass("hide");
$("#series3minmax").addClass("hide");
$("#series3minmax").removeClass("inline");
$("#series3").val("");
$("#min3").val("");
$("#max3").val("");
$("#series3").removeAttr("disabled");
});
$("#removeaxes4").click(function() {
console.log("removeaxes4 clicked");
removeAxes("#series4");
$("#removeaxes4").addClass("hide");
$("#series4minmax").addClass("hide");
$("#series4minmax").removeClass("inline");
$("#series4").val("");
$("#min4").val("");
$("#max4").val("");
$("#series4").removeAttr("disabled");
});
function addSeries(id, minMaxId, isOpposite, isAdditional) {
var chart = $('#container').highcharts();
indicies = {}
console.log('climlckedaddaxes');
var series = $(id).val()
var top = 210
if (isAdditional) top = 380
var options = {
title: {
text: series.split("|")[1]
},
top: top,
height: 150,
opposite: isOpposite,
id: id,
offset: -30
}
chart.addAxis(options)
$.each(chart.yAxis, function(index, element) {
indicies[element.options.id] = index;
console.log(element.options.id);
});
getTimeSeriesData(series, indicies[id]);
$(minMaxId).removeClass("hide")
$(minMaxId).addClass("inline")
}
$("#addaxes1").click(function() {
addSeries('#series1', "#series1minmax", false, false);
$("#addaxes1").addClass("hide")
$("#removeaxes1").removeClass("hide")
$("#series1").attr("disabled", "disabled")
});
$("#addaxes2").click(function() {
addSeries('#series2', "#series2minmax", true, false);
$("#addaxes2").addClass("hide")
$("#removeaxes2").removeClass("hide")
$("#series2").attr("disabled", "disabled")
});
$("#addaxes3").click(function() {
addSeries('#series3', "#series3minmax", false, true);
$("#addaxes3").addClass("hide")
$("#removeaxes3").removeClass("hide")
$("#series3").attr("disabled", "disabled")
});
$("#addaxes4").click(function() {
addSeries('#series4', "#series4minmax", true, true);
$("#addaxes4").addClass("hide")
$("#removeaxes4").removeClass("hide")
$("#series4").attr("disabled", "disabled")
});
})
$('#addtochart').click(function() {
var selectedValues = $('#seriesselector').val();
$.each(selectedValues, function(index, value) {
$('#savedseries').append($('<option>', {
value: value,
text: value,
selected: true,
}));
$('#seriesselector option[value="' + value +'"]').remove();
});
});
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function parseDate(inputdate, value) {
var date = inputdate;
var year = parseInt(date.split("-")[0]);
var month = parseInt(date.split("-")[1]) - 1;
var day = parseInt(date.split("-")[2]);
var outputdate = Date.UTC(year, month, day);
if (year == 2013 && month == 3) {
//console.log(inputdate, outputdate, value);
}
return outputdate;
};
function getTimeSeriesData(seriesName, axis) {
var csrftoken = getCookie('csrftoken');
console.log('csrftoken is :: ' + csrftoken);
$.ajax({ // create an AJAX call...
beforeSend: function(xhr, settings) {
var csrftoken = getCookie('csrftoken');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
},
data: {'seriesName': seriesName }, // get the form data
type: 'POST',
url: '/api/get_time_series_data/',
success: function(response) { // on success..
console.log(response);
var series = {}
series['name'] = response[0]['series_name'];
series['data'] = []
$.each(response, function(index, value) {
series['data'][index] = [
parseDate(response[index]['date'], response[index]['value']),
parseFloat(response[index]['value'])
];
});
series['yAxis'] = axis
series['marker'] = {
enabled : true,
radius : 3
}
var chart = $('#container').highcharts();
chart.addSeries(series);
var nav = chart.get('navigator');
if (axis == 0) nav.setData(series['data']);
}
});
return false;
};
function getSeries(ticker) {
var csrftoken = getCookie('csrftoken');
$.ajax({ // create an AJAX call...
beforeSend: function(xhr, settings) {
var csrftoken = getCookie('csrftoken');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
},
data: {'ticker': ticker }, // get the form data
type: 'POST',
url: '/api/get_series/',
success: function(response) { // on success..
$('#seriesselector').empty()
for (var i = 0; i < response.length; i++) {
if (response[i].value == 'PX_LAST') continue;
$('#series1').append($('<option>', {
value: ticker + "|" + response[i].value,
text: response[i].value
}));
$('#series2').append($('<option>', {
value: ticker + "|" + response[i].value,
text: response[i].value
}));
$('#series3').append($('<option>', {
value: ticker + "|" + response[i].value,
text: response[i].value
}));
$('#series4').append($('<option>', {
value: ticker + "|" + response[i].value,
text: response[i].value
}));
}
}
});
return false;
};
</script>
{% endblock %}
Turns out you need the
{% csrf_token %}
regardless of whether or not you are posting a html form. I was only doing AJAX requests, but Django won't include the token in the response header unless it sees it the template.