How can jTable work with Symfony 2? - javascript

I created a Datagrid with jTable, here is my JavaScript code in twig:
<script type="text/javascript">
$(document).ready(function () {
jQuery('#grid').jtable({
title: 'Table of product',
paging: true,
pageSize: 2,
sorting: true,
defaultSorting: 'Name ASC',
actions: {
listAction: '{{path("_db_show")}}',
createAction: '{{path("_serverproc")}}?action=create',
updateAction: '{{path("_serverproc")}}?action=update',
deleteAction: '{{path("_serverproc")}}?action=delete'
},
fields: {
id: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '40%'
},
Price: {
title: 'Price',
width: '20%'
},
Description: {
title: 'Description',
width: '30%',
}
}
});
//Load person list from server
$('#grid').jtable('load');
});
</script>
And the following is the php code in controller:
/**
* #Route("/show", name="_db_show")
* #Template()
*/
public function showAction()
{
$product = array({'id' => 1, 'Name' => "test",'Price' => "200",'Description' => "ok"});
$jTableResult = array();
$jTableResult['Result'] = "OK";
$jTableResult['Records'] = $product;
$JsonResponse = new JsonResponse($jTableResult);
return $JsonResponse;
}
The result I got is:
{"Result":"OK","Records":{"id":1,"Name":"test","Price":"200","Description":"ok"}}
Could someone kindly tell me what should I do to use jTable with Symfony? A working example will be great. Thank you very much.

try with:
$product = array('id' => 1, 'Name' => "test",'Price' => "200",'Description' => "ok");
without {} in array definition;

Related

EditableProTable Edit is Not working in ant design pro

I created table with ant design ProTable Component and its Edit function is not working. It showing error like this. ("Cannot read properties of undefined (reading 'toString')"). I tried many ways to solve this problem and cannot found a solution yet.
I want get table data from CSV file upload. That function is already working and data retrieved to the table.
const columns = [
{
title: 'First Name',
valueType: 'string',
typeof:'string',
dataIndex: 'fName',
formItemProps: () => {
return {
rules: [{ required: true, message: '' }],
};
},
},
{
title: 'Last Name',
valueType: 'string',
typeof:'string',
dataIndex: 'lName',
formItemProps: () => {
return {
rules: [{ required: true, message: '' }],
};
},
},
{
title: 'Email',
valueType: 'string',
typeof:'string',
dataIndex: 'email',
formItemProps: () => {
return {
rules: [{ required: true, message: '' }],
};
},
},
{
title: 'Position',
valueType: 'string',
typeof:'string',
dataIndex: 'position',
formItemProps: () => {
return {
rules: [{ required: true, message: '' }],
};
},
},
{
title: 'Actions',
valueType: 'option',
width: 200,
render: (text, record, _, action) => [
<a
key="delete"
onClick={() => {
setData(data.filter((item) => item.id !== record.id));
}}
>
Delete
</a>,
<a
key="editable"
onClick={() => {
var _a;
(_a = action === null || action === void 0 ? void 0 : action.startEditable) === null ||
_a === void 0
? void 0
: _a.call(action, record.id);
}}
>
Edit
</a>,
],
},
];
EditableProTable
rowKey="id"
actionRef={actionRef}
headerTitle=""
maxLength={5}
recordCreatorProps={false}
columns={columns}
request={async () => ({
data: data,
total: 3,
success: true,
})}
value={csvArray}
onChange={setCsvArray}
editable={{
type: 'multiple',
editableKeys,
onSave: async (rowKey, data, row) => {
await waitTime(2000);
},
onChange: setEditableRowKeys,
actionRender: (row, config, defaultDom) => [
defaultDom.save,
defaultDom.delete || defaultDom.cancel,
],
}}
/>[![enter image description here][1]][1]
The editableKeys array contains rows that are in the editing state
const [editableKeys, setEditableRowKeys] = useState(() => csvArray.map((item) => item.index)); // or .map((item=) => item.key));

