dxDataGrids not working with Bootstrap tabs - devexpress

I just updated DevExtreme from 17.1.4 to 20.2.7. Almost everything is working fine. However, the dxDataGrids now have a problem with Bootstrap tabs that they didn't before.. I have 6 bs tabs; 1 grid in each. There was never an issue before, but now only the initially active tab shows data and moving to another tab shows an empty grid.. which doesn't even have column names.
What I've tried:
Using Bootstrap tab events to figure out which tab is active and then refresh the grid (ugly hack):
$(window).on('shown.bs.tab', function () {
var tab = $(event.target).text();
switch (tab) {
case "Example1": $("#grid-example1").dxDataGrid("instance").refresh(); break;
case "Example2": $("#grid-example2").dxDataGrid("instance").refresh(); break;
case "Example3": $("#grid-example3").dxDataGrid("instance").refresh(); break;
case "Example4": $("#grid-example4").dxDataGrid("instance").refresh(); break;
case "Example5": $("#grid-example5").dxDataGrid("instance").refresh(); break;
case "Example6": $("#grid-example6").dxDataGrid("instance").refresh(); break;
default: break;
}
});
This sort of works.. but it has the following 3 issues:
Has to get data from server every time I change a tab..
Doesn't show any column names for any of the grids (except the first one when page loaded)
For some reason the first column is now very wide and the grids are not responsive at all.. except again the first one showing when page is loaded.
I tried calling updateDimensions() as well.. but that didn't make any difference:
$(window).on('shown.bs.tab', function () {
var tab = $(event.target).text();
switch (tab) {
case "Example1":
$("#grid-example1").dxDataGrid("instance").refresh();
$("#grid-example1").dxDataGrid("instance").updateDimensions();
break;
case "Example2":
$("#grid-example2").dxDataGrid("instance").refresh();
$("#grid-example2").dxDataGrid("instance").updateDimensions();
break;
case "Example3":
$("#grid-example3").dxDataGrid("instance").refresh();
$("#grid-example3").dxDataGrid("instance").updateDimensions();
break;
case "Example4":
$("#grid-example4").dxDataGrid("instance").refresh();
$("#grid-example4").dxDataGrid("instance").updateDimensions();
break;
case "Example5":
$("#grid-example5").dxDataGrid("instance").refresh();
$("#grid-example5").dxDataGrid("instance").updateDimensions();
break;
case "Example6":
$("#grid-example6").dxDataGrid("instance").refresh();
$("#grid-example6").dxDataGrid("instance").updateDimensions();
break;
default: break;
}
});
Please tell me how I can solve this issue.
EDIT: In case there's some misunderstanding here, the problem appears to be that the new version appears to have an issue being initialized inside an invisible container, whereas the old one worked perfectly fine. That's why I tried refreshing the grids in the shown.bs.tab event, but that doesn't help, as I have mentioned above.

Sample Code:
$('a[data-toggle="tab"]').on("shown.bs.tab", function(e) {
var $link = $(e.target)
var target = $link.attr("href"); // activated tab
$(target).find("#grid").dxDataGrid("instance").updateDimensions();
});
Reference: https://supportcenter.devexpress.com/ticket/details/t625427/data-grid-is-rendered-incorrectly-inside-bootstrap-tabs/

Related

Angular SlickGrid is it possible to use pagination AND set row color based on value?

Is it possible to set the background color for a row in slickgrid (based on data values) AND use pagination? For angular-slickgrid package.
I used getItemMetadata as suggested multiple other (old) posts - example SlickGrid: How to loop through each row and set color based on the condition?.
This code:
metadata(old_metadata_provider) {
return function(row) {
var item = this.getItem(row);
var ret = (old_metadata_provider(row) || {});
if (item) {
ret.cssClasses = (ret.cssClasses || '');
if ("attribute" in item) {
return { cssClasses: 'redRow' }; //redRow is in styles.css
}
}
return ret;
}
}
and the call is:
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
It works correctly. However, when I turn pagination on, the color does not work as expected. I read that SlickGrid re-uses the same row elements when scrolling or paginating and will overwrite the styles associated with them. Is there another way to do it? Thanks for any help on this.
I tried adding the following code, after reading suggestion from ghiscoding, but the colors are still not working when pagination is enabled.
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
this.checkRowBackgroundColor(); //where I call the metadata function from my previous post, if the dataView object is defined.
//I added this code:
var self = this;
this.dataViewObj.onPagingInfoChanged.subscribe(function (e, dataView, grid) {
self.gridObj.invalidate();
self.gridObj.render();
});
}
Try this approach:
angularGridReady(angularGrid: AngularGridInstance) {
this.angularGrid = angularGrid;
this.dataViewObj = angularGrid.dataView;
this.gridObj = angularGrid.slickGrid;
// check color change logic for the first time page load
this.checkRowBackgroundColor();
// use arrow function so that 'this' works properly
this.dataViewObj.onPagingInfoChanged.subscribe((e, dataView, grid) => {
// check your color change logic every time Paging Info Changed
this.checkRowBackgroundColor();
});
}
Inside your checkRowBackgroundColor:
checkRowBackgroundColor() {
// ... any of your logic
// get metadata
this.dataViewObj.getItemMetadata = this.metadata(this.dataViewObj.getItemMetadata);
// rerender the grid after getting new metadata
this.gridObj.invalidate();
this.gridObj.render();
}
Your problem should be solved now. As I have not tested on my local machine, I can not give guarantee. You can checkout original documentation of angular-slickgrid about this specific topic here: Dynamically Add CSS Classes to Item Rows

