Change valueField config on Ext-JS combobox? - javascript

I have a combobox on a form where I need to reset its store along with the 'displayField' and 'valueField' configs.
Resetting the store via cmb.bindStore(newStore) works great.
Setting cmb.displayField = 'newfieldname'; also works great.
However, cmb.valueField = 'newValField'; does not work. The combo displays the right stuff, but when i select an item, the value is using the old valueField value, not the new one.
I've tried:
doing a cmb.reset() afterwards
Ext.apply(...)
Is it because valueField is somehow special because it is a required field? Is there some special way to set a config value on an Ext-JS component I don't know about or is it just not possible to change the value of 'valueField'?
FYI - Here is my code:
comp.bindStore(Ext.create('Ext.data.Store', {
fields : [ {
name : 'abbr',
type : 'string'
}, {
name : 'name',
type : 'string'
}, {
name : 'slogan',
type : 'string'
} ],
data : [ {
"abbr" : "AL",
"name" : "Alabama",
"slogan" : "The Heart of Dixie"
}, {
"abbr" : "AK",
"name" : "Alaska",
"slogan" : "The Land of the Midnight Sun"
}, {
"abbr" : "AZ",
"name" : "Arizona",
"slogan" : "The Grand Canyon State"
}, {
"abbr" : "AR",
"name" : "Arkansas",
"slogan" : "The Natural State"
}, ]
}));
comp.displayField = 'abbr'; // THIS WORKS
comp.valueField = 'abbr'; // THIS DOESNT WORK

You are nearly there but you where looking at the wrong property cause valueField is not your issue, it is displayField. Your exact problem are preconfigured and cached properties. The first is the display template the second is the picker instance. You need to override the template and remove the picker instance. Here's a working snipped (JSFiddle)
In the example I added a second trigger with a cross. Hit it and the ComboBox get the new values. I recommend you to create your own component for this by extending from ComboBox and wrap all into a reconfigure method that would expect tree parameters.
Ext.onReady(function() {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL1", "name":"Alabama1"},
{"abbr":"AK1", "name":"Alaska1"},
{"abbr":"AZ1", "name":"Arizona1"}
//...
]
});
var comp = Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Choose State',
id: 'combo-ident',
trigger2Cls: 'x-form-clear-trigger',
onTrigger2Click: function (args) {
var comp = Ext.getCmp('combo-ident');
comp.clearValue();
comp.bindStore(Ext.create('Ext.data.Store', {
fields : [ {
name : 'abbr',
type : 'string'
}, {
name : 'name',
type : 'string'
}, {
name : 'slogan',
type : 'string'
} ],
data : [ {
"abbr" : "AL",
"name" : "Alabama",
"slogan" : "The Heart of Dixie"
}, {
"abbr" : "AK",
"name" : "Alaska",
"slogan" : "The Land of the Midnight Sun"
}, {
"abbr" : "AZ",
"name" : "Arizona",
"slogan" : "The Grand Canyon State"
}, {
"abbr" : "AR",
"name" : "Arkansas",
"slogan" : "The Natural State"
}, ]
}));
comp.displayField = 'abbr';
comp.valueField = 'name';
comp.displayTpl = new Ext.XTemplate(
'<tpl for=".">' +
'{[typeof values === "string" ? values : values["' + comp.displayField + '"]]}' +
'<tpl if="xindex < xcount">' + comp.delimiter + '</tpl>' +
'</tpl>'
);
comp.picker = null;
},
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: Ext.getBody()
});
comp.on('select', function(){ console.log(arguments); console.log(arguments[0].getSubmitValue()); })
});

I am not sure it is possible to reconfigure the combo box this way, but perhaps you can create another combobox with a different store and valueField. Hide/destroy one or the other based on your logic.

Related

How to find data on MongoDB by passing part of array objects

