Have in Grid.js a option of "inline edit" cell values? - gridjs

Have in Grid.js an option of "inline edit" cell values or possibility/plugin to implements them?
Like this:
http://tabulator.info/examples/4.9#editable
https://editor.datatables.net/

You can add the "contenteditable" : "true" attribute (part of HTML 5) to your column definition:
new gridjs.Grid({
columns: [
{ id: 'name',
name: 'Name',
sort: false,
attributes:{
"contenteditable" : "true"
}
},
{ id: 'email',
name: 'Email',
sort: false
},
...
You can then add a listener (with vanilla JavaScript or whatever framework you're using) for the "input" event - which will fire when the data changes.

Related

ExtJS 7.2 - Loading record into a form with chained comboboxes and forceSelection:true does not load all values

I have a form with two chained comboboxes. The first chained combobox dictates the values that appear in the second. I have forceSelection:true on the second combobox so that when a user changes the first combo, the second will be set blank because it no longer will be a valid option. The chained combos function as expected but when I load a record into this form using getForm().loadRecord(record) the value for the first combo is set properly but the second is not unless I set forceSelection:false.
The following fiddle should make things pretty clear: sencha fiddle
Clicking "Load Record" should load in Fruits/Apple, but only Fruits is shown. Clicking "Load Record" a second time achieves the desired result. If you comment out forceSelection: true it works as expected but then the chained combos don't function as desired. Is there anything I'm doing wrong here?
It is not so easy. What is happening when you are running form.loadRecord(rec).
you set the FoodGroup combobox
you set the FoodName combobox. BUT the value is not there, because your filter did not switch to appropriate food groups. That is why commenting force selection helps. (That is why commenting filter also help).
turned on the filter of food names. Store now have new values.
You are clicking the button second time. The first combobox value is the same, filters are not trigged (triggered?), you already have appropriate values in the second store and the value is selected.
How to fix:
The fix is ugly. You can listen on store 'refresh' (it means the filters are triggered) and then set the second value (or set the values again).
Ext.define('Fiddle.view.FormModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.fiddle-form-model',
stores: {
foodgroups: {
fields: ['name'],
data: [{
foodgroupname: 'Fruits'
}, {
foodgroupname: 'Vegetables'
}]
},
foods: {
fields: ['foodgroupname', 'foodname'],
filters: {
property: 'foodgroupname',
value: '{selectedFoodgroup.foodgroupname}'
},
data: [{
foodname: 'Apple',
foodgroupname: 'Fruits'
}, {
foodname: 'Banana',
foodgroupname: 'Fruits'
}, {
foodname: 'Lettuce',
foodgroupname: 'Vegetables'
}, {
foodname: 'Carrot',
foodgroupname: 'Vegetables'
}]
}
}
});
Ext.define('Fiddle.view.Form', {
extend: 'Ext.form.Panel',
xtype: 'fiddle-form',
viewModel: {
type: 'fiddle-form-model'
},
title: 'Combos',
items: [{
xtype: 'combo',
itemId: 'FoodGroup', // To access FoodGroup
displayField: 'foodgroupname',
bind: {
store: '{foodgroups}',
selection: '{selectedFoodgroup}'
},
valueField: 'foodgroupname',
forceSelection: true,
name: 'foodgroup',
fieldLabel: 'Food Group',
value: 'Vegetables'
}, {
xtype: 'combo',
itemId: 'FoodName', // To access FoodName
bind: {
store: '{foods}'
},
queryMode: 'local',
forceSelection: true, //COMMENTING THIS OUT ACHIEVES DESIRED LOAD RECORD BEHAVIOR
displayField: 'foodname',
valueField: 'foodname',
name: 'food',
fieldLabel: 'Food',
value: 'Carrot'
}],
buttons: [{
text: 'Load Record',
handler: function (btn) {
// OUR UGLY FIX
var form = btn.up('form'),
foodGroupComboBox = form.down('combobox#FoodGroup'),
foodNameComboBox = form.down('combobox#FoodName'),
record = Ext.create('Ext.data.Model', {
foodgroup: 'Fruits',
food: 'Apple'
});
foodNameComboBox.getStore().on('refresh', function (store) {
form.loadRecord(record);
}, this, {
single: true
})
form.loadRecord(record);
}
}]
});
Ext.application({
name: 'Fiddle',
launch: function () {
var form = new Fiddle.view.Form({
renderTo: document.body,
width: 600,
height: 400
});
}
});

How to make sanity io array select as multiselect?

I have a lot of tags, and I need to select a lot for each document. It is uncomfortable to click one by one every time. Also I see selected elements. How can I remake it into somefield like a multiselect? It could be even native. Or how to select all tags at once?
I am using array:
{
title: 'Language',
name: 'language',
type: 'array',
options: {
layout: 'grid'
},
of: [{
type: 'reference',
title: 'Lang',
to: {
type: 'settingLanguages'
}
}],
},
Dropdown example (Add field to schema):
{
title: 'Genre',
name: 'genre',
type: 'string',
options: {
list: [
{ title: 'Sci-Fi', value: 'sci-fi' },
{ title: 'Western', value: 'western' },
],
},
},
This is currently not possible out of the box with the default array component, but you should be able to create an input like this by building a custom input for it with the behaviour you want.
More on how to build custom inputs: https://www.sanity.io/docs/extending/custom-input-widgets

How to add empty rows to grid and fill the columns and then submit in EXTJS

How to add rows to grid and add some values with in the columns
and then submit the data as json format to the rest api in EXTJS
Json data like :
[
{
"col1" : "john",
"col2" : "xyz",
"col3" : "01/05/2018"
},
{
"col1" : "bush",
"col2" : "xpao",
"col3" : "01/08/2018"
},
.......
]
Some thing like above
I want to add data as above in grid column and submit to API in EXTJS
Thanks in Advance -:)
I want to add data as above in grid column and submit to API
For this, You need to use the store.sync() and rowediting plugin for grid.
store.sync() synchronizes the store with its proxy. This asks the proxy to batch together any new, updated and deleted records in the store, updating the store's internal representation of the records as each operation completes.
The Ext.grid.plugin.RowEditing plugin injects editing at a row level for a Grid. When editing begins, a small floating dialog will be shown for the appropriate row. Each editable column will show a field for editing. There is a button to save or cancel all changes for the edit.
You can check with working FIDDLE
Note : I have used dummy api name you need to use your actual api with store proxy for create, read, update and delete records.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create('Ext.data.Store', {
storeId: 'gridStore',
fields: ['col1', 'col2', 'col3'],
autoLoad: true,
pageSize: 25,
remoteSort: true,
proxy: {
type: 'ajax',
method: 'POST',
api: {
read: 'data.json',
update: 'your_update_api',
create: 'your_create_api',
destroy: 'your_delete_api'
},
reader: {
type: 'json'
},
writer: {
type: 'json',
encode: true,
root:'data'
}
},
});
Ext.create('Ext.grid.Panel', {
title: 'Add Row Example',
store: 'gridStore',
height: 300,
border: true,
renderTo: Ext.getBody(),
tools: [{
xtype: 'button',
iconCls: 'fa fa-plus-circle',
tooltip: 'Add New Record',
handler: function () {
let store = this.up('grid').getStore();
store.insert(0, {
col1: '',
col2: '',
col3: ''
})
}
}],
columns: [{
text: 'col1',
dataIndex: 'col1',
flex: 1,
editor: {
xtype: 'textfield'
}
}, {
header: 'col2',
dataIndex: 'col2',
editor: {
xtype: 'textfield'
},
flex: 1
}, {
header: 'col3',
dataIndex: 'col3',
editor: {
xtype: 'datefield',
dateFormat: 'd/m/Y'
},
flex: 1
}],
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1
})
],
bbar:['->',{
text:'Submit Changes',
handler:function(){
this.up('grid').getStore().sync()
}
}]
});
}
});
In real life situation you will need the following components:-
1- Ext.data.Model -> [Record] to map your model and add you validations and logic if needed.
2- Ext.data.Store -> [Set of records] which will consume the model.
3- Proxy which will handle the call the the web service, proxy can be added to the model or the store.
4- Grid Row Editor or cell row editor to be able to insert you data.
This is a working example FIDDLE
When you press Add data the model is created [record], you can start editing the data based on the editor property in the columns, this record is stored in the grid store so you can add as many records as you need.
When you press submit the store.sync is responsible to read the proxy apis and send the data to your service, you will need to open your dev tools network inspect to see the data sent in the request as json.

