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/
Related
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]} }}
]);
How can I create a select DOM object with options in jquery similar to this input creation example?
$('<input />', {
name: 'age',
type: 'number',
placeholder: 'enter a number 1'
}).appendTo('#app');
Is there a way to create it passing attributes?
When creating an element with jQuery, any attribute, or even jQuery method, can be used in the options object, so you can do
$('<select />', {
name : 'test',
on : {
change : function() { /* stuff */ }
},
append : [
$('<option />', {value : "1", text : "Opt 1"}),
$('<option />', {value : "2", text : "Opt 2"}),
$('<option />', {value : "3", text : "Opt 3"})
]
}).appendTo('#app');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
You can create just by passing the entire select with option as string
$('<select name="number">' +
'<option>1</option>' +
'<option>2</option>' +
'<option>3</option>' +
'</select>').appendTo('body');
Another solution, using an array of objects having the required value and text and creating new select element based on the array information.
$(document).ready(function () {
var arrSelect = [
{ value: 1, text: 'One' },
{ value: 2, text: 'Two' },
{ value: 3, text: 'Three' }
];
var select = $('<select>').appendTo('body'); //Create new select element
//Loop through the array of objects and then create new option and append to select element
arrSelect.map(function (arr) { select.append($("<option>").attr('value', arr.value).text(arr.text)) });
$("body").append(select); //Append select to body element
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
1_ you can select Multiple DOM Multi DOM Select
like so :
$( "div, .sCLASS, p.myClass" ).whatever...
2_ you can also select Single DOM with concate Single DOM Select
like so :
$( "p" + ".sCLASS" ).whatever...
BUT you can't pass arg with it
The object select is created and then the options objects are appended.
$('<select />', {
id: 'my-numbers',
name: 'select-number'
})
.append($("<option/>", {
value: '1',
text: 'number1'
}))
.append($("<option/>", {
value: '2',
text: 'number2'
}))
.appendTo('#app');
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() ?
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.
This is probably a noobish question, however I have spent quite some time on it now.
So this is my structure, highly minimized:
{
name : 'Some dude',
deck : [{
name : 'Awesome card',
value : 30
},
{
name : 'another awesome card',
value: 50
}]
}
I want to select from all cards in the deck, where name == 'Awesome card', returning this
{
name : 'Some dude',
deck : [{
name : 'Awesome card',
value : 30
}]
}
been trying loads of commands like
db.heroes.find({name : "Some dude"}, {'deck' : 1, 'deck.name' : 'Awesome card})
How should I query this?
Use $elemMatch projection:
db.heroes.find({name : "Some dude"}, {'deck' : {$elemMatch:{name:'Awesome card}}})
See docs here.
You can use the $ position operator which identifies the index of the matched deck array element in your field selection:
db.heroes.find(
{name : "Some dude", 'deck.name' : 'Awesome card'},
{_id: 0, name: 1, 'deck.$.name': 1}
);
deck = deck.filter(function (card) { return card.name === 'Awesome card' });
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/filter