leaflet map - adding a custom control similar to to the layers control but would like a different icon - defined by CSS - leaflet

leaflet map - adding a custom control similar to to the layers control but would like a different icon - defined by CSS
I'm building a custom control on a leaflet map which I'd like to have work similarly to the leaflet layers control. I've copied the logic from the layers control to display the icon on the map and pop up the interface when the mouse hovers over it. It wasn't straight-forwards as the layers control is Javascript and I'm working in typescript. But it is working now, except for one small problem.
I cannot change the icon used by the layers tool since it is defined in CSS. The .SCSS styles I create can be used in the main form where the map is displayed, but not in the leaflet map itself. One brute force method would be to modify the leaflet source .css file and add my new css there. But I'm trying to avoid that.
Is there a way to get the map custom control to recognize CSS defined outside of leaflet?
In the code below, the line which creates the filter icon creates the class name leaflet-control-layers-toggle. This class defines the icon image. If I change this class to anything else, no icon is displayed.
this.filtersLink = L.DomUtil.create('a', className + '-toggle', this.container);
this.filtersLink.href = '#';
this.filtersLink.title = 'Filters';
/* ... */
private InitLayout() {
const className = 'leaflet-control-layers';
this.container = L.DomUtil.create('div', className);
this.container.style.backgroundColor = 'white';
this.container.setAttribute('aria-haspopup', 'true');
L.DomEvent.disableClickPropagation(this.container);
L.DomEvent.disableScrollPropagation(this.container);
this.section = L.DomUtil.create('section', className + '-list');
if (this.collapsed) {
this.map.on('click', this.CollapseDialog, this);
if (!L.Browser.android) {
L.DomEvent.on(this.container, {
mouseenter: this.ExpandDialog,
mouseleave: this.CollapseDialog
}, this);
}
}
this.filtersLink = L.DomUtil.create('a', className + '-toggle', this.container);
this.filtersLink.href = '#';
this.filtersLink.title = 'Filters';
if (L.Browser.touch) {
L.DomEvent.on(this.filtersLink, 'click', L.DomEvent.stop);
L.DomEvent.on(this.filtersLink, 'click', this.ExpandDialog, this);
} else {
L.DomEvent.on(this.filtersLink, 'focus', this.ExpandDialog, this);
}
this.AddLabel('Temporal');
this.AddRadioButton ( 'temporal01', 'temporal', 'Today', '1', false);
this.AddRadioButton ( 'temporal02', 'temporal', 'Yesterday', '2', false );
this.AddRadioButton ( 'temporal03', 'temporal', '7 Days', '3', true );
this.AddRadioButton ( 'temporal04', 'temporal', '30 Days', '4', false );
this.AddSeparator();
this.AddLabel('Severity');
this.AddCheckBox1 ( 'severity01', 'Major', '1', true );
this.AddCheckBox1 ( 'severity02', 'Minor', '2', true );
this.AddCheckBox1 ( 'severity03', 'Insignificant', '3', true );
this.AddSeparator();
this.AddLabel('Status');
this.AddCheckBox2 ( 'status01', 'Active', '1', true );
this.AddCheckBox2 ( 'status02', 'Reinspect', '2', true );
this.AddCheckBox2 ( 'status03', 'Reactivated', '3', true );
this.AddCheckBox2 ( 'status04', 'Closed', '4', false );
this.container.appendChild(this.section);
if (!this.collapsed) {
this.ExpandDialog();
}
}

Got it figured out - two ways to do this:
override with :ngdeep
add it to the styles.scss in the root of the project

Related

Ant Design - How to remove arrow icon in Select component?

enter image description here
I'm using Select in Ant Design and don't know how to remove this icon.
Does anyone know the solution?
I try to edit some css and try config provider also but nothing work. Maybe i don't know the right way to do it
Hope you guys can help me
You can pass null to suffix prop in Select Component.
import { Select } from 'antd';
const App = () => {
return (
<Select
style={{ width: '200px' }}
suffixIcon={null}
options={[
{ value: '1', label: '1' },
{ value: '2', label: '2' }
]}
/>
);
};
export default App;

ReactDataGrid row selection does not work