Form field to pick from a list of objects in a store

I'm new to Sencha, trying to implement a Sencha formpanel with a field to pick from a list of objects in a store. This seems like a sufficiently basic pattern that there must be a simple solution. I have a model which defines an ajax endpoint returning a json array (places) of name/id pairs:
Ext.define('MyApp.model.Place', {
extend: 'Ext.data.Model',
config: {
fields: [
{name: 'name', type: 'string'},
{name: 'id', type: 'int'},
],
proxy: {
type: 'ajax',
url: '/m/places/',
reader: {
type: 'json',
rootProperty: 'places',
},
},
},
});
And a store:
Ext.define('MyApp.store.Place', {
extend: 'Ext.data.Store',
requires: ['MyApp.model.Place'],
config: {
model: 'MyApp.model.Place',
autoLoad: true,
sorters: [
{
property : 'name',
direction: 'ASC',
},
],
},
});
I want a read-only text field for the place name and a hidden field to submit the place id:
{
xtype: 'textfield',
name: 'place_name',
label: 'Place',
readOnly: true,
listeners: {
focus: function () {
var place_picker = Ext.create('Ext.Picker', {
slots: [
{
name: 'place_name',
title: 'Choose a Place',
store: Ext.create('MyApp.store.Place'),
itemTpl: '{name}',
listeners: {
itemtap: function (obj, index, target, record, e, eOpts) {
var form = Ext.getCmp('entityform');
form.setValues({
place_name: record.get('name'),
place_id: record.get('id'),
});
// how to dismiss the picker?
obj.parent.hide();
},
},
},
]
});
Ext.Viewport.add(place_picker);
place_picker.show();
},
},
},
{
xtype: 'hiddenfield',
name: 'place_id',
},
At this point, tapping the field causes the picker to slide up from the bottom and display the loading animation, but it is not being populated with the list of place names, although I can see that the ajax request has been made and that it has returned the expected json document.
I'll stop here and ask if I'm on the right track or is there some better approach out there?
Why isn't the picker being populated with the results of the ajax request? Is my use of itemTpl incorrect?
Am I setting the form fields in a sencha-appropriate way?
How should I dismiss the picker on itemtap? I somehow doubt that my use of hide() is the proper way.
Picker slots has an data config which is an array of objects. It should have a specific format with text and value.
slots :[
data : [{
text : someValue,
value : someValue1,}] ]
You need to add objects which has the fields text and value to slots.

