How to disable / enable Select in Bootstrap-Select? - bootstrap-select

I'm trying to disable/enable a select multiple dynamically, and I already tried using javascript with disabled, I already tried to use jquery and I already tried to use the methods of the library itself and nothing happens.
HTMLElements.forEach(divs => {
if(divs.hasAttribute('data-for') && divs.getAttribute('data-for') === 'Contracted Member') {
const HTMLInputElements = divs.querySelectorAll('input'),
HTMLSelectElements = divs.querySelectorAll('select');
HTMLInputElements.forEach(_inputElements => _inputElements.removeAttribute('disabled'));
HTMLSelectElements.forEach(_selectElement => {
console.log(_selectElement.id)
$('#RSCICMS').prop('disabled', true);
$('#RSCICMS').selectpicker('render');
});
divs.setAttribute('data-status', 'actived');
}
});
Animation
Note
I've tried to follow this question, but it's no use.

Have you tried using $('#RSCICMS').selectpicker('refresh') instead of $('#RSCICMS').selectpicker('render')?
From the docs: render is only for changing values whereas refresh is used when enabling/disabling the selectpicker.

Related

Triggering a lexical.js mentions menu programatically when clicking on a mention

What I need
Let's start with The mentions plugin taken from the docs.
I would like to enhance if with the following functionality:
Whenever I click on an existing MentionNode, the menu gets rendered (like it does when menuRenderFunction gets called), with the full list of options, regardless of queryString matching
Selecting an option from menu replaces said mention with the newly selected one
Is there a way to implement this while leaving LexicalTypeaheadMenuPlugin in control of the menu?
Thank you for your time 🙏🏻
What I've tried
I figured that maybe I could achieve my desired behaviour simply by returning the right QueryMatch from triggerFn. Something like this:
const x: FC = () => {
const nodeAtSelection = useNodeAtSelection() // Returns LexicalNode at selection
return (
<LexicalTypeaheadMenuPlugin<VariableTypeaheadOption>
triggerFn={(text, editor) => {
if ($isMentionsNode(nodeAtSelection)) {
// No idea how to implement `getQueryMatchForMentionsNode`,
// or whether it's even possible
return getQueryMatchForMentionsNode(nodeAtSelection, text, editor)
}
return checkForVariableBeforeCaret(text, editor)
}}
/>
)
}
I played around with it for about half an hour, unfortunately I couldn't really find any documentation for triggerFn or QueryMatch, and haven't really made any progress just by messing around.
I also thought of a potential solution the I think would work, but feels very hacky and I would prefer not to use it. I'll post it as an answer.
So here is my "dirty" solution that should work, but feels very hacky:
I could basically take the function which I provide to menuRenderFn prop and call it manually.
Let's say I render the plugin like this:
const menuRenderer = (
anchorElementRef,
{ selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }
) => { /* ... */}
return (
<LexicalTypeaheadMenuPlugin menuRenderFn={menuRenderer} /* ... other props */ />
)
I could then create a parallel environment for rendering menuRenderer, something like this:
const useParallelMenu = (
menuRenderer: MenuRenderFn<any>,
allOptions: TypeaheadOption[],
queryString: string
) => {
// I could get anchor element:
// 1. either by using document.querySelector("." + anchorClassName)
// 2. or by extracting it from inside `menuRenderFn`:
// menuRenderFn={(...params) => {
// extractedRef.current = params[0].current;
// return menuRenderer(...params)
// }}
const anchorEl = x
const [selectedIndex, setHighlightedIndex] = useState(0)
const nodeAtSelection = useNodeAtSelection() // Returns LexicalNode at selection
const selectOptionAndCleanUp = (option: TypeaheadOption) => {
// Replace nodeAtSelection with new MentionsNode from `option`
}
return () =>
$isMentionsNode(nodeAtSelection) &&
menuRenderer(
anchorEl,
{
selectedIndex,
setHighlightedIndex,
selectOptionAndCleanUp,
options: allOptions
},
queryString
)
}
On paper, this seems like a viable approach to me... but I would really prefer not to have to do this and instead let LexicalTypeaheadMenuPlugin manage the state of my menu, as it is intended to do.

Change detection is not working even with ngZone or Array Copy or with setTimeout