Is there a way to change the body class of a Wordpress page based on Rev Slider's slide?

The goal is: as the slide of rev slider changes, the body's page background color changes. The only way that I think it could be possible is using custom class on page slug. But how to insert a class based on the slide? Is it possible?
1) You must find where Revolution Slider is initialized in your theme or plugin, and either a) note the variable it is assigned to or b) assign it to a variable. It should be something like this:
var revapi2 = jQuery('#slider_id').show().revolution();
New versions of Revolution Slider already assign the slider to a variable that allows binding. The format for this variable is revapi{id}.
2) Once the slider is assigned to a variable, you'll have access to the slide's API methods, described fully here. One of the methods, revolution.slide.onchange will enable detecting when the slider is about to change slides. Then you can do something like this to assign the body class depending on the slide's index. Note I'm using jQuery because it's a jQuery plugin and I'm using the variable automatically assigned by the Revolution Slider WordPress plugin:
revapi2.on('revolution.slide.onbeforeswap', function(event, data) {
switch (data.nextSlideIndex) {
case 1:
bodyClass = "green";
break;
case 2:
bodyClass = "blue";
break;
case 3:
bodyClass = "red";
break;
default:
bodyClass = "yellow";
}
$('body').removeClass('red green blue yellow').addClass(bodyClass);
});

Bootstrap Datepicker return colour for select dates

Ok,
so I'm using this calendar https://bootstrap-datepicker.readthedocs.io/en/latest/
I have an MVC controller which is already passing an array of dates and a known state for these dates, I can disable these fine.
What I'm trying to attempt is that for a certain state, I change the colour of the number on the calendar.
An exmaple on the site has a a rather intersting return green, now I couldn't get it work when I experimented.
So I copied the entire example(which is the code snippet), and it all worked except for the return green, yet if you us the sandbox and enable the 'before show day' you can see this returning green.
Looking at the DOM in the Sandbox you can see the class change to 'green day' in my code it changes it to 'day green'.
My question is, has anyone actually got this working?
If so, what colours can you change to? I've searched through the libary, but I'm coming up blank on how this actually works.
$('#sandbox-container div').datepicker({
beforeShowDay: function(date){
if (date.getMonth() == (new Date()).getMonth())
switch (date.getDate()){
case 4:
return {
tooltip: 'Example tooltip',
classes: 'active'
};
case 8:
return false;
**case 12:
return "green";**
}
}
});
Ok, so I actuallly worked this out while I was typing this.
add to the bootstrapper-datepicker css the below
.day.purple {
color: purple;
}
The code names the day whatever you return, so you don't need to return a color, you could return 'sausage' and on the css return green, what's important is the name you return is the name of your css class
$('#sandbox-container div').datepicker({
beforeShowDay: function(date){
if (date.getMonth() == (new Date()).getMonth())
switch (date.getDate()){
case 4:
return {
tooltip: 'Example tooltip',
classes: 'active'
};
case 8:
return false;
**case 12:
return "purple";**
}
}
});

View specific mode in FullCalendar

I'm trying to call a specific FullCalendar view, not necessarily my default view, through a URL.
Something like /my_calendar/?&mode=month.
I searched the documentation and couldn't easily find anything that points to this.
I found this though where they claim this is implemented in Drupal somehow. Not sure how to backport (if easily possible?).
Any idea on how to achieve this?
So on your calendar page, before your fullcalendar configuration you will need to add the following code. This will check if $_GET['mode'] is set in the url and if it is, it will use a switch to make sure it is a valid value and then assign the JavaScript variable to that value and echo it to the page and if it is not set or if the value does not match it will assign the default value of month.
<script>
<?php
if(isset($_GET['mode'])) {
switch ($_GET['mode']) {
case "month":
echo "var mode = 'month';";
break;
case "agendaWeek":
echo "var mode = 'agendaWeek';";
break;
default:
echo "var mode = 'month';";
break;
}
} else {
echo "var mode = 'month';";
}
?>
</script>
Then in your fullcalendar configuration you just need to set the following.
defaultView: mode,
Note: your IDE may say that mode is not defined if your fullcalendar configuration and fullcalendar page are separate. Thats fine as long as its defined on the calendar page before the script. With this code, a page like calendar.php?mode=agendaWeek will load the calendar with default view set to agendaWeek.

How do I create a paragraph break in Google Form help text?

