dojo xmlstore and data grid item count - dojo

I ahve an xml store that calls an url and fetch data from database. It has to be displayed in the data grid when there is data returned from the database. When there is no data, it has to show appropriate error message.
I have the following js file.
require(["dojo/date/locale","dojox/grid/DataGrid","dojox/data/XmlStore","dijit/registry", "dojo/fx","dijit/form/ValidationTextBox", "dojo/dom-form", "dojo/dom", "dojo/on", "dojo/request","dojox/xml/parser", "dojo/ready","dojo/domReady!"],
function(locale,DataGrid,XmlStore,registry,coreFx,dijit, domForm, dom, on, request, parser, ready){
var format;
var siteId;
var phoneNum;
var grid;
var dataGrid=new DataGrid({
autoWidth:true,
autoHeight:true,
clientSort:true,
structure: [
{name:"Order ID", field:"orderId"},
{name:"Sender", field:"senderName"},
{name:"Recipient", field:"recipientName"},
{name:"Phone Number", field:"phone"},
{name:"Gift Amount", field:"amount"}
]
},"showGrid");
dataGrid.startup();
on(dom.byId("submitButton"), "click", function(){
ready(function()
{
submitValue();
});
});
on(dom.byId("printGiftcard"), "click", function(){
ready(function()
{
window.print();
});
});
function submitValue(){
grid=registry.byId("showGrid");
grid.set("store", null);
grid.filter();
document.getElementById("outcomeMessage").innerHTML="";
var orderNumber= document.getElementById("orderNumber");
var num=orderNumber.value;
if(num==""){
document.getElementById("outcomeMessage").innerHTML="Please enter Order number";
return;
}
var myStore= new XmlStore({
url:"/hello/"+num,
urlPreventCache : false,
query:{},
queryOptions:{},
onComplete:sizeCount
});
var sizeCount = function(items,request){
console.log(items.length);
if(items.length == 0){
document.getElementById("outcomeMessage").innerHTML="data not found";
}
}
var request = myStore.fetch({query:{},queryOptions:{},onComplete:sizeCount});
grid=registry.byId("showGrid");
grid.set("store", myStore);
//grid.filter();
}
});
The problem is it is calling database twice now in order to check the number of items returned.Once to set the store for the grid and other to check if the data returned is null.Can someone give me a simplified solution for this.
Thanks

I finally resolved my issue.
dojo.connect(dataGrid,"_onFetchComplete",function(items){
console.log(datagrid.rowCount);
}
})
Thanks!

Related

Ember.js - Reload paginated list from API after model deletion (and probably insertion)

I have a paginated list of models which comes from my REST api.
I use the api's pagination metadata to get the total number of records from my DB, and see if there are previous or next pages.
If I delete one of the records on the current page, I would like several things to happen:
- The first record of the next page should appear in the current page (if it exists).
- My metadata to be updated. (Total and pagination data)
The direct transitionToRoute method on the controller is not doing any of that. I believe an API reload of the current page is the way to go, but it doesn't seem implemented as far as I know.
I have managed to get the result I want by doing self.transitionToRoute('index') followed by another self.transitionToRoute to the page I want reloaded... This is downright horrible and makes me cringe. There must be a better way!
Here is some of the relevant code:
//router.js
App.Router.map(function(){
this.resource('jobs', function(){
this.resource('job', { path:'/:job_id' }, function(){
this.route('edit');
});
this.route('create');
});
});
//mixins.js
App.PaginatedListController = Ember.Mixin.create({
queryParams: ['page'],
page: 1,
total: function(){
return this.get('meta').count;
}.property('meta'),
previousAPIPage: function(){
return this.get('meta').previous;
}.property('meta'),
nextAPIPage: function(){
return this.get('meta').next;
}.property('meta'),
hasPreviousPage: function(){
return this.get('previousAPIPage') ? true : false;
}.property('previousAPIPage'),
hasNextPage: function(){
return this.get('nextAPIPage') ? true : false;
}.property('nextAPIPage'),
actions:{
previousPage: function(){
this.decrementProperty('page');
this.transitionToRoute({
queryParams: {
page: this.get('page')
}
});
},
nextPage: function(){
this.incrementProperty('page');
this.transitionToRoute({
queryParams: {
page: this.get('page')
}
});
},
},
});
//controllers\jobController.js
App.JobsController = Ember.ArrayController.extend(App.PaginatedListController, {
sortProperties: ['name'],
sortAscending: true,
meta: function(){
return this.store.metadataFor('job');
}.property('model.#each')
});
App.JobController = Ember.ObjectController.extend({
needs: ['jobs'],
deleteMode: false,
actions: {
delete: function(){
// our delete method now only toggles deleteMode's value
this.toggleProperty('deleteMode');
},
cancelDelete: function(){
// set deleteMode back to false
this.set('deleteMode', false);
},
confirmDelete: function(){
var self = this;
this.set('deleteMode', false);
this.get('model').destroyRecord().then(function(response) {
var qParams = self.get('controllers.jobs').get('queryParams');
//This is where it hurts
self.transitionToRoute('index');
//This is what I want reloaded
self.transitionToRoute('jobs', {queryParams:qParams});
});
},
}
});

