I use a GeoJSON as my source, where every entity has a state.
I want to draw circles for every entity, where the circle color is based on the state, and whether the circle has been clicked or not.
Determining the "clicked-state" is done via setFeatureState() where a feature receives the "click" state when clicked.
I tried to first check for the click state and match the state, based on the feature being clicked or not:
"circle-color": [
'case',
['boolean',
['feature-state', 'click'],
false,
],
['match', //Feature clicked = true
['get', 'state'],
'SOME_FEATURE_STATE_STRING',
'#57E757', // possible match
'SOME_OTHER_FEATURE_STATE_STRING',
'#123456', // possible match
'#123456' //fallback
],
'#001ebe' //Feature clicked = false
]
The "unclicked" circle has the correct color. However, when I click the circle, the circle-color is changed to black and not my "match" color.
Any advice is greatly appreciated!
I think your case expression is incorrect here :
['boolean',
['feature-state', 'click'],
false,
],
You have used the boolean types expression, which is a type expression (it asserts that the input value is a boolean).
In your case, you want to use a decision expression.
With the == operator, you can return true if the input values are equal, false otherwise.
Your case expression would become :
"circle-color": [
'case',
['==', ['feature-state', 'click'], true],
['match', // Feature clicked = true
['get', 'state'],
'SOME_FEATURE_STATE_STRING',
'#57E757', // Possible match
'SOME_OTHER_FEATURE_STATE_STRING',
'#123456', // Possible match
'#123456' // Fallback
],
'#001ebe' // Feature clicked = false
]
Related
Using Mapbox GL, I want to be able to create polygons and give them individual colors, but after along search and read through the api doc, just can'tfigure out out this is supposed to be done.
nb: I want to use draw not addlayer as I want the polygon to still be editable afterwards.
nb: this.color is a hex value selected by the user
maybe I'm a newbie n00bing out, maybe the approach isn't quite right.
// when a poly is created add a color property to it and save it into the stagedFeatures array
this.map.on('draw.create', e => {
e.features.forEach(feature => {
feature['properties'] = { color: this.color }
this.stagedFeatures.push(feature)
})
})
// set the color of the next polygon
document.getElementById('colourSelector').addEventListener('change', e => {
if (e.target['value']) {
this.color = e.target['value']
this.setStyle()
}
})
// generate the styles
getStyles() {
return [
{
'id': 'gl-draw-polygon-fill-inactive',
'type': 'fill',
'filter': [
'all',
['==', 'active', 'false'],
['==', '$type', 'Polygon'],
['!=', 'mode', 'static']
],
'paint': {
// my problem is likely here, have tried many expressions etc but mapbox
// expressions aren't super easy to figure out
'fill-color': this.color,
'fill-outline-color': this.color,
'fill-opacity': 0.5
}
},
...
// redraw the map and readd the polygons
setStyle() {
this.map.removeControl(this.draw)
if (typeof this.map.getSource('staged-features') !== 'undefined') {
this.map.removeSource('staged-features')
}
this.map.addSource("staged-features", {
type: "geojson",
data: {
type: "FeatureCollection",
features: this.stagedFeatures
},
})
this.draw = new MapboxDraw({
userProperties: true,
displayControlsDefault: false,
controls: {
polygon: true,
trash: true
},
styles: this.getStyles()
})
this.map.addControl(this.draw)
// loop through any features that the map needs to redraw
this.stagedFeatures.forEach(i => {
console.warn('restore polygons', i)
this.draw.add(i)
})
}
whats happening is the polys redraw but using only the selected color, I'm wanted to get an expression workeing the pulls back the color from the feature.properties.color value
['get', 'color'] with a fallback to this.color doesn't appear to work here.
whats happening is the polys redraw but using only the selected color, I'm wanted to get an expression workeing the pulls back the color from the feature.properties.color value
['get', 'color'] with a fallback to this.color doesn't appear to work here.
https://docs.mapbox.com/mapbox-gl-js/style-spec/expressions/
tried the null operators suggested here:
https://github.com/mapbox/mapbox-gl-js/issues/5761
Usually a regular person's name does not contain numbers, so I added this search property to prevent numbers with RegEx to my Input element:
type: new sap.ui.model.type.String({}, { search: "^[^0-9]+$" })
But numbers should be allowed for a company's name. So how can I make this search value dynamic?
To visualize it:
"dwd3" should be invalid when it's anything other than "Company"
"dwd3" should be valid when it's a "Company"
Here's my minimal example - what I've tried so far is commented out, since it didn't work (resulted in numbers being valid at all times).
// Set data model
let data = {
"salutation": "Company",
"name": ""
};
let oModel = new sap.ui.model.json.JSONModel();
oModel.setData(data);
// Create page
let oPage = new sap.m.VBox();
oPage.setModel(oModel);
// Add salutation input
oPage.addItem(
new sap.m.Input({
value: {
path: "/salutation"
}
})
);
// Add name input
oPage.addItem(
new sap.m.Input({
value: {
type: new sap.ui.model.type.String({}, {
minLength: 2,
maxLength: 40,
search: "^[^0-9]+$"
/* not working...
search: {
parts: [
"/salutation",
],
formatter: (salutation) =>
salutation === "Company" ? "^.*$" : "^[^0-9]+$"
}
*/
}),
path: "/name",
},
required: true,
})
);
// Attach validation handlers
sap.ui.getCore().attachValidationError(function(oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.Error);
});
sap.ui.getCore().attachValidationSuccess(function(oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.None);
});
// Insert page
oPage.placeAt("content");
<script id='sap-ui-bootstrap' type='text/javascript' src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-libs="sap.m,sap.ui.commons,sap.ui.table" data-sap-ui-theme="sap_bluecrystal">
</script>
<body class='sapUiBody'>
<div id='content'></div>
</body>
If the validation rule of one field depends on the value of another field, you could use events like change (with or without valueLiveUpdate=true) for validation.
A type should be something that does not depend on external life.
Another thing you could do is reacting on change event of your salutation field and exchange the type of the input field for the name (depending on the value of salutation)
PS: (edit) to be hontest, I wouldn't restrict a name field to anything that it may or may not contain. Depending on the country specific laws you may be allowed to use digits...
Ok, I'm new to angular and angular ui-grid.
I'm using angularjs(v1.4) with angular-ui-grid(v3.0.7).
I have defined a grid as below
seec.gridOptions = {};
seec.gridOptions.rowEditWaitInterval = -1;
seec.gridOptions.onRegisterApi = function (gridApi) {
$scope.gridApi = gridApi;
gridApi.rowEdit.on.saveRow($scope, $scope.saveRow);
};
seec.gridOptions.columnDefs = [
{name: 'pouch', displayName: 'Pouch', enableCellEdit: false, enableHiding: false, width: 250},
{name: 'content', displayName: 'Content', enableHiding: false, width: 150},
{
name: 'units',
displayName: 'Number of Items',
type: 'number',
enableHiding: false,
width: 150
},
{name: 'active', displayName: 'Status', type: 'boolean', enableHiding: false, width: 150}
];
The controller basically makes a http call and feeds data to the grid.
if (response.status === 200) {
seec.gridOptions.data = angular.copy(seec.data);
}
Currently, the last item in the grid is being displayed as either 'true' or 'false' based on the boolean field value., and when I double click on the field a checkbox appears.
So, I need to display true as 'active' and false as 'inactive'.
Is there any way of doing this with angular ui-grid?
There certainly is! One approach could be to use a cellTemplate and map your rowvalues to something different.
I created a Plunkr showcasing a possible setup.
There are two steps to take. First add a cellTemplate to your column:
cellTemplate: "<div ng-bind='grid.appScope.mapValue(row)'></div>"
Note: Instead of ng-bind you could also use "<div>{{grid.appScope.mapValue(row)}}</div>", if you are more familiar with that.
Second step is to define your mapping function, for example:
appScopeProvider: {
mapValue: function(row) {
// console.log(row);
return row.entity.active ? 'active' : 'inactive';
},
}
#CMR thanks for including the Plunkr. As I was looking at it I checked, and in this case it seems overkill to have the mapValue function.
This worked for me:
cellTemplate: "<div class='ui-grid-cell-contents'>{{row.entity.active ? 'active' : 'inactive'}}</div>"
(I added the class in there to match the other cells). I will say that this still smells a little hacky to me.
This question leads to using a function as the field itself: In ui-grid, I want to use a function for the colDef's field property. How can I pass in another function as a parameter to it?
I'd still like to see an answer with the logic directly in the columnDefs.
You can use angular filter specifying in your columnDef for a column cellFilters : 'yourfiltername:args'.
args can be a variable or a value, in that case pay attention to use right quoting. if args is a string cellFilters : 'yourfiltername:"active"'
Your filter can be directly a function or a filter name. Here a plunkr
I am creating a radiogroup and when it's created, I set the "inputValue" to set the value of the field. For the first radio button, inputValue is set to 'I' (for in) and 'O' (for out) is set for the second radio button.
If someone clicks the "OUT" radio, then a window pops up and asks them to choose a value from a combo box. The possible values there are 'F', 'R' or 'T' and if they select one of those, I'd like to modify the 'OUT' inputValue to reflect that. So when the form is submitted, it should, for example, send back 'F' instead of 'O'.
Here is the code for the radio buttons:
items: [
{
xtype: 'container',
defaultType: 'radiofield',
allowBlank: false,
blankText: 'Required',
hideLabel: true,
layout: 'hbox',
items: [
{
xtype: 'radiofield',
boxLabel: 'IN',
name: 'susceptible_populations_1',
width: 50,
padding: '2 0 0 10',
checked: true,
inputValue: 'I',
id: 'susceptible_populations_1_in'
},
{
xtype: 'radiofield',
boxLabel: 'OUT',
name: 'susceptible_populations_1',
width: 115,
padding: '2 0 0 10',
inputValue: 'O',
id: 'susceptible_populations_1_out',
listeners: {
click: {
element: 'el',
fn: function() {
show_popup_window('susceptible_populations_1_out', '9A(5)');
}
}
}
}
]
}
]
I have Googled around and found a couple of solutions, but none of them seem to work for me. All of them still return 'O' when I submit the form.
Here are some definitions for my popup window:
FIELD_NAME is passed as the first parameter to the function. In this instance it is 'susceptible_populations_1_out'
TRUNCATED_FIELD_NAME is the same as above, except the '_out' has been removed. In this instance, it is 'susceptible_populations_1'. This is the name of the field that actually gets returned with my form post.
record is the value of the combo box. For this example, we can use the letter 'F'.
Here are some of the examples I am trying:
Ext.getCmp(FIELD_NAME).setValue(record);
This appears to set the value of the radio to true. The value should have already been set to true when I clicked on it, so this is redundant and doesn't change the inputValue to 'F'
Ext.get(FIELD_NAME).set({inputValue:record});
This appears to do nothing that I can tell. I'm guessing that it's because to set something, the set needs a current name AND value and just sets that instance to true when it makes a match. This is not what I'm attempting to do.
var temp = Ext.get(Ext.ComponentQuery.query('[name=' + TRUNCATED_FIELD_NAME + ']')).getValue().elements[1];
Ext.get(temp).set({value:record});
Here I am attempting to access the element directly and it doesn't seem to do anything either. I've tried many different combinations of the preceeding code snippets also, (including replacing FIELD_NAME with TRUNCATED_FIELD_NAME in the above examples), but the value of the radio always comes back as 'O'.
In Sencha Touch, there seems to be a setGroupValue, but I couldn't find that in the EXT JS 4 docs anywhere. (Although getGroupValue works as expected.)
Can someone please give me some guidance on this?
Thanks so much!
you can set the config property later at any time
Ext.getCmp(FIELD_NAME).inputValue = 'F'
only notice that getCmp with static ids should not be used, instead use ComponentQuery and itemId.
Below is a sample of a filteringSelect populated with user data. My goal is to have perform wilcard match on the displayed values. for example, if the user types 'son', the dropdown matches will be "homer simpSON' and 'carl calSON'.
By default, the match will only be on the beginning of the label.
I tried changing dijit.byId('userselect').searchAttr, but setting it to anything but a string causes erronious behaviour.
<input id="userselect">
<script type="text/javascript">
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
var user_data = {
"itentifier":"user_id",
"label":"label",
"items":[
{"first_name":"Waylon","last_name":"Smithers","label":"Waylon Smithers","user_id":7}
,{"first_name":"Carl","last_name":"Carlson","label":"Carl Carlson","user_id":6}
,{"first_name":"Homer","last_name":"Simpson","label":"Homer Simpson","user_id":4}
,{"first_name":"Lenny","last_name":"Leonard","label":"Lenny Leonard","user_id":5}
,{"first_name":"Montgomery","last_name":"Burns","label":"Montgomery Burns","user_id":8}
]
};
dojo.addOnLoad(function() {
var userStore = new dojo.data.ItemFileReadStore({
//url: "/user/lookup",
data: user_data
});
var filteringSelect = new dijit.form.FilteringSelect({
id: "userselect",
name: "userselect",
store: userStore,
searchAttr: 'label' //["first_name", "last_name", "oasis"]
},
"userselect");
});
</script>
You'll need to set queryExpr and set autoComplete to false
var filteringSelect = new dijit.form.FilteringSelect({
id: "userselect",
name: "userselect",
store: userStore,
searchAttr: 'label',
queryExpr: '*${0}*',
autoComplete: false
},"userselect");
Dojo documentation for queryExpr:
This specifies what query is sent to the data store, based on what the
user has typed. Changing this expression will modify whether the
results are only exact matches, a "starting with" match, etc.
dojo.data query expression pattern. ${0} will be substituted for the
user text. * is used for wildcards.
${0}* means "starts with"
*${0}* means "contains"
${0} means "is"
Have a look at queryExpr