I've looked on Google's product forums, and I can't find anything. The help text field is designed for brief text, but I want to insert a mulit-paragraph article. Without paragraph breaks, I wind up with a bunch of text that's difficult to read.
This has been bugging me for a long time and I've came up with a not so elegant but efficient solution based on Apps Script. Pavel Agarkov had the same idea! My version also works with multiple occurences and can be re-run if Google Forms removes the line breaks when you edit the text.
When editing a form, open the Script Editor from the main menu.
Create a new script, replace the content with the code below. Save it and return to your form.
Reload the page. You will notice a new option in the main menu, looking like this
That "Scripts" menu was added by our script. Don't use it for now, it won't do much.
When editing content, use fours spaces as a placeholder for line breaks.
Run the script from the Scripts menu. Now celebrate 👯‍♀️
Some things worth noting:
You will get a permission request the first time you run the script. It's ok, read the message and do what you have to do.
Once the line breaks are there, Google Forms, god bless its heart, will remove them every time you edit the field. Mildly infuriating. Just run the script again.
The script you need to use is:
// From https://stackoverflow.com/questions/22207368/
function onOpen() {
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('Replace 4+ spaces with line breaks in Title and Description', 'addLineBreaks')
.addToUi();
}
function addLineBreaks() {
var theForm = FormApp.getActiveForm();
var theQuestions = theForm.getItems();
var thePlaceholder = new RegExp(/\s{4,99}|\n/, 'gi');
for (i = 0; i < theQuestions.length; i++) {
var theText = theQuestions[i].getHelpText();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setHelpText(theText.replace(thePlaceholder,' \n'));
}
theText = theQuestions[i].getTitle();
if (theText.search(thePlaceholder) > 0 ) {
theQuestions[i].setTitle(theText.replace(thePlaceholder,' \n'));
}
}
}
I found that you can't do it through the editor but it is possible via the script.
Go to main menu -> script editor;
past the following code to the editor;
function addLineBreaks()
{
var form = FormApp.getActiveForm();
// find form items you need
var questions = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
for(i = 0; i < questions.length; i++)
{
var title = questions[i].getTitle();
// if no replacement has been done yet
if(title.indexOf("\n") < 0)
{
// this will add line break after <double space> like in markdown
questions[i].setTitle(title.replace(" ", " \n"));
}
}
}
then set up trigger to start this method on form open.
I struggled with this question myself for too long!
However, when you know how its simple:
Go to "Add Item"
Choose "Section Header"
This option allows you to put paragraphed text into your Form.
As of June, 2018, the following work (but only the second option is documented):
Just put new lines in the description and it will be shown in the form - try using two for a paragraph.
If you want a bit more style - add a 'Title and Description' - see the second option in the tool bar showing 'Tᴛ'. The Title will always add extra space (even if it's empty) and will show any title as inverted, larger, text. You can disable the description if you just want a 'heading' followed by questions.
None of the above solutions worked for me, SO I added a unicode character https://www.compart.com/en/unicode/U+2002 pasted 4 to 5 times and this is how it looks
Sorry for the bad news, but this seems impossible to me.
I found the answer! While in the box into which you are entering text, go to Properties in the Developer tab. You will get a drop-down menu. At the bottom of the menu is "Plain Test Properties" with a check box for "Allow carriage returns (multiple paragraphs).
This is a better solution but based on the above. It allows you to edit the form which amazingly the above solutions don't:
// Version 2020-10-07a: by Dennis Bareis
// Handles "{nl}" in form & question descriptions
// Forms API: https://developers.google.com/apps-script/reference/forms
// Based on https://stackoverflow.com/questions/22207368/
// This code #: https://stackoverflow.com/a/64216993/3972414
// [0] ... -> Script Editor -> Create New Script
// [1] Paste into script editor
// [2] Run onOpen()
// [3] On first run authorise script
// [4] This adds 2 scripts under a new button in the edit form UI
// (to the left of the "Send" button)
// [5] Use "START" before re-editing form
// [6] Use "END" to publish the changes
// 5&6 required as otherwise you end up with "line1Line2Line3" etc
String.prototype.replaceAll = function(search, replacement)
{
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
//This doesn't perform the function on open, just adds it to the UI, you run when finished.
function onOpen()
{
var ui = FormApp.getUi();
ui.createMenu('Scripts')
.addItem('[1] Prepare for RE-EDITING this form (restore {nl})', 'editFormStart')
.addItem('[2] Publish the form (finished editing, remove {nl})', 'editFormEnd')
.addToUi();
}
function editFormStart()
{
swapLineBreaks("\n", "{nl}")
}
function editFormEnd()
{
swapLineBreaks("{nl}", "\n")
}
function swapLineBreaks(FromText, ToText)
{
var form = FormApp.getActiveForm();
// find form items you need
var oForm = FormApp.getActiveForm();
var questions = oForm.getItems();
// Fix the form's description
var formDesc = oForm.getDescription()
oForm.setDescription(formDesc.replaceAll(FromText, ToText))
// Work through each question
for(i = 0; i < questions.length; i++)
{
//var QTitle = questions[i].getTitle();
//questions[i].setTitle( QTitle.replaceAll(FromText, ToText));
var QText = questions[i].getHelpText();
questions[i].setHelpText(QText.replaceAll(FromText, ToText));
}
}

Resources