How do I load data for Dojo Dgrid Table using AJAX? - javascript

I am exploring using DGrid for my web application. I am trying to have a table similar to this.
The code for the example above is here.
The table uses a memory store as the source of its data - the summary field there is what shows up when we click and expand each row.
I want the details(i.e the text shown when we click a row) to be fetched from the server on clicking on the row instead of being statically loaded along with rest of the page.
How do I modify the above code to be able to do that?
(My requirement is that of an HTML table, each row expandable on clicking, where the data on each expansion is fetched from the server, using AJAX for instance. I am just exploring dgrid as an option, as I get sortable columns for free with dgrid. If there is a better option, please let me know)
EDIT: Basically I am looking for ideas for doing that and not expecting anyone to actually give me the code. Being rather unfamiliar with Dojo, I am not sure what would be the right approach

If your ajax call returns html, you could place a dijit/layout/ContentPane in your renderer, and set the url of the contents you want to fetch in the ContentPane's href property. Assuming that your initial data (the equivalent of the example's memory store) would have a property called "yourServiceCallHref" containing the url you want to lazy load, your could try this :
require(["dijit/layout/ContentPane", ...], function(ContentPane){
renderers = {
...,
table: function(obj, options){
var div = put("div.collapsed", Grid.prototype.renderRow.apply(this, arguments)),
cp = new ContentPane({
href : obj.yourServiceCallHref
}),
expando = put(div, "div.expando", cp.domNode);
cp.startup();
return div;
}
});
If your service returns json, you could probably do something with dojo/request in a similar fashion. Just add your dom creation steps in your request callback and put them inside the div called "expando"...
Another option would be to replace the Memory store by a JsonRest store, and have the server output the same json format than the one you see on the Memory store. That means all the data would be fetched in a single call though...

Related

Go to an anchor point in a template with code in Angular 4

I have an Angular 4 application in which I need to add the following functionality:
There is a component with a list of objects. When the user double clicks on one of them, the app retrieves from a DB a list of objects and it should scroll to where the object appears.
I'd like to know how I could move to the desired position in the data once that it has been displayed in the browser. Right now, I have the following code:
let objElement = document.querySelector("#object_"+searchItem._objectID);
if (objElement){
objElement.scrollIntoView();
console.log("****** SCROLLING TO OBJECT");
}
The problem is that, the first time that I load the data from the DB, it seems that 'document.querySelector' returns null, as if the HTML wasn't 100% constructed yet, so it doesn't scroll to the position. If I try to locate the element again, it scrolls perfectly (as it doesn't reload the data from the DB).
Is there a "more Angular" way of doing this? I'm trying to find an example like this in the Angular Router documentation but I can't find anything...
EDIT:
To make things clearer, this is the pseudo-code that I run when the user selects an object:
if(selectedObject IS IN currentLoadedObjects) {
scrollTo(selectedObject); // This function runs the code above
}
else { // The object is in a different list, so retrieve it from the DB
ObjectService.getObjectListFromDB(selectedObject)
.subscribe((returnedList) => {
displayObjectList(returnedList); // Basically, this function parses the returned data, which is displayed in the template using an *ngFor loop
scrollTo(selectedObject);
});
}
As you can see, I try to scroll to the object inside the 'subscribe' method, once that I have the data from the database and after I've parsed it. The object list is pretty big, so it takes 1-2 seconds to be displayed in the browser.
Thanks!

javascript/jQuery is automatically updating data in div after data is retrieved

I am building a Ruby on Rails application where I am performing an Ajax request to retrieve some data, perform calculations on it, and place it on the page. The page is going to be performing these calculations every 30 seconds or so on new data from the database, so this means I need to keep the original data from the Ajax request intact. When I'm retrieving the original data, I'm placing it in a div using jQuery like so:
$('#info').data('original', data);
and then taking that data object and running said calculations on it. After the calculations are complete, I place it in a separate data attribute in the same div like so:
$('#info').data('modified', data);
The data in the 'modified' attribute goes to the page, and when the time has come, it pulls the new data from the database, the original data from the div, gets passed to a method for calculating, and then is placed back in the 'modified' attribute for being displayed on the page:
function calculate(data) {
// doing some stuff here
$('#info').data('modified', data);
}
var data = $('#info').data('original');
calculate(data);
All of this is working just fine, however when the very first calculation is being ran, it seems that the 'original' attribute in the div is being overwritten with the data that has been calculated, even though I'm not explicitly telling it to do so. Does anyone have any insight on why this could be happening?

ExtJS 4 grid and some problems with mask

I have a not too big grid (30x20) with numbers in cells. I have to display all, calculate them in different ways (by columns, rows, some cells, etc.) and write values to some cells. This data is also written and read from db table fields. Everything is working, excluding simple (theoretically) mask tools.
In time of e.g. writing data to the field in the table I try to start mask and close it on finish. I used such a “masks” very often but only in this situation I have a problem and can’t solve it.
I prepare this mask the following way:
msk = new Ext.LoadMask(Ext.getBody(), { msg: "data loading ..." });
msk.show();
[writing data loops]
msk.hide();
msk.destroy();
I also tried to use grid obiect in place of Ext.getBody(), but without result.
I found also that the program behaves in a special way – loops which I use to write data to the table field are "omitted" by this mask, and it looks like loops are working in the background (asynchronously).
Would you be so kind as to suggest something?
No, no, no, sorry guys but my description isn’t very precise. It isn’t problem of loading or writing data to the database. Let’s say stores are in the memory but my problem is to calculate something and write into the grid. Just to see this values on the screen. Let me use my example once again:
msk = new Ext.LoadMask(Ext.getBody(), { msg: "data loading ..." });
msk.show();
Ext.each(dataX.getRange(), function (X) {
Ext.each(dataY.getRange(), function (Y) {
…
X.set('aaa', 10);
…
}
msk.hide();
msk.destroy();
And in such a situation this mask isn’t visible or is too fast to see it.
In the mean time I find (I think) a good description of my problem but still can’t find a solution for me. When I use e.g. alert() function I see this mask, when I use delay anyway, mask is too fast. Explanation is the following:
The reason for that is quite simple - JS is single threaded. If you modify DOM (for example by turning mask on) the actual change is made immediately after current execution path is finished. Because you turn mask on in beginning of some time-consuming task, browser waits with DOM changes until it finishes. Because you turn mask off at the end of method, it might not show at all. Solution is simple - invoke store rebuild after some delay.*
I have no idea how is your code looks in general but this is some tip that you could actually use.
First of all loading operations are asynchronously so you need to make that mask show and then somehow destroy when data are loaded.
First of all check if in your store configuration you have autoLoad: false
If yes then we can make next step:
Since Extjs is strongly about MVC design pattern you should have your controller somewhere in your project.
I suppose you are loading your data on afterrender or on button click event so we can make this:
In function for example loadImportantData
loadImportantData: function(){
var controller = this;
var store = controller.getStore('YourStore'); //or Ext.getStore('YourStore'); depends on your configuration in controller
var myMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."});
myMask.show();
store.load({
callback: function (records, operation, success) {
//this callback is fired when your store load all data.
//then hide mask.
myMask.hide();
}
});
}
When data is loaded your mask will disappear.
If you have a reference to the grid, you can simply call grid.setLoading(true) to display a loading mask over the grid at any time.

Lightswitch - Passing Paramaters in the HTML Client

ive been trying for ages now to pass the value with little success, the image below is what I am aiming for:
and this is the table structure/relationships
cheers for any help you can give me guys, this is beginning to be a real pain in the arse
based on this I managed to solve my issue by doing the following
LightSwitch: Passing data from one screen to another -> for Desktop Client
For HTML Client
You MUST have a parameter on the screen from which you are passing the data, this is done by creating a data item, i.e. int in the below example, and in the post render code for this use the following code:
myapp.ViewDeliveryNote.DeliveryIDPass_postRender = function (element, contentItem) {
contentItem.screen.DeliveryIDPass = //created parameter
contentItem.screen.DeliveryNote.DeliveryID; //the unique ID from the screen
};
On the screen you want to pass to, add a new data item as that datatype OR if you are using it as a search parameter, use this.
Find the parameter/data item you added on the left hand panel and click on the item, now in the properties window tick (is parameter)
If there was a previous link between the pages via a button, remove the on tap and re-add it... you will now see an additional box where the application is asking for the value to pass, select the one you want and that shoud work :)
hope this helps

jquery footable $('#classes').trigger('footable_redraw'); return hidden table

this is my first Question, may be hard to understand.
calling $('#classes').trigger('footable_redraw'); , it return the data but hide the table heading and data rows,but when i used $('#classes').trigger('footable_initialize'); its work fine but reduplicate the data .
Ajax method is called on submitting form.
$.ajax({
url : baseurl+'index.php/settings/classes/viewclasses',
success : function(data) {
$('.classestbody').append(data);
$('#classes').trigger('footable_redraw'); }
});
How can i only get my updated data in table after saving any Values by calling submitting for saving ?
Basically you need to check to see if the data is in the table already. If the data is not in the table, add it; if it is in the table, don't. You'll need some way to positively identify a row that matches the data. If data is an array, you'll need to loop through the array and check each row.
Another option would be to use a data binding framework. This would allow you to bind the data to the table, then you just add/update/delete rows from the data and the framework takes care of updating the table (view) for you.
I personally use Knockout.js. They have a really good tutorial: http://learn.knockoutjs.com/. Even if you don't end up using Knockout.js, I think the tutorial is pretty cool and it will only take you a couple of hours to go through all of them.
If your script on index.php/settings/classes/viewclasses always returns the hole table, and since you said the data gets duplicated this seems to be the case.
Then it is easier to delete all rows then add them all again, just add $('.classestbody').empty(); before $('.classestbody').append(data);. Your code would look like this:
$.ajax({
url : baseurl+'index.php/settings/classes/viewclasses',
success : function(data) {
$('.classestbody').empty();
$('.classestbody').append(data);
$('#classes').trigger('footable_redraw');
}
});

Categories