Dashing: Changing text color based on input to List widget - dashing

I am fairly new to HTML/CSS so this may be a newbie question.
I have a list widget that I am using to show the name of nodes (:label) from an API and the last time those nodes reported (:value). If the node has reported within the last hour I want the text color to be green, if it hasn't I want it to be red (pretty simple logic).
I have been trying to use :status-warning and :status-danger to do this, but these options do not change each value independently, rather it changes the whole widget's text color.
This is my coffeescript code, which I got from https://github.com/Shopify/dashing/issues/24 :
ready: ->
if #get('unordered')
$(#node).find('ol').remove()
else
$(#node).find('ul').remove()
onData: (data) ->
#clear existing "status-*" classes
$(#get('node')).attr 'class', (i,c) ->
c=c.replace /\bstatus-\S+/g, ''
# add new class
$(#get('node')).addClass "status-#{x.status}"
Do I need to create a custom widget for this, or is there a built in mechanism to change the text color of values?

I wouldn't bother changing the coffeescript. It's not necessary.
Not sure if you are still looking for an answer for this, but I managed to work something out for this recently. If you set up your code in the .rb file that sends data to your list so that it does some checking for whether the value was updated or not, and then determines and adds a 'color' attribute to the set of data that is sent, you can then tell your list to use that 'color' value to specify which CSS class to look at. The CSS class can then be set up with whatever colors fits the 'color' attribute.
My dashboard (.erb) code for the list is the same, so that doesn't need to change.
In the job file:
myList.rb
# get your label and value for the list before here.
if myValue >= 75.00
myColor = "green"
elsif myValue <= 74.99
myColor = "red"
else
myColor = "white"
end
results.push({:label => myLabel, :value => myValue, :color => myColor})
send_event("myList", items: results)
so from the above we can see that a color variable is sent with the label and value. Now we just need to make the list.html and the list.scss recognise it.
here's the changes in my list.html Only 4 lines should change to look like the 2 below (in the ordered list (<ol></ol>), and unordered list(<ul></ul>):
list.html
<span class="label"><div data-bind-class="item.color" data-bind="item.label"></div></span>
<span class="value"><div data-bind-class="item.color" data-bind="item.value"></div></span>
The data-bind-class is binding the class to whatever is in item.color (which i know in my example will be: red, green, or white)
Then we just need to tell the list.scss how to handle these classes by adding this to the bottom of the file:
list.scss
.white {
color: white;
}
.red {
color: #B31D2B;
}
.green {
color: green;
}
Note: CSS can handle plain English colors. You mentioned you were new to css so I guess it's worth clarifying. I've used a mixture of plain English colors: 'white', and 'green' and a hex code color: '#B31D2B'. This hex code is a darker red which I found was a bit easier on the eyes.
You could use this method to do anything with the text just thinking about it now. It doesn't need to be 'color' specifically. So you could change color to 'state' and have a 'good' state passed through as item.state and then have a 'good' class in your scss that changes the font style, font size, color, font weight. Whatever you'd like really :)

Related

How to search for and highlight a substring in Codemirror 6?

I'm building a simple code editor to help children learn HTML. One feature I'm trying to add is that when users mouseover their rendered code (in an iframe), the corresponding HTML code in the editor is highlighted. So, for example, if a user mouses-over an image of kittens, the actual code, , would be highlighted in the editor.
Mousing-over the iframe to get the html source for that element is the easy part, which I've done (using document.elementFromPoint(e.clientX, e.clientY in the iframe itself, and posting that up to the parent) - so that's not the part I need help with. The part I can't figure out is how to search for and highlight that string of selected code in the code editor.
I'm using Codemirror 6 for this project, as it seems as it will give me the most flexibility to create such a feature. However, as a Codemirror 6 novice, I'm struggling with the documentation to find out where I should start. It seems like the steps I need to complete to accomplish this are:
Search for a range in the editor's text that matches a string (ie.'<img src="kittens.gif"').
Highlight that range in the editor.
Can anyone out there give me some advice as to where in the Codemirror 6 API I should look to start implementing this? It seems like it should be easy, but my unfamiliarity with the Codemirror API and the terse documentation is making this difficult.
1. Search for a range in the editor's text that matches a string (ie.'<img src="kittens.gif"').
You can use SearchCursor class (iterator) to get the character's range where is located the DOM element in your editor.
// the import for SearchCursor class
import {SearchCursor} from "#codemirror/search"
// your editor's view
let main_view = new EditorView({ /* your code */ });
// will create a cursor based on the doc content and the DOM element as a string (outerHTML)
let cursor = new SearchCursor(main_view.state.doc, element.outerHTML);
// will search the first match of the string element.outerHTML in the editor view main_view.state.doc
cursor.next()
// display the range where is located your DOM element in your editor
console.log(cursor.value);
2. Highlight that range in the editor.
As described in the migration documentation here, marked text is replace by decoration. To highlight a range in the editor with codemirror 6, you need to create one decoration and apply it in a dispatch on your view. This decoration need to be provide by an extension that you add in the extensions of your editor view.
// the import for the 3 new classes
import {StateEffect, StateField} from "#codemirror/state"
import {Decoration} from "#codemirror/view"
// code mirror effect that you will use to define the effect you want (the decoration)
const highlight_effect = StateEffect.define();
// define a new field that will be attached to your view state as an extension, update will be called at each editor's change
const highlight_extension = StateField.define({
create() { return Decoration.none },
update(value, transaction) {
value = value.map(transaction.changes)
for (let effect of transaction.effects) {
if (effect.is(highlight_effect)) value = value.update({add: effect.value, sort: true})
}
return value
},
provide: f => EditorView.decorations.from(f)
});
// this is your decoration where you can define the change you want : a css class or directly css attributes
const highlight_decoration = Decoration.mark({
// attributes: {style: "background-color: red"}
class: 'red_back'
});
// your editor's view
let main_view = new EditorView({
extensions: [highlight_extension]
});
// this is where the change takes effect by the dispatch. The of method instanciate the effect. You need to put this code where you want the change to take place
main_view.dispatch({
effects: highlight_effect.of([highlight_decoration.range(cursor.value.from, cursor.value.to)])
});
Hope it will help you to implement what you want ;)
Have a look at #codemirror/search.
Specifically, the source code implementation of Selection Matching may be of use for you to adapt.
It uses Decoration.mark over a range of text.
You can use SearchCursor to iterate over ranges that match your pattern (or RegExpCursor)
Use getSearchCursor, something like this:
var cursor = cmEditor.getSearchCursor(keyword , CodeMirror.Pos(cmEditor.firstLine(), 0), {caseFold: true, multiline: true});
if(cursor.find(false)){ //move to that position.
cmEditor.setSelection(cursor.from(), cursor.to());
cmEditor.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
}
Programmatically search and select a keyword
Take a look at getSearchCursor source code it it give some glow about how it works and its usage.
So use getSearchCursor for finding text and optionally use markText for highlighting text because you can mark text with setSelection method of editor.
Selection Marking Demo
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
styleSelectedText: true
});
editor.markText({line: 6, ch: 26}, {line: 6, ch: 42}, {className: "styled-background"});
And it seem this is what you are looking for:
codemirror: search and highlight multipule words without dialog
RegExpCursor is another option that you can use:
new RegExpCursor(
text: Text,
query: string,
options⁠?: {ignoreCase⁠?: boolean},
from⁠?: number = 0,
to⁠?: number = text.length
)
Sample usage at:
Replacing text between dollar signs for Mathml expression.