I have a function like below, which is invoked from within ngAfterViewInit(). I have a ngFor in the view using the countryUsageTypesArr variable. Now I have tried to put that part of the code inside ngZone.run(), setTimeout(), tried to use spread operator (to create a new array), but nothing makes angular to catch the change. The only option is using ChangeDetectionRef (which works well, I have tested). But I am not feeling well to use ChangeDetector every where. Is there any other way I should try?
getCategoryById(categoryId: number) {
this.categoryService.getCategoryById(categoryId).subscribe((response: any) => {
if (response.result == 1) {
window.setTimeout(() => {
this.countryUsageTypesArr = [...response.data.country_usage_types, []];
}, 0);
}
}, (error: any) => {
// console.log(error.error.msg);
});
}

Mui-datatables custom search

how do I add a custom search in mui-datatables which can be used for data fetched from API. can u please provide me a working example? I tried using
customSearch: (searchQuery, currentRow, columns) => {
let isFound = false;
currentRow.forEach(col => {
if (col.toString().indexOf(searchQuery) >= 0) {
isFound = true;
}
});
return isFound;
},
in options.
note: in console, I got react_devtools_backend.js:6 Server-side filtering is enabled, hence custom search will be ignored.
You're probably looking for something like this:
https://github.com/gregnb/mui-datatables/blob/master/examples/serverside-filters/index.js
Or this (debounceSearchRender plugin):
https://github.com/gregnb/mui-datatables/blob/master/examples/large-data-set/index.js
Your backend is going to return the results, so your custom search needs to be defined in the server.

Detect react event from Tampermonkey

I'm enhancing a React front end with Tampermonkey , by adding highlights to show cursor location in a grid, and allowing users to directly enter data , rather than then enter data.
After 2 or 3 cursor moves or data entry the grid refreshes or updates - no page change - and looses the highlighting I set up.
I'd like to catch the refresh/update and reset the highlighting.
I'm a noob..
The network tab shows post events so I tried https://jsbin.com/dixelocazo/edit?js,console
var open = window.XMLHttpRequest.prototype.open,
send = window.XMLHttpRequest.prototype.send;
to try and use POST events to detect the refresh. No joy !
I also looked at ajax events.
No luck :(
Can someone point me in the right direction here ?
Once I catch the event, I can then reset the highlighting to fix the problem
Since normally the userscripts run in a sandbox, JavaScript functions or objects cannot be used directly by default, here's what you can do:
Disable the sandbox:
// #grant none
You won't be able to use any GM functions, though.
Run in the page context via unsafeWindow:
const __send = unsafeWindow.XMLHttpRequest.prototype.send;
unsafeWindow.XMLHttpRequest.prototype.send = function () {
this.addEventListener('loadend', e => {
console.log('intercepted', e);
}, {once: true});
__send.apply(this, arguments);
};
Use MutationObserver to detect changes in page DOM:
const observer = new MutationObserver(mutations => {
const matched = [];
for (const {addedNodes} of mutations) {
for (const n of addedNodes) {
if (!n.tagName)
continue;
if (n.matches('.prey:not(.my-highlight)')) {
matched.push(n);
} else if (n.firstElementChild) {
matched.push(...n.querySelectorAll('.prey:not(.my-highlight)'));
}
}
}
// process the matched elements
for (const el of matched) {
el.classList.add('my-highlight');
}
});
observer.observe(document.querySelector('.surviving-ancestor') || document.body, {
subtree: true,
childList: true,
});
.surviving-ancestor means the element that isn't replaced/recreated by the page script. In devtools element inspector it's the one that isn't highlighted temporarily during DOM updates.
See also Performance of MutationObserver.

Check which column has been clicked on rowClick event

I am looking for a way to see which column the rowClick event has happened.
Because based on which column this happend we want other things to happen.
We already got something like this:
this.chart.listen('rowClick', (event) => {
if (event['period'] && event['period'].itemType === GanttItemType.work) {
setTimeout(() => this.clickedDetail(event), 1);
} else if (event['item'] && event['item'].get('technicianId') && !event['period']) {
// HERE WE WANT TO KNOW IN WHICH COLUMN WE ARE
const technicianId = event['item'].get('technicianId');
setTimeout(() => this.openTechnician(technicianId), 1);
} else {
this.preventDef(event);
}
});
Thanks in advance I cannot seem to find if/where this is possible
Unfortunately, there's no out-of-the-box method to implement such functionality, so it requires some tricks.
The idea is quite simple – if dataGrid columns width is predefined we can compare the click X-coordinate and the column width. For details, check the sample by the link provided in the comment below.

Resources