ExtJS: Multiple JsonStores from one AJAX call? - javascript

I have an ExtJS based application. When editing an object, an ExtJS window appears with a number of tabs. Three of these tabs have Ext GridPanels, each showing a different type of data. Currently each GridPanel has it's own JsonStore, meaning four total AJAX requests to the server -- one for the javascript to create the window, and one for each of the JsonStores. Is there any way all three JsonStores could read from one AJAX call? I can easily combine all the JSON data, each one currently has a different root property.
Edit: This is Ext 2.2, not Ext 3.

The javascript object created from the JSON response is available in yourStore.reader.jsonData when the store's load event is fired. For example:
yourStore.on('load', function(firstStore) {
var data = firstStore.reader.jsonData;
otherStore.loadData(data);
thirdStore.loadData(data);
}
EDIT:
To clarify, each store would need a separate root property (which you are already doing) so they'd each get the data intended.
{
"firstRoot": [...],
"secondRoot": [...],
"thirdRoot": [...]
}

You could get the JSON directly with an AjaxRequest, and then pass it to the loadData() method of each JSONStore.

You may be able to do this using Ext.Direct, where you can make multiple requests during a single connection.

Maybe HTTP caching can help you out. Combine your json data, make sure your JsonStores are using GET, and watch Firebug to be sure the 2nd and 3rd requests are not going to the server. You may need to set a far-future expires header in that json response, which may be no good if you expect that data to change often.

Another fantastic way is to use Ext.Data.Connection() as shown below :
var conn = new Ext.data.Connection();
conn.request({
url: '/myserver/allInOneAjaxCall',
method: 'POST',
params: {
// if you wish too
},
success: function(responseObj) {
var json = Ext.decode(responseObj.responseText);
yourStore1.loadData(json.dataForStore1);
yourStore2.loadData(json.dataForStore2);
},
failure: function(responseObj) {
var message = Ext.decode(responseObj.responseText).message;
alert(message);
}
});
It worked for me.

Related

Ajax Parameter Being Received as {string[0[} in MVC Controller

First of all, I have never successfully built an AJAX call that worked. This is my first real try at doing this.
I am working on building a function to update existing records in a SQL database. I am using ASP.NET Core (.NET 6) MVC but I also use JavaScript and jQuery. I cannot have the page refresh, so I need to use ajax to contact the Controller and update the records.
I have an array that was converted from a NodeList. When I debug step by step, the collectionsArray looks perfectly fine and has data in it.
//Create array based on the collections list
const collectionsArray = Array.from(collectionList);
$.ajax({
method: 'POST',
url: '/Collections/UpdateCollectionSortOrder',
data: collectionsArray,
})
.done(function (msg) {
alert('Sent');
});
However, when I run the application and debug the code, the array is received in the Controller as {string[0]}.
Here is the method which is in the Controller, with my mouse hovered over the parameter:
Do not pay attention to the rest of the code in the controller method. I have not really written anything in there of importance yet. I plan to do that once the data is correctly transferred to the Controller.
I have tried dozens of ideas including what you see in the Controller with the serialize function, just to see if it processes the junk data that is getting passed, but it hasn't made a difference.
I have been Googling the issue & reading other StackOverflow posts. I've tried things like adding/changing contentType, dataType, adding 'traditional: true', using JSON.stringify, putting 'data: { collections: collectionsArray }' in a dozen different formats. I tried processing it as a GET instead of POST, I tried using params.
I am out of ideas. Things that have worked for others are not working for me. What am I doing wrong? I'm sure it's something minor.
UPDATE: Here is the code which explains what the collectionList object is:
//Re-assign SortID's via each row's ID value
var collectionList = document.querySelectorAll(".collection-row");
for (var i = 1; i <= collectionList.length; i++) {
collectionList[i - 1].setAttribute('id', i);
}
What I am doing is getting a list off the screen and then re-assigning the ID value, because the point of this screen is to change the sort order of the list. So I'm using the ID field to update the sort order, and then I plan to pass the new IDs and names to the DB, once I can get the array to pass through.
UPDATE: SOLVED!
I want to post this follow up in case anyone else runs into a similar issue.
Thanks to #freedomn-m for their guidance!
So I took the NodeList object (collectionList) and converted it to a 2-dimensional array, pulling out only the fields I need, and then I passed that array onto the controller. My previous efforts were causing me to push all sorts of junk that was not being understood by the system.
//Create a 2-dimensional array based on the collections list
const collectionArray = [];
for (var i = 0; i < collectionList.length; i++) {
collectionArray.push([collectionList[i].id, collectionList[i].children[1].innerHTML]);
}
$.ajax({
method: 'POST',
url: '/Collections/UpdateCollectionSortOrder',
data: { collections: collectionArray }
})
.done(function (msg) {
alert('Sent');
});
2-d array is coming through to the Controller successfully

Using JSON to store multiple form entries

I'm trying to create a note taking web app that will simply store notes client side using HTML5 local storage. I think JSON is the way to do it but unsure how to go about it.
I have a simple form set up with a Title and textarea. Is there a way I can submit the form and store the details entered with several "notes" then list them back?
I'm new to Javascript and JSON so any help would be appreciated.
there are many ways to use json.
1> u can create a funciton on HTML page and call ajax & post data.
here you have to use $("#txtboxid").val(). get value and post it.
2> use knock out js to bind two way.and call ajax.
here is simple code to call web app. using ajax call.
var params = { "clientID": $("#txtboxid") };
$.ajax({
type: "POST",
url: "http:localhost/Services/LogisticsAppSuite.svc/Json/GetAllLevelSubClients",
contentType: 'application/json',
data: JSON.stringify(params),
dataType: 'json',
async: false,
cache: false,
success: function (response) {
},
error: function (ErrorResponse) {
}
I have written a lib that works just like entity framework. I WILL put it here later, you can follow me there or contact me to get the source code now. Then you can write js code like:
var DemoDbContext = function(){ // define your db
nova.data.DbContext.call(this);
this.notes=new nova.data.Repository(...); // define your table
}
//todo: make DemoDbContext implement nova.data.DbContext
var Notes = function(){
this.id=0; this.name="";
}
//todo: make Note implement nova.data.Entity
How to query data?
var notes = new DemoDbContext().notes.toArray(function(data){});
How to add a note to db?
var db = new DemoDbContext();
db.notes.add(new Note(...));
db.saveChanges(callback);
Depending on the complexity of the information you want to store you may not need JSON.
You can use the setItem() method of localStorage in HTML5 to save a key/value pair on the client-side. You can only store string values with this method but if your notes don't have too complicated a structure, this would probably be the easiest way. Assuming this was some HTML you were using:
<input type="text" id="title"></input>
<textarea id="notes"></textarea>
You could use this simple Javascript code to store the information:
// on trigger (e.g. clicking a save button, or pressing a key)
localStorage.setItem('title', document.getElementById('title').value);
localStorage.setItem('textarea', document.getElementById('notes').value);
You would use localStorage.getItem() to retrieve the values.
Here is a simple JSFiddle I created to show you how the methods work (though not using the exact same code as above; this one relies on a keyup event).
The only reason you might want to use JSON, that I can see, is if you needed a structure with depth to your notes. For example you might want to attach notes with information like the date they were written and put them in a structure like this:
{
'title': {
'text':
'date':
}
'notes': {
'text':
'date':
}
}
That would be JSON. But bear in mind that the localStorage.setItem() method only accepts string values, you would need to turn the object into a string to do that and then convert it back when retrieving it with localStorage.getItem(). The methods JSON.stringify will do the object-to-string transformation and JSON.parse will do the reverse. But as I say this conversion means extra code and is only really worth it if your notes need to be that complicated.

Problems with displaying JSON data I got from a server

I'm new to JSON/AJAX and
I've some problems with displaying data out of a JSON-object I've got from a server..
The url "http://localhost:8387/rest/resourcestatus.json" represents this object, which I would like to display via HTML/Javascript.. This object stores some monitoring information:
{"groupStatus":[
{"id":"AL Process","time":1332755316976,"level":0,"warningIds":[],"errorIds":[]},
{"id":"AL:instance1","time":1332919465317,"level":0,"warningIds":[],"errorIds":[]},
{"id":"AL:instance2","time":1332919465317,"level":1,"warningIds":["documentarea.locked"],"errorIds":[]},
{"id":"SL","time":1331208543687,"level":0,"warningIds":[],"errorIds":[]}
]}
Since the requested url is different from my domain I can't create a typical XMLHttpRequest.. So I found out that there's an AJAX cross-domain request which can be realised via jQuerys "getJSON()" method.
I want to display the ids and their level in a table.
Any solution to achieve this?
i think you are referring to JSONP. see jQuery.ajax Ex:
var url = 'http://localhost:8387/rest/resourcestatus.json';
$.getJSON(url+'?callback=?', function(data)
{
//data is
/*{
"groupStatus":
[
{"id":"AL Process","time":1332755316976,"level":0,"warningIds":[],"errorIds":[]},
{"id":"AL:instance1","time":1332919465317,"level":0,"warningIds":[],"errorIds":[]},
{"id":"AL:instance2","time":1332919465317,"level":1,"warningIds":["documentarea.locked"],"errorIds":[]},
{"id":"SL","time":1331208543687,"level":0,"warningIds":[],"errorIds":[]}
]
}*/
});
on the server side you will need to wrap the response into a JavaScript function: response = Request["callback"] +"("+ response+")";
the result will look like this:
?({"groupStatus":[{"id":"AL ....})
So the browser will actually load a valid java script code.
The callback function of $.getJSON contains the result of the AJAX call in it's argument.
$.getJSON('http://localhost:8387/rest/resourcestatus.json', function(data) {
$(data.groupStatus).each(function() {
// do something with $(this).id
});
});

Convert many GET values to AJAX functionality

I have built a calendar in php. It currently can be controlled by GET values ​​from the URL. Now I want the calendar to be managed and displayed using AJAX instead. So that the page not need to be reloaded.
How do I do this best with AJAX? More specifically, I wonder how I do with all GET values​​? There are quite a few. The only solution I find out is that each link in the calendar must have an onclick-statement to a great many attributes (the GET attributes)? Feels like the wrong way.
Please help me.
Edit: How should this code be changed to work out?
$('a.cal_update').bind("click", function ()
{
event.preventDefault();
update_url = $(this).attr("href");
$.ajax({
type : "GET"
, dataType : 'json'
, url : update_url
, async : false
, success : function(data)
{
$('#calendar').html(data.html);
}
});
return false;
});
Keep the existing links and forms, build on things that work
You have existing views of the data. Keep the same data but add additional views that provide it in a clean data format (such as JSON) instead of a document format (like HTML). Add a query string parameter or HTTP header that you use to decide which view to return.
Use a library (such as YUI 3, jQuery, etc) to bind event handlers to your existing links and forms to override the normal activation functionality and replace it with an Ajax call to the alternative view.
Use pushState to keep your URLs bookmarkable.
You can return a JSON string from the server and handle it with Ajax on the client side.

Caching AJAX query results with prototype

I'm looking at putting together a good way of caching results of AJAX queries so that the same user doesn't have to repeat the same query on the same page twice. I've put something together using a Hash which works fine but i'm not sure if there's a better method i could be using. This is a rough snippet of what i've come up with which should give you a general idea:
var ajaxresults;
document.observe("dom:loaded", function() {
ajaxresults = new Hash();
doAjaxQuery();
});
function doAjaxQuery(){
var qs = '?mode=getSomething&id='+$('something').value;
if(ajaxresults.get(qs)){
var vals = (ajaxresults.get(qs)).evalJSON();
doSomething(vals);
}else{
new Ajax.Request('/ajaxfile.php'+qs,{
evalJSON: true,
onSuccess: function(transport){
var vals = transport.responseText.evalJSON();
ajaxresults.set(qs,transport.responseText);
},
onComplete: function(){
doSomething(vals);
}
});
}
}
Did you try caching the AJAX requests by defining the cache content headers. Its another way and your browser will take care of caching. You dont have to create any hash inside your libraray to maintaing cache data.
High performance websites discussed lot about this. I dont know much about the PHP, but there is a way in .Net world to setting cache headers before writing the response to stream. I am sure there should be a similar way in PHP too.
If you start building a results tree with JSON you can check of a particular branch (or entry) exists in the tree. If it doesn't you can go fetch it from the server.
You can then serialize your JSON data and store it in window.name. Then you can persist the data from page to page as well.
Edit:
Here's a simple way to use JSON for this type of task:
var clientData = {}
clientData.dataset1 = [
{name:'Dave', age:'41', userid:2345},
{name:'Vera', age:'32', userid:9856}
]
if(clientData.dataset2) {
alert("dataset 2 loaded")
}
else {
alert("dataset 2 must be loaded from server")
}
if(clientData.dataset1) {
alert(clientData.dataset1[0].name)
}
else {
alert("dataset 1 must be loaded from server")
}
Well, I guess you could abstract it some more (e.g. extend Ajax by a cachedRequest() method that hashes a combination of all parameters to make it universally usable in any Ajax request) but the general approach looks fine to me, and I can't think of a better/faster solution.

Categories