use form for add and update data,how is that possible in extjs4?

i have a form panel and a tree panel
the form is used to add new users, the tree is used to show the list of users
what i want is to right click a node in my tree ,click edit (already can do that) then i have my data in the add form panel and be able to modify there and update my user
so basically use the same form for adding and updating
this is how im trying to do up to know
but its not working at all
i added a model to my tree,i used loadRecord(rec), but i dont know how to bind my tree data with the form fields!
tried adding displayfield with same name from my tree model!!
my tree model and store:
Ext.define('TreeModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'text' },
{ name: 'id' }
]
});
window.ATreeStore = Ext.create('Ext.data.TreeStore', {
model: 'TreeModel',
root: Ext.decode(objt.TreeToJson()),
proxy: {
type: 'ajax'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});
my tree menu:
var myContextMenu = new Ext.menu.Menu({
items: [{
text: 'Edit',
handler: function () {
Ext.getCmp('addaform').getForm().loadRecord(rec);
}
}
}]
my form:
Ext.define("Ext.app.Adduser", {
extend: "Ext.form.Panel",
title: 'Add user',
id : 'addform',
closable: true,
collapsible: true,
animCollapse: true,
draggable: true,
resizable: true,
margin: '5 5 5 5',
height: 400,
frame: true,
fieldDefaults: {
labelAlign: 'top',
msgTarget: 'side'
},
defaults: {
anchor: '100%'
},
items: [{
layout: 'column',
border: false,
items: [{
padding: '5',
columnWidth: .5,
border: false,
layout: 'anchor',
defaultType: 'textfield',
items: [{
fieldLabel: ' Name',
name: 'name',
allowBlank: false,
displayfield:'id',//
anchor: '95%'
}]
}, {
padding: '5',
columnWidth: .5,
border: false,
layout: 'anchor',
defaultType: 'textfield',
items: [{
fieldLabel: 'First name',
name: 'fname',
allowBlank: false,
anchor: '95%'
}, {
xtype: 'textarea',
fieldLabel: 'Profile',
name: 'prof',
anchor: '95%'
}]
}],
buttons: [{
text: 'Save',
handler: function () {
this.up('form').getForm().submit
({
url: 'AddData.ashx',
params: { action: 'add' },
success: function (form, action)
{
Ext.MessageBox.show({ title: 'Success !',
msg: 'User added successfully<br />',
icon: Ext.MessageBox.INFO,
buttons: Ext.MessageBox.OK
}) }
}) }]
thank you
If your TreePanel uses a TreeStore which in turn has a Ext.data.Model, then when you right click on a node (say nodeA), you should be just able to do form.loadRecord(nodeA), the API for loadRecord is here
If it's still not clear, I think this blog post could help, it talks about loading a grid record into a form. I know it's not ExtJS 4, but the key functions are the same.
Ok, let me show this with a super simple example, hope it will help.
First we create the form that we want to display stuff in, note that the renderTo property is bound to a div inside my HTML, so you might need to change that. Also note that the name property of the textarea and textfield, they are the key for the loadRecord to work, they have to match the fields defined in the model later.
var form = Ext.create('Ext.form.Panel',{
renderTo : 'form-div',
items : [{
xtype : 'textarea',
fieldLabel : 'label 1',
name : 'name'
},{
xtype : 'textfield',
fieldLabel : 'label 2',
name : 'age'
}]
});
Next, we create the tree to display our data, we start by creating a simple model :
Ext.define('Person',{
extend : 'Ext.data.Model',
fields : [{
name : 'name',
type : 'string'
},{
name : 'age',
type : 'int'
}]
});
Then we create a TreeStore that uses that model and initialize it with some inline data:
var store = Ext.create('Ext.data.TreeStore',{
model : 'Person',
root : {
expanded : true,
children : [{
name : 'John',
age : 10,
leaf : true
},{
name : 'Joe',
age : 100,
leaf : true
}]
}
});
Then we create the tree to display the data in the store. (Note that the nodes will show up as "undefined" because we are not using the default "text" property of a Node)
var tree = Ext.create('Ext.tree.Panel',{
height : 300,
width : 300,
store : store,
rootVisible : false,
renderTo : 'tree-div',
listeners : {
itemclick : function(view, record){
form.loadRecord(record);
}
}
});
Now, you should see a tree with two nodes both displayed as "undefined" on your page, as well as a Form with a textarea and a textfield. If you click on a node inside the tree, the form will display the name and age of the selected node.