How to read values from multiselector component

I am trying to use multiselector from EXTJS 6.5.2
This is the code that I am using to create multiselector with the values that I need
{
xtype: 'multiselector',
title: 'I caktohet:',
name: 'Caktohen[]',
bind: '{userfullname.value}',
fieldName: 'userfullname',
viewConfig: {
deferEmptyText: false,
emptyText: 'Askush i zgjedhur'
},
search: {
field: 'userfullname',
model: 'InTenders.model.UserModel',
store: {
type: 'users',
sorters: 'userfullname',
// proxy: {
// type: 'rest',
// limitParam: null,
// url: 'api/User'
// }
}
}
}
When I call form = win.down('form') records I can get all values except the multiselector values, they show like this on console.
Anyone can help me or guide me how to get the values?
Thank you.
//Code that I'm trying to get multiselector items and save them
saveTenderForm: function (button, e, eOpts) {
var userMultiSelector = Ext.getCmp('AssignedUsers'); //save assigned users
var selectedUsers = userMultiSelector.getStore().getData(); //get store and put them in array
var me = this,
win = button.up('window'),
form = win.down('form'),
// formApplyUpload = this.getFormApplyUpload(),
// var ko = win.items.items[0].items.items[0].value;
recordtenderUsers = Ext.create('InTenders.model.TenderSaveModel');
// recordtenderUsers = form.getRecord();
// record = form.getRecord(),
values = form.getValues();
// appFile = this.getApplicationFile(),
// callbacks;
recordtenderUsers.set(values);
recordtenderUsers.set('tenderUsers',selectedUsers.items);
// // me.showMask();
// if (form.isValid()) {
recordtenderUsers.save({
success: function (recordtenderUsers, operation) {
win.close();
me.hideMask();
},
failure: function (recordtenderUsers, operation) {
me.hideMask();
}
});
You can get value using multiselector.down('grid') this will return you the grid. And grid have method getSelection().
In this FIDDLE, I have created a demo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'form',
renderTo: Ext.getBody(),
items: [{
xtype: 'multiselector',
title: 'Multi selector example',
fieldName: 'text',
viewConfig: {
deferEmptyText: false,
emptyText: 'No value selected'
},
search: {
field: 'text',
store: {
fields: [{
name: 'text',
type: 'string'
}],
data: [{
text: 'ABC'
}, {
text: 'ABC 1'
}, {
text: 'ABC 2 '
}, {
text: 'ABC 3'
}, {
text: 'ABC 4'
}]
}
}
}, {
xtype: 'button',
text: 'Get Value',
margin:15,
handler: function (btn) {
var multiselector = btn.up('form').down('multiselector');
if (multiselector.down('grid')) {
multiselector.down('grid').getSelection().forEach(rec => {
console.log(rec.get('text'));
});
}
}
}]
});
}
});

Piechart not displaying store data