Change TextField (MUI) background color when data present

Using the 'styled' MUI component, with theme, a TextField component has been created.
When the TextField has no data (ie, empty), below styles were used to render the background as a custom-grey color:
'& .MuiInputBase-root': {
backgroundColor: theme.palette.background.grey01,
height: '40px'
},
This backgroundColor needs to change (to white) when data has been entered into the TextField. Not just 'on focus', but if data is present (ie, TextField is not-empty) the white-background must persist; however, if user deletes/removes data (ie, TextField is emptied by user), backgroundColor needs to go back to custom-grey.
From Chrome Inspect, was able to track down the relevant classes (including .Mui-focused):
MuiOutlinedInput-root MuiInputBase-root MuiInputBase-colorPrimary Mui-Focused MuiInputBase-formControl css-1byr8j2-MuiInputBase-root-MuiOutlinedInput-root
Have reviewed MUI documentation at https://mui.com/customization/how-to-customize/#use-rulename-to-reference-a-local-rule-within-the-same-style-sheet but unable to determine a way to know when value is populated / empty.
UPDATE:
I had overlooked the easiest and most elegant solution.
const StyledTextField = styled(TextField)`
.MuiInputBase-root {
background-color: ${({theme, value}) =>
!value && theme.palette.background.grey01};
}
`

