EXTJS Grid grouping by Object error - javascript

I am trying to implement a grid with grouping feature. This is my Model:
Model
Ext.define('myApp.model.ModelPrueba2', {
extend: 'Ext.data.Model',
fields: ['id', {
name: 'name',
type: 'string'
},'sign']
});
I fill my store from an AJAX proxy request. This is my JSON:
{
success: true,
data: [{
id: 1,
name: 'Name 1',
sign: {
id: 1,
name: 'F1'
}
}, {
id: 2,
name: 'Name 2',
sign: {
id: 2,
name: 'F2'
}
}]
}
You can appreciate that my 'sign' field is an 'object'. My problem is: when I group by 'name', it works fine, and if I collapse some group, it only collapses the group that I selected. However, if I group by 'sign', the groups are well-formed and displayed, but when I collapse a specific group, all the groups get collapsed, and the only difference with the previous test is the field type, 'name' is string and 'sign' is an object... So I don't really know if this a bug. I am using 4.2 version.
This is a fiddle where you can test my problem: https://fiddle.sencha.com/#fiddle/vt
Here you can group by 'probabilities to win', and collapse one group, it works fine, but if you delete every
toString: function() {
return this.value;
}
from the 'data' array and do the same, you will see how all groups get collapsed in one. What can I do to fix this?, I don't like to use this toString() in my store or JSON.
How can I group by an Object attribute?

you MAY have some luck with a "hasOne" relationship in your model instead of the "auto' type. (I'm not sure if it's possible to group using a relationship)
Or you could create another field just for the grouping (type string or int) like this :
{
success: true,
data: [{
id: 1,
name: 'Name 1',
myGroupField : 1,
sign: {
id: 1,
name: 'F1'
}
}, {
id: 2,
name: 'Name 2',
myGroupField : 2,
sign: {
id: 2,
name: 'F2'
}
}]
}
A similar solution is to bring up the field from your nested object to the parent object :
{
success: true,
data: [{
id: 1,
name: 'Name 1',
signId: 1,
signName: 'F1'
}, {
id: 2,
name: 'Name 2',
signId: 2,
signName: 'F2'
}]
}
and then group by signId

Related

Angular search a key in an object and change the value of another key

I have this data below.
I need to be able to search in the objet for the id or name key and then change the 'show' key to a different value.
How example:
Search the data for id value 2 and change the show value to false.
data = [
{
id: 1,
name: 'one',
show: false;
title: 'title1',
data: [
{
id: 1,
description: 'some description'
},
{
id: 2,
description: 'some other description'
}
]
},
{
id: 2,
name: 'two',
show: true;
title: 'title2',
data: [
{
id: 1,
description: 'some description'
},
{
id: 2,
description: 'some other description'
}
]
}
]
How can I do this?
You can use the findIndex method, and then access your array using the found Index and change any property you want, here's some code that match your use case
let index = data.findIndex((x) => x.id == THE_ID_YOU_ARE_LOOKING_FOR);
if(index > -1) {
data[index].show = THE_VALUE_YOU_WANT;
}
You can also use normal array find method.
let item = data.find(x=>x.id===REQUIRED_ID);
if(item) item.show = false

add item into specific list array redux

I know there is a lot of similar threads but I didn't find a solution there.
Okay so I have a state which looks:
[
{
id: 1,
title: 'todo',
items: [
{
itemID: 1,
itemText: 'finish this project'
},
{
itemID: 2,
itemText: 'take trash out'
},
{
itemID: 3,
itemText: 'sleep'
},
]
},
{
id: 2,
title: 'doing now',
items: [
{
itemID: 1,
itemText: 'add redux'
},
{
itemID: 2,
itemText: 'fixing bugs'
},
]
},
{
id: 3,
title: 'done',
items: [
{
itemID: 1,
itemText: 'add components'
},
{
itemID: 2,
itemText: 'add material ui'
},
]
}
]
and I have a redux reducer that should add an item into specific list, I have id of that list, and itemText which I should add. I managed somehow to make it kinda work, it is adding item into specifin array but problem is that also creates new blank list. Here is how reducer looks:
case "ADD_ITEM":
return [
state.map((list)=>(
(list.id === action.payload.id) ? list.items.push({
itemID: 89,
itemText: action.payload.description
}) : list
))
]
Any idea how to add an item to specific list items without creating a new list?
Map and return the lists (state), and use spread syntax to update the items:
case "ADD_ITEM":
return state.map(list =>
list.id === action.payload.id ? {
...list,
items: [
...list.items,
{
itemID: 89,
itemText: action.payload.description
}
]
} : list
)
Try this:
case "ADD_ITEM":
state.forEach((list, index)=>(
if (list.id === action.payload.id){
state[index].items.push({
itemID: 89,
itemText: action.payload.description
}
})
))
Note that this is pseudocode, but it should still work.
Your example was not working because you were returning a new array, which had (about) the same structure as state, except with the added element. To add it, simply add it directly to state without using map + return, thereby not creating a new array.

Check if my string contains elements from array