I tried to create an API for filtering the products by sending an array of objects as filters.
this is my Product schema:
const mongoose = require("mongoose");
const { s, rs, rn, rref, ref } = require("../utils/mongo");
let schema = new mongoose.Schema(
{
user: rref("user"),
name: rs,
description: s,
images: [s],
price: rn,
category: ref("category"),
filters: [
{
parent: ref("filter"),
value: s,
name: s,
},
],
subFilter: [
{
parent: s,
value: s,
title: s,
},
],
},
{ timestamps: true }
);
module.exports = mongoose.model("product", schema);
and this one is what I want to send as body to the API
{
category: '62445c3d922d127512867245'
filters: [
{ name: 'filter name 1', value: '62445c3d922d127512861236' },
{ name: 'filter name 2', value: '62445c3d922d127512861458' },
.....
]
}
as you see I want to filter my products based on category Id and an array of filter objects. I tried to write this query but it return an empty array.
this is my query:
filter: async (req, res) => {
try {
const { category, filters } = req.body;
const products = await Product.find({
category,
filters: {
$in: filters,
},
});
res.status(200).json(products);
} catch (err) {
res.status(500).json(err);
}
},
what stored on db
{
"_id" : ObjectId("62643acf19636d7db1804cb3"),
"images" : [
"image-1650735823476۸.jpg"
],
"user" : ObjectId("622606af0f40cb8ea37383dc"),
"name" : "شیر توپی 2 اینچ کلاس 150 پیشگام",
"description" : " برند پیشگام با مدارک و تاییدیه ",
"price" : NumberInt(5000000),
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
{
"_id" : ObjectId("62643acf19636d7db1804cb4"),
"parent" : ObjectId("6264307f19636d7db1804b77"),
"value" : "626430bb19636d7db1804b78",
"name" : "Valve Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb5"),
"parent" : ObjectId("6264319819636d7db1804b7b"),
"value" : "6264319819636d7db1804b7e",
"name" : "Body Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb6"),
"parent" : ObjectId("626431ef19636d7db1804b82"),
"value" : "626431ef19636d7db1804b83",
"name" : "Bore Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb7"),
"parent" : ObjectId("6264328519636d7db1804b85"),
"value" : "6264328519636d7db1804b86",
"name" : "Material Type"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb8"),
"parent" : ObjectId("626435de19636d7db1804c10"),
"value" : "626439b619636d7db1804ca7",
"name" : "Trim Material"
},
{
"_id" : ObjectId("62643acf19636d7db1804cb9"),
"parent" : ObjectId("6264367919636d7db1804c17"),
"value" : "6264367919636d7db1804c18",
"name" : "End Conection"
},
{
"_id" : ObjectId("62643acf19636d7db1804cba"),
"parent" : ObjectId("626436a719636d7db1804c1f"),
"value" : "6264378119636d7db1804c28",
"name" : "Size"
},
{
"_id" : ObjectId("62643acf19636d7db1804cbb"),
"parent" : ObjectId("6264389219636d7db1804c6d"),
"value" : "6264389219636d7db1804c6f",
"name" : "Class / Pressure"
}
],
"subFilter" : [
{
"_id" : ObjectId("62643acf19636d7db1804cbc"),
"parent" : "6264328519636d7db1804b85",
"value" : "626433b919636d7db1804b93",
"title" : "Body Material"
}
],
"createdAt" : ISODate("2022-04-23T17:43:43.421+0000"),
"updatedAt" : ISODate("2022-04-23T17:53:29.016+0000"),
"__v" : NumberInt(0)
}
Consider this shrunk down set of inputs that capture the essence of the question. The comments "give away" what we are going to try to find and why. We only show one value for category because matching on that is trivial and not the interesting part of the query.
[
{
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
// Matching Valve/value; include this doc
{"name" : "Valve", "value" : "626430bb19636d7db1804b78"},
// ALSO match Body/value; include this doc (but needs only 1 match)
{"name" : "Body", "value" : "6264319819636d7db1804b7e"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
"filters" : [
// Not target value for Valve name (..79 instead of ...78):
{"name" : "Valve", "value" : "626430bb19636d7db1804b79"},
// ...but correct value for Body, so include this doc
{"name" : "Body", "value" : "6264319819636d7db1804b7e"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
// No matching Valve or Body so this whole doc is ignored.
"filters" : [
{"name" : "Valve", "value" : "626430bb19636d7db1804b79"},
{"name" : "Body", "value" : "6264319819636d7db1804b7f"}
]
}
,{
"category" : ObjectId("62445c4d922d127512867246"),
// Not even name matches so ignore this too:
"filters" : [
{"name" : "Pipe", "value" : "6264319819636d7db1804eee"}
]
}
]
Assume also we set up inputs coming from the API like this, in their native form i.e. strings NOT ObjectId:
var targ_cat = '62445c4d922d127512867246';
var any_one_of = [
{ name: 'Valve', value: '626430bb19636d7db1804b78' },
{ name: 'Body', value: '6264319819636d7db1804b7e'}
];
We will use $filter as our main function but to do so, we must convert the incoming material into a form required by $filter.
// Convert inbound array of any_one_of into a something designed to work
// in the $filter function by comparing each name/value entry in the
// filters field to the item presented in $$this, meaning take:
// { name: 'Valve', value: '626430bb19636d7db1804b78' },
// and turn it into:
// {$and: [ {$eq:['Valve','$$this.name']}, {$eq:['62643...','$$this.value']} ] }
// Since any one of the entries is considered a hit, we package it all
// into an $or wrapper, not $and.
var or_list = [];
any_one_of.forEach(function(f) {
or_list.push( {$and: [
{$eq:[f['name'], '$$this.name']},
{$eq:[f['value'], '$$this.value']}
]});
});
var or_expr = {$or: or_list};
Now we are ready to query mongoDB:
db.foo.aggregate([
// Get this out of the way quickly; note we must make a new ObjectId!
{$match: {'category': new ObjectId(targ_cat)}}
// The interesting part of the query:
,{$addFields: {filters: {$filter: {input: '$filters', cond: or_expr}}}}
// Only keep those items where $filter found at least one of the
// targets:
,{$match: {$expr: {$gt:[{$size: '$filters'},0]} }}
]);

X-Editable JQuery Plugin - Select Get Source Object

I am having issues trying to get the selected object rather than the "newValue" that is passed to the success callback.
Here is an example:
$("select").editable({
type : "select",
title: 'Select Fruit',
source : [
{text : "Apple", value: "option_1"},
{text : "Orange", value: "option_2"},
{text : "Mango",value: "option_3"},
{text : "Strawberry",value: "option_4"}
],
success:function(response,newValue){
console.log(newValue); // newValue contains the "text" string ok..
// How do I get the selected source object? eg. {text : "Orange", value: "option_2"}
// So I can access the object like..
console.log(newValue.value); // output option_*
}
});
Thanks
Carl
You can use the display callback to access value, or even the entire selected object:
<script>
$(function() {
$("#status").editable({
type: "select",
title: 'Select Fruit',
source: [
{text : "Apple", value: "option_1"},
{text : "Orange", value: "option_2"},
{text : "Mango",value: "option_3"},
{text : "Strawberry",value: "option_4"}
],
display: function(value, sourceData) {
if (value) { // value = "option_3" etc.
$(this).html(value);
}
/* OR if you want to access the selected source object ...
var selected = $.fn.editableutils.itemsByValue(value, sourceData);
if (selected.length) {
$(this).html(selected[0].value);
} */
}
});
});
</script>
Demo: http://jsfiddle.net/6vzrug72/

ExtJS : How to map Store fields to JSON properties?

I have the following JSON data :
{
"disclaimer": "Exchange rates provided for informational purposes only and do not constitute financial advice of any kind. Although every attempt is made to ensure quality, no guarantees are made of accuracy, validity, availability, or fitness for any purpose. All usage subject to acceptance of Terms: https://openexchangerates.org/terms/",
"license": "Data sourced from various providers; resale prohibited; no warranties given of any kind. All usage subject to License Agreement: https://openexchangerates.org/license/",
"timestamp": 1475110853,
"base": "USD",
"rates": {
"AED": 3.672983,
"AFN": 66.5538,
"ALL": 122.0421,
"AMD": 473.5925,
"ANG": 1.7763,
"AOA": 165.571834,
"ARS": 15.3169,
"AUD": 1.299338,
"AWG": 1.792667,
"YER": 250.130999,
"ZAR": 13.61321,
"ZMK": 5252.024745,
"ZMW": 9.831204,
"ZWL": 322.387247
}
}
And I have defined my model as follows:
Ext.define('CurrencyConvert.model.CurrencyCode', {
extend : 'Ext.data.Model',
fields : [
{
name : 'code',
value : 'string'
},
{
name : 'rate',
value : 'float'
}
]
});
So that I can have the currency code(i.e. "USD") and the rate. But the problem is that the currency code itself is the property name of the actual rate; so how would I create my store so as to get both the code and the rate in my model ?
Ex:
For "AED": 3.672983, I want the code value to hold "AED" and rate field to hold 3.672983.
You can do like this:
Ext.define('CurrencyConvert.model.CurrencyCode', {
extend : 'Ext.data.Model',
fields : [
{
name : 'code',
value : 'string',
convert:function(v,rec){
=== Add Your Logic Here ===
}
},
{
name : 'rate',
value : 'float'
convert:function(v,rec){
=== Add Your Logic Here ===
}
}
]
});
Ext.define('CurrencyConvert.model.CurrencyCode', {
extend : 'Ext.data.Model',
fields : [
{
name : 'code',
value : 'string'
},
{
name : 'rate',
value : 'float',
convert : function(value, record) {
return jsonData.rates[record.get('code')]
}
}
]
});

Display relational data in Firebase using AngularJS

I want to display content using a flat relational data structure (similar to that of Firefeed). Everything is working the way it should, except I can't figure out how to display the actual content. I'm struggling for a while now and I think I'm almost there actually, but something is still missing.
I have two references:
var userFeedRef = new Firebase(FIREBASE_URL).child("users").child($rootScope.currentUser.$id).child("feed");
var uploadsRef = new Firebase(FIREBASE_URL).child("uploads");
The JSON looks like this:
{
"uploads" : {
"-KGkxzQj0FM2CMAXo5Em" : {
"author" : "87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d",
"date" : 1462184179564,
"name" : "Zizazorro",
"reasonUpload" : "Test",
"startSec" : 80,
"uploadTitle" : "Kid Ink - Promise (Audio) ft. Fetty Wap"
},
"-KGlCoD7kEa1k3DaAtlG" : {
"author" : "87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d",
"date" : 1462188328130,
"name" : "Zizazorro",
"reasonUpload" : "Test2",
"startSec" : 80,
"uploadTitle" : "Kid Ink - Show Me ft. Chris Brown"
}
},
"users" : {
"87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d" : {
"date" : 1459369248532,
"feed" : {
"-KGkxzQj0FM2CMAXo5Em" : true,
"-KGlCoD7kEa1k3DaAtlG" : true
},
"firstname" : "Bob",
"followers" : {
"e3de536b-03a1-4fb4-b637-ebcebaae55c6" : true
},
"following" : {
"e3de536b-03a1-4fb4-b637-ebcebaae55c6" : true
},
"regUser" : "87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d",
"uploads" : {
"-KGkxzQj0FM2CMAXo5Em" : true,
"-KGlCoD7kEa1k3DaAtlG" : true
},
"username" : "Zizazorro"
},
"e3de536b-03a1-4fb4-b637-ebcebaae55c6" : {
"date" : 1459369285026,
"feed" : {
"-KGkxzQj0FM2CMAXo5Em" : true,
"-KGlCoD7kEa1k3DaAtlG" : true
},
"firstname" : "Anna",
"followers" : {
"87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d" : true
},
"following" : {
"87a8b6c8-7f72-45c2-a8c5-bb93fe9d320d" : true
},
"regUser" : "e3de536b-03a1-4fb4-b637-ebcebaae55c6",
"username" : "Sven8k"
}
}
}
The problem is: How can I display the actual content of the upload, when there is only a ID reference? I need a reference to the IDs for a user (userFeedRef) and a reference to the actual content of those specific IDs, not all uploads (uploadsRef).
How can I display this user ng-repeat in my html? So for example: ng-repeat {{feed.reasonUpload}} for user1 has to show:
Test
Test2
EDIT I've looked at this example, but I can't figure out how to render the content on the actual html feed in my case
var commentsRef =
new Firebase("https://awesome.firebaseio-demo.com/comments");
var linkRef =
new Firebase("https://awesome.firebaseio-demo.com/links");
var linkCommentsRef = linkRef.child(LINK_ID).child("comments");
linkCommentsRef.on("child_added", function(snap) {
commentsRef.child(snap.key()).once("value", function() {
// Render the comment on the link page.
));
});
You can do something like this:
$scope.finalData = (Object).values($scope.firebaseData.uploads);
//$scope.firebaseData is data what you retrieving from firebase.
Hope this plunker will help you.

Data not shown in slickgrid

I'm working with slickgrid in my webpage, the problem I'm getting while using it that I'm unable to see the data in the grid. While when I try to get the data through grid object (i.e. grid.getData();) , I can get the whole data which I have previously set in the grid but don't know why its not showing up. May be I'm missing some thing.
following is my code for drawing the grid.
HTML code:
<div id="myGrid" width="100%"; height="500px"></div>
JS code:
drawBlotterForOrders : function(data){
try{
var columns = this.getBlotterColumns();
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
var dataArray = [];
dataArray = self.setDataInGrid(data);
gridObj = new Slick.Grid("#myGrid" , dataArray , columns , options);
console.log(gridObj.getData());//here I'm able to get the data
}catch(exp){
}
},
setDataInGrid : function(data){
try{
var dataArray = [];
i++;
dataArray[0] = {
id : i,
clOrdId : data.clOrdId,
cumQty : data.cumQty,
execId : data.execId,
execType : data.execType,
leavesQty : data.leavesQty,
ordStatus : data.ordStatus,
orderId : data.orderId,
orderQty : data.orderQty,
side : data.side,
symbol : data.symbol
};
return dataArray;
}catch(exp){
}
},
getBlotterColumns : function(){
var col = [
{ id: 'id',
name : 'id',
field : 'id'
},{
id: 'clOrdId',
name : 'clOrdId',
field : 'clOrdId'
},{
id: 'cumQty',
name : 'cumQty',
field : 'cumQty'
},{
id: 'execId',
name : 'execId',
field : 'execId'
},{
id: 'execType',
name : 'execType',
field : 'execType'
},{
id: 'leavesQty',
name : 'leavesQty',
field : 'leavesQty'
},{
id: 'ordStatus',
name : 'ordStatus',
field : 'ordStatus'
},{
id: 'orderId',
name : 'orderId',
field : 'orderId'
},{
id: 'orderQty',
name : 'orderQty',
field : 'orderQty'
},{
id: 'side',
name : 'side' ,
field : 'side'
},{
id: 'symbol',
name : 'symbol',
field : 'symbol'
}
];
return col;
}
I'm unable to detect the mistake I'm making. I'll be really thankful for any help.
You forgot to render the grid I think, did you put a grid.render() ?

Categories