Ext js View
There is option called treelist in the view. when use some static data in the tree list it working fine. when changed to dynamic data load from store it not loading.
Ext.define('Count.view.History', {
extend : 'Ext.Panel',
xtype : 'historyView',
controller : 'main',
requires : ['Count.store.History'],
width : '100%',
height : '100%',
title : 'History',
closable : true,
autoDestroy : true,
centered : true,
layout : 'fit',
fullscreen : true,
scrollable : true,
items :
[
{
xtype : 'tree',
store : 'History'
}
],
});
Store
Ext.define('Count.store.History', {
extend : 'Ext.data.TreeStore',
autoLoad : false,
alias : 'store.HistoryStore',
requires : ['Count.Db', 'Count.model.history'],
config :
{
model : 'Count.model.history'
},
loadData : function()
{
var meObj=this;
var sqlString = "SELECT tbl_list.ListName, tbl_list.MasterCount, tbl_sub_count.masterCountId, tbl_sub_count.subCount FROM tbl_list INNER JOIN tbl_sub_count ON tbl_list.Id=tbl_sub_count.masterCountID where tbl_sub_count.status='1';";
Count.Db.selectQuery(sqlString, meObj.callbackLoadData, meObj);
},
callbackLoadData : function(results, scope)
{
var store = scope;
var len = results.rows.length;
var MainListArray = {'root': {'expanded': true, 'children': []}};
var masterCountId = "";
var resultObj = "";
for (var i=0; i<len; i++)
{console.log(results);
if(masterCountId == "" || masterCountId != results.rows.item(i).masterCountId)
{
if(resultObj != "")
{
MainListArray.root.children.push(resultObj);
}
resultObj = {'ListName': results.rows.item(i).ListName, 'expanded': true, 'children': []}
masterCountId = results.rows.item(i).masterCountId;
var subListObj = {'subCount': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
else
{
var subListObj = {'subCount': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
}
if(resultObj != "")
{
MainListArray.root.children.push(resultObj);
}
console.log(MainListArray);
store.setData(MainListArray);
}
});
Controller
onShowHistory:function()
{
var showHistoryView = Ext.create('Count.view.History');
var storeHistory = Ext.create('Count.store.History');
storeHistory.loadData();
Ext.Viewport.add(showHistoryView);
}
But when call loadData function in store data looping loading infinitely?
I tried all the solution before answered few solutions. But it won't work.
Anyone please suggest me good solution for this.
Thanks in Advance.
I can't test without a working fiddle, anyway it seems you are not filling the TreeStore correctly.
Here is some changes can help you to load/view data correctly. First try to initialize the store with an empty root node adding root: {} in your store config.
And then try to load data using setRoot instead of setData, change
var MainListArray = {'root': {'expanded': true, 'children': []}};
with
var MainListArray = {'ListName': 'root', 'expanded': true, 'children': []};
and then
store.setData(MainListArray);
with
store.setRoot(MainListArray);
Finally got the solution.
Store.js
Ext.define('Count.store.History', {
extend : 'Ext.data.TreeStore',
alias : 'store.HistoryStore',
requires : ['Count.Db', 'Count.model.History'],
autoLoad: false,
rootProperty: "root",
root: {},
loadData : function()
{
var meObj=this;
var sqlString = "SELECT list.ListName, list.Count, sub_count.masterCountId, tbl_sub_count.subCount FROM tbl_japa_list INNER JOIN tbl_sub_count ON list.Id=tbl_sub_count.masterCountID where tbl_sub_count.status='1';";
Count.Db.selectQuery(sqlString, meObj.callbackLoadData, meObj);
}, callbackLoadData : function(results, scope)
{
var store = scope;
var len = results.rows.length;
var MainListArray = { 'expanded': true, 'children': []};
var CountId = "";
var resultObj = "";
for (var i=0; i<len; i++)
{
if(CountId == "" || CountId != results.rows.item(i).CountId)
{
if(resultObj != "")
{
MainListArray.children.push(resultObj);
}
resultObj = {'text': results.rows.item(i).ListName, 'expanded': true, 'children': []}
CountId = results.rows.item(i).CountId;
var subListObj = {'text': results.rows.item(i).subCount, 'leaf': true}
resultObj.children.push(subListObj);
}
else
{
var subListObj = {'text': results.rows.item(i).sub, 'leaf': true}
resultObj.children.push(subListObj);
}
}
if(resultObj != "")
{
MainListArray.children.push(resultObj);
}
store.setRoot(MainListArray);
}
View .js
item :[ { xtype : 'treelist' }]
Related
I need to create a phone mask for some columns when I add or edit a record using jqGrid (my jqGrid version is 4.5.4).
Below my code:
this.montarGRID = function (p_gridName, p_dados, p_header, p_descriptor, p_contentName, p_primaryKey, p_filtroGrid) {
jQuery("#" + p_gridName).jqGrid( {
data : p_dados,
datatype : "local",
sortable : true,
colNames : p_header,
colModel : p_descriptor,
...
This grid is generated dynamically. I pass a json with the content of colModel.
[
{"formatter":"integer","index":"id","hidden":true,"sortable":true,"sorttype":"integer","width":75,"align":"center","name":"id"},
{"formatter":"telefone","index":"TELCONTATO01","search":true,"hidden":false,"sorttype":"text","sortable":true,"width":0,"align":"right","name":"TELCONTATO01","editoptions":{"text":true,"required":false,"dataInit":"function (elem) { return mostra_telefone(elem); }"},"editrules":{"text":true,"required":false,"dataInit":"function (elem) { return mostra_telefone(elem); }"},"editable":true},
{"formatter":"telefone","index":"TELCONTATO02","search":true,"hidden":false,"sorttype":"text","sortable":true,"width":0,"align":"right","name":"TELCONTATO02","editoptions":{"text":true,"required":false,"dataInit":"function (elem) { return mostra_telefone(elem); }"},"editrules":{"text":true,"required":false,"dataInit":"function (elem) { return mostra_telefone(elem); }"},"editable":true}
]
the method that generates the phone mask ...
(function($) {
'use strict';
$.extend($.fn.fmatter, {
mostra_telefone : function (elem) {
$(elem).mask("(99)9999-9999?");
}
});
})(jQuery);
But it is never invoked when I select, change or add the record.
Here is a pice of code which do the desired behavior. For this purpose we use inputpask plugin.
$("#jqGrid").jqGrid({
...
colModel :[
{
name: 'Telephone',
width: 100,
formatter: function(cellvalue, options, rowObject) {
var re = new RegExp("([0-9]{3})([0-9]{3})([0-9]{4,6})", "g");
return cellvalue.replace(re, "($1) $2-$3");
},
unformat : function(cellvalue, options, rowObject) {
return cellvalue.replace("(",'').replace(") ",'').replace("-",'');
},
editable: true,
edittype: "custom",
editoptions :{
custom_element : function(value, options) {
var el = document.createElement("input");
el.type="text";
el.value = value;
$(el).addClass('inline-edit-cell ui-widget-content ui-corner-all').inputmask({"mask": "(999) 999-9999"});
return el;
},
custom_value : function(elem, operation, value) {
if(operation === 'get') {
return $(elem).val().replace("(",'').replace(") ",'').replace("-",'').replace(/\_/g,'');;
} else if(operation === 'set') {
$(elem).val(value);
}
}
},
editrules : {
requiered : true,
custom : true,
custom_func : function(val, name) {
// special replace mask at end
var cel = val.replace("(",'').replace(") ",'').replace("-",'').replace(/\_/g,'');
if(cel.length !== 10) {
return [false,"Please, enter correct phone number"];
}
return [true,""];
}
}
},
....
],
....
});
This code should work in you version too.
Also here is a link to the demo.
I solved the problem with this:
function custom_element_telefone(value, options){
var el = document.createElement("input");
el.type="text";
el.value = value;
$(el).addClass('inline-edit-cell ui-widget-content ui-corner-all').inputmask({"mask": "(99)9999-9999#"});
return el;
};
this.montarGRID = function (p_gridName, p_dados, p_header, p_descriptor, p_contentName, p_primaryKey, p_filtroGrid) {
p_descriptor.forEach(col => {
if (!col.editoptions) return;
if (!col.editoptions.custom_element) return;
switch (col.editoptions.custom_element) {
case "custom_element_telefone":
col.editoptions.custom_element = custom_element_telefone;
break;
}
});
jQuery("#" + p_gridName).jqGrid( {
data : p_dados,
datatype : "local",
sortable : true,
colNames : p_header,
colModel : p_descriptor,
...
Overview
I developed an employment application that has several different features. Long story short, there are a few sections within the application that allow you to add employment history, add address history, accident and license history, etc. At the end of the whole shebang, I build a JSON object and prepare it for submission to the server. That's the gist.
The Problem
Let's say you have a ton of job history over the last ten years, and you obviously will put almost all of it that you can remember, or that is relevant on the application. Let's say it's 12 jobs. Let's say you also have 3 total addresses in your address history. This will give us a total of 13 clone objects. Now the loop that I generated will read these just fine, but what happens is, and I'm guessing it's my loop structure, is that when the count on the cloned objects gets so high, it starts to cause a timeout error while looping and basically freezes.
The Fix
I need to find the error in my loop that may or may not be causing this.
I'll post my code below and a link to the live application so anyone who wants to take a shot at this can play around with it and see what I mean. It's taken a couple days of some incredible debugging to even get this far with it.
Resources
$('#applicationForm').submit(function(e){
e.preventDefault(); //stop the form from the default submission
$('body').spin('large');
var application_info = new Object(); //start the application form Object
$('#submit-btn').prop('disabled', true);
if(checkHeadings(sections)){
for(var i = 0; i < sections.length; i++){
application_info[sections[i]] = new Object(); //create a new object for each section
//traverse each select by form control
$("#"+sections[i]).find(".form-control").map(function (index, element){
$(element).each(function (index){
var name = $(element).attr('name');
if((sections[i] !== 'addressRecords') && (sections[i] !== 'employmentHistory') && (sections[i] !== 'drivingExperience')){
application_info[sections[i]][$(element).attr('name')] = $('[name="'+name+'"]').eq(index).val(); //application_info
}else if(sections[i] === 'addressRecords'){
application_info['addresses'] = $('.form-control').map(function (index, element) {
return {
line1: $('[name="address"]').eq(index).val(),
line2: $('[name="address2"]').eq(index).val(),
city: $('[name="city"]').eq(index).val(),
state: $('[name="state"]').eq(index).val(),
zip: $('[name="zip"]').eq(index).val(),
from_date: $('[name="from_date"]').eq(index).val(),
to_date: $('[name="to_date"]').eq(index).val()
};
}).get();
}else if(sections[i] === 'employmentHistory'){
application_info['employmentHistory'] = $('.form-control').map(function (index, element) {
return {
from_date: $('[name="emp_from_date"]').eq(index).val(),
to_date: $('[name="emp_to_date"]').eq(index).val(),
company: $('[name="company"]').eq(index).val(),
contact: $('[name="supervisor"]').eq(index).val(),
phone: $('[name="company_phone"]').eq(index).val(),
address: $('[name="company_address"]').eq(index).val(),
city: $('[name="company_city"]').eq(index).val(),
state: $('[name="company_state"]').eq(index).val(),
zip: $('[name="company_zip"]').eq(index).val(),
position_held: $('[name="position"]').eq(index).val(),
reason_left: $('[name="reason_left"]').eq(index).val(),
fmscr: $('.fmscr:checked').eq(index).val(),
drug_testing: $('.drug_testing:checked').eq(index).val()
};
}).get();
}else if(sections[i] === 'drivingExperience'){
application_info['drivingExperience'] = {
tt_from_date : $('[name="tt-from-date"]').eq(index).val(),
tt_to_date : $('[name="tt-to-date"]').eq(index).val(),
tt_miles : $('[name="tt-miles"]').eq(index).val(),
st_from_date : $('[name="st-from-date"]').eq(index).val(),
st_to_date : $('[name="st-to-date"]').eq(index).val(),
st_miles : $('[name="st-miles"]').eq(index).val(),
accident_records : $('.form-control').map(function (index, element) {
return {
date : $('[name="accident-date"]').eq(index).val(),
nature : $('[name="nature"]').eq(index).val(),
location : $('[name="location"]').eq(index).val(),
fatalities : $('[name="fatalities"]').eq(index).val(),
injuries : $('[name="injuries"]').eq(index).val()
};
}).get(),
traffic_citations : $('.form-control').map(function (index, element) {
return {
location : $('[name="citation-location"]').eq(index).val(),
date : $('[name="citation-date"]').eq(index).val(),
charge : $('[name="charge"]').eq(index).val(),
penalty : $('[name="penalty"]').eq(index).val()
};
}).get(),
license_records : $('.form-control').map(function (index, element) {
return {
state : $('[name="license_state"]').eq(index).val(),
license_no : $('[name="license_no"]').eq(index).val(),
type : $('[name="license_type"]').eq(index).val(),
endorsements : $('[name="endorsements"]').eq(index).val(),
date : $('[name="license_date"]').eq(index).val()
};
}).get(),
qa : $('[name="qa"]:checked').eq(index).val(),
qa_explain : $('[name="qa_explain"]').eq(index).val(),
qb : $('[name="qb"]:checked').eq(index).val(),
qb_explain : $('[name="qb_explain"]').eq(index).val(),
qc : $('[name="qc"]:checked').eq(index).val(),
qc_explain : $('[name="qc_explain"]').prop('checked') ? 1 : -1,
qd : $('[name="qd"]:checked').eq(index).val()
};
}
});
}).get();
if($('input[name="other"]').is(":visible")){
application_info['generalInformation']['other'] = $('input[name="other"]').val();
}else{
application_info['generalInformation']['other'] = "";
}
application_info['selfIdentification'] = new Object();
application_info['selfIdentification']['race'] = $('[name="race"]').is(":checked") ? $('[name="race"]:checked').val() : "";
application_info['selfIdentification']['gender'] = $('[name="gender"]').is(":checked") ? $('[name="gender"]:checked').val() : "";
application_info['selfIdentification']['disability'] = $('[name="disability"]').is(":checked") ? $('[name="disability"]:checked').val() : "";
application_info['selfIdentification']['veteran'] = $('[name="veteran"]').is(":checked") ? $('[name="veteran"]:checked').val() : "";
}
$.ajax({
url: '../assets/server/application_process.php',
type : 'post',
data : application_info,
dataType : 'JSON',
success : function (data){
$('body').spin(false);
if(!data.errors){
$('#applicationForm').html("<h3>"+data.message+"</h3>");
}else{
bootbox.alert(data.message);
}
}
});
}else{
$('body').spin(false);
$('#submit-btn').prop('disabled', false);
}
});
The application:
http://www.driveforeagle.com/apply/page2
In this part it seems like you have extra iteration.
$("#"+sections[i]).find(".form-control").map(function (index, element){
$(element).each(function (index){
...
})
})
You don't need $(element).each(function (index){...} - you are already iterating the selects in map.
EDIT
I tried to refactor your code as I understood your logic, expand below. There is still room for optimization but I hope that helps.
$('#applicationForm').submit(function(e) {
e.preventDefault(); //stop the form from the default submission
$('body').spin('large');
var application_info = { //start the application form Object
generalInformation: {
other: $('input[name="other"]').is(":visible") ? $('input[name="other"]').val() : ""
},
selfIdentification: {
race: $('[name="race"]').is(":checked") ? $('[name="race"]:checked').val() : "",
gender: $('[name="gender"]').is(":checked") ? $('[name="gender"]:checked').val() : "",
disability: $('[name="disability"]').is(":checked") ? $('[name="disability"]:checked').val() : "",
veteran: $('[name="veteran"]').is(":checked") ? $('[name="veteran"]:checked').val() : ""
}
};
$('#submit-btn').prop('disabled', true);
if (checkHeadings(sections)) {
var obj = {};
for (var i = 0; i < sections.length; i++) {
var sectionId = sections[i],
$section = $("#" + sectionId);
//traverse each select by form control
switch (sectionId) {
case 'addressRecords':
obj['addresses'] = [];
$section.find('[name="address"]').each(function(index, element) {
obj['addresses'].push({
line1: $section.find('[name="address"]').eq(index).val(),
line2: $section.find('[name="address2"]').eq(index).val(),
city: $section.find('[name="city"]').eq(index).val(),
state: $section.find('[name="state"]').eq(index).val(),
zip: $section.find('[name="zip"]').eq(index).val(),
from_date: $section.find('[name="from_date"]').eq(index).val(),
to_date: $section.find('[name="to_date"]').eq(index).val()
});
});
break;
case 'employmentHistory':
obj['employmentHistory'] = [];
$section.find('[name="address"]').each(function(index, element) {
obj['employmentHistory'].push({
from_date: $section.find('[name="emp_from_date"]').eq(index).val(),
to_date: $section.find('[name="emp_to_date"]').eq(index).val(),
company: $section.find('[name="company"]').eq(index).val(),
contact: $section.find('[name="supervisor"]').eq(index).val(),
phone: $section.find('[name="company_phone"]').eq(index).val(),
address: $section.find('[name="company_address"]').eq(index).val(),
city: $section.find('[name="company_city"]').eq(index).val(),
state: $section.find('[name="company_state"]').eq(index).val(),
zip: $section.find('[name="company_zip"]').eq(index).val(),
position_held: $section.find('[name="position"]').eq(index).val(),
reason_left: $section.find('[name="reason_left"]').eq(index).val(),
fmscr: $section.find('.fmscr:checked').eq(index).val(),
drug_testing: $section.find('.drug_testing:checked').eq(index).val()
});
});
break;
case 'drivingExperience':
obj['drivingExperience'] = {
tt_from_date: $section.find('[name="tt-from-date"]').eq(0).val(),
tt_to_date: $section.find('[name="tt-to-date"]').eq(0).val(),
tt_miles: $section.find('[name="tt-miles"]').eq(0).val(),
st_from_date: $section.find('[name="st-from-date"]').eq(0).val(),
st_to_date: $section.find('[name="st-to-date"]').eq(0).val(),
st_miles: $section.find('[name="st-miles"]').eq(0).val(),
accident_records: [],
traffic_citations: [],
license_records: [],
qa: $section.find('[name="qa"]:checked').eq(0).val(),
qa_explain: $section.find('[name="qa_explain"]').eq(0).val(),
qb: $section.find('[name="qb"]:checked').eq(0).val(),
qb_explain: $section.find('[name="qb_explain"]').eq(0).val(),
qc: $section.find('[name="qc"]:checked').eq(0).val(),
qc_explain: $section.find('[name="qc_explain"]').prop('checked') ? 1 : -1,
qd: $section.find('[name="qd"]:checked').eq(0).val()
};
$section.find('[name="accident-date"]').each(function(index, element) {
obj['accident_records'].push({
date: $section.find('[name="accident-date"]').eq(index).val(),
nature: $section.find('[name="nature"]').eq(index).val(),
location: $section.find('[name="location"]').eq(index).val(),
fatalities: $section.find('[name="fatalities"]').eq(index).val(),
injuries: $section.find('[name="injuries"]').eq(index).val()
});
});
$section.find('[name="citation-location"]').each(function(index, element) {
obj['traffic_citations'].push({
location: $section.find('[name="citation-location"]').eq(index).val(),
date: $section.find('[name="citation-date"]').eq(index).val(),
charge: $section.find('[name="charge"]').eq(index).val(),
penalty: $section.find('[name="penalty"]').eq(index).val()
});
});
$section.find('[name="license_state"]').each(function(index, element) {
obj['license_records'].push({
state: $section.find('[name="license_state"]').eq(index).val(),
license_no: $section.find('[name="license_no"]').eq(index).val(),
type: $section.find('[name="license_type"]').eq(index).val(),
endorsements: $section.find('[name="endorsements"]').eq(index).val(),
date: $section.find('[name="license_date"]').eq(index).val()
});
});
break;
default:
// = if (( !== 'addressRecords') && (sections[i] !== 'employmentHistory') && (sections[i] !== 'drivingExperience')) {
obj[sectionId][element.name] = element.value;
break;
}
application_info[sectionId] = obj;
}
$.ajax({
url: '../assets/server/application_process.php',
type: 'post',
data: application_info,
dataType: 'JSON',
success: function(data) {
$('body').spin(false);
if (!data.errors) {
$('#applicationForm').html("<h3>" + data.message + "</h3>");
} else {
bootbox.alert(data.message);
}
}
});
} else {
$('body').spin(false);
$('#submit-btn').prop('disabled', false);
}
});
I am having trouble to bind a String value of 00 and 98 to false and true. I have found quite a few possible solutions but none of them works for me and I don't quite understand why.
Suppose I receive data from a server and create a JSON Model and set that to the table model.
function createTableColumns(columns) {
var oTable = sap.ui.getCore().byId("mainTable");
var statusTemplate = new sap.ui.commons.CheckBox({
editable: false,
// THIS WAS MY FIRST ATTEMPT TO GET IT WORKING
//checked: {
// path: "{TableModel>status}",
// formatter: function(val) {
// console.log(val);
// return val === "98";
// }
//}
});
// SECOND ATTEMPTS, DOESN'T WORK EITHER
statusTemplate.bindProperty("checked", "{TableModel>status}", function(val) { return val === "98"; });
for(var i = 0; i < columns.length; i++) {
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: columns[i]}),
name: columns[i],
flexible: false,
autoResizable: true,
template: columns[i] === 'status' ? statusTemplate : new sap.ui.commons.TextView({text: "{TableModel>" + columns[i] + "}"}),
sortProperty: columns[i],
filterProperty: columns[i],
}));
}
}
Both ways in the code above do not work. I don't know whether it is the logic or whether I am using the model wrong. Every other (TextView) Column displays data to which it is bound... so I believe that the binding is correct!?
I also have tried this way but that doesn't work at all for me: OpenUI5 binding property with a function, instead of direct access
I keep on getting the error that "00" is not a valid value for the checkbox.
Am I doing something obviously wrong?
EDIT: Current state
This function is basically called everytime the user switches
the table in the application. The old data (rows and columns) will be
deleted and filled new. The parameter columns contains an array of
strings of the column names! No data is in the data model yet!!!
function createTableColumns(columns) {
var oTable = sap.ui.getCore().byId("mainTable");
oTable.destroyColumns();
sap.ui.getCore().setModel(null, "TableModel");
var statusCheckBoxTemplate = new sap.ui.commons.CheckBox({
text: "{TableModel>status}",
editable: false,
checked: {
path: "{TableModel>status}",
formatter: function(v) {
console.debug(v);
if(v === "98") return true;
else return false;
}
}
});
for(var i = 0; i < columns.length; i++) {
if(columns[i] !== 'rowid') {
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: columns[i]}),
name: columns[i],
flexible: false,
autoResizable: true,
template: columns[i] === 'status' ? statusCheckBoxTemplate : new sap.ui.commons.TextView({text: "{TableModel>" + columns[i] + "}"}),
sortProperty: columns[i],
filterProperty: columns[i],
}));
}
}
}
After a user selected a table to display it sits there only displaying
the columns. Data is fetched from the server (ajax call) as an JSON object and a data model is created. It all works fine. Data is bound without problems and displayed correctly.
function tableBtnReloadPressed() {
// ajax call
var tabledata = readTableData(ACTIVE_TABLE);
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(tabledata);
sap.ui.getCore().setModel(oModel, "TableModel");
var oTable = sap.ui.getCore().byId("mainTable");
oTable.setModel(oModel);
oTable.bindRows("TableModel>/");
}
EDIT: Third try with factory
function createTableColumns(columns) {
var oTable = sap.ui.getCore().byId("mainTable");
oTable.destroyColumns();
sap.ui.getCore().setModel(null, "TableModel");
sap.ui.model.SimpleType.extend("BooleanStringType", {
formatValue: function(s) {
console.debug(typeof s, s);
return s === "98";
},
parseValue: function(s) {
console.debug(typeof s, s)
return s ? "98" : "00";
},
validateValue: function(s) {
console.debug(typeof s, s)
}
});
var statusCheckBoxTemplate = new sap.ui.commons.CheckBox({
text: "{TableModel>status}",
editable: false,
//checked: {
// path: "{TableModel>status}",
// formatter: function(v) {
// console.debug(v);
// if(v === "98") return true;
// else return false;
// }
//}
});
statusCheckBoxTemplate.bindProperty("checked", {
path: "{TableModel>status}",
type: new BooleanStringType()
});
for(var i = 0; i < columns.length; i++) {
if(columns[i] !== 'rowid') {
oTable.addColumn(new sap.ui.table.Column({
label: new sap.ui.commons.Label({text: columns[i]}),
name: columns[i],
flexible: false,
autoResizable: true,
template: columns[i] === 'status' ? statusCheckBoxTemplate : new sap.ui.commons.TextView({text: "{TableModel>" + columns[i] + "}"}),
sortProperty: columns[i],
filterProperty: columns[i],
}));
}
}
}
You should simplify to get it working. First thing is to use a textview / label to check if the binding is working. Only then change to the checkbox and use a formatter / custom datatype for the conversion.
For instance, this is not valid (from the code above):
checked: {
path: "{TableModel>status}",
because when you pass an explicit path property, you should not use the {} in the string.
Ok, I put this into jsbin and played arount wiht it a bit. jsbin with solution
The correct template for the checkbox is this:
var statusCheckBoxTemplate = new sap.ui.commons.CheckBox({
text: "{TableModel>status}",
editable: false,
checked: {
path: "TableModel>status",
formatter: function(v) {
return(v === "98");
}
}
});
Edit: #jumpifzero beat me to it. But I wanted to edit my post for a complete picture. Such an easy to miss answer. ^^"
I have tried to reload the data populated by an ajax call but I cant get it to work, it shows the old data even after using the reload method. The thing is that if I change some variables to populate a different data and try to call the following code without refreshing the page it does not reload the updated data =/ Here is my code:
function populateDataGrid() {
$.ajaxSetup({async: false});
var gridinfo="";
$.post("lib/function.php",{activity: activity, shift: shift, date: date},
function (output){
gridinfo = JSON.parse(output);
});
$.ajaxSetup({async: true});
// INITIALIZING THE DATAGRID
var dataSource = new StaticDataSource({
columns: [
{
property: 'id',
label: '#',
sortable: true
},
{
property: 'date',
label: 'date',
sortable: true
},
....
],
formatter: function (items) {
var c=1;
$.each(items, function (index, item) {
item.select = '<input type="button" id="select'+c+'" class="select btn" value="select" onclick="">';
c=c+1;
});
},
data: gridinfo,
delay:300
});
$('#grid').datagrid({
dataSource: dataSource
});
$('#grid').datagrid('reload');
$('#modal-fast-appointment-results').modal({show:true});
}
I found a solution... I had to create a new DataSource (lets call it "AjaxDataSource") and add the ajax request functionality within the data constructor:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore'], factory);
} else {
root.AjaxDataSource = factory();
}
}(this, function () {
var AjaxDataSource = function (options) {
this._formatter = options.formatter;
this._columns = options.columns;
this._delay = options.delay || 0;
this._data = options.data;
};
AjaxDataSource.prototype = {
columns: function () {
return this._columns;
},
data: function (options, callback) {
var self = this;
setTimeout(function () {
var data;
$.ajax({
url: 'getdata.php',
type: 'POST',
data: 'param1:param1,param2,param2,...,paramN:paramN', // this is optional in case you have to send some params to getdata.php
dataType: 'json',
async: false,
success: function(result) {
data = result;
},
error: function(data){
//in case we want to debug and catch any possible error
// console.log(data);
}
});
// SEARCHING
if (options.search) {
data = _.filter(data, function (item) {
var match = false;
_.each(item, function (prop) {
if (_.isString(prop) || _.isFinite(prop)) {
if (prop.toString().toLowerCase().indexOf(options.search.toLowerCase()) !== -1) match = true;
}
});
return match;
});
}
var count = data.length;
// SORTING
if (options.sortProperty) {
data = _.sortBy(data, options.sortProperty);
if (options.sortDirection === 'desc') data.reverse();
}
// PAGING
var startIndex = options.pageIndex * options.pageSize;
var endIndex = startIndex + options.pageSize;
var end = (endIndex > count) ? count : endIndex;
var pages = Math.ceil(count / options.pageSize);
var page = options.pageIndex + 1;
var start = startIndex + 1;
data = data.slice(startIndex, endIndex);
if (self._formatter) self._formatter(data);
callback({ data: data, start: start, end: end, count: count, pages: pages, page: page });
}, this._delay)
}
};
return AjaxDataSource;
}));
After defining the new DataSource, we just need to create it and call the datagrid as usual:
function populateDataGrid(){
// INITIALIZING THE DATAGRID
var dataSource = new AjaxDataSource({
columns: [
{
property: 'id',
label: '#',
sortable: true
},
{
property: 'date',
label: 'date',
sortable: true
},
....
],
formatter: function (items) { // in case we want to add customized items, for example a button
var c=1;
$.each(items, function (index, item) {
item.select = '<input type="button" id="select'+c+'" class="select btn" value="select" onclick="">';
c=c+1;
});
},
delay:300
});
$('#grid').datagrid({
dataSource: dataSource
});
$('#grid').datagrid('reload');
$('#modal-results').modal({show:true});
}
So now we have our datagrid with data populated via ajax request with the ability to reload the data without refreshing the page.
Hope it helps someone!
I modified the following example code to checkbox model. Here is the link
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.plugin.DragDrop
Two questions, first:
When dragging an item, all the selected items are being moved too. How to drag only one item each time?
Another question:
When dragging an item, it is forced to become selected. How to make it remain state unchange? (keep unselected when it is unselected before the drag, and vice versa)
And I am using version 4.2.1.
Here is the code modified from the given example:
Ext.onReady(function () {
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name'],
data: [
["Lisa"],
["Bart"],
["Homer"],
["Marge"]
],
proxy: {
type: 'memory',
reader: 'array'
}
});
Ext.create('Ext.grid.Panel', {
store: 'simpsonsStore',
selModel: {mode: 'SIMPLE'}, //added
selType: 'checkboxmodel', //added
columns: [{
header: 'Name',
dataIndex: 'name',
flex: true
}],
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize'
}
},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
});
Thank you!
You need to overwrite the dragZone in the DragDrop plugin, so it is only sending this record.
the drag has a mousedown event, which is selecting the rows in the grid (because this has a mousedown event too), so it's fired before drag ends.
To understand this I explain this events (for more info w3schools:
row selection event: this is a mousedown event on a grid row.
row drag event: drag = mousepress + (optional) mousemove, BUT: mousepress doesn't really exist so it decides it with the help of time between mousedown and mouseup
the time measurement is done with delayedTasks
if mouseup fired before the delayed time, then it will not be executed, else drag starts
row drop event: drop = dragged + mouseup
There are more ways to prevent this:
try to put the selection to another event, which is fired after drag starts, but it can be messy because this event is used lots of times...
it's selecting it on mousedown, but we deselect it on drag start event and at drop we prevent the selection, I do this in the code.
The working code:
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name'],
data: [["Lisa"], ["Bart"], ["Homer"], ["Marge"]],
proxy: {
type: 'memory',
reader: 'array'
}
});
Ext.create('Ext.grid.Panel', {
store: 'simpsonsStore',
selModel: {mode: 'SIMPLE'}, //added
selType: 'checkboxmodel', //added
columns: [
{header: 'Name', dataIndex: 'name', flex: true}
],
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize',
onViewRender : function(view) {
var me = this,
scrollEl;
if (me.enableDrag) {
if (me.containerScroll) {
scrollEl = view.getEl();
}
me.dragZone = new Ext.view.DragZone({
view: view,
ddGroup: me.dragGroup || me.ddGroup,
dragText: me.dragText,
containerScroll: me.containerScroll,
scrollEl: scrollEl,
//to remember if the row was selected originally or not
onBeforeDrag: function(data, e) {
var me = this,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
if (!selectionModel.isSelected(record)) {
data.rowSelected = false;
}
return true;
},
onInitDrag: function(x, y) {
var me = this,
data = me.dragData,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
//for deselect the dragged record
if (selectionModel.isSelected(record) && data.rowSelected == false) {
selectionModel.deselect(record, true);
}
//added the original row so it will handle that in the drag drop
data.records = [record];
me.ddel.update(me.getDragText());
me.proxy.update(me.ddel.dom);
me.onStartDrag(x, y);
return true;
}
});
}
if (me.enableDrop) {
me.dropZone = new Ext.grid.ViewDropZone({
view: view,
ddGroup: me.dropGroup || me.ddGroup,
//changed the selection at the end of this method
handleNodeDrop : function(data, record, position) {
var view = this.view,
store = view.getStore(),
index, records, i, len;
if (data.copy) {
records = data.records;
data.records = [];
for (i = 0, len = records.length; i < len; i++) {
data.records.push(records[i].copy());
}
} else {
data.view.store.remove(data.records, data.view === view);
}
if (record && position) {
index = store.indexOf(record);
if (position !== 'before') {
index++;
}
store.insert(index, data.records);
}
else {
store.add(data.records);
}
if (view != data.view) {
view.getSelectionModel().select(data.records);
}
}
});
}
}
}
},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
Thanks to Alexander's reply. After reading his reply, I get into the related source code of Extjs. And finally solved the problem of changing state back immediately instead of keep it remains unchange. The code:
Ext.onReady(function () {
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
fields: ['name'],
data: [
["Lisa"],
["Bart"],
["Homer"],
["Marge"]
],
proxy: {
type: 'memory',
reader: 'array'
}
});
Ext.create('Ext.grid.Panel', {
store: 'simpsonsStore',
/* Start: Code block added to the original example */
selModel: {mode: 'SIMPLE', onRowMouseDown: Ext.emptyFn /* throw away onRowMouseDown handler to answer Q2 */},
selType: 'checkboxmodel',
listeners: {
afterrender: function(){
/* override the original handleNodeDrop function to answer Q1 */
this.view.plugins[0].dropZone.handleNodeDrop = function(data, record, position) {
var view = this.view,
store = view.getStore(),
index, records, i, len;
if (data.copy) {
records = data.records;
data.records = [];
for (i = 0, len = records.length; i < len; i++) {
data.records.push(records[i].copy());
}
} else {
data.view.store.remove(data.records, data.view === view);
}
if (record && position) {
index = store.indexOf(record);
if (position !== 'before') {
index++;
}
store.insert(index, data.records);
}
else {
store.add(data.records);
}
// view.getSelectionModel().select(data.records);
};
/* override the original onInitDrag function to answer Q2 */
this.view.plugins[0].dragZone.onInitDrag = function(x, y){
var me = this,
data = me.dragData,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
// if (!selectionModel.isSelected(record)) {
// selectionModel.select(record, true);
// }
// data.records = selectionModel.getSelection();
data.records = [selectionModel.lastFocused];
me.ddel.update(me.getDragText());
me.proxy.update(me.ddel.dom);
me.onStartDrag(x, y);
return true;
};
}
},
/* End: Code block added to the original example */
columns: [{
header: 'Name',
dataIndex: 'name',
flex: true
}],
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize'
}
},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
});
If anyone is interested in 4.1.1 Solution here is the modified Alexander's code that keeps previously selected rows selected after drop.
I slightly modified onInitDrag to select already-selected row back on drag start,
and handleNodeDrop to get it selected on drop.
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name'],
data: [["Lisa"], ["Bart"], ["Homer"], ["Marge"]],
proxy: {
type: 'memory',
reader: 'array'
}
});
Ext.create('Ext.grid.Panel', {
store: 'simpsonsStore',
selModel: {mode: 'SIMPLE'}, //added
selType: 'checkboxmodel', //added
columns: [
{header: 'Name', dataIndex: 'name', flex: true}
],
resizable: true,
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize',
onViewRender : function(view) {
var me = this,
scrollEl;
if (me.enableDrag) {
if (me.containerScroll) {
scrollEl = view.getEl();
}
me.dragZone = new Ext.view.DragZone({
view: view,
ddGroup: me.dragGroup || me.ddGroup,
dragText: me.dragText,
containerScroll: me.containerScroll,
scrollEl: scrollEl,
//to remember if the row was selected originally or not
onBeforeDrag: function(data, e) {
var me = this,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
if (!selectionModel.isSelected(record)) {
data.rowSelected = false;
} else {
data.rowSelected = true;
}
return true;
},
onInitDrag: function(x, y) {
var me = this,
data = me.dragData,
view = data.view,
selectionModel = view.getSelectionModel(),
record = view.getRecord(data.item);
//to deselect the dragged record
if (selectionModel.isSelected(record) && data.rowSelected == false) {
selectionModel.deselect(record, true);
} else {
selectionModel.select(record, true);
}
//added the original row so it will handle that in the drag drop
data.records = [record];
me.ddel.update(me.getDragText());
me.proxy.update(me.ddel.dom);
me.onStartDrag(x, y);
return true;
}
});
}
if (me.enableDrop) {
me.dropZone = new Ext.grid.ViewDropZone({
view: view,
ddGroup: me.dropGroup || me.ddGroup,
//changed the selection at the end of this method
handleNodeDrop : function(data, record, position) {
var view = this.view,
store = view.getStore(),
selectionModel = view.getSelectionModel(),
index, records, i, len;
if (data.copy) {
records = data.records;
data.records = [];
for (i = 0, len = records.length; i < len; i++) {
data.records.push(records[i].copy());
}
} else {
data.view.store.remove(data.records, data.view === view);
}
if (record && position) {
index = store.indexOf(record);
if (position !== 'before') {
index++;
}
store.insert(index, data.records);
}
else {
store.add(data.records);
}
//select row back on drop if it was selected
if (data.rowSelected) {
selectionModel.select(data.records, true);
}
if (view != data.view) {
view.getSelectionModel().select(data.records);
}
}
});
}
}
}
},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
PS: easiest way to test - https://fiddle.sencha.com/#view/editor
just select 4.1.1 and copy-paste.