Below is code showing that the size of a sweetalert when bootstrap is used is very large. If you comment out the navbarpage() code chunk I note in the sample below the sweetalert is smaller.
I suppose I could overwrite with new .css which is fine. But, is there an alternative way to deal with that via arguments in the function itself? I don't see an argument in the help, but there is the ... which passes to .js. I'm not savvy enough with js to know if that's an option and if so what might that look like?
Thanks for any suggestions
library(shiny)
library(bslib)
library(shinyBS)
ui <- fluidPage(
### Code Chunk to comment out
navbarPage(
theme = bs_theme(bootswatch = "flatly", version = 4),
title = 'Methods',
tabPanel('One'),
),
### end BS code chunk
tags$h2("Sweet Alert examples"),
actionButton(
inputId = "success",
label = "Launch a success sweet alert",
icon = icon("check")
),
actionButton(
inputId = "error",
label = "Launch an error sweet alert",
icon = icon("remove")
),
actionButton(
inputId = "sw_html",
label = "Sweet alert with HTML",
icon = icon("thumbs-up")
)
)
server <- function(input, output, session) {
observeEvent(input$success, {
sendSweetAlert(
title = "Success !!",
text = "All in order",
type = "success"
)
})
observeEvent(input$error, {
sendSweetAlert(
title = "Error !!",
text = "It's broken...",
type = "error"
)
})
observeEvent(input$sw_html, {
sendSweetAlert(
title = NULL,
text = tags$span(
tags$h3("With HTML tags",
style = "color: steelblue;"),
"In", tags$b("bold"), "and", tags$em("italic"),
tags$br(),
"and",
tags$br(),
"line",
tags$br(),
"breaks",
tags$br(),
"and an icon", icon("thumbs-up")
),
html = TRUE
)
})
}
shinyApp(ui, server)
In an asp.net Core web application I'm using the Tagify component (Tagify home page & examples) for showing tags in input and textarea controls. Following an example from the link (see under: Same using custom suggestions) I have the following code:
<div class="col-auto" title="Start typing to show available tags ...">
<textarea name="tbSearch2" placeholder="Filter by tags" id="tbSearch2" class="form-control email-filter" rows="1"></textarea>
</div>
and javascript (ajax executes only once -> on page load):
var tagslist = '';
$.ajax({
'url': "Email/GetTags",
'success': function (data) {
tagslist = data;
// load tags for searching
var tagify1 = new Tagify(document.querySelector('textarea[name=tbSearch2]'), {
tagTextProp: 'name',
enforceWhitelist: true,
delimiters: null,
whitelist: tagslist,
editTags: false,
dropdown: {
mapValueTo: 'name',
searchKeys: ['name'],
maxItems: 20, // <- maximum allowed rendered suggestions
classname: 'tags-look', // <- custom classname for this dropdown, so it could be targeted
enabled: 0, // <- show suggestions on focus
closeOnSelect: false // <- do not hide the suggestions dropdown once an item has been selected
},
});
}
});
The tags work, but only when the user starts typing some text into the textarea. The dropdown does not appear immediately when Tagify control has focus (as in the example in the link in the beginning of this post).
Any ideas what I'm doing wrong?
*note: there are no errors in the browser console.
You can try to check the versions of tagifycss and js, Here is a working demo:
GetTags action:
public List<string> GetTags()
{
return new List<string>{ "A# .NET", "A# (Axiom)", "A-0 System", "A+", "A++", "ABAP", "ABC", "ABC ALGOL", "ABSET", "ABSYS", "ACC", "Accent", "Ace DASL", "ACL2", "Avicsoft", "ACT-III", "Action!", "ActionScript"};
}
js:
<script src="https://cdnjs.cloudflare.com/ajax/libs/tagify/4.3.0/tagify.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tagify/4.3.0/tagify.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script>
var tagslist = '';
$(function () {
$.ajax({
'url': "GetTags",
'success': function (data) {
tagslist = data;
// load tags for searching
var tagify1 = new Tagify(document.querySelector('textarea[name=tbSearch2]'), {
tagTextProp: 'name',
enforceWhitelist: true,
delimiters: null,
whitelist: tagslist,
editTags: false,
dropdown: {
mapValueTo: 'name',
searchKeys: ['name'],
maxItems: 20, // <- maximum allowed rendered suggestions
classname: 'tags-look', // <- custom classname for this dropdown, so it could be targeted
enabled: 0, // <- show suggestions on focus
closeOnSelect: false // <- do not hide the suggestions dropdown once an item has been selected
},
});
}
});
})
</script>
result:
I'm new to WP's gutenberg and React(but not WP/PHP). I'm trying to add a series of custom controls that show up on all core blocks. Using the WP documentation, I was able to add a new inspector section with a simple toggle:
var el = wp.element.createElement;
const { ToggleControl, PanelBody, PanelHeader, BaseControl } = wp.components;
var withInspectorControls = wp.compose.createHigherOrderComponent( function( BlockEdit ) {
return function( props ) {
return el(
wp.element.Fragment,
{},
el(
BlockEdit,
props
),
el(
wp.editor.InspectorControls,
{},
el(
PanelBody,
{
title: 'Section Controls'
},
el(
ToggleControl,
{
label: 'Full Width Section',
checked: props.attributes.full_width_section,
onChange: function(value){ props.setAttributes( { full_width_section: value } ); }
}
),
)
)
);
};
}, 'withInspectorControls' );
wp.hooks.addFilter( 'editor.BlockEdit', 'brink/with-inspector-controls', withInspectorControls );
What I can't do is figure out the proper way to utilize blocks.getSaveContent.extraProps to save the new full_width_section toggle.
I know I'll then need to figure out how to manipulate the block output after this, but one problem at a time!
I finally figured this out by dissecting a few Gutenberg plugins. In this case, before adding controls to the inspector I had to create attributes for all blocks:
// Attributes
const backgroundSettings = {
fullWidthSection: {
type: "boolean",
},
};
function addAttributes(settings) {
const { assign } = lodash;
settings.attributes = assign(settings.attributes, backgroundSettings);
return settings;
}
wp.hooks.addFilter( 'blocks.registerBlockType', 'brink/add-attributes', addAttributes ); // Add Attributes
From here all you have to do is add any attributes you want and their settings, default, etc. in backgroundSettings.
I need to get the selected row 1st column value from the DT Data Table. Using, DataTable_rows_selected , I am able to get the selected row count, Now I am looking for ways to extract the row values from the data table. In the example below, there are two observeEvent based on action button, 1st observe event is import and displays the data and 2nd one needs to display the selected row 1st col value so that I can use the same achieve other features. Please note,In Actual Application, the imported data is a web service API and which I am parsing in R and converting to data frame.
Sample Example:
library(shiny)
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Data Table Example"),
dashboardSidebar(
sidebarMenu(
menuItem('Tabs', tabName='tabs',
menuSubItem('Tab 1', tabName='tab1'),
menuSubItem('Tab 2', tabName='tab2')
)
)
),
dashboardBody(
tabItems(
tabItem(tabName='tab1',
actionButton("import","Import"),
br(),
tags$div(tags$h3(tags$b(" Get Selected Row Values",align="middle",style="color: rgb(57,156,8)"))),
br(),
DT::dataTableOutput('ProductDataTable')
),
tabItem(tabName='tab2',
actionButton("display","Display"),
uiOutput('info')
)
)
)
)
server <- function(input, output) {
observeEvent(input$import,{
Product <- read.csv2("RulesData.csv", header=TRUE, sep=";")
output$ProductDataTable <- DT::renderDataTable({
DT::datatable(Product,selection = "single",
extensions = c('Buttons', 'ColReorder', 'FixedHeader', 'Scroller'),
rownames=FALSE,
options=list(dom = 'Bfrtip',
searching = T,
pageLength = 25,
searchHighlight = TRUE,
colReorder = TRUE,
fixedHeader = TRUE,
filter = 'bottom',
buttons = c('copy', 'csv','excel', 'print'),
paging = TRUE,
deferRender = TRUE,
scroller = TRUE,
scrollX = TRUE,
scrollY = 700
))
})
})
observeEvent(input$display,{
row_count <- input$ProductDataTable_rows_selected
output$info <- renderPrint({
cat('Row Selected: ')
cat(row_count, sep = ', ')
cat(Product[1,2], sep = ', ')
})
})
}
shinyApp(ui, server)
check this code below if this is what You are looking for:
library(shiny)
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Data Table Example"),
dashboardSidebar(
sidebarMenu(
menuItem('Tabs', tabName='tabs',
menuSubItem('Tab 1', tabName='tab1'),
menuSubItem('Tab 2', tabName='tab2')
)
)
),
dashboardBody(
tabItems(
tabItem(tabName='tab1',
actionButton("import","Import"),
br(),
tags$div(tags$h3(tags$b(" Get Selected Row Values",align="middle",style="color: rgb(57,156,8)"))),
br(),
DT::dataTableOutput('ProductDataTable')
),
tabItem(tabName='tab2',
actionButton("display","Display"),
uiOutput('info')
)
)
)
)
server <- function(input, output) {
Product <- reactive({mtcars})
observeEvent(input$import,{
output$ProductDataTable <- DT::renderDataTable({
DT::datatable(Product(),selection = "single",
extensions = c('Buttons', 'ColReorder', 'FixedHeader', 'Scroller'),
rownames=FALSE,
options=list(dom = 'Bfrtip',
searching = T,
pageLength = 25,
searchHighlight = TRUE,
colReorder = TRUE,
fixedHeader = TRUE,
filter = 'bottom',
buttons = c('copy', 'csv','excel', 'print'),
paging = TRUE,
deferRender = TRUE,
scroller = TRUE,
scrollX = TRUE,
scrollY = 700
))
})
})
observeEvent(input$display,{
output$info <- renderPrint({
row_count <- input$ProductDataTable_rows_selected
data <- Product()[row_count, ]
cat('Row Selected: ')
cat(data[,1]) #display the selected row 1st col value
})
})
}
shinyApp(ui, server)
I have used mtcars dataset as an example, the problem was that Your data was inside of the observer (one with input$import) and as You need to use it for other analysis such as displaying of the row value of first column (i have not understood well what did You mean about that as Your code is telling different thing), data had to be moved outside of the observer and put into reactive.
[UPDATE]
I have used if statement to import the data instead of observeEvent
library(shiny)
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Data Table Example"),
dashboardSidebar(
sidebarMenu(
menuItem('Tabs', tabName='tabs',
menuSubItem('Tab 1', tabName='tab1'),
menuSubItem('Tab 2', tabName='tab2')
)
)
),
dashboardBody(
tabItems(
tabItem(tabName='tab1',
actionButton("import","Import"),
br(),
tags$div(tags$h3(tags$b(" Get Selected Row Values",align="middle",style="color: rgb(57,156,8)"))),
br(),
DT::dataTableOutput('ProductDataTable')
),
tabItem(tabName='tab2',
actionButton("display","Display"),
uiOutput('info')
)
)
)
)
server <- function(input, output) {
Product <- reactive({
if(input$import == 0)
{
return()
}
isolate({
input$import
data <- mtcars # Here read Your data: read.csv2("RulesData.csv", header=TRUE, sep=";")
})
})
output$ProductDataTable <- DT::renderDataTable({
DT::datatable(Product(),selection = "single",
extensions = c('Buttons', 'ColReorder', 'FixedHeader', 'Scroller'),
rownames=FALSE,
options=list(dom = 'Bfrtip',
searching = T,
pageLength = 25,
searchHighlight = TRUE,
colReorder = TRUE,
fixedHeader = TRUE,
filter = 'bottom',
buttons = c('copy', 'csv','excel', 'print'),
paging = TRUE,
deferRender = TRUE,
scroller = TRUE,
scrollX = TRUE,
scrollY = 700
))
})
observeEvent(input$display,{
output$info <- renderPrint({
row_count <- input$ProductDataTable_rows_selected
data <- Product()[row_count, ]
cat('Row Selected: ')
cat(data[,1]) #display the selected row 1st col value
})
})
}
shinyApp(ui, server)
one more way to get row values from Data Table is DT:DataTable Call Back option in association with Java Script JS().
Here is the code:
library(shiny)
library(shinydashboard)
library(DT)
ui <- dashboardPage(
dashboardHeader(title = "Data Table Example"),
dashboardSidebar(
sidebarMenu(
menuItem('Tabs', tabName='tabs',
menuSubItem('Tab 1', tabName='tab1'),
menuSubItem('Tab 2', tabName='tab2')
)
)
),
dashboardBody(
tabItems(
tabItem(tabName='tab1',
actionButton("import","Import"),
br(),
tags$div(tags$h3(tags$b("Get Selected Row Values",style="color: rgb(57,156,8)"))),
br(),
DT::dataTableOutput('ProductDataTable')
),
tabItem(tabName='tab2',
actionButton("display","Display"),
uiOutput('info')
)
)
)
)
server <- function(input, output) {
observeEvent(input$import,{
Product <- mtcars
output$ProductDataTable <- DT::renderDataTable({
DT::datatable(Product,selection = "single",
# JS using call back function to get the row values on single click
callback = JS("table.on('click.dt', 'tr',
function() {
Shiny.onInputChange('rows', table.rows(this).data().toArray());
});"),
extensions = c('Buttons', 'ColReorder', 'FixedHeader', 'Scroller'),
rownames=FALSE,
options=list(dom = 'Bfrtip',
searching = T,
pageLength = 25,
searchHighlight = TRUE,
colReorder = TRUE,
fixedHeader = TRUE,
filter = 'bottom',
buttons = c('copy', 'csv','excel', 'print'),
paging = TRUE,
deferRender = TRUE,
scroller = TRUE,
scrollX = TRUE,
scrollY = 700
))
})
})
observeEvent(input$display,{
row_count <- input$ProductDataTable_rows_selected
output$info <- renderPrint({
cat('Row Selected 1st Col Value: ')
# getting 1st row col value
cat(input$rows[1], sep = ', ')
})
})
}
shinyApp(ui, server)
I'm working on a Shiny module and generating data table using Javascript code through Ajax. But when the module is used in a Shiny app, Chrome keeps saying there is synchronous XMLHttpRequest on the main thread and I can't figure out why.
The module ui is generated by Javascript code which has a data table listing some data objects retrieved by Ajax call to a local desktop application's RESTful API. There is two buttons in the UI, one is 'Refresh', when it is clicked, ajax.reload() gets called while the other one is an 'Import' button which will import the selected row into the Shiny app.
I'm assuming the issue is not caused by the 'Import' button because when the page loads, the warning message shows up immediately, the 'Import' button didn't get clicked and plus the importing process is explicitly specified to use an async call. So the issue is caused by the initial ajax call that initializes the data table but I think it should default use a async call as well.
Any suggestions? Thanks!
wrapWithDocumentReady <- function(jsCode) {
return(paste0("$(document).ready(function(){", jsCode, "});"))
}
myModuleUI <- function(id) {
ns <- NS(id)
jsCode <- paste0(
# 1st to initialize the data table
"let objectTable = $('#",
ns("dataObjectTable"),
"').DataTable( {
ajax: {
url: 'http://localhost:XXXX/some_application/data',
dataSrc: ''
},
columns: [
{ name: 'name', data: 'name', title: 'Name' },
{ name: 'data_type', data: 'data_type', title: 'Data Type', visible:false },
{ name: 'id', data: 'id', title: 'ID', visible: false },
{ name: 'dimension', data: 'dimension', title: 'Dimension'},
],
select: {
style: 'single'
},
} );",
# 2nd to bind the 'Import' button with event
"$('#",
ns("importButton"),
"').click(function() {",
"
let selectedDataId = objectTable.cell('.selected', 'id:name').data();
var xmlhttp = new XMLHttpRequest();
var url = 'http://localhost:XXXX/some_application/data/'.concat(selectedDataId);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
var dataJson = this.responseText;
Shiny.onInputChange('", ns("addDataObject"),"', dataJson);
}
}
};
xmlhttp.open('GET', url, true);
xmlhttp.send();
});",
# 3rd to bind the 'Reresh' button with event
"$('#",
ns("refreshButton"),
"').click(function() {
objectTable.ajax.reload();
});"
);
tagList(
div(tags$table(id = ns("dataObjectTable"), width="100%")),
actionButton(ns("refreshButton"), "Refresh"),
actionButton(ns("importButton"), "Import"),
tags$script(wrapWithDocumentReady(jsCode))
)
}
myModule <- function(input, output, session) {
importedData <- reactive ({
jsonStr <- input$addDataObject
if (!is.null(jsonStr)) {
# passing the data and return
} else {NULL}
})
return(importedData)
}