Xpages Dojo xhrGET chaining load functions of different xhrGET

I have an interesting situation. I am creating an Enhanced Datagrid (ith about 24000 entries). So I am planning to load a small subset to display some data to user while another request finishes. you can see what I am trying to do in code below. Now issue is, both these functions in "load" will update grid datastore. I want to make sure that updateDataStore() from second xhrGet is called ONLY after createDataStore() is finished. This is required because I am creating ids dynamically for rows in data store.
I do not want to hold second xhrGET request till first xhrGET is completed.
** code to update store**
var ds = dijit.byId("grid").store;
ds.newItem();
code to create grid and make two xhrGET requests
CreateEmptyGrid();
dojo.require("dojo._base.xhr");
dojo.xhrGet({
url:"url1",
handleAs:"json",
load: function(data){createDataStore(data);
}
});
dojo.xhrGet(
{
url:"url2",
handleAs:"json",
load: function(data){updateDataStore(data);}
});
Here an example with DeferredList
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:scriptBlock id="scriptBlockPromises">
<xp:this.value><![CDATA[
require(["dojo/request", "dojo/DeferredList"], function(request, DeferredList) {
var responses = new Array();
var promise1 = request("/path/to/data/1").then(function(response) {
createDataStore(response);
});
var promise2 = request("/path/to/data/2").then(function(response) {
responses[0] = response;
});
var list = new DeferredList([promise1, promise2]);
list.then(function(result) {
updateDataStore(responses[0]);
});
});]]></xp:this.value>
</xp:scriptBlock>
</xp:view>
You can nest the second request in the load function of the first:
CreateEmptyGrid();
dojo.require("dojo._base.xhr");
dojo.xhrGet({ url:"url1", handleAs:"json", load: function(data){
createDataStore(data);
dojo.xhrGet( {
url:"url2",
handleAs:"json",
load: function(data){
updateDataStore(data);
}
});
} });
You could use a global variable to get the state of the data store and periodically check if it has been created:
CreateEmptyGrid();
dojo.require("dojo._base.xhr");
hasDataStore=false;
dojo.xhrGet({
url:"url1",
handleAs:"json",
load: function(data){ createDataStore(data); hasDataStore=true; }
});
dojo.xhrGet(
{
url:"url2",
handleAs:"json",
load: function(data){
itvCheckDataStore=setInterval(function() {
if (hasDataStore) {
clearInterval(itvCheckDataStore);
updateDataStore(data);
}
},256);
}
});
I didn't try the code, so I can't say if I might have missed some closing brackets or so.

Changing Jquery variables

I have some jquery that inputs text into a database and then clears the textarea. However the textarea is not being cleared. Below is the code indicating which line doenst work. When i replace this line with alert(commentbox) I get the value of the comment box so i know that the variable is working. I just don't know how to clear the variable.
Jquery:
<script type='text/javascript'>
$('document').ready(function () {
$('.commentContainer').load('../writecomment.php');
$("form").on("submit", function (e) {
e.preventDefault();
var $form = $(this);
var commentbox = $(this).children('.commentBox').val();
$.ajax({
"url": $form.attr("action"),
"data": $form.serialize(),
"type": $form.attr("method"),
success: function () {
$('.commentContainer').load('../writecomment.php');
commentbox = ""; //this line doesnt work
}
});
});
});
I should also mention that when i replace the bad line with $('.commentBox').val(''); the values clear. the problem is that it clears all the textareas, not just the one that i use .children() to find.
</script>
var commentboxElem = $(this).children('.commentBox');
and in your success:
commentboxElem.val('');
var $form = $(this);
var commentboxObj = $(this).children('.commentBox');
var commentBoxVal=commentboxObj.val();
$.ajax({
"url": $form.attr("action"),
"data": $form.serialize(),
"type": $form.attr("method"),
success: function () {
$('.commentContainer').load('../writecomment.php');
commentboxObj.val(""); //this will work
}
});
with commentbox="", you were trying to update the content of a javascript variable, not the actual textbox.

How to refilter a dojo DataGrid?