I have a pie chart in sencha-touch that is not retrieving data from my store, it is gender data coming from a mysql database, the data is being retrieved using an ajax request here is the request and the store
Ext.define('Qvidi.controller.MyController', {
extend: 'Ext.app.Controller',
config: {
},
getGender: function() {
Ext.Ajax.request({
method: 'POST',
params: {
class: 'Qvidi',
method: 'getDataM'
},
url: 'server/index.php',
success: function( response ){
var r = Ext.decode( response.responseText );
Ext.getStore('GenderStore').setData( r.results );
}
});
}
});
and here is the store
Ext.define('Qvidi.store.GenderStore', {
extend: 'Ext.data.Store',
requires: [
'Qvidi.model.GenderModel',
'Ext.data.proxy.Ajax'
],
config: {
model: 'Qvidi.model.GenderModel',
storeId: 'GenderStore',
proxy: {
type: 'ajax',
extraParams: {
class: 'Qvidi',
method: 'getDataM'
},
url: 'server/index.php'
}
}
});
and lastly here is my model
Ext.define('Qvidi.model.GenderModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
config: {
fields: [
{
name: 'types'
},
{
name: 'counter'
}
]
}
});
here is a log data from inspect in google chrome
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
sencha-touch.js:13032 The key "minimum-ui" is not recognized and ignored.
app.js:39 loaded
Console.js?_dc=1456999436953:35 [DEPRECATE][Anonymous] loadData is deprecated, please use either add or setData
The last log was after I changed setData to loadData
and here is the retrieved sql in my method decoded to json
{
success: true,
total: 2,
results: [
{
types: "Male",
counter: 2182
},
{
types: "Females",
counter: 1134
}
]
}
here is my chart code
{
xtype: 'polar',
height: 377,
id: 'genderPieChart',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
store: 'GenderStore',
series: [
{
type: 'pie',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
labelField: 'types',
xField: 'counter',
yField: 'types'
}
],
interactions: [
{
type: 'rotate'
}
]
}
here is my php code
class Qvidi extends Connect {
function __construct(){
parent::__construct();
}
public function getDataM( $vars ){
$sql = "Select 'Male' as 'types', count(gender) AS 'counter' from quividi.vidireports where gender='1'
union
Select 'Females' as 'types', count(gender) AS 'counter' from quividi.vidireports where gender='2'";
$data = array();
$total = 0;
if( $result = $vars->db->query( $sql ) ) {
while( $row = $result->fetch_assoc() ){
$data[] = array( "types"=>$row["types"], "counter" => intval ($row["counter"] ) );
$total++;
}
$result->free();
}
echo json_encode( array( "success" => true, "total" => $total, "results" => $data ) );
}
ok so:
my php code
<?php
$callback=false;
if(isset($_REQUEST['callback']))
$callback = $_REQUEST['callback'];
$dati=array(
(object) array( 'types'=> 'Male', 'counter'=> 2182),
(object) array( 'types'=> 'Female', 'counter'=> 1134)
);
$resultObj= new stdClass();
$resultObj->results=$dati;
$resultObj->success=true;
if ($callback) {
header('Content-Type: text/javascript');
echo $callback . '(' . json_encode($resultObj) . ');';
}else {
echo json_encode($resultObj);
}
?>
my json response:
{"results":[{"types":"Male","counter":2182},{"types":"Female","counter":1134}],"success":true}
my model:
Ext.define('MyApp.model.GenderModel', {
extend: 'Ext.data.Model',
requires: [
'Ext.data.field.Field'
],
fields: [
{
name: 'types'
},
{
name: 'counter'
}
]
});
my store:
you will need these requires for the store:
requires: [
'Ext.data.Store',
'Ext.data.proxy.JsonP',
'Ext.data.reader.Json'
]
myStore: {
autoLoad: true,
model: 'MyApp.model.GenderModel',
proxy: {
type: 'jsonp',
url: 'myphpurl',
reader: {
type: 'json',
rootProperty: 'results'
}
}
}
my chart:
{
xtype: 'polar',
colors: [
'#115fa6',
'#94ae0a',
'#a61120',
'#ff8809',
'#ffd13e',
'#a61187',
'#24ad9a',
'#7c7474',
'#a66111'
],
bind: {
store: '{myStore}'
},
series: [
{
type: 'pie',
angleField: 'counter',
label: {
field: 'types',
display: 'rotate',
contrast: true,
font: '12px Arial'
},
xField: 'counter',
yField: 'types'
}
],
interactions: [
{
type: 'rotate'
}
]
}
my final view:

Populating dropdown from database via Struts 2 action class (using jtable)

I am using jtable http://jtable.org/ in my project. jTable is a jQuery plugin that is used to create AJAX based CRUD tables without coding HTML or Javascript.
http://i62.tinypic.com/3461eo3.jpg
jtable code for above form is
HTML code:
<div id="StudentTableContainer"></div>
JavaScript code:
<script type="text/javascript">
$(document).ready(function () {
$('#StudentTableContainer').jtable({
title: 'Student List',
paging: true,
pageSize: 10,
sorting: true,
defaultSorting: 'Name ASC',
actions: {
listAction: '/Demo/StudentList',
deleteAction: '/Demo/DeleteStudent',
updateAction: '/Demo/UpdateStudent',
createAction: '/Demo/CreateStudent'
},
fields: {
StudentId: {
key: true,
create: false,
edit: false,
list: false
},
Name: {
title: 'Name',
width: '30%'
},
EmailAddress: {
title: 'Email address',
list: false
},
Password: {
title: 'User Password',
type: 'password',
list: false
},
Gender: {
title: 'Gender',
options: { 'M': 'Male', 'F': 'Female' },
list: false
},
ContinentalId: {
title: 'Continental',
options: '/Demo/GetContinentalOptions',
list: false
},
CountryId: {
title: 'Country',
dependsOn: 'ContinentalId', //Countries depends on continentals. Thus, jTable builds cascade dropdowns!
options: function (data) {
if (data.source == 'list') {
//Return url of all countries for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/Demo/GetCountryOptions?continentalId=0';
}
//This code runs when user opens edit/create form or changes continental combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/Demo/GetCountryOptions?continentalId=' + data.dependedValues.ContinentalId;
},
list: false
},
CityId: {
title: 'City',
width: '30%',
dependsOn: 'CountryId', //Cities depends on countries. Thus, jTable builds cascade dropdowns!
options: function (data) {
if (data.source == 'list') {
//Return url of all cities for optimization.
//This method is called for each row on the table and jTable caches options based on this url.
return '/Demo/GetCityOptions?countryId=0';
}
//This code runs when user opens edit/create form or changes country combobox on an edit/create form.
//data.source == 'edit' || data.source == 'create'
return '/Demo/GetCityOptions?countryId=' + data.dependedValues.CountryId;
}
},
BirthDate: {
title: 'Birth date',
type: 'date',
displayFormat: 'yy-mm-dd',
list: false
},
Education: {
title: 'Education',
list: false,
type: 'radiobutton',
options: [
{ Value: '1', DisplayText: 'Primary school' },
{ Value: '2', DisplayText: 'High school' },
{ Value: '3', DisplayText: 'University' }
]
},
About: {
title: 'About this person',
type: 'textarea',
list: false
},
IsActive: {
title: 'Status',
width: '15%',
type: 'checkbox',
values: { 'false': 'Passive', 'true': 'Active' },
defaultValue: 'true'
},
RecordDate: {
title: 'Record date',
width: '25%',
type: 'date',
displayFormat: 'yy-mm-dd',
create: false,
edit: false,
sorting: false //This column is not sortable!
}
}
});
//Load student list from server
$('#StudentTableContainer').jtable('load');
});
</script>
I want to have a Dropdown in my project which should take values from database through struts2 action class .
Like in the above demo code, list of continents can be accessed from database via struts2 action class (using URL pattern /Demo/GetContinentalOptions
As jtable only understands json so please guide me what should I write in Struts2 Action class and Struts.xml
Note: In your sample code you can even hardcode dropdown values
You can populate your json field with the following action. You also need a convention plugin to use annotations. To use json result you need a json plugin.
#Action(value="GetContinentalOptions", results=#Result(type="json", params = {"root", "map"}))
public class ContinentalOptionsAction extends ActionSupport {
Map<String, String> map=new HashMap<>();
public Map<String, String> getMap() {
return map;
}
#Override
public String execute() throws Exception {
map.put("1", "Asia");
map.put("2", "America");
map.put("3", "Europe");
map.put("4", "Africa");
return SUCCESS;
}
}
In the options function
var options = [];
$.ajax({ //get from server
url: '<s:url action="GetContinentalOptions"/>',
dataType: 'json',
success: function (data) {
options = data;
}
});
return options;
EDIT:
Without convention plugin you should write action configuration in struts.xml
<action name="GetContinentalOptions" class="com.action.ContinentalOptionsAction">
<result type="json">
<param name="root" value="map"/>
</result>
</action>

Unable to access data from Rally wsapidatastore

When I create a WsapiDataStore, store.data.items and store.data.keys return empty arrays although I am able to see the keys and items when I do console.log(store.data)
store = Ext.create('Rally.data.WsapiDataStore', {
model: 'Defect',
context: {
project: '/project/xxxxxx'
},
autoLoad: true,
fetch: ['Rank', 'FormattedID', 'Name']
});
Output of console.log(store.data):
constructor {items: Array[0], map: Object, keys: Array[0], length: 0, allowFunctions: falseā€¦}
allowFunctions: false
events: Object
generation: 8
getKey: function (record) {
hasListeners: HasListeners
items: Array[7]
keys: Array[7]
length: 7
map: Object
sorters: constructor
__proto__: TemplateClass
Notice how the first line says "items: Array[0]" and "keys: Array[0]" but when expanded it says "items: Array[7]" and "keys: Array[7]". I'm also able to see the 7 records when I expand further.
Everything works as expected when I add a load listener and access the data from the listener function (but I don't want to do that)
I think the best way is to process the data via two Rally.data.WsapiDataStore's. You'll need to chain the listeners for the two stores together in order to properly handle the asynchronous loads. Here's an example that illustrates the process:
<!DOCTYPE html>
<html>
<head>
<title>MultipleModelExample</title>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/2.0p5/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
// Combined Story/Defect Records
dataRecords: null,
launch: function() {
//Write app code here
this.dataRecords = [];
Rally.data.ModelFactory.getModels({
types: ['HierarchicalRequirement','Defect'],
scope: this,
success: function(models) {
this.myModels = models;
this.storyStore = Ext.create('Rally.data.WsapiDataStore', {
model: models.HierarchicalRequirement,
fetch: true,
autoLoad: true,
remoteSort: true,
sorters: [
{ property: 'FormattedID', direction: 'Asc' }
],
listeners: {
load: this._processStories,
scope: this
}
});
}
});
},
_processStories: function(store, records, successful, opts) {
var storyRecords = [];
Ext.Array.each(records, function(record) {
//Perform custom actions with the data here
//Calculations, etc.
storyRecords.push({
FormattedID: record.get('FormattedID'),
Name: record.get('Name'),
Description: record.get('Description')
});
});
this.dataRecords = storyRecords;
this.defectStore = Ext.create('Rally.data.WsapiDataStore', {
model: this.myModels.Defect,
fetch: true,
autoLoad: true,
remoteSort: true,
sorters: [
{ property: 'FormattedID', direction: 'Asc' }
],
listeners: {
load: this._processDefects,
scope: this
}
});
},
_processDefects: function(store, records, successful, opts) {
var defectRecords = [];
Ext.Array.each(records, function(record) {
//Perform custom actions with the data here
//Calculations, etc.
defectRecords.push({
FormattedID: record.get('FormattedID'),
Name: record.get('Name'),
Description: record.get('Description')
});
});
var combinedRecords = defectRecords.concat(this.dataRecords);
this.add({
xtype: 'rallygrid',
store: Ext.create('Rally.data.custom.Store', {
data: combinedRecords,
pageSize: 25
}),
columnCfgs: [
{
text: 'FormattedID', dataIndex: 'FormattedID'
},
{
text: 'Name', dataIndex: 'Name', flex: 1
},
{
text: 'Description', dataIndex: 'Description', flex: 1
}
]
});
}
});
Rally.launchApp('CustomApp', {
name: 'MultipleModelExample'
});
});
</script>
<style type="text/css">
.app {
/* Add app styles here */
}
</style>
</head>
<body></body>
</html>

Categories