I have an array of objects and I wish to filter out those objects if my filter array matches the string of a key.
// my stores
var stores = [
{
id: 1,
store: 'Store 1',
storeSells: "Belts|Handbags|Watches|Wallets"
},
{
id: 2,
store: 'Store 2',
storeSells: "Handbags|Personal Accessories|Jewelry|Eyewear|"
},
{
id: 3,
store: 'Store 3',
storeSells: "Belts|Travel|Charms|Footwear|"
},
{
id: 4,
store: 'Store 3',
storeSells: "Charms|Footwear|"
}
]
// my filters
var filters = ["Handbags","Belts"]
So, If my filters array has handbags and belts. I wish to filter stores with id's 1,2 and 3 only as they contains these keywords. Can you please help me with this?
You can try with Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Array.prototype.some()
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.
And String.prototype.includes()
The includes() method determines whether one string may be found within another string, returning true or false as appropriate.
// my stores
var stores = [
{
id: 1,
store: 'Store 1',
storeSells: "Belts|Handbags|Watches|Wallets"
},
{
id: 2,
store: 'Store 2',
storeSells: "Handbags|Personal Accessories|Jewelry|Eyewear|"
},
{
id: 3,
store: 'Store 3',
storeSells: "Belts|Travel|Charms|Footwear|"
},
{
id: 4,
store: 'Store 3',
storeSells: "Charms|Footwear|"
}
]
// my filters
var filters = ["Handbags","Belts"];
var res = stores.filter(item => filters.some(i=>item.storeSells.includes(i)));
console.log(res);

Select2.js v4.0: how set the default selected value with a local array data source?

By using select2.js v4 plugin , how set the default selected value when I use a local array data for source?
for example with this code
var data_names = [{
id: 0,
text: "Henri",
}, {
id: 1,
text: "John",
}, {
id: 2,
text: "Victor",
}, {
id: 3,
text: "Marie",
}];
$('select').select2({
data: data_names,
});
How set id 3 as the default selected value?
$('.select').select2({
data: data_names,
}).select2("val",3);
this worked for me with V4.0.3
$('.select').select2({
data: data_names,
})
$('select').val(3);
$('select').trigger('change.select2');
It is better you send another attribute (selected in my case below) for select and use it to set the default value. I did something like below -
var data_names = [{
id: 0,
text: "Henri",
}, {
id: 1,
text: "John",
}, {
id: 2,
text: "Victor",
}, {
id: 3,
text: "Marie",
selected: true
}];
then do
$(".select").select2({
data : data_names
});
data_names.forEach(function(name){
if(name.selected) {
$(".select").select2('val',name.id);
}
});
It's worked for me.
$('#select').select2({data: data_names}).val(3).trigger('change')

Twitter bootstrap - typeahead

i use Twitter Bootstrap and typeahead.
i download the plugin: Twitter Bootstrap Typeahead Plugin Extension
and so long so good, its working when i use a static javascript json array eg.
$('#demo1').typeahead({
source: [
{ id: 9000, name: 'Aalborg' },
{ id: 2, name: 'Montreal' },
{ id: 3, name: 'New York' },
{ id: 4, name: 'Buffalo' },
{ id: 5, name: 'Boston' },
{ id: 6, name: 'Columbus' },
{ id: 7, name: 'Dallas' },
{ id: 8, name: 'Vancouver' },
{ id: 9, name: 'Seattle' },
{ id: 10, name: 'Los Angeles' }
],
itemSelected: displayResult
});
When i try to use ajax its will do enerything, my code look like this.
$('.typeahead').typeahead({
ajax: '/actions/search/synonymSearch',
itemSelected: displayResult
});
and its return this json array ( i can rebuild its on all ways, and i can't get it to work )
[
{ id: 1, name: 'Toronto' },
{ id: 2, name: 'Montreal' },
{ id: 3, name: 'New York' },
{ id: 4, name: 'Buffalo' },
{ id: 5, name: 'Boston' },
{ id: 6, name: 'Columbus' },
{ id: 7, name: 'Dallas' },
{ id: 8, name: 'Vancouver' },
{ id: 9, name: 'Seattle' },
{ id: 10, name: 'Los Angeles' }
]
The plugin home pages.
https://github.com/tcrosen/twitter-bootstrap-typeahead
i hobe enybardy can help me here :)
thanks a lot for all helping, :)
EDIT - Problem resovle! :)
Just need to added header("content-type: application/json");
into my PHP file, hobe this answere are usefull for orther peopole! :)
I don't think typeahead can read the source of your array and therefore I would parse it first.
var data = [{"id":"9000","name":"Aalborg"},{"id":"9220","name":null},{"id":"9210","name":null},{"id":"9200","name":"Aalborg SV"}];
// using underscore.js get an array of the city names
var cities = _.pluck(data, "name");
// now start typeahead
$el.typeahead(
source: cities,
// the value of the `city` selected gets passed to the onselect
onselect: function(city) {
// get the index of city selected from the data array
var i = _.indexOf(data, city);
// then using the index get what ever other value you need from the array
// and insert in the DOM etc..
}
);
This problem you are experiencing may be due to the page that you are calling via ajax isn't returning the right headers.
If you are using PHP try adding header('Content-type: application/json'); to the document that contains the JSON array.

Categories

Resources