I am trying to build data table using react and react-data-grid version "^7.0.0-canary.16",
The render method looks like this:
render() {
return (
<div className={"component"}>
<ReactDataGrid width={600} height={400}
rowKey="id"
columns={this.state.columns}
rows={this.state.rows}
onRowClick={this.onRowClick}
rowSelection={{
showCheckbox: true,
enableShiftSelect: true,
onRowsSelected: this.onRowsSelected,
onRowsDeselected: this.onRowsDeselected,
selectBy: {
indexes: this.state.selectedIndexes
}
}}
/>
</div>
)
}
So following the documentation on page https://adazzle.github.io/react-data-grid/docs/examples/row-selection
it should display checkbox in first column and when I select the checkbox it should call method this.onRowsSelected.
Alas, no checkbox is shown and no matter how I click the this.onRowsSelected method is never called.
On the other hand the method this.onRowClick is called, whenever I click somewhere in the table.
Does anyone have experience with this?
It seems to be showing the checkboxes with "react-data-grid": "6.1.0"
Although, I'm having issue with the checkboxes when we filter the data. The rowIdx changes and we lose context of that was previously selected. We want to make BE calls on selected Data. I tried changing it to use the row.id but no luck. It messes up the selection.
Here is a hook for managing the selection
import {useState} from 'react';
export const useRowSelection = () => {
const [selectedIndexes, setSelectedIndexes] = useState([]);
const onRowsSelected = rows => {
setSelectedIndexes(prevState => {
return prevState.concat(rows.map(r => r.rowIdx));
});
};
const onRowsDeselected = rows => {
let rowIndexes = rows.map(r => r.rowIdx);
setSelectedIndexes(prevState => {
return prevState.filter(i => rowIndexes.indexOf(i) === -1);
});
};
return {
selectedIndexes,
onRowsDeselected,
onRowsSelected,
};
};
Pass them to the RDG
const {selectedIndexes, onRowsDeselected, onRowsSelected} = useRowSelection();
const rowSelectionProps = enableRowSelection
? {
showCheckbox: true,
enableShiftSelect: true,
onRowsSelected: onRowsSelected,
onRowsDeselected: onRowsDeselected,
selectBy: {
indexes: selectedIndexes,
},
}
: undefined;
<ReactDataGrid
columns={columnDefinition}
getValidFilterValues={getFilterValues}
rowGetter={i => filteredData[i]}
rowsCount={filteredData.length}
onAddFilter={filter => handleOnAddFilter(filter)}
onClearFilters={() => handleOnCleanFilters()}
toolbar={toolbar}
contextMenu={contextMenu}
RowsContainer={ContextMenuTrigger}
rowSelection={rowSelectionProps}
rowKey="id"
/>

Mform SELECT - Moodle

Is there mform select tag, when option is selected so that it highlights and stick to the selected one and select more options without the use of control key to select. I tried with selectMulitple, where it allows holding control key to select the options.
$select = $mform->addElement('select', 'course', get_string('course', 'core_course'), $options);
$mform->addHelpButton('course', 'course', 'core_course');
$mform->addRule('course', null, 'required', null, 'client');
$mform->setType('course', PARAM_INT);
$select->setMultiple(true);
Short answer is no. You need to use the control key to select multiple items in a select.
You could use a series of checkboxes though, something like this:
$courses = core_course_category::get(0)->get_courses(
array('recursive' => true, 'sort' => array('fullname' => 1)));
foreach ($courses as $course) {
$mform->addElement('advcheckbox', "courses[{$course->id}]",
format_string($course->fullname), null, array('group' => 1));
}
$this->add_checkbox_controller(1);
Then in your edit code, use something like this
for each($formdata->courses as $courseid => $selected) {
if ($selected) {
// User selected this course.
} else {
// User unselected this course.
}
}

TYPO3 6.2 performance, Typoscript Select, Typoscript Cache