I have a DataGrid that I already filtered using grid.filter(query, rerender). If I add another item, after calling save() I see the new item in the grid even though it shouldn't display because of the filter. I'm thinking "ok, I'll just filter it again when the store finishes saving. But after calling grid.filter with the same query all the rows disappear. Any ideas what I might be doing wrong?
Code to filter the grid:
var filterQuery = dijit.byId("filterTextbox").attr("value");
var grid = dijit.byId("grid");
var queryValue = "*";
if(filterQuery != ""){
queryValue += filterQuery + "*";
}
grid.filter({name: queryValue}, true);
Code to add new items to the grid
function addItemToGrid(newItemName){
var newItem = {name: newItemName};
var grid = dijit.byId("grid");
var store = grid.store;
store.addItem(newItem);
store.save();
}
Try to use:
store.newItem(newItem);
instead of store.addItem(newItem);
(addItem is not a standard method to add items into store)
Inside of your addItemToGrid function, try adding an onComplete listener to your save method and sort or filter the grid in the onComplete function
store.save({onComplete: function() {
grid.filter({name: queryValue}, true);
}
});
I had the same problem and only managed to fix it by running the grid filter periodically in the background with the help of some jQuery. Here is some sample code; hope this helps someone else having problems with this.
// ADD JQUERY
<script src="http://code.jquery.com/jquery-latest.js"></script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
$(document).ready(function() {
function filterTheDataGrid() {
if (dijit.byId("grid") != undefined) {
dijit.byId("grid").filter({color: "Red"});
}
}
// RUN THE filterTheDataGrid FUNCTION EVERY ONE SECOND (1000 MILLISECONDS) //
// LOWER '1000' FOR FASTER REFRESHING, MAYBE TO 500 FOR EVERY 0.5 SECOND REFRESHES //
var refreshDataGrid = setInterval(function() { filterTheDataGrid(); }, 1000);
}
</script>
.
// PUT THIS IN THE <HEAD> OF THE PAGE
<script type="text/javascript">
// SETUP THE LAYOUT FOR THE DATA //
var layoutItems = [[
{
field: "id",
name: "ID",
width: '5px',
hidden: true
},
{
field: "color",
name: "Color",
width: '80px'
}
]];
// Create an empty datastore //
var storeData = {
identifier: 'id',
label: 'id',
items: []
}
var store3 = new dojo.data.ItemFileWriteStore( {data : storeData} );
</script>
.
// PUT THIS IN THE <HTML> OF THE PAGE
<div id="grid" dojoType="dojox.grid.DataGrid" jsId="grid5" store="store3" structure="layoutItems" query="{ type: '*' }" clientSort="true" rowsPerPage="40"></div>
.
<script type="text/javascript">
function addItemToGrid(formdata) {
// THIS FUNCTION IS CALLED BY A DIALOG BOX AND GETS FORM DATA PASSED TO IT //
var jsonobj = eval("(" + dojo.toJson(formData, true) + ")");
var myNewItem = {
id: transactionItemID,
color: jsonobj.color
};
// Insert the new item into the store:
store3.newItem(myNewItem);
store3.save({onComplete: savecomplete, onError: saveerror});
}
</script>

looping through DOM / mootools sortables

I can't seem to get a handle on my list of sortables. They are a list of list elements, each with a
form inside, which I need to get the values from.
Sortables.implement({
serialize: function(){
var serial = [];
this.list.getChildren().each(function(el, i){
serial[i] = el.getProperty('id');
}, this);
return serial;
}
});
var sort = new Sortables('.teams', {
handle: '.drag-handle',
clone: true,
onStart: function(el) {
el.fade('hide');
},
onComplete: function(el) {
//go go gadget go
order = this.serialize();
alert(order);
for(var i=0; i<order.length;i++) {
if (order[i]) {
//alert(order[i].substr(5, order[i].length));
}
}
}
});
the sortables list is then added to a list in a loop with sort.addItems(li); . But when I try to get the sortables outside of the sortables onComplete declaration, js says this.list is undefined.
Approaching the problem from another angle:
Trying to loop through the DOM gives me equally bizarre results. Here are the firebug console results for some code:
var a = document.getElementById('teams').childNodes;
var b = document.getElementById('teams').childNodes.length;
try {
console.log('myVar: ', a);
console.log('myVar.length: ', b);
} catch(e) {
alert("error logging");
}
Hardcoding one li element into the HTML (rather than being injected via JS) changes length == 1, and allows me to access that single element, leading me to believe that accessing injected elements via the DOM is the problem (for this method)
Trying to get the objects with document.getElementById('teams').childNodes[i] returns undefined.
thank you for any help!
not sure why this would fail, i tried it in several ways and it all works
http://www.jsfiddle.net/M7zLG/ test case along with html markup
here is the source that works for local refernece, using the native built-in .serialize method as well as a custom one that walks the dom and gets a custom attribute rel, which can be your DB IDs in their new order (I tend to do that)
var order = []; // global
var sort = new Sortables('.teams', {
handle: '.drag-handle',
clone: true,
onStart: function(el) {
el.fade('hide');
},
onComplete: function(el) {
//go go gadget go
order = this.serialize();
}
});
var mySerialize = function(parentEl) {
var myIds = [];
parentEl.getElements("li").each(function(el) {
myIds.push(el.get("rel"));
});
return myIds;
};
$("saveorder").addEvents({
click: function() {
console.log(sort.serialize());
console.log(order);
console.log(mySerialize($("teams")));
}
});