Color and Colors class in Flutter

I was working with Colors class in Flutter.
Added a buildkey function with input "Color zinc" and the same takes the value like Colors.red, Colors purple etc.
However, if I add the input as "Colors Zinc" the values like Colors.red, Colors.purple throws an error. Why this is so?
The class Colors should match the input class (Colors in this case) I think?enter image description here
It would be helpful if you could attach a screenshot or maybe paste the exact error that you are getting.
But meanwhile as I understood it, It seems like that you are telling this works fine for you:
Expanded buildkey(Color zinc, int buildnumber) { ... }
But you are getting some error with this:
Expanded buildkey(Colors zinc, int buildnumber) { ... }
Which is correct behaviour as Colors.[color] returns a swatch constant which is of type color.
e.g: Color selection = Colors.green[400];
For more info: https://api.flutter.dev/flutter/material/Colors-class.html
May be I found the solution of my issue..
When i looked into the dart file of colors class. I found that,
Colors.green is actually an object of Color class. Code is something like this
Class Colors
Color green = Color(....);
Might be that is the reason thats why it requires it requires color class while initilization of variable and not Colors.

GXT - How to set the grid cell background color

I want to change background color of a cell in GXT Grid, I am using GXT 3.0 .I have got one link which is related to my query( http://ui-programming.blogspot.in/2010/01/gxt-how-to-set-cell-grid-background.html) but setRenderer method is not present columnConfig in GXT 3.0 .How can i get desired output? pLz help.
Code i have done till now:-
ColumnConfig<Stock, Double> changeCol = new ColumnConfig<Stock, Double>(props.change(), 100, "Change");
changeCol.setCell(new AbstractCell<Double>() {
#Override
public void render(Context context, Double value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
store.get(context.getIndex());
GWT.log(DOM.getCaptureElement().getId());
String style = "style='background-color: " + (value < 0 ? "red" : "green") + "'";
String v = number.format(value);
sb.appendHtmlConstant("<span " + style + " qtitle='Change' qtip='" + v + "'>" + v + "</span>");
}
});
For those that need to change cell colour based on data in the grid, I've just had to do this (GXT 3.1) but unfortunately the solution isn't perfect.
In general, one can do custom cell rendering with ColumnConfig.setCell(MyCell) where 'MyCell' is a subclass of AbstractCell. Unfortunately there is the problem of 'padding' in the host 'div' which isn't coloured. There are a few ways around this...
The simplest way is to:
ColumnConfig.setCellPadding(false)
Render your own coloured divs that fill up the whole cell (with padding if desired)
Unfortunately this doesn't play well with single cell selection (CellSelectionModel). The css class for cell selection is obfuscated so it can't be referenced in other stylesheets. :(
My (ugly) alternative was to render a custom stylesheet that is linked in the module's html page (eg. Main.html). Then I can colour cells using css 'class' instead of 'style' attributes. IE:
Create a custom JSP that renders a stylesheet (content type 'text/css')
Link the stylesheet to the module html (after 'reset.css')
The stylesheet needs to have selector td.someClass (.someClass is not specific enough)
Use Grid.getView().setViewConfig() to supply a GridViewConfig that returns the appropriate class(es)
Unfortunately this requires a good knowledge of CSS rules and also the possible colours need to be known at user login time.
There may be a third way using the style attribute of the 'td' element. Have a look at this issue from Sencha:
http://www.sencha.com/forum/showthread.php?289347-Influencing-cell-td-style-in-a-grid&p=1057079 (work in progress)
Note that other styling options include:
Various ColumnConfig.setXxxClassName()
Various ColumnConfig.setXxxStyle()

Typo3 Easy way to add a new field to the text and images content element

Is there a easy way to just add a new form to a content element? Like I want an option selector where you can pick a color for the header.
Why not use the header_layout for that? You can customize it in the page-TSConfig
Like this:
# change labels of existing header_layouts
TCEFORM.tt_content {
header_layout.altLabels.0 = white
header_layout.altLabels.1 = red
header_layout.altLabels.2 = green
}
# add layouts
TCEFORM.tt_content{
header_layout.addItems.4 = blue
header_layout.addItems.5 = black
}
# remove layouts
TCEFORM.tt_content{
header_layout.removeItems = 3
}
That's will then set a class to the layout-number, and you can style it with css.
If you actually need a separate field, that's a bit more involved.