The problem itself is solved, but the question is still open cause I want to test the tipps from Krystian. See Edit 3 at the bottom of this question.
I have a TYPO3 project that is very slow. So I did some tests and found some problems.
I tested the startpage, the startpage containers 2 news list (total 9 articles) (tx_news version 2.3.0 - not the newest one). It contains the menu (created with fluid v:page.menu), the footer (also created with v:page.menu), a right column (mainly image content elements, gathered from another page with typoscript) and a news-taglist (created with typoscript). The news-taglist is used twice - once in the menu and once in the right column.
First the performance overview:
No Menu/No Footer (without taglist), No News, No Labellist
0.65s
With menu and footer (without taglist)
0.95s
With menu and footer (with taglist)
2.3s
With menu and footer (with taglist) and Taglist in right column
3s
With all
4.2s
A big point is the taglist (right now there is a total of 1303 tags). here is the Typoscript that generate the taglist:
plugin.tx_mytemplate {
newsTags = CONTENT
newsTags {
table = tx_news_domain_model_tag
select {
pidInList = 1,589
hidden = 0
deleted = 0
orderBy = title
}
orderBy = title
renderObj = COA
renderObj {
1 = LOAD_REGISTER
1 {
Counter.cObject = TEXT
Counter.cObject.data = register:Counter
Counter.cObject.wrap = |+1
Counter.prioriCalc = intval
}
2 = TEXT
2.insertData = 1
2 = TEXT
2.insertData = 1
2.field = title
2.typolink {
# link to page
parameter = 588
# the current tag
additionalParams = &tx_news_pi1[overwriteDemand][tags]={field:uid}
additionalParams.insertData = 1
}
2.wrap = <li data-test="{field:uid}" data-index="{register:Counter}">|</li>
}
wrap = <ul>|</ul>
}
}
I use this once in the menu and once in a content element with:
<f:cObject typoscriptObjectPath="plugin.tx_mytemplate.newsTags" />
What I don't understand is, for my understanding there should not be a big difference in using it once or twice (or even more), cause after the first use the typoscript-object should be created and there is no need to create it a second time. Am I missing something here?
This is the SQL:
SELECT * FROM tx_news_domain_model_tag WHERE tx_news_domain_model_tag.pid IN (1,589) AND tx_news_domain_model_tag.deleted=0 AND tx_news_domain_model_tag.hidden=0 ORDER BY title;
It needs 0.004s to execute this query. So the other point I don't understand is, why is it so expensive to create this typoscript-object? Is it the typolink that is used to create all 1303 Links? (I used realURL)
Also, this taglist does not change often, is it somehow possible to full cache it? And for example only create a new taglist when Flush general caches (or frontend cahches) is executed?
Any other ideas? ( I know I could load the taglist via ajax after the page is loaded, but that is just the last work around and maybe there are better solutions)
Edit: I tested the taglist without the typolink and its around 1s faster. That means to create a typolink for 1303 Link costs around 1s.
Edit 2: I found a hidden config.no_cache = 1 And testing right now if everything works when cache is enabled. But anyway I am interessted why typolink is so expensive.
.
Edit 3: I test Krystians answer:
Cache the Typoscript Object with stdWrap.cache.key = someHash
plugin.tx_mytemplate {
newsTags = CONTENT
newsTags {
table = tx_news_domain_model_tag
select {
pidInList = 1,589
hidden = 0
deleted = 0
orderBy = title
}
orderBy = title
renderObj = COA
renderObj {
1 = LOAD_REGISTER
1 {
Counter.cObject = TEXT
Counter.cObject.data = register:Counter
Counter.cObject.wrap = |+1
Counter.prioriCalc = intval
}
2 = TEXT
2.insertData = 1
2 = TEXT
2.insertData = 1
2.field = title
2.typolink {
# link to page
parameter = 588
# the current tag
additionalParams = &tx_news_pi1[overwriteDemand][tags]={field:uid}
additionalParams.insertData = 1
}
2.wrap = <li data-test="{field:uid}" data-index="{register:Counter}">|</li>
}
wrap = <ul>|</ul>
stdWrap.cache.key = mytaglist
stdWrap.cache.lifetime = unlimited
}
}
I can't see any changes in loading time. is there a way to check if this object really gets cached? Did I something wrong?
Using VHS to cache the content with v:render.cache
I replaced
<f:cObject typoscriptObjectPath="plugin.tx_mytemplate.newsTags" />
with
<v:render.cache content="<f:cObject typoscriptObjectPath='plugin.tx_mytemplate.newsTags' />" identity="test1234" />
It seems to work, cause the first call needs longer. But then the next call is "normal" (as I would not use the v.render.cache) until I take the content part out and just use the identify:
<v:render.cache content="test" identity="test1234" />
This is faster and still displays the taglist. So it works so far, that the cached version behind test1234 is used. But it also seems that he render the f:cObject typoscript object in the content part every time. What am I missing here?
Even stranger is, when I use the code with content="test"and flush frontend caches and flush general caches the taglist is still displayed (and not "test"). The docu says: The cache behind this ViewHelper is the Extbase object cache, which is cleared when you clear the page content cache.. What exactly is the page content cache? Not one of the two flush frontend caches or flush general caches ?
Edit 4: With cache enabled I found a problem with the news plugin. I use realURL for the newsplugin:
'category' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][categories]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_category',
'id_field' => 'uid',
'alias_field' => 'CONCAT(title, "-", uid)',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
'tag' => array(
array(
'GETvar' => 'tx_news_pi1[overwriteDemand][tags]',
'lookUpTable' => array(
'table' => 'tx_news_domain_model_tag',
'id_field' => 'uid',
'alias_field' => 'CONCAT(title, "-", uid)',
'addWhereClause' => ' AND NOT deleted',
'useUniqueCache' => 1,
'useUniqueCache_conf' => array(
'strtolower' => 1,
'spaceCharacter' => '-'
)
)
)
),
Calling a category link works without problem, but when I call a tag link then I see only the news from the first hit (changing the tag does not affect anything, it still shows the news filtered by the first tag). So it seems something went wrong there with the cache, but I can not figure out what. For me categories and tag looks pretty much the same, the only difference is another parameter, but realURL should handle that.
Try that:
plugin.tx_mytemplate = TEXT
plugin.tx_mytemplate {
stdWrap.cache.key = mytaglist
stdWrap.cache.lifetime = unlimited
stdWrap.append = CONTENT
stdWrap.append {
# ... your TS
}
}
The first thing you can do is to cache all elements that are common for all pages. Good candidates for that are header and footer elements and in your case maybe the tag list. If you have header done with typoscript then you can use "cache" property of stdWrap.
5 = TEXT
5 {
stdWrap.cache.key = someHash
}
Read the docs here: http://docs.typo3.org/typo3cms/TyposcriptReference/Functions/Cache/Index.html
If you use this construction then this element is rendered on first page hit. Then for all next pages when TYPO3 needs to render this element it uses value from cache.
If you think that you can not use it for menu becase you have states like "active"/"current" then you are wrong. You can set the staes using Javascript. Here the example.
var urlSplitted = window.location.pathname.substring(1).split('/');
var urlToCheck = [];
$.each(urlSplitted, function (index, value) {
if (value.length) {
urlToCheck.push(value);
$('#main-nav a').filter(function () {
var match = '^/' + urlToCheck.join('/') + '/$';
if ($(this).attr('href') != undefined) {
return $(this).attr('href').match(new RegExp(match, "i"));
} else {
return false;
}
}).parent().addClass('current');
}
})
If you use Fluid then you can also use such caching of common element. Install ext: vhs and then use this ViewHelper
https://fluidtypo3.org/viewhelpers/vhs/1.1.0/Render/CacheViewHelper.html

