Read and Display values from json using ajax - ajax

Im trying to get data from a .json file that is recieved via post method to a external server, using ajax function and display it all on html (tags and data).
I can get the json data and display it via console log, however im not able to iterate over it, or simply display in on the html side.
I've tryed to create a public array and push the response to it, create a function, etc.. but looks like ajax function loads after it, and there's no data at all, then i've tried to concat a string with the values that i get on console, but no success.
I can't even get the actual data, only the tags. Im a little bit confused here. Can some one help me?
Here's my code and what it displays on console.
component.hmt:
<ul>
<li>{{res}}</li>
</ul>
component.ts
public res = "";
ngOnInit() {
let settings = {
"async": true,
"crossDomain": true,
"url": "ip/to/api",
"context": this, //added this
"method": "POST",
"data": "\"dataApi\"",
};
$.ajax(settings).done(function (response) {
console.log(response);
this.res = response; //added this
for(let i in response)
{
//console.log(i);
this.res += i + " - ";
for(let j in response[i])
{
//console.log(j);
this.res += j + " : \n ";
for(let t in response[i][j])
{
//console.log(t);
this.res += t +"\n";
}
}
}
console.log(this.res);
return this.res;
});
}
}
Here's the output on console.log:
the thing is that on console log i can get all the tags : data, but i can't never get the data on res string to display.
Console.log(response) : All the data i need to display.
this.res : the tags without any data.
Thanks in advance!!
Edit: Here's the output of {{res | json}} on html side:
{ "Challenges": [ { "Challenge.Closed": false,
"Challenge.EndSubmissionDate": "Sat Feb 13 00:00:00 GMT 2010",
"Challenge.Title": "net.Partner", "Challenge.CompositeId":
"Id=3_Tenant=103", "Challenge.Code": "2010/001"....
I have the json like text based..i want for example:
Challenge.Closed : false
....
Idea.id: 4
...
and access some of the tags that i know that exists, like id..
Do i have to map it?

So i think i am close, i know that with {{res | json }} i can print all the data and tags, including curly braces etc from the json file. (its like a json file to text)
But i need to print only the entity: tags and values. keep in mind that i neves know what comes on the json file. Here's what i have so far:
public entity = [];
public cont = [];
.Created and array and pushes all the entities:
this.res = response;
for(let i in response)
{
//array with entities inside json
this.entity.push(i);
}
return this.res;
the on the html side i can get:
<!-- all the data from json-->
<ng-container>
<li>{{res}}</li>
</ng-container>
<!-- all the Challenges or whatever comes after res --- res.HERE-->
<ng-container>
<li>{{res.Challenges | json}}</li>
</ng-container>
<!-- or (example with Ideas)-->
<ng-container *ngFor="let x of res.Ideas">
<li>{{x | json}}</li>
</ng-container>
<!-- print all the entities that come in the json
(challenges, Ideas, whatever.. that goes with res.HERE)-->
<ng-container *ngFor="let i of entity">
<li>{{i}}</li>
</ng-container>
so, i can get the entities, each entity has its own attributes, for example to entity Challenges:
Challenge.Closed
Challenge.EndSubmissionDate
Challenge.Title
etc..
but how can i acess the values to each attribute? with the html i've posted i can get what's inside the coments, so i could iterate each entity like:
<!-- json file has 2 entities -->
<ng-container *ngFor="let i of entity">
<!-- trying to print res.Challenges and res.Ideas -->
<ng-container *ngFor="let jsn of res.i">
<li>{{jsn | json}}</li>
</ng-container>
</ng-container>
but, no success. i don't see how can i solve it!
with that for loop i've posted earlier:
for(let i in response)
{
this.cont.push(i);
for(let j in response[i])
{
this.cont.push(j);
for(let t in response[i][j])
{
this.cont.push(t);
}
}
}
I've printed on the html side:
the best thing was to get the values for each "entity.attribute" and not only the tags like i have (showed on the image)

A little closer to the solution, i've found the way to retrive the values, for example to entity Challenge:
this.responseList.Challenges["0"]["Challenge.Code"]
gives me the challenge code.
But instead of challenge it can be whatever, that's the name of entity, for example Ideas:
this.responseList.Ideas["0"]["Idea.Code"]
gives me the idea code.
if i want to know the names of each entity:
this.responseList
>{Challenges: Array(13), Ideas: Array(1)}
The test was made on console with a debugger in the 'for loop' inside the code that follows:
html - Im just printing Challenges, but i neves knwo what entity i have.. it can me Ideas, or other..
<ul *ngFor="let res of responseList.Challenges">
<li> {{res | json}} </li>
</ul>
Component.ts
public entity = []; //has the entity names ideias, challenges whatever...
public responseList = ""; //the json that comes from the server
ngOnInit() {
let settings = {
"async": true,
"crossDomain": true,
"url": "ip/to/api",
"method": "POST",
"data": "\"dataApi\"",
};
$.ajax(settings).done((rest) => this.response(rest));
}
response(res){
this.responseList = res; //the json file with allt he information
for(let i in res)
{
//array with all entities inside json
this.entity.push(i);
}
debugger;
}
Based on that information, i have to work inside .ts with for loops and arrays and the just print the result on .html, right? Can somebody help me with that?
Edited for solution
If i could print the values on the console, i can print them too with my previous for loop:
component.ts:
for(let i in res)
{
for(let j in res[i])
{
this.singleArray.push({
tag: i,
value: val
});
for(let t in res[i][j])
{
this.singleArray.push({
tag: t,
value: this.responseList[i][j][t]
});
if(t.split(".",2)[1] === "CompositeId")
{
this.singleArray.push({
tag: "URL:",
value: this.moduleName + "/" + t.split(".",2)[0] + "/" + this.responseList[i][j][t].match(/=(.*)_/)[1]
});
}
}
}
}
with that 'for loop' i can get the tag and the value:
to print them on html side:
html
<ng-container *ngFor="let item of singleArray">
<li>
{{item.tag}} - {{item.value}}
</li>
<a *ngIf="item.tag.includes('URL')"> <li>- LINK -</li></a>
</ng-container>

You should use the $.ajax() context object here like:
let settings = {
"async": true,
"crossDomain": true,
"url": "ip/to/api",
"context": this,
"method": "POST",
"data": "\"dataApi\"",
};

try this:
all you have to do is to loop through response
.HTML
<div class="div1">
<ul class="r " *ngFor="let res of responseList.challenges">
<li>
{{res.closed}}
</li>
</ul>
</div>
.TS
public responseList = "";
ngOnInit() {
let settings = {
"async": true,
"crossDomain": true,
"url": "ip/to/api",
"method": "POST",
"data": "\"dataApi\"",
};
$.ajax(settings).done() = (res) => this.response(res);
response(res){
console.log(res);
this.responseList = res;
}

Related

vue 2 v-for not working after loading json with axios

I searched the internet for a solution but none did work so far.
I am having a Vue component where I want to load dropdown content afterwards. Since it does not work, I simplified the code such that it should only show me the elements (which are driver names).
The problem is, that the v-for seems not to work, as the elements are not created in the DOM.
Here goes the code:
<template>
<div class="list-group">
<a class="list-group-item" v-for="driver in drivers">
{{driver.name}}
</a>
</div>
</template>
<script>
export default {
name: "DriverComponent",
data: function (){
return {
drivers: [],
}
},
mounted(){
this.loadDrivers();
console.log(this.drivers);
},
methods: {
loadDrivers: function(){
axios.get('/api/drivers')
.then(
(response) => {
this.drivers = response.data.data;
console.log(this.drivers);
}
)
.catch(function(error){
console.log(error);
});
// console.log(this.drivers);
}
}
}
</script>
In my app.js:
require('./bootstrap');
window.Vue = require('vue').default;
Vue.component('driver-component', require('./components/DriverComponent.vue').default);
const drivers = new Vue({
el: '#driv',
});
And my html looks as follows:
<div id="driv">
<driver-component></driver-component>
</div>
As you can see, I added some logs, which look like this:
Image of console output
Interestingly, it should be the same array, but the first array is empty but the second has the right values in it.-> EDIT: clarified, thank you
to highlight the problem: i would expect a list like:
v-for created list
Instead, I get a blank page.
It works, if I initialize the drivers array with the data I get in json. However, since I load the data afterwards, it seems not to work
Thank you for your help!
BR
Johannes
EDIT:
I am using "axios": "^0.21" and the controller is:
public function index(){
return DriverResource::collection(Drivers::all());
}
this controller returns the array in a data field, therefore, I set the response.data.data (meaning two times data)
The backend returns:
{"data":[{"id":1,"name":"UPS"},{"id":2,"name":"Hermes"}]}
See the homepage for axios. Under the "Response Schema" section they provide what a response looks like. Specifically for data, it's
{
// `data` is the response that was provided by the server
data: {}
< ... omitted for brevity ... >
}
Please check again what your backend is returning or is supposed to return. Log the whole response you get.
The this.drivers = response.data.data; seems to be incorrect, however the this.drivers = response.data; should work.
You didn't say which version of axios you are using or show your configuration so I'm using the following for an example:
axios = ^0.21.1
vue-axios = ^3.2.4
Replaced "name" with "title" to match the response format below:
{
"title": "delectus aut autem",
< ... omitted for brevity ... >
},
--
loadDrivers: function(){
Vue.axios.get('https://jsonplaceholder.typicode.com/todos')
.then(
(response) => {
this.drivers = response.data; // <<-- works and many task titles are shown on page
// this.drivers = response.data.data; // <<-- DOES NOT WORK LIKE FOR YOU, blank page
console.log(this.drivers);
}
)
.catch(function(error){
console.log(error);
});
// console.log(this.drivers);
}

Vue.js Retrieving Remote Data for Options in Select2

I'm working on a project that is using Vue.js and Vue Router as the frontend javascript framework that will need to use a select box of users many places throughout the app. I would like to use select2 for the select box. To try to make my code the cleanest I can, I've implemented a custom filter to format the data the way select2 will accept it, and then I've implemented a custom directive similar to the one found on the Vue.js website.
When the app starts up, it queries the api for the list of users and then stores the list for later use. I can then reference the users list throughout the rest of the application and from any route without querying the backend again. I can successfully retrieve the list of users, pass it through the user list filter to format it the way that select2 wants, and then create a select2 with the list of users set as the options.
But this works only if the route that has the select2 is not the first page to load with the app. For example, if I got to the Home page (without any select2 list of users) and then go to the Users page (with a select2), it works great. But if I go directly to the Users page, the select2 will not have any options. I imagine this is because as Vue is loading up, it sends a GET request back to the server for the list of users and before it gets a response back, it will continues with its async execution and creates the select2 without any options, but then once the list of users comes back from the server, Vue doesn't know how to update the select2 with the list of options.
Here is my question: How can I retrieve the options from an AJAX call (which should be made only once for the entire app, no matter how many times a user select box is shown) and then load them into the select2 even if the one goes directly to the page with the select2 on it?
Thank you in advance! If you notice anything else I should be doing, please tell me as I would like this code to use best practices.
Here is what I have so far:
Simplified app.js
var App = Vue.extend({
ready: function() {
this.fetchUsers();
},
data: function() {
return {
globals: {
users: {
data: []
},
}
};
},
methods: {
fetchUsers: function() {
this.$http.get('./api/v1/users/list', function(data, status, response) {
this.globals.users = data;
});
},
}
});
Sample response from API
{
"data": [
{
"id": 1,
"first_name": "John",
"last_name": "Smith",
"active": 1
},
{
"id": 2,
"first_name": "Emily",
"last_name": "Johnson",
"active": 1
}
]
}
User List Filter
Vue.filter('userList', function (users) {
if (users.length == 0) {
return [];
}
var userList = [
{
text : "Active Users",
children : [
// { id : 0, text : "Item One" }, // example
]
},
{
text : "Inactive Users",
children : []
}
];
$.each( users, function( key, user ) {
var option = { id : user.id, text : user.first_name + ' ' + user.last_name };
if (user.active == 1) {
userList[0].children.push(option);
}
else {
userList[1].children.push(option);
}
});
return userList;
});
Custom Select2 Directive (Similar to this)
Vue.directive('select', {
twoWay: true,
bind: function () {
},
update: function (value) {
var optionsData
// retrive the value of the options attribute
var optionsExpression = this.el.getAttribute('options')
if (optionsExpression) {
// if the value is present, evaluate the dynamic data
// using vm.$eval here so that it supports filters too
optionsData = this.vm.$eval(optionsExpression)
}
var self = this
var select2 = $(this.el)
.select2({
data: optionsData
})
.on('change', function () {
// sync the data to the vm on change.
// `self` is the directive instance
// `this` points to the <select> element
self.set(select2.val());
console.log('emitting "select2-change"');
self.vm.$emit('select2-change');
})
// sync vm data change to select2
$(this.el).val(value).trigger('change')
},
unbind: function () {
// don't forget to teardown listeners and stuff.
$(this.el).off().select2('destroy')
}
})
Sample Implementation of Select2 From Template
<select
multiple="multiple"
style="width: 100%"
v-select="criteria.user_ids"
options="globals.users.data | userList"
>
</select>
I may have found something that works alright, although I'm not sure it's the best way to go about it. Here is my updated code:
Implementation of Select2 From Template
<select
multiple="multiple"
style="width: 100%"
v-select="criteria.reporting_type_ids"
options="globals.types.data | typeList 'reporttoauthorities'"
class="select2-users"
>
</select>
Excerpt from app.js
fetchUsers: function() {
this.$http.get('./api/v1/users/list', function(data, status, response) {
this.globals.users = data;
this.$nextTick(function () {
var optionsData = this.$eval('globals.users.data | userList');
console.log('optionsData', optionsData);
$('.select2-users').select2({
data: optionsData
});
});
});
},
This way works for me, but it still kinda feels hackish. If anybody has any other advice on how to do this, I would greatly appreciate it!
Thanks but I'm working on company legacy project, due to low version of select2, I encountered this issue. And I am not sure about the v-select syntax is from vue standard or not(maybe from the vue-select libaray?). So here's my implementation based on yours. Using input tag instead of select tag, and v-model for v-select. It works like a charm, thanks again #bakerstreetsystems
<input type="text"
multiple="multiple"
style="width: 300px"
v-model="supplier_id"
options="suppliers"
id="select2-suppliers"
>
</input>
<script>
$('#app').ready(function() {
var app = new Vue({
el: "#app",
data: {
supplier_id: '<%= #supplier_id %>', // We are using server rendering(ruby on rails)
suppliers: [],
},
ready: function() {
this.fetchSuppliers();
},
methods: {
fetchSuppliers: function() {
var self = this;
$.ajax({
url: '/admin_sales/suppliers',
method: 'GET',
success: function(res) {
self.suppliers = res.data;
self.$nextTick(function () {
var optionsData = self.suppliers;
$('#select2-suppliers').select2({
placeholder: "Select a supplier",
allowClear: true,
data: optionsData,
});
});
}
});
},
},
});
})
</script>

Bootstrap Typeahead with AJAX source (not working)

I'm trying to implement a search bar dropdown using bootstrap v3.0.0 with typeahead.js.
My search bar will take a student's firstname and lastname. I'm using a MYSQL database which consists of a table called practice with afirstname, alastname, aid as columns. The search bar should not only contain the firstname and lastname in the dropdown, but also the id associated with it in a second row. I've read all the examples on the typeahead.js page and I'm unable to do it with ajax call.
Below is the code of my index.php
JS
<script type="text/javascript">
$(document).ready(function() {
$('.cr.typeahead').typeahead({
source: header: '<h3>Select</h3>',
name: 'accounts',
source: function (query, process) {
return $.getJSON(
'localhost/resultly/source.php',
{ query: query },
function (data) {
return process(data);
});
});
});
</script>
HTML:
<body>
<div class="container">
<br/><br/>
<input type="text" name="query" class="form-control cr typeahead" id="firstname" />
<br/><br/>
</div>
</body>
Code for source.php : This should return the firstname and lastname from my database in the form of a json string or object?
<?php
$query = $_POST['query'];
try {
$conn = new PDO('mysql:host=localhost;dbname=practice','root','');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $conn->prepare("SELECT * FROM actualtable WHERE afirstname LIKE '%($query)%'");
$stmt->execute();
}
catch (PDOException $e) {
echo 'ERROR:' . $e->getMessage();
}
foreach ($stmt as $row) {
$afirstname[] = $row['afirstname'];
$alastname[] = $row['alastname'];
}
echo json_encode($afirstname);
echo json_encode($alastname);
?>
result:
http://oi41.tinypic.com/50moi1.jpg
Nothing shows up. I've tried adding a prefetch:
prefetch: {
url: 'localhost/resultly/source.php',
filter: function(data) {
r1 = [];
for (var i = 0; i < data.length; i++) {
r1.push({
value: data[i].afirstname,
tokens: [data[i].afirstname, data[i]alastname],
afirstname: data[i].afirstname,
alastname: data[i].alastname,
template: '<p>{{afirstname}} - {{alastname}}</p>',
});
}
return r1;
}
}
Please do provide a solution or an example which I could refer.
Update:
The source.php should return a list of json encoded data. I debugged by looking at the output that the source.pho created. What I did wrong was whenever I was supposed to put a url I did localhost/source.php instead of just source.php.
Solution provided by Bass Jobsen works and now I have run into another problem.
I'm using
if(isset($_POST['query']))
{ $q_uery = $_POST['query'];
$query = ucfirst(strtolower($q_uery))};
to take the user's data and use it for searching logic
$stmt = $conn->prepare("SELECT * FROM actualtable WHERE afirstname LIKE '%($query)%'");
The updated source.php is http://pastebin.com/T9Q4m10g
I get an error on this line saying Notice: Undefined variable: stmt I guess the $query is not being initialized. How do I get this to work. Thanks.
Update 3
I used prefetch: instead of 'remote:' that did all the matching.
Your return is not correct:
echo json_encode($afirstname);
echo json_encode($alastname);
See for example Twitter TypeAhead.js not updating input
Try echo json_encode((object)$stmt);, see: typeahead.js search from beginng
Update
I tried echo json_encode((object)$stmt);still doesn't work.
Do you use any kind of debugging? What does? source.php return? Try to follow the steps from
typeahead.js search from beginng without the filter.
html:
<div class="demo">
<input class="typeahead" value="" type="text" spellcheck="off" autocomplete="off" placeholder="countries">
</div>
javascript:
$('.typeahead').typeahead({
remote: 'http://testdrive/source.php?q=%QUERY',
limit: 10
});
php (source.php):
<?php
$people = array();
$people[] = array("lastname"=>"Inaw",
"firstname"=>"Dsajhjkdsa");
$people[] = array("lastname"=>"Dsahjk",
"firstname"=>"YYYsgbm");
$people[] = array("lastname"=>"Dasjhdsjka",
"firstname"=>"JHJKGJ");
$datums = array();
foreach($people as $human)
{
$datums[]=(object)array('value'=>$human['firstname'],'tokens'=>array($human['firstname'],$human['lastname']));
}
echo json_encode((object)$datums);
This should work
update2
Thanks, it worked. How do I display 2 or more 'value'?
add some values to your datums in source.php:
foreach($people as $human)
{
$datums[]=(object)array
(
'value'=>$human['firstname'],
'tokens'=>array($human['firstname'],$human['lastname']),
'firstname'=>$human['firstname'],
'lastname'=>$human['lastname']
);
}
firstname and lastname now are field you csn use in your templates
Add a template and template engine to your javascript declaration:
$('.typeahead').typeahead({
remote: 'http://testdrive/source.php?q=%QUERY',
limit: 10,
template: [
'<p>{{firstname}} - {{lastname}}</p>'
].join(''),
engine: Hogan
});
The above make use of https://github.com/twitter/hogan.js. You will have to include the template engine by javascript, for example:
<script src="http://twitter.github.io/typeahead.js/js/hogan-2.0.0.js"></script>
It is working for me. please follow below step.
Please add below Js and give proper reference.
bootstrap3-typeahead
--- Ajax Call ----
$("#cityId").keyup(function () {
var al = $(this).val();
$('#cityId').typeahead({
source: function (valuequery, process) {
var states = [];
return $.ajax({
url: http://localhost:4000/GetcityList,
type: 'POST',
data: { valueType: "", valueFilter: valuequery },
dataType: 'JSON',
success: function (result) {
var resultList = result.map(function (item) {
states.push({
"name": item.Value,
"value": item.Key
});
});
return process(states);
}
});
},
});
});
---- Cs Code ---
public JsonResult SearchKeyValuesByValue(string valueType, string valueFilter)
{
List<KeyValueType> returnValue = SearchKeyValuesByValue(valueType, valueFilter);
return Json(returnValue);
}
Auto suggest of Bootstrap typehead will get accept only "name" and "value" so create reponse accordinly

How to populate Kendo Upload with previously uploaded files

I'm using the Kendo UI File Upload for MVC and it works great. On my edit page, I want to show the files that were previously uploaded from the Create page. For visual consistency, I would like to re-use the upload widget on my edit page so the user can use the "remove" functionality, or add additional files if they choose. Does the upload widget support this?
Thanks!
So, I realize this is question pretty old, but I recently figured out how to do this reliably. While the other answer on here will certainly display the files, it doesn't really wire it up to any of the events (specifically the "remove" event). Also, rather than manually setting all of this up, I figured I'd much rather have Kendo do all of the real dirty work.
Note, this only applies if your file upload is not set to autosync. If you use the auto upload feature, you can find examples in the Kendo documentation here: http://docs.kendoui.com/api/web/upload#configuration-files
So anyway, let's assume we have a file input that we've made into a Kendo Upload:
<input id="files" name="files" type="file" multiple="multiple" />
$(document).ready(function () {
var $upload = $("#files");
var allowMultiple = Boolean($upload.attr("multiple"));
$upload.kendoUpload({
multiple: allowMultiple,
showFileList: true,
autoUpload: false
});
}
Then, we just need to get the information about the files to our jQuery. I like to jam it into JSON strings in hidden fields, but you can do it however you want.
Here's an example using the Mvc HtmlHelpers and Newtonsoft's JSON.NET (I don't use Razor, but you should get the general idea):
if (Model.Attachments.Count > 0)
{
var files = Model.Attachments.Select(x => new { name = x.FileName, extension = x.FileExtension, size = x.Size });
var filesJson = JsonConvert.SerializeObject(files);
Html.Render(Html.Hidden("existing-files", filesJson));
}
Note, the format there is incredibly important. We're tying to match the structure of the JavaScript object that Kendo is expecting:
{
relatedInput : sourceInput,
fileNames: [{ // <-- this is the collection we just built above
name: "example.txt",
extenstion: ".txt",
size: 1234
}]
}
So, then all that's left to do is put it all together. Basically, we're going to recreate the onSelect function from Kendo's internal syncUploadModule:
$(document).ready(function () {
// setup the kendo upload
var $upload = $("#files");
var allowMultiple = Boolean($upload.attr("multiple"));
var upload = $upload.kendoUpload({
multiple: allowMultiple,
showFileList: true,
autoUpload: false
}).getKendoUpload();
// initialize the files
if (upload) {
var filesJson = $("[name$='existing-files']").val();
if (filesJson) {
var files = JSON.parse(filesJson);
var name = $.map(files, function (item) {
return item.name;
}).join(", ");
var sourceInput = upload._module.element.find("input[type='file']").last();
upload._addInput(sourceInput.clone().val(""));
var file = upload._enqueueFile(name, {
relatedInput : sourceInput,
fileNames : files
});
upload._fileAction(file, "remove");
}
}
});
And that's pretty much it!
I came up with a way to do this.
Basically, you need HTML that mimics what the Upload control generates, and you use a bit of JavaScript to hook each item up. I initially render the HTML as hidden, then after you initialize the Kendo Upload control, you append the HTML list to the parent container that Kendo creates.
This is my MVC view:
#if (Model.Attachments != null && Model.Attachments.Count > 0)
{
<ul id="existing-files" class="k-upload-files k-reset" style="display: none;">
#foreach (var file in Model.Attachments)
{
<li class="k-file" data-att-id="#file.Id">
<span class="k-icon k-success">uploaded</span>
<span class="k-filename" title="#file.Name">#file.Name</span>
<button type="button" class="k-button k-button-icontext k-upload-action">
<span class="k-icon k-delete"></span>
Remove
</button>
</li>
}
</ul>
}
and here is the JavaScript (note, it was generated from CoffeeScript):
var $fileList, $files, item, _fn, _i, _len;
$fileList = $("#existing-files");
if ($fileList.length > 0) {
$(".k-upload").append($fileList);
$files = $(".k-file");
_fn = function(item) {
var $item, fileId, filenames;
$item = $(item);
fileId = $item.data("att-id");
filenames = [
{
name: fileId
}
];
return $item.data("fileNames", filenames);
};
for (_i = 0, _len = $files.length; _i < _len; _i++) {
item = $files[_i];
_fn(item);
}
$fileList.show();
}
You can find the full write up on my blog where I go into depth on the topic. I hope this helps you!
Some additional searches gave me the answer I wasn't looking for - According to this and this, Telerik does not support pre-populating an upload widget with previously uploaded documents.
It has been added in the options since this question has been asked.
Check out http://docs.telerik.com/kendo-ui/api/web/upload#configuration-files
It only works in async mode.
Try this...
#(Html.Kendo().Upload()
.Name("files")
.Async(a => a
.Save("SaveFile", "Home")
.Remove("RemoveFile", "Home")
.AutoUpload(true))
.Files(files =>
{
foreach (var file in Model.FundRequest.Files)
{
files.Add().Name(file.Name).Extension(Path.GetExtension(file.Name)).Size((long)file.SizeKb * 1024);
}
}))
My Model has a reference to my "FundRequest" object that has a List of "File" objects, so I just loop through each "File" and add.
Check this out!
<script>
var files = [
{ name: "file1.doc", size: 525, extension: ".doc" },
{ name: "file2.jpg", size: 600, extension: ".jpg" },
{ name: "file3.xls", size: 720, extension: ".xls" },
];
$("#upload").kendoUpload({
async: {
saveUrl: "Home/Save",
removeUrl: "Home/Remove",
autoUpload: true
},
files: files
});
</script>
<input type="file" name="files" id="upload" />
Check this out, this is it.
Below code is copied and adapted from kendo-ui documentation:
<div id="example">
<div>
<div class="demo-section">
<input name="files" id="files" type="file" />
</div>
</div>
<script>
$(document).ready(function () {
if (sessionStorage.initialFiles === undefined) {
sessionStorage.initialFiles = "[]";
}
var initialFiles = JSON.parse(sessionStorage.initialFiles);
$("#files").kendoUpload({
showFileList: true,
multiple: true,
async: {
saveUrl: "save",
autoUpload: false,
batch: true
},
files: initialFiles,
success: onSuccess
});
function onSuccess(e) {
var currentInitialFiles = JSON.parse(sessionStorage.initialFiles);
for (var i = 0; i < e.files.length; i++) {
var current = {
name: e.files[i].name,
extension: e.files[i].extension,
size: e.files[i].size
}
if (e.operation == "upload") {
currentInitialFiles.push(current);
} else {
var indexOfFile = currentInitialFiles.indexOf(current);
currentInitialFiles.splice(indexOfFile, 1);
}
}
sessionStorage.initialFiles = JSON.stringify(currentInitialFiles);
}
});
</script>
</div>

Django Jquery Get URL Conf

Ok, so I'm trying to call the function
def user_timetable(request, userid):
user = get_object_or_404(TwobooksUser,id = userid)
timeSlots = TimeSlot.objects.filter(user = request.user)
rawtimeslots = []
for timeSlot in timeSlots:
newSlot = {
'userid': timeSlot.user.id,
'startTime': str(timeSlot.startTime),
'endTime': str(timeSlot.endTime),
}
rawtimeslots.append(newSlot)
return HttpResponse(simplejson.dumps(rawtimeslots))
through the javascript in
{% include 'elements/header.html' %}
<script type='text/javascript'>
$(document).ready(function() {
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
data = JSON.parse(data);
var events = new Array();
for (var i in data) {
events.push({
id: data[i].id,
title: '{{ request.user.name }}',
start: Date.parse(data[i].startTime, "yyyy-MM-dd HH:mm:ss"),
end: Date.parse(data[i].endTime, "yyyy-MM-dd HH:mm:ss"),
allDay: false
});
}
where the above exists in a template that's being rendered (I think correctly).
The url conf that calls the function user_timetable is
url(r'^books/personal/(?P<userid>\d+)/timetable/$',twobooks.ajax.views.user_timetable),
But, user_timetable isn't being called for some reason.
Can anyone help?
EDIT-
Ok the original problem was that the template was not being rendered correctly, as the url in firebug comes to '/books/personalNone/timetable/' , which is incorrect.
I'm rendering the template like this -
def renderTimetableTemplate(request):
#if request.POST['action'] == "personalTimetable":
user = request.user
return render_to_response(
'books/personal.html',
{
'user': user,
},
context_instance = RequestContext(request)
)
Is there a mistake with this?
There is a slash missing after "personal"
$.get('/books/personal{{ user.id }}/timetable/', {}, function(data) {
should be
$.get('/books/personal/{{ user.id }}/timetable/', {}, function(data) {
Btw. you should use the {% url %} template tag.
There is a mismatch between the data you're converting to JSON and passing to the script, and the data that the script is expecting. You are passing a userId element in each timeslot, whereas the script is expecting just id.
This error should have shown up in your browser's Javascript console, and would be even easier to see in Firebug (or Chrome's built-in Developer Tools).

Resources