Let me introduce myself, I’m Antoine. I really like data, but I have only recently started development with R & R Shiny as I have some free time in my company.
My goal? To enable employees internally to visualize our database while we wait for the migration to a new CRM. I found a lot of interesting things on the internet and got inspired by them! It works quite well and is much smoother than manipulating an Excel file for a B2B database of 69,000 people.
To get to the point, I managed to do quite a lot, but I am stuck with some things and would greatly appreciate any help or guidance!
So, I would like to add:
When exporting filtered data, I don’t want just the data visible on the screen but all the filters.
Fix the bug when performing a column search.
Ability to double-click on a cell and edit it, then have it update directly on the source Excel file upon saving.
Similarly, the ability to add data.
Attached, you will find my code and also a sample database (obviously not the real one!).
library(shiny)
library(DT)
ui <- shinyUI(navbarPage(
"Application de gestion de données",
tabPanel("Base de données",
sidebarLayout(
sidebarPanel(
actionButton("delete_btn", "Déplacer vers la corbeille", class = "btn-danger")
),
mainPanel(
DTOutput("table")
)
)
),
tabPanel("Corbeille",
sidebarLayout(
sidebarPanel(
actionButton("permanent_delete_btn", "Supprimer définitivement", class = "btn-warning"),
actionButton("restore_btn", "Restaurer la ligne sélectionnée", class = "btn-primary")
),
mainPanel(
DTOutput("trash_table")
)
)
),
tabPanel("Dashboard",
# UI pour dashboard
),
tabPanel("Contacter le marketing",
# UI pour contacter le marketing
)
))
library(shiny)
library(DT)
library(readxl)
library(writexl)
library(openxlsx)
library(shinyFeedback)
library(dplyr)
shinyServer(function(input, output, session) {
path_to_file <- "C:/Users/a.goupil/OneDrive - BAW SAS/Bureau/visualisation-bdd/bdd2024_4.xlsx"
data <- reactiveVal(read_excel(path_to_file))
trash <- reactiveVal(data.frame())
output$table <- renderDT({
datatable(
data(),
selection = 'single',
extensions = 'Buttons',
options = list(
pageLength = 10,
lengthMenu = list(c(5, 10, 20, 50, 100, -1), c('5', '10', '20', '50', '100', 'All')),
autoWidth = TRUE,
dom = 'Blfrtip',
buttons = list(
'copy',
'csv',
'excel',
'pdf',
'print'
),
initComplete = JS(
"function(settings, json) {",
"$(this.api().table().header()).css({'background-color': '#D3D3D3', 'color': '#000'});",
"}"
)
),
filter = "top",
callback = JS(
"table.on('keyup change', 'input[type=search]', function() {",
" table.column($(this).parent().index()).search(this.value).draw();",
"});"
)
)
}, server = TRUE)
output$trash_table <- renderDT({
datatable(
trash(),
selection = 'single',
extensions = 'Buttons',
options = list(
pageLength = 10,
lengthMenu = list(c(5, 10, 20, 50, 100, -1), c('5', '10', '20', '50', '100', 'All')),
autoWidth = TRUE,
dom = 'Blfrtip',
buttons = list(
'copy',
'csv',
'excel',
'pdf',
'print'
)
)
)
}, server = TRUE)
observeEvent(input$delete_btn, {
showModal(modalDialog(
title = "Confirmation de suppression",
textInput("password", "Entrez le mot de passe pour supprimer :", value = ""),
footer = tagList(
modalButton("Annuler"),
actionButton("confirm_delete", "Confirmer la suppression", class = "btn-danger")
)
))
})
observeEvent(input$confirm_delete, {
removeModal()
if (input$password == "BAW2024AGO") {
selected_row <- input$table_rows_selected
print(paste("Déplacement de la ligne vers la corbeille:", selected_row))
tryCatch({
req(selected_row)
data_df <- data()
trash_df <- trash()
if (!is.null(selected_row) && selected_row > 0 && selected_row <= nrow(data_df)) {
trash_df <- rbind(trash_df, data_df[selected_row, ])
data_df <- data_df[-selected_row, ]
data(data_df)
trash(trash_df)
}
showToast("success", "Ligne déplacée vers la corbeille")
}, error = function(error) {
showToast("error", "Erreur lors du déplacement vers la corbeille")
})
} else {
showToast("error", "Mot de passe incorrect")
}
})
observeEvent(input$restore_btn, {
selected_row <- input$trash_table_rows_selected
if (!is.null(selected_row)) {
data_df <- data()
trash_df <- trash()
data_df <- rbind(data_df, trash_df[selected_row, ])
trash_df <- trash_df[-selected_row, ]
data(data_df)
trash(trash_df)
showToast("success", "Ligne restaurée")
}
})
observeEvent(input$permanent_delete_btn, {
selected_row <- input$trash_table_rows_selected
if (!is.null(selected_row)) {
trash_df <- trash()
trash_df <- trash_df[-selected_row, ]
trash(trash_df)
showToast("success", "Ligne supprimée définitivement")
}
})
})
Here are the names of all the columns (of the data frame):
# Creating a data frame with the specified column names
df1 <- data.frame(
SIREN = character(),
SIRET = character(),
Civilité = character(),
Prénom = character(),
Nom = character(),
Mail = character(),
Qualité_du_mail = character(),
Service = character(),
Match_fonction = character(),
Fonction = character(),
Fonction_INES = character(),
LinkedIn = character(),
Campagne_Marketing = character(),
Désabonnement = character(),
Niveau_hiérarchique = character(),
Business_Strategy = character(),
Resp_hiérarchique = character(),
Nom_raison_sociale = character(),
Société_Nb_d_Employés = character(),
Groupe_Nb_Employés = character(),
Segment_CA_BAW = character(),
CA_Groupe = numeric(),
CA = numeric(),
CA_GROUPE2 = numeric(),
Commercial = character(),
Pays = character(),
Ville = character(),
Région = character(),
Code_postal = character(),
Département = character(),
Téléphone_1 = character(),
Téléphone_2 = character(),
Site_Web = character(),
LinkedIn_de_l_entreprise = character(),
Marque_source = character(),
Marque_Active = character(),
Secteur_d_Activité = character(),
Secteur_d_Activité_BAW2 = character(),
Territoire_BAW = character(),
Provenance = character(),
Score_Marketing = numeric(),
Niveau_de_décision = character(),
Centre_d_intérêt = character(),
Origine = character(),
Scoring = numeric(),
Type = character(),
ERP = character(),
ERP2 = character(),
EPM = character(),
SIRH = character(),
BI_Data = character(),
Middleware = character(),
Infrastructures_Cloud = character(),
Autres_Solutions = character(),
Autre = character(),
Resp_Technique = character(),
Opportunity_owner = character(),
Etape = character(),
Engagement = character(),
Motifs_de_cloture = character(),
Revente_com = character(),
Type_d_opération = character(),
BU = character(),
Campagne_Marketing2 = character(),
Action_Marketing = character(),
Axe_SAP = character(),
Axe_Oracle = character(),
Axe_RH = character(),
Initiative_Analytics = character(),
Initiative_RFE_Démat_Automatisation = character(),
Initiative_IFS = character(),
Initiative_Cloud_DevOps = character(),
Niveau_de_proximité = character(),
Niveau_Hiérarchique2 = character(),
Data_d_ajout = character(),
Spécifité = character(),
Spécifité2 = character(),
Segment_CA = character(),
Index = numeric(),
stringsAsFactors = FALSE
)
# Displaying the structure of the data frame
str(df1)
I tried several things in JavaScript, but it is beyond my skills, and I haven’t been able to find a real equivalent on the web.
Akilinox is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.