CKEditor Link dialog modification

I am trying to add a drop down to CKEditor's link dialog. When selected, the drop down should insert corresponding class name to the link.
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'link' ) {
var infoTab = dialogDefinition.getContents( 'info' );
infoTab.add({
type: 'select',
label: 'Display link as a button',
id: 'buttonType',
'default': '',
items: [
['- Not button -', ''],
['Button one', 'btn-primary'],
['Button two', 'btn-success'],
['Button three', 'btn-danger']
],
commit: function(data) {
data.className = this.getValue();
}
});
}
});
I have a feeling commit function is not doing the job, but cannot figure out how to make it work. I saw a code that almost does the same thing as I want at http://www.lxg.de/code/simplify-ckeditors-link-dialog. I tried it and it does not work either.
I am using CKEditor 4.3.2.
I appreciate your help in advance.
If you console.log the data object in link dialog's onOk, you'll find quite a different hierarchy. Element classes are in data.advanced.advCSSClasses. But even if you decide to override (or extend) the value of this property in your commit, your string will be nuked by the original commit of advCSSClasses input field ("Advanced" tab) anyway. So the approach got to be a little bit different:
Always store the value of the select in data.
Override commit of advCSSClasses input field to consider stored value.
Remember to execute the original commit of advCSSClasses input.
Here we go:
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'link' ) {
var infoTab = dialogDefinition.getContents( 'info' ),
advTab = dialogDefinition.getContents( 'advanced' ),
advCSSClasses = advTab.get( 'advCSSClasses' );
infoTab.add( {
type: 'select',
label: 'Display link as a button',
id: 'buttonType',
'default': '',
items: [
['- Not button -', ''],
['Button one', 'btn-primary'],
['Button two', 'btn-success'],
['Button three', 'btn-danger']
],
commit: function( data ) {
data.buttonType = this.getValue();
}
});
var orgAdvCSSClassesCommit = advCSSClasses.commit;
advCSSClasses.commit = function( data ) {
orgAdvCSSClassesCommit.apply( this, arguments );
if ( data.buttonType && data.advanced.advCSSClasses.indexOf( data.buttonType ) == -1 )
data.advanced.advCSSClasses += ' ' + data.buttonType;
};
}
});
Now you got to only write a setup function which will detect whether one of your button classes is present to set a proper value of your select field once the dialog is open.