Popular New Releases in User Interface
react-native
0.68.1
material-ui
v5.4.0
vuetify
v3.0.0-beta.1
nerd-fonts
v2.2.0-RC: Workflow for building release candidate (WIP)
chakra-ui
@chakra-ui/tooltip@2.0.0-next.0
Popular Libraries in User Interface
by facebook javascript
102222 NOASSERTION
A framework for building native applications using React
by mui-org javascript
75241 MIT
MUI (formerly Material-UI) is the React UI library you always wanted. Follow your own design system, or start with Material Design.
by vuetifyjs typescript
34010 MIT
π Material Component Framework for Vue
by ryanoasis css
33737 NOASSERTION
Iconic font aggregator, collection, & patcher. 3,600+ icons, 50+ patched fonts: Hack, Source Code Pro, more. Glyph collections: Font Awesome, Material Design Icons, Octicons, & more
by google html
31786 Apache-2.0
Material Design Components in HTML/CSS/JS
by chakra-ui typescript
25337 MIT
β‘οΈ Simple, Modular & Accessible UI Components for your React Applications
by sentsin javascript
24021 MIT
ιη¨θͺ身樑εθ§θηΌεηεη«― UI ζ‘ζΆοΌι΅εΎͺεη HTML/CSS/JS ηδΉ¦εε½’εΌοΌζδ½ι¨ζ§οΌζΏζ₯ε³η¨γ
by react-native-elements typescript
22069 MIT
Cross-Platform React Native UI Toolkit
by powerline shell
21854
Patched fonts for Powerline users.
Trending New libraries in User Interface
by tailwindlabs typescript
14223 MIT
Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
by jdan css
5958 MIT
A design system for building faithful recreations of old UIs
by nextui-org typescript
5926 MIT
π Beautiful, fast and modern React UI library.
by radix-ui typescript
4076 MIT
An open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @modulz.
by sixtyfpsui rust
2964 NOASSERTION
SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.
by arco-design typescript
2940 MIT
A comprehensive React UI components library based on Arco Design
by hug-sun javascript
2892 MIT
A Vue.js 3.0 UI Toolkit for Web.
by bernaferrari typescript
2394 GPL-3.0
Generate responsive pages and apps on HTML, Tailwind, Flutter and SwiftUI.
by fontsource css
2384 MIT
Self-host Open Source fonts in neatly bundled NPM packages.
Top Authors in User Interface
1
46 Libraries
2413
2
31 Libraries
6319
3
29 Libraries
25235
4
25 Libraries
181
5
21 Libraries
540
6
18 Libraries
2429
7
18 Libraries
98
8
16 Libraries
194
9
15 Libraries
385
10
14 Libraries
1854
1
46 Libraries
2413
2
31 Libraries
6319
3
29 Libraries
25235
4
25 Libraries
181
5
21 Libraries
540
6
18 Libraries
2429
7
18 Libraries
98
8
16 Libraries
194
9
15 Libraries
385
10
14 Libraries
1854
Trending Kits in User Interface
Here are some famous Vue UI Libraries. Vue UI Libraries' use cases include Developing Single Page Applications, Creating Reusable Components, Building Responsive Applications, and Creating Cross-Platform Applications.
Vue UI libraries/frameworks refer to a set of tools, components, and libraries that help developers build user interfaces (UI) with the Vue.js framework. These libraries and frameworks provide pre-defined components and functions that can be quickly and easily integrated into an application, resulting in a powerful and feature-rich UI.
Let us look at these libraries in detail below.
vuetify
- Offers a wide range of pre-made UI components.
- Designed to follow the Material Design guidelines and provides a comprehensive library of UI components.
- Designed to work on all major devices, from desktop to mobile, providing a consistent user experience across all platforms.
quasar
- Has a robust theming system.
- Abstracts away the complexities of the DOM.
- Developers can customize and extend the library without having to pay for a commercial license.
bootstrap-vue
- Fully compatible with Bootstrap 4 and offers easy access to the standard Bootstrap components.
- Unique directives allow developers to quickly and easily create components like tabs, modals, and popovers.
- Includes an extensive set of utility classes and components.
Keen-UI
- Doesnβt impose any styling or coding conventions on the user.
- Modular, allowing you to include only the components you need.
- Wide range of components, from basic form elements to more complex components like a multi-select.
vuikit
- Offers a flexible layout system that allows developers to create complex applications quickly.
- Built to be cross-browser compatible, allowing developers to create applications that work on all major web browsers.
- Highly customizable, allowing developers to create applications that look and feel unique.
iview
- Provides an extensive library of components, including tables, inputs, buttons, forms, and more.
- Easy customization of themes to match the desired look and feel of your project.
- Provides advanced features such as server-side rendering, progressive web apps, and code splitting.
KendoUI-VueJS
- Provides support for internationalization.
- Supports declarative syntax, making it easy to create complex and highly interactive user interfaces.
- Comprehensive support for responsive design.
Here are some of the famous jQuery UI Libraries. These Libraries are used for Creating custom user interfaces, Enhancing user experience, Making web pages interactive, Creating custom animation, and Building custom themes.
jQuery UI is a collection of user interface libraries and plugins built on top of the jQuery JavaScript library. It provides abstracted user interface elements such as date pickers, accordions, tabs, and sliders that can be used to quickly build interactive web applications.
Let us have a look at these libraries in detail below.
jquery-ui
- ο»ΏProvides a comprehensive set of user interface widgets.
- Provides an easy way to implement drag and drop functionality.
- Designed to meet the accessibility guidelines set by the W3C.
kendo-ui-core
- Comprehensive UI framework containing numerous widgets and components.
- Offers a wide range of customizable themes and styling options.
- Built-in support for MVVM (Model-View-ViewModel) which makes it easy to create dynamic, interactive applications.
jQuery-ContextMenu
- Designed to be cross-browser compatible.
- Built-in help system and extensive documentation, making it simple to get started.
- Allows developers to create menus with multiple levels of complexity.
jQueryGantt
- Includes a built-in resource management system.
- Intuitive drag-and-drop functionality for rearranging tasks.
- Offers an interactive zoom feature.
jQuery-steps
- Supports server-side validation to prevent incomplete or incorrect data from being submitted.
- Provides an intuitive and easy to use interface for creating step-by-step wizards.
- Offers a flexible layout system which allows you to customize the look and feel of your wizards.
jQuery-Form-Validator
- Built-in validation functions and a wide range of options.
- Easy to integrate with any web page and can be quickly customized to match the look and feel of any project.
- Allows for the creation of custom validation messages in multiple languages.
layout
- Responsive design support for mobile and tablet devices.
- Built-in support for accessibility and internationalization.
- A powerful API that makes it easy to create custom widgets and implement complex interactions.
jQuery-easyui
- Includes an easy-to-use drag-and-drop feature.
- Provides an easy-to-use, organized, and lightweight user interface library.
- Supports AJAX (Asynchronous JavaScript and XML), JSON, and HTML5 technologies.
jqueryfiletree
- Built-in security system to protect sensitive files from being accessed.
- Highly configurable and allows users to customize the look and feel of the file browser.
- Built-in search feature to help users quickly locate a file or folder.
A font file contains a set of digital typefaces (typefaces or fonts). Font files typically contain vector or bitmap data describing each character's shape in the typeface. They are used to display text in a specified format and style.
Pygame is a cross-platform Python modules designed to write video game code. It contains computer graphics and sound libraries designed for the Python programming language. Pygame will add functionality on top of the excellent SDL library. It is free and open source software available for Windows, Mac OS X, Linux, and Android.
Pygameβs font module is used to render text on the screen. One can load a font file in Pygame using the pygame.font.Font() method.
- This method takes the font file name as an argument and returns a Font object.
- Once the Font object is created, one can use it to render text on the screen using the render() method.
Here is an example of loading a font file in Pygame
Fig1: Preview of the Code
Fig2: Preview of a part of the Output
Code
In this solution, we will load a font file in Pygame.
Instructions
- Install Jupyter Notebook on your computer.
- Open terminal and install the required libraries with following commands.
- Install Pygame - pip install pygame
- Copy the snippet using the 'copy' button and paste it into that file.
- Run the file using run button.
I hope you found this useful. I have added the link to dependent libraries, version information in the following sections.
I found this code snippet by searching for "Loading a font file in Pygame " in kandi. You can try any such use case!
Dependent Libraries
If you do not have Pygame that is required to run this code, you can install it by clicking on the above link and copying the pip Install command from the Pygame page in kandi.
You can search for any dependent library on kandi like Pygame.
Environment Tested
I tested this solution in the following versions. Be mindful of changes when working with other versions.
- The solution is created in Python3.9.6
- The solution is tested on Pygame 2.3.0 version.
Using this solution, we are able to load a font file in Pygame
This process also facilities an easy to use, hassle free method to create a hands-on working version of code which would help us to load a font file in Pygame.
Support
- For any support on kandi solution kits, please use the chat.
- For further learning resources, visit the Open Weaver Community learning page.
Tkinter is a popular Python library for creating graphical user interfaces (GUIs). It provides a wide range of widgets and tools for building interactive applications. Within tkinter, fonts play a crucial role in the visual appearance of text. The text is displayed in GUI elements such as labels, buttons, text boxes, and more.
In tkinter, fonts define the style, size, weight, and other text attributes. They allow developers to customize the look and feel of their GUIs. It is done by choosing different font families, sizes, and styles. By modifying the font settings, you can create appealing and readable text. That text is aligned with your application's design requirements.
The tkinter library provides a class called font. The font allows you to define and manipulate fonts. With the Font class, you can specify various properties. It can be the font family (e.g., Arial, Times New Roman), font size, font weight (bold, normal), and font style (italic, Roman). These properties can be combined to create a specific font configuration.
Different types of tkinter fonts:
- System Fonts - Tkinter allows you to use system fonts available on the operating system. You can specify fonts such as "Arial," "Helvetica," "Times New Roman," "Courier," etc.
- Named Fonts - Tkinter offers a few predefined named fonts. These fonts include "TkDefaultFont," "TkTextFont," "TkFixedFont," and "TkMenuFont.
- Custom Fonts - Allows you to create custom fonts by specifying various attributes. It includes family, size, weight, slant, and underline.
- External Fonts - Supports using external fonts that are not available by default. Using the font, you can load custom fonts from files (e.g., True Type fonts).Font class.
- Font Metrics - These metrics allow you to position and align text within GUI elements.
Tkinter is the standard GUI toolkit for Python. It offers various features for working with fonts. These features help customize the appearance of text in your Tkinter.
Different features available in Tkinter fonts:
- Typeface Selection: You can choose from various typefaces (fonts).
- Font Size: You can set the font size using the size option. The size can be specified in points (e.g., 12) or pixels (e.g., "12px").
- Font Weight: Supports different font weights. Such as "normal," "bold," "italic," and "bold italic."
- Font Slant: The slant option allows you to specify the slant style of the font. It can be set to "Roman" (no slant), "italic," or "oblique."
- Underline and Overstrike: fonts can be underlined and/or overstruck for emphasis.
- Character Sets: Tkinter supports various character sets, including ASCII, Latin-1 (ISO-8859-1), and Unicode.
- Text Alignment: Fonts in Tkinter can be aligned.
- Font Color: You can set the color of the text using the foreground or fg option.
- Font Background: provides an option to set the background color of the text.
- Advanced Formatting: Allows you to apply advanced formatting to text. It can be superscript and subscript.
There are several factors to consider while choosing the right tkinter font. Here are some tips to help you make the right decision:
- Purpose and context
- Readability
- Typeface style
- Consistency
- Target audience
- Platform compatibility
- Test and experiment
Tkinter is a popular Python library for creating graphical user interfaces (GUIs). It provides various tools and functionalities to design and customize GUI elements. This includes text formatting and font manipulation.
Here are some different ways you can use tkinter fonts to enhance your GUI:
- Basic Text Styling:
Tkinter allows you to apply font settings to individual text widgets. It would be like labels, buttons, or entry fields. You can specify the font family, size, weight, and style.
- Global Font Settings:
Suppose you apply the same font settings to many widgets throughout your GUI. You can configure a global font for the root window. This ensures consistency across different elements.
- Dynamic Font Changes:
Tkinter allows you to change the font of a widget during runtime. This can be useful when you want to provide font customization options to the user.
- Font Metrics and Attributes:
Tkinter provides methods to retrieve font metrics and attributes. It can be the height, width, or whether the font is bold or italic. You can use these attributes to adjust the layout of your GUI elements.
Using tkinter fonts can enhance the appearance of your applications. It gives them a more professional look.
Here are some tips on using tkinter fonts to create professional-looking applications:
- Choose appropriate font families.
- Use consistent font styles.
- Pay attention to font size and spacing.
- Use font weight and styles.
- Align text.
- Use colors.
- Be mindful of accessibility.
- Experiment with font customization.
- Test and iterate.
- Seek inspiration and study design principles.
In conclusion, Fonts play a role in the design and aesthetic of an application. Tkinter provides a powerful and versatile set of tools. These tools are used for managing and manipulating fonts. Tkinter fonts offer a wealth of options and flexibility for creating professional-looking applications. You can enhance visual appeal, readability, and consistency by utilizing these fonts. So, embrace the power of Tkinter fonts and take your application's design to the next level.
Here is an example of using custom fonts in Tkinter Python.
Fig 1: Preview of the code and the output.
Code
In this solution, we are using custom fonts in Tkinter Python.
Instructions
Follow the steps carefully to get the output easily.
- Install Jupyter Notebook on your computer.
- Open terminal and install the required libraries with following commands.
- Install tkinter by using the following command.
- !pip install ipywidgets
- !pip install tkinter
- Copy the code using the "Copy" button above and paste it into your IDE's Python file.
- Run the file.
I hope you found this useful. I have added the link to dependent libraries, version information in the following sections.
I found this code snippet by searching for "How to use custom fonts in Tkinter Python" in kandi. You can try any such use case!
Dependent Libraries
If you do not have tkinter that is required to run this code, you can install it by clicking on the above link and copying the pip Install command from the tkinter page in kandi.
You can search for any dependent library on kandi like Tkinter
Environment Tested
I tested this solution in the following versions. Be mindful of changes when working with other versions.
- The solution is created in Python 3.9.6
- The solution is tested on tkinter version 8.6
Using this solution, we are able to use custom fonts in Tkinter Python.
Support
- For any support on kandi solution kits, please use the chat
- For further learning resources, visit the Open Weaver Community learning page.
FAQ:
1. What are the different font families available in Tkinter Text?
The system's fonts determine the font families available for the Text widget. The available font families can vary depending on the OS and fonts installed on the system. But several common font families are available across different platforms.
Here are some used font families in Tkinter:
- Arial
- Helvetica
- Times New Roman
- Courier New
- Verdana
- Tahoma
- Georgia
- Comic Sans MS
- Trebuchet MS
- Impact
2. How can I import Tk into my Python program to access tkinter fonts?
To import Tkinter (Tk) and access tkinter fonts in your Python program, you can follow these steps:
- Import the Tkinter module.
- Create an instance of the Tkinter Tk class.
- Access the fonts using the tkinter.font module.
3. What font attributes can be used to customize a text widget's look and feel?
With the text widget, you can use various font attributes to achieve the desired effect. Here are some used font attributes:
- Typeface/Font Family: You can specify the typeface or font family for the text.
- Font Size: This attribute determines the size of the text.
- Font Style: You can apply different styles to the text, such as normal, italic, or oblique.
- Font Weight: This attribute determines the thickness or boldness of the text.
- Text Decoration: You can add visual effects, like underline, overline, or line-through.
- Text Transform: This attribute allows you to control the capitalization of the text.
- Letter Spacing: It determines the spacing between characters in the text.
- Word Spacing: Like letter spacing, this controls the spacing between words in the text.
- Text Alignment: You can align the text to the left, right, and center or justify it (align both left and right edges).
- Text Color: You can specify the color of the text using various color formats. It includes colors, hexadecimal values, RGB values, or HSL values.
4. Are there other widgets besides Label where tkinter fonts can be applied?
Yes, tkinter fonts can be applied to other widgets in the tkinter library. Some of the used widgets that support font customization include:
- Button: You can apply fonts to buttons using the font option.
- Entry: Fonts can be applied to the Entry widgets using the font option.
- Text: The Text widget supports font customization using the font option.
- Listbox: Fonts can be applied to Listbox items using the font option.
- Checkbutton: The Checkbutton widget supports font customization using the font option.
- Radiobutton: Fonts can be applied to the Radiobutton widget using the font option.
- OptionMenu: Fonts can be applied to the OptionMenu widget using the font option.
5. How do you measure font metrics such as width, height, or size in Python programs using tkinter fonts?
In the tkinter library, you can measure font metrics like width, height, or size. In a real-world application, you would use tkinter widgets. It helps display text on the screen and measure the font metrics.
Trending Discussions on User Interface
Why Metamask if web3.js can interact directly with ganache?
Is it possible to save several values to a button?
How to upload an Image File modified by OpenCV using FileSystemStorage in Django?
How to dynamically define Headers and Settings for UWP NavigationView's menu, using C++/winRT?
With Stripe API, How To Get session_id of Checkout Session That Created a payment_intent Object, From payment_intent.succeeded Webhook
Is it safe to store, access and HTMLElement objects directly inside an object, vs. relying on CSS selectors?
How to increase height of jQueryUI selectmenu?
Is a work manager good for these situations?
Data exchange between websocket clients and server
Register all inputs inside a multi-page data table
QUESTION
Why Metamask if web3.js can interact directly with ganache?
Asked 2022-Mar-30 at 17:55I am new to blockchain app development, I saw a project where ganache accounts are imported into Metamask, then web3.js is used to access and print those accounts and balances on Frontend (user interface).
If web3.js can directly access ganache blockchain accounts and balances, why do we need Metamask in between?
ANSWER
Answered 2022-Feb-08 at 09:11If web3.js can directly acccess ganache blockchain accounts and balances, why we need metamask in between?
In this case, you don't need MetaMask to sign the transaction, as the node (Ganache) holds your private key.
But in a public environment (testnets and mainnet), the node doesn't hold your private key, so you'd need to sign the transaction using MetaMask (or any other tool that holds the private key).
QUESTION
Is it possible to save several values to a button?
Asked 2022-Mar-08 at 02:57Traditionally buttons are designed to save only ONE single value, eg:
1<button type="button" value="Love" onclick="fetchValue(this)"> Primary </button>
2
3function fetchValue(_button){
4 alert(_button.value);
5}
6
For instance, in the above HTML
code, when a user clicks on the Primary button, an alert with the word Love will pop up!
For (UI/UX)User Interface/Experience purposes, I need to design a button that can hold several values and NOT just one value. This is because I plan on coupling a click event to the button to send/post all stored values.
The much desired code would be something like the code below:
1<button type="button" value="Love" onclick="fetchValue(this)"> Primary </button>
2
3function fetchValue(_button){
4 alert(_button.value);
5}
6<button type="button" value="Love", value2="Love",
7value3="Love" onclick="fetchValue(this)"> Primary </button>
8
Is there someone who might know how to resolve this or even a better solution to my problem?
Thanks in advance
ANSWER
Answered 2022-Mar-07 at 15:34You can use data
attributes for additional values.
1<button type="button" value="Love" onclick="fetchValue(this)"> Primary </button>
2
3function fetchValue(_button){
4 alert(_button.value);
5}
6<button type="button" value="Love", value2="Love",
7value3="Love" onclick="fetchValue(this)"> Primary </button>
8function fetchValue(_button){
9 alert(`${_button.value} ${_button.dataset.value2}`);
10}
1<button type="button" value="Love" onclick="fetchValue(this)"> Primary </button>
2
3function fetchValue(_button){
4 alert(_button.value);
5}
6<button type="button" value="Love", value2="Love",
7value3="Love" onclick="fetchValue(this)"> Primary </button>
8function fetchValue(_button){
9 alert(`${_button.value} ${_button.dataset.value2}`);
10}<button type="button" value="Love" data-value2="you" onclick="fetchValue(this)"> Primary </button>
QUESTION
How to upload an Image File modified by OpenCV using FileSystemStorage in Django?
Asked 2022-Feb-13 at 16:57I am taking an uploaded image from the user and then sending it to a YOLO model which then returns me an image.
I want to store that returned image in my Local Directory and then display it on the user interface.
This is the Code of views.py
that takes in an image and sends it to the Yolo Model,
1def predictImage(request):
2 # print(request)
3 # print(request.POST.dict())
4 fileObj = request.FILES['filePath']
5 fs = FileSystemStorage()
6 filePathName = fs.save(fileObj.name, fileObj)
7 filePathName = fs.url(filePathName)
8 testimage = '.'+filePathName
9 # img = image.load_img(testimage, target_size=(img_height, img_width))
10 img = detect_image(testimage)
11 filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
12 filePathName = fs.url(filePathName)
13
This is the function of YOLO Model that uses OpenCV to read the image (Image is sent as argument to the function) and then returns that image,
1def predictImage(request):
2 # print(request)
3 # print(request.POST.dict())
4 fileObj = request.FILES['filePath']
5 fs = FileSystemStorage()
6 filePathName = fs.save(fileObj.name, fileObj)
7 filePathName = fs.url(filePathName)
8 testimage = '.'+filePathName
9 # img = image.load_img(testimage, target_size=(img_height, img_width))
10 img = detect_image(testimage)
11 filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
12 filePathName = fs.url(filePathName)
13import numpy as np
14import cv2
15
16def detect_image(img_path):
17
18 confidenceThreshold = 0.5
19 NMSThreshold = 0.3
20
21 modelConfiguration = 'cfg/yolov3.cfg'
22 modelWeights = 'yolov3.weights'
23
24 labelsPath = 'coco.names'
25 labels = open(labelsPath).read().strip().split('\n')
26
27 np.random.seed(10)
28 COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")
29
30 net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
31
32 image = cv2.imread(img_path)
33 (H, W) = image.shape[:2]
34
35 #Determine output layer names
36 layerName = net.getLayerNames()
37 layerName = [layerName[i - 1] for i in net.getUnconnectedOutLayers()]
38
39 blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
40 net.setInput(blob)
41 layersOutputs = net.forward(layerName)
42
43 boxes = []
44 confidences = []
45 classIDs = []
46
47 for output in layersOutputs:
48 for detection in output:
49 scores = detection[5:]
50 classID = np.argmax(scores)
51 confidence = scores[classID]
52 if confidence > confidenceThreshold:
53 box = detection[0:4] * np.array([W, H, W, H])
54 (centerX, centerY, width, height) = box.astype('int')
55 x = int(centerX - (width/2))
56 y = int(centerY - (height/2))
57
58 boxes.append([x, y, int(width), int(height)])
59 confidences.append(float(confidence))
60 classIDs.append(classID)
61
62 #Apply Non Maxima Suppression
63 detectionNMS = cv2.dnn.NMSBoxes(boxes, confidences, confidenceThreshold, NMSThreshold)
64
65 if(len(detectionNMS) > 0):
66 for i in detectionNMS.flatten():
67 (x, y) = (boxes[i][0], boxes[i][1])
68 (w, h) = (boxes[i][2], boxes[i][3])
69
70 color = [int(c) for c in COLORS[classIDs[i]]]
71 cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
72 text = '{}: {:.4f}'.format(labels[classIDs[i]], confidences[i])
73 cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
74
75 return image
76
77 #cv2.imshow('Image', image)
78 #cv2.waitKey(0)
79
On this line,
1def predictImage(request):
2 # print(request)
3 # print(request.POST.dict())
4 fileObj = request.FILES['filePath']
5 fs = FileSystemStorage()
6 filePathName = fs.save(fileObj.name, fileObj)
7 filePathName = fs.url(filePathName)
8 testimage = '.'+filePathName
9 # img = image.load_img(testimage, target_size=(img_height, img_width))
10 img = detect_image(testimage)
11 filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
12 filePathName = fs.url(filePathName)
13import numpy as np
14import cv2
15
16def detect_image(img_path):
17
18 confidenceThreshold = 0.5
19 NMSThreshold = 0.3
20
21 modelConfiguration = 'cfg/yolov3.cfg'
22 modelWeights = 'yolov3.weights'
23
24 labelsPath = 'coco.names'
25 labels = open(labelsPath).read().strip().split('\n')
26
27 np.random.seed(10)
28 COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")
29
30 net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
31
32 image = cv2.imread(img_path)
33 (H, W) = image.shape[:2]
34
35 #Determine output layer names
36 layerName = net.getLayerNames()
37 layerName = [layerName[i - 1] for i in net.getUnconnectedOutLayers()]
38
39 blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
40 net.setInput(blob)
41 layersOutputs = net.forward(layerName)
42
43 boxes = []
44 confidences = []
45 classIDs = []
46
47 for output in layersOutputs:
48 for detection in output:
49 scores = detection[5:]
50 classID = np.argmax(scores)
51 confidence = scores[classID]
52 if confidence > confidenceThreshold:
53 box = detection[0:4] * np.array([W, H, W, H])
54 (centerX, centerY, width, height) = box.astype('int')
55 x = int(centerX - (width/2))
56 y = int(centerY - (height/2))
57
58 boxes.append([x, y, int(width), int(height)])
59 confidences.append(float(confidence))
60 classIDs.append(classID)
61
62 #Apply Non Maxima Suppression
63 detectionNMS = cv2.dnn.NMSBoxes(boxes, confidences, confidenceThreshold, NMSThreshold)
64
65 if(len(detectionNMS) > 0):
66 for i in detectionNMS.flatten():
67 (x, y) = (boxes[i][0], boxes[i][1])
68 (w, h) = (boxes[i][2], boxes[i][3])
69
70 color = [int(c) for c in COLORS[classIDs[i]]]
71 cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
72 text = '{}: {:.4f}'.format(labels[classIDs[i]], confidences[i])
73 cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
74
75 return image
76
77 #cv2.imshow('Image', image)
78 #cv2.waitKey(0)
79filePathName = fs.save(fileObj.name + "_result", img)
80
I am getting this following error,
1def predictImage(request):
2 # print(request)
3 # print(request.POST.dict())
4 fileObj = request.FILES['filePath']
5 fs = FileSystemStorage()
6 filePathName = fs.save(fileObj.name, fileObj)
7 filePathName = fs.url(filePathName)
8 testimage = '.'+filePathName
9 # img = image.load_img(testimage, target_size=(img_height, img_width))
10 img = detect_image(testimage)
11 filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
12 filePathName = fs.url(filePathName)
13import numpy as np
14import cv2
15
16def detect_image(img_path):
17
18 confidenceThreshold = 0.5
19 NMSThreshold = 0.3
20
21 modelConfiguration = 'cfg/yolov3.cfg'
22 modelWeights = 'yolov3.weights'
23
24 labelsPath = 'coco.names'
25 labels = open(labelsPath).read().strip().split('\n')
26
27 np.random.seed(10)
28 COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")
29
30 net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
31
32 image = cv2.imread(img_path)
33 (H, W) = image.shape[:2]
34
35 #Determine output layer names
36 layerName = net.getLayerNames()
37 layerName = [layerName[i - 1] for i in net.getUnconnectedOutLayers()]
38
39 blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
40 net.setInput(blob)
41 layersOutputs = net.forward(layerName)
42
43 boxes = []
44 confidences = []
45 classIDs = []
46
47 for output in layersOutputs:
48 for detection in output:
49 scores = detection[5:]
50 classID = np.argmax(scores)
51 confidence = scores[classID]
52 if confidence > confidenceThreshold:
53 box = detection[0:4] * np.array([W, H, W, H])
54 (centerX, centerY, width, height) = box.astype('int')
55 x = int(centerX - (width/2))
56 y = int(centerY - (height/2))
57
58 boxes.append([x, y, int(width), int(height)])
59 confidences.append(float(confidence))
60 classIDs.append(classID)
61
62 #Apply Non Maxima Suppression
63 detectionNMS = cv2.dnn.NMSBoxes(boxes, confidences, confidenceThreshold, NMSThreshold)
64
65 if(len(detectionNMS) > 0):
66 for i in detectionNMS.flatten():
67 (x, y) = (boxes[i][0], boxes[i][1])
68 (w, h) = (boxes[i][2], boxes[i][3])
69
70 color = [int(c) for c in COLORS[classIDs[i]]]
71 cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
72 text = '{}: {:.4f}'.format(labels[classIDs[i]], confidences[i])
73 cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
74
75 return image
76
77 #cv2.imshow('Image', image)
78 #cv2.waitKey(0)
79filePathName = fs.save(fileObj.name + "_result", img)
80'numpy.ndarray' object has no attribute 'read'
81
I am not sure how can I resolve this. I tried searching how can I store OpenCV Modified file usnig FileSystemStorage but found nothing of help. Can anyone help me regarding this?
ANSWER
Answered 2022-Feb-13 at 16:57You can use the imwrite
function of cv2
library to store your files in the local directory, i.e.,
In your case, simply do this,
1def predictImage(request):
2 # print(request)
3 # print(request.POST.dict())
4 fileObj = request.FILES['filePath']
5 fs = FileSystemStorage()
6 filePathName = fs.save(fileObj.name, fileObj)
7 filePathName = fs.url(filePathName)
8 testimage = '.'+filePathName
9 # img = image.load_img(testimage, target_size=(img_height, img_width))
10 img = detect_image(testimage)
11 filePathName = fs.save(fileObj.name + "_result", img) # -> HERE IS THE ERROR
12 filePathName = fs.url(filePathName)
13import numpy as np
14import cv2
15
16def detect_image(img_path):
17
18 confidenceThreshold = 0.5
19 NMSThreshold = 0.3
20
21 modelConfiguration = 'cfg/yolov3.cfg'
22 modelWeights = 'yolov3.weights'
23
24 labelsPath = 'coco.names'
25 labels = open(labelsPath).read().strip().split('\n')
26
27 np.random.seed(10)
28 COLORS = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")
29
30 net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)
31
32 image = cv2.imread(img_path)
33 (H, W) = image.shape[:2]
34
35 #Determine output layer names
36 layerName = net.getLayerNames()
37 layerName = [layerName[i - 1] for i in net.getUnconnectedOutLayers()]
38
39 blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416), swapRB = True, crop = False)
40 net.setInput(blob)
41 layersOutputs = net.forward(layerName)
42
43 boxes = []
44 confidences = []
45 classIDs = []
46
47 for output in layersOutputs:
48 for detection in output:
49 scores = detection[5:]
50 classID = np.argmax(scores)
51 confidence = scores[classID]
52 if confidence > confidenceThreshold:
53 box = detection[0:4] * np.array([W, H, W, H])
54 (centerX, centerY, width, height) = box.astype('int')
55 x = int(centerX - (width/2))
56 y = int(centerY - (height/2))
57
58 boxes.append([x, y, int(width), int(height)])
59 confidences.append(float(confidence))
60 classIDs.append(classID)
61
62 #Apply Non Maxima Suppression
63 detectionNMS = cv2.dnn.NMSBoxes(boxes, confidences, confidenceThreshold, NMSThreshold)
64
65 if(len(detectionNMS) > 0):
66 for i in detectionNMS.flatten():
67 (x, y) = (boxes[i][0], boxes[i][1])
68 (w, h) = (boxes[i][2], boxes[i][3])
69
70 color = [int(c) for c in COLORS[classIDs[i]]]
71 cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
72 text = '{}: {:.4f}'.format(labels[classIDs[i]], confidences[i])
73 cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
74
75 return image
76
77 #cv2.imshow('Image', image)
78 #cv2.waitKey(0)
79filePathName = fs.save(fileObj.name + "_result", img)
80'numpy.ndarray' object has no attribute 'read'
81img = detect_image(testimage)
82cv2.imwrite(fileObj.name+"_result.jpg", img=img)
83
QUESTION
How to dynamically define Headers and Settings for UWP NavigationView's menu, using C++/winRT?
Asked 2022-Feb-02 at 17:01I'm working on a cross-platform project in C++ generating the UI dynamically, and I am struggling with C++/winRT UWP NavigationView on two problems:
- When defining a NavigationViewItemHeader, the resulting header title doesn't show in the navigation menu, the space remains empty,
- When trying to update the SettingsItem of the navigation menu, the value of the Settings navigation item is nullptr as returned by SettingsItem().
Here is the code I wrote for generating the menu from a list of items managed independently from the host (e.g. Windows):
1bool
2CANavigationView::UpdateHostView( void )
3{
4 TNavigationItemPtr item;
5 TIndex index;
6
7 if( _hostViewUpdateNeeded == false )
8 return false;
9
10 Windows::UI::Xaml::Controls::NavigationViewItemBase hItem( nullptr );
11 Windows::UI::Xaml::Controls::TextBlock hText( nullptr );
12 winrt::hstring hTag;
13
14 // Remove all navigation items from the current host view:
15 _hostNavigationView.MenuItems().Clear();
16 _hostNavigationView.IsSettingsVisible( false );
17
18 // Build the navigation menu items:
19 for( index = 0; index < _navigationItems.CountOfItems(); index++ )
20 {
21 item = * _navigationItems.GetItemAtIndex( index );
22
23 if( item->identifier == kSettingsItem )
24 {
25 _hostNavigationView.IsSettingsVisible( true );
26 hText = Windows::UI::Xaml::Controls::TextBlock();
27 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
28 hText.Text( hTag );
29// Issue #1 : cannot access to the Settings item
30// _hostNavigationView.SettingsItem().as< Windows::UI::Xaml::Controls::NavigationViewItem >().Content( hText );
31// SettingsItem() returns nullptr...
32 }
33 else
34 {
35 switch( item->type )
36 {
37 case eNavigationHeader:
38 hItem = Windows::UI::Xaml::Controls::NavigationViewItemHeader();
39 hText = Windows::UI::Xaml::Controls::TextBlock();
40 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
41 hText.Text( hTag );
42// Issue #2: The header's title is not displayed
43 hItem.Content( hText );
44 _hostNavigationView.MenuItems().Append( hItem );
45 break;
46
47 case eNavigationSeparator:
48 hItem = Windows::UI::Xaml::Controls::NavigationViewItemSeparator();
49 _hostNavigationView.MenuItems().Append( hItem );
50 break;
51
52 case eNavigationItem:
53 hItem = Windows::UI::Xaml::Controls::NavigationViewItem();
54 CSString::ConvertToUIString( CAUIElement::GetStringFromUIIdentifier( item->identifier ), & hTag );
55 hItem.Tag( winrt::box_value( hTag ) );
56 hText = Windows::UI::Xaml::Controls::TextBlock();
57 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
58 hText.Text( hTag );
59 hItem.Content( hText );
60 hItem.as< Windows::UI::Xaml::Controls::NavigationViewItem>().Icon( GetHostIcon( item->icon ) );
61 _hostNavigationView.MenuItems().Append( hItem );
62 break;
63
64 default:
65 break;
66 }
67 }
68 }
69
70 _hostViewUpdateNeeded = false;
71
72 return true;
73}
74
As I'm using my own string format (I'm stuck in old C++ standards...) and I18N support, I need to first convert the UTF8 string to the host (here Windows) before setting the value of the text block, using the hTag variable of type hstring. In debugging mode, the text is well transcoded in the hstring format...
What is puzzling me is the fact that both NavigationSeparator and NavigationItem cases are working fine, in line with the official Microsoft documentation (including the Tag for menu event handling and Icon setting for NavigationViewItem).
I understand this is not the "mainstream XAML way" of working on UWP user interface but so far the approach is working well on other UI elements.
Here is a screenshot of the navigation view with the empty spaces for the headers:
Also, in the example above, I logged the number of menu items in the host navigation view (_hostNavigationView.MenuItems().Size()) and got 7 as a result, which is correct...
At last, here's the detailed log I'm generating in DEBUG mode:
1bool
2CANavigationView::UpdateHostView( void )
3{
4 TNavigationItemPtr item;
5 TIndex index;
6
7 if( _hostViewUpdateNeeded == false )
8 return false;
9
10 Windows::UI::Xaml::Controls::NavigationViewItemBase hItem( nullptr );
11 Windows::UI::Xaml::Controls::TextBlock hText( nullptr );
12 winrt::hstring hTag;
13
14 // Remove all navigation items from the current host view:
15 _hostNavigationView.MenuItems().Clear();
16 _hostNavigationView.IsSettingsVisible( false );
17
18 // Build the navigation menu items:
19 for( index = 0; index < _navigationItems.CountOfItems(); index++ )
20 {
21 item = * _navigationItems.GetItemAtIndex( index );
22
23 if( item->identifier == kSettingsItem )
24 {
25 _hostNavigationView.IsSettingsVisible( true );
26 hText = Windows::UI::Xaml::Controls::TextBlock();
27 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
28 hText.Text( hTag );
29// Issue #1 : cannot access to the Settings item
30// _hostNavigationView.SettingsItem().as< Windows::UI::Xaml::Controls::NavigationViewItem >().Content( hText );
31// SettingsItem() returns nullptr...
32 }
33 else
34 {
35 switch( item->type )
36 {
37 case eNavigationHeader:
38 hItem = Windows::UI::Xaml::Controls::NavigationViewItemHeader();
39 hText = Windows::UI::Xaml::Controls::TextBlock();
40 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
41 hText.Text( hTag );
42// Issue #2: The header's title is not displayed
43 hItem.Content( hText );
44 _hostNavigationView.MenuItems().Append( hItem );
45 break;
46
47 case eNavigationSeparator:
48 hItem = Windows::UI::Xaml::Controls::NavigationViewItemSeparator();
49 _hostNavigationView.MenuItems().Append( hItem );
50 break;
51
52 case eNavigationItem:
53 hItem = Windows::UI::Xaml::Controls::NavigationViewItem();
54 CSString::ConvertToUIString( CAUIElement::GetStringFromUIIdentifier( item->identifier ), & hTag );
55 hItem.Tag( winrt::box_value( hTag ) );
56 hText = Windows::UI::Xaml::Controls::TextBlock();
57 CSString::ConvertToUIString( item->title->GetString( gAppLanguageCode ), & hTag );
58 hText.Text( hTag );
59 hItem.Content( hText );
60 hItem.as< Windows::UI::Xaml::Controls::NavigationViewItem>().Icon( GetHostIcon( item->icon ) );
61 _hostNavigationView.MenuItems().Append( hItem );
62 break;
63
64 default:
65 break;
66 }
67 }
68 }
69
70 _hostViewUpdateNeeded = false;
71
72 return true;
73}
74DBG-[000002686A230710]CANavigationView::UpdateDisplayedLanguage() {
75 DBG-[000002686A230710]CANavigationView::UpdateHostView() {
76 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 0, type 2
77 DBG-[000002686A230710]CANavigationView::UpdateHostView() Header case: Reference Library
78 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 1, type 1
79 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
80 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 2, type 1
81 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
82 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 3, type 1
83 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
84 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 4, type 3
85 DBG-[000002686A230710]CANavigationView::UpdateHostView() Separator case
86 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 5, type 2
87 DBG-[000002686A230710]CANavigationView::UpdateHostView() Header case: Project Library
88 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 6, type 1
89 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item case
90 DBG-[000002686A230710]CANavigationView::UpdateHostView() Navigation item 7, type 1
91 DBG-[000002686A230710]CANavigationView::UpdateHostView() Settings case
92 DBG-[000002686A230710]CANavigationView::UpdateHostView() Value of SettingsItem(): 0000000000000000
93 DBG-[000002686A230710]CANavigationView::UpdateHostView() Count of menu items for the navigation view: 7 (8)
94 DBG-}
95DBG-}
96
Your help in solving those two issues would be greatly appreciated !
Best regards,
Arnaud
ANSWER
Answered 2022-Feb-02 at 11:34Dynamic Headers/Footers enable different grouping options in reports, such as "By Location" or "By Location By System": Note that the words "Report Definitions" are circled above. Although reports can have up to three Dynamic Headers/Footers, some reports only have one or two Dynamic Groups.
QUESTION
With Stripe API, How To Get session_id of Checkout Session That Created a payment_intent Object, From payment_intent.succeeded Webhook
Asked 2022-Jan-31 at 22:04I am working on developing and testing a Stripe integration, written in PHP, and it's working beautifully. I can create sessions, redirect to the checkout form, and when the payments are complete it sends an event to my webhhook script, which successfully processes the information about the payment going through.
When I create a session, I store the data about the form filled out on my site, in a database, and when the payment goes through, I store information in a different table, which is great.
The problem I'm having is that I don't know how to link up the information about the successful payment, with the session that generated it.
Linking up these data is essential to me, because I want to track which sessions actually result in successful payments, so that I can analyze the flow of the user interface and track conversion rates and analyze factors that lead to abandonment of the checkout session.
In some cases, it is easy to link these things up. For example, if there's only one session generated and one successful payment, associated with a given email in a given time-frame, I can just link them up. The problem is that I want to be able to deal with the (likely common) scenario where a person creates multiple sessions and abandons them. I cannot link the payment to the most recent session associated with the email, in this scenario, because it's possible that a single customer would create two sessions, but complete the payment on the first, earlier-created session.
I can't figure out how to access the session_id from the payment_intent object that is returned to my webhook. Some thoughts I have had about how to possibly approach this include:
- Listening for some other event in my webhook script, that occurs, that would possibly allow me to link the two records.
- Passing metadata to the session, such as a uniquely-generated ID, and then accessing that same metadata from the payment_intent object. However I cannot figure out from reading the Stripe documentation how metadata works and even if the metadata is passed from the session to the payment_intent object (the documentation does not explicitly state this or explain it, and the fact that the session_id is not passed makes me wonder if the metadata would be passed at all). I would prefer not to do this solution because it would require the additional step of generating a unique ID before generating the session, which would require more work on my end and also make my code more complex and involve more database calls and more potential steps that can go wrong (currently I am generating the session and then storing the information in response to the successful creation of the session), but I could tolerate it if there are really no better options.
I would like to follow "best practices" here, but it's not clear to me how Stripe intends people to link up or access the data, or if this is perhaps an oversight on their end.
If you give me example code I would prefer seeing it in PHP if possible but you don't need to show me any code at all; just giving me an abstract or general idea of how to accomplish this would be sufficient and I could come up with the coding details on my own.
ANSWER
Answered 2021-Nov-10 at 00:01The payment_intent.succeeded
event gives you the PaymentIntent ID. You can use the CheckoutSessions "list" endpoint [0] to get the CheckoutSession that used that PaymentIntent ID by passing the payment_method
parameter.
[0] https://stripe.com/docs/api/checkout/sessions/list#list_checkout_sessions-payment_intent
QUESTION
Is it safe to store, access and HTMLElement objects directly inside an object, vs. relying on CSS selectors?
Asked 2022-Jan-22 at 09:00I have a vanilla Javascript class that builds a bunch of HTML, essentially a collection of related HTMLElement objects that form the user interface for a component, and appends them to the HTML document. The class implements controller logic, responding to events, mutating some of the HTMLElements etc.
My gut instinct (coming from more backend development experience) is to store those HTMLElement objects inside my class, whether inside a key/value object or in an array, so my class can just access them directly through native properties whenever it's doing something with them. But everything I look at seems to follow the pattern of relying on document selectors (document.getElementById
, getElementsByClassName
, etc etc). I understand the general utility of that approach but it feels weird to have a class that creates objects, discards its own references to them, and then just looks them back up again when needed.
A simplified example would look like this:
1<html>
2<body>
3<script>
4/* Silly implementation of the "Concentration" memory match game.
5 This is just a S/O example but it should actually work =P
6 */
7
8class SymbolMatchGame {
9
10 constructor(symbolsArray) {
11 this.symbols = symbolsArray.concat(symbolsArray); // we want two of every item
12 this.allButtons = [];
13 this.lastButtonClicked = null;
14 }
15
16 shuffle() {
17 for (let i = this.symbols.length - 1; i > 0; i--) {
18 const j = Math.floor(Math.random() * (i + 1));
19 const temp = this.symbols[i];
20 this.symbols[i] = this.symbols[j];
21 this.symbols[j] = temp;
22 }
23 }
24
25 build(parentElement) {
26 document.body.innerHTML = '';
27 this.shuffle();
28 const rowSize = Math.floor(Math.sqrt(this.symbols.length));
29 for (let i = 0; i < this.symbols.length; i++) {
30 const button = document.createElement('input');
31 button.type = 'button';
32 button.setAttribute('secret-value', this.symbols[i]);
33 button.value = ' ';
34 button.onclick = (event) => this.turnOver(event);
35 this.allButtons.push(button);
36 document.body.appendChild(button);
37 if ((i+1) % rowSize === 0) {
38 const lineBreak = document.createElement('br');
39 document.body.appendChild(lineBreak);
40 }
41 }
42 }
43
44 turnOver(event) {
45 const button = event.target;
46 if (this.lastButtonClicked === null) {
47 this.allButtons.forEach(button => button.value = button.disabled ? button.value : ' ');
48 this.lastButtonClicked = button;
49 } else if (button === this.lastButtonClicked) {
50 button.value = ' ';
51 this.lastButtonClicked = null;
52 } else {
53 if (button.getAttribute('secret-value') === this.lastButtonClicked.getAttribute('secret-value')) {
54 console.log('Match found!');
55 button.disabled = true;
56 this.lastButtonClicked.disabled = true;
57 } else {
58 console.log('No match!');
59 }
60 this.lastButtonClicked = null;
61 }
62 button.value = button.getAttribute('secret-value');
63 if (this.gameIsSolved()) {
64 alert('You did it! Game will reset.')
65 this.build();
66 }
67 }
68
69 gameIsSolved() {
70 const remainingButtons = game.allButtons.filter(button => !button.disabled)
71 return remainingButtons.length === 0;
72 }
73
74}
75
76const alphabetArray = Array.from(Array(8).keys()).map(k => String.fromCharCode(k+65));
77game = new SymbolMatchGame(alphabetArray);
78game.build();
79</script>
80</body>
81</html>
82
(Note: I'm not expecting you to examine this code in detail; just illustrating what I mean when I talk about storing element references in the class and accessing them directly instead of via document.get*
lookups)
I don't want this to be a style/"best practice" question that isn't appropriate for S/O, so I'm more looking for concrete information about whether my approach actually works the way I think it does. My question: what are the implications or side effects of what I'm doing? Is storing references to created elements inside my class instead of of a "just in time" document.get*
lookup every time I want to access or modify them unsafe in some way, prone to side effects or stale references, or otherwise lacking implicit guarantees about document state, that might break things on me?
ANSWER
Answered 2022-Jan-22 at 09:00In general, you should always cache DOM elements when they're needed later, were you using OOP or not. DOM is huge, and fetching elements continuously from it is really time-consuming. This stands for the properties of the elements too. Creating a JS variable or a property to an object is cheap, and accessing it later is lightning-fast compared to DOM queries.
Many of the properties of the elements are deep in the prototype chain, they're often getters, which might execute a lot of hidden DOM traversing, and reading specific DOM values forces layout recalculation in the middle of JS execution. All this makes DOM usage slow. Instead, create a simplified JavaScript model of the page, and store all the needed elements and values to the model whenever possible.
A big part of OOP is just keeping up states, that's the key of the model too. In the model you keep up the state of the view, and access the DOM only when you need to change the view. Such a model will prevent a lot of "layout trashing", and it allows you to bind data to elements without actually revealing it in the global namespace (ex. Map object is a great tool for this). Nothing beats good encapsulation when you've security concerns, it's an effective way ex. to prevent self-XSS. Additionally, a good model is reusable, you can use it where ever the functionality is needed, the end-user just parametrizes the model when taken into use. That way the model is almost independent from the used markup too, and can also be developed independently (see also Separation of concerns).
A caveat of storing DOM elements into object properties (or into JS variables in general) is, that it's an easy way to create memory leaks. Such model objects are usually having long life-time, and if elements are removed from the DOM, the references from the object have to be deleted as well in order to get the removed elements being garbage-collected.
In practice this means, that you've to provide methods for removing elements, and only those methods should be used to delete elements. Additionally to the element removal, the methods should update the model object, and remove all the unused element references from the object.
It's notable, that when having methods handling existing elements, and specifically when creating new elements, it's easy to create variables which are stored in closures. When such a stored variable contains references to elements, they can't be removed from the memory even with the aforementioned removing methods. The only way is to avoid creating these closures from the beginning, which might be a bit easier with OOP compared to other paradigms (by avoiding variables and creating the elements directly to the properties of the objects).
As a sidenote, document.getElementsBy*
methods are the worst possible way to get references to DOM elements. The idea of the live collection of the elements sounds nice, but the way how those are implemented, ruins the good idea.
QUESTION
How to increase height of jQueryUI selectmenu?
Asked 2022-Jan-04 at 13:00How can I increase the height of a select menu styled with jQuery's user interface? I want to increase the height of the actual element, not the height of the dropdown menu of options that appears when you click it (there are a few answers on the site already for that). Basically, I want the menu to look squared, almost like a button instead.
I tried setting the height at the moment of applying the UI to the element in javascript. However, any height value I use seems to be ignored:
1$(document).ready(function() {
2
3 let testSelect = document.createElement('select');
4 let firstOption = document.createElement('option');
5 firstOption.text = 'blablablabla...';
6 firstOption.defaultSelected = true;
7 testSelect.appendChild(firstOption);
8
9 document.getElementById('testDiv').appendChild(testSelect);
10 $(testSelect).selectmenu({height: '50%'}); // no matter what value of height I use, the menu does not change
11
12 testButton = document.createElement('button');
13 testButton.innerHTML = 'Like this example button';
14 $(testButton).button();
15 document.getElementById('testDiv').appendChild(testButton); // I want the select menu to look similar to a button like this
16
17});
1$(document).ready(function() {
2
3 let testSelect = document.createElement('select');
4 let firstOption = document.createElement('option');
5 firstOption.text = 'blablablabla...';
6 firstOption.defaultSelected = true;
7 testSelect.appendChild(firstOption);
8
9 document.getElementById('testDiv').appendChild(testSelect);
10 $(testSelect).selectmenu({height: '50%'}); // no matter what value of height I use, the menu does not change
11
12 testButton = document.createElement('button');
13 testButton.innerHTML = 'Like this example button';
14 $(testButton).button();
15 document.getElementById('testDiv').appendChild(testButton); // I want the select menu to look similar to a button like this
16
17});<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
18<script type="text/javascript" src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js"></script>
19<link rel="stylesheet" href="http://code.jquery.com/ui/1.13.0/themes/redmond/jquery-ui.css">
20
21<div id="testDiv" style="width:100px; height:100px;"></div>
ANSWER
Answered 2022-Jan-04 at 13:00you forget to use .css()
function to add the css of height. add .css(height:100px)
and then you will get your height
QUESTION
Is a work manager good for these situations?
Asked 2022-Jan-02 at 00:08I'm developing some features that need to run in the background with a UI update like creating a file from the input stream and notifying the user after it's finished
After trying the work manager for this task. It works well, but is it a good option in your opinion?
Note: I am very interested in updating the user interface during the process and as you know async task deprecated
ANSWER
Answered 2022-Jan-02 at 00:08Yes. Initially, WorkManager
was a library for managing defferable background work. Now however, WorkManager
is a recommended solution for any persistent work, that is, the work that must be completed - no matter if the application process is stopped, or even the device is rebooted. From version 2.3.0-alpha01
, WorkManager
provides first-class support for setting and observing intermediate progress for workers. Updatig the user interface is exactly what this feature can be used for.
For me the easiest way to reason about WorkManager is an extension of your app scopes:
Activity
Scope - the works lives untilonDestroy
lifecycle eventViewModel
Scope - the works lives as long as ViewModel. If you navigate away - the work is stoppedApplication
Scope (eg. Coroutine'sGlobalScope
) - the work lives as long as applcation process. If the user ends the app process in task manager or the system kills it - the work is lostWorkManager
- the work survives process death and device reboot. It is persisted with help of Room DB under the hood, so that you can continue the work after your application process was restarted.
QUESTION
Data exchange between websocket clients and server
Asked 2021-Dec-20 at 01:50I have a system that has a fastAPI server, a python client implemented on Raspberry and Javascript clients for the user interface. Data is sent from python client to server then forwarded to Js client and vice versa. I established the connection between the server and each type of client but when sending from a client-side to the server, it just send back to that client and the rest ones receive nothing. What is the proper way to deal with this problem? Hope for your help. Thanks.
ANSWER
Answered 2021-Dec-20 at 01:50The problem with websocket is it doesn't support broadcasting. You can store somewhere list of connected clients and iterate over them to send a message
1CLIENTS = set()
2async def broadcast():
3 while True:
4 await asyncio.gather(
5 *[ws.send("woof") for ws in CLIENTS],
6 return_exceptions=False,
7 )
8 await asyncio.sleep(2)
9
10asyncio.create_task(broadcast())
11
12async def handler(websocket, path):
13 CLIENTS.add(websocket)
14 try:
15 async for msg in websocket:
16 pass
17 finally:
18 CLIENTS.remove(websocket)
19
20start_server = websockets.serve(handler, ...)
21
22asyncio.get_event_loop().run_until_complete(start_server)
23asyncio.get_event_loop().run_forever()
24
QUESTION
Register all inputs inside a multi-page data table
Asked 2021-Dec-17 at 16:15I have a datatable in which I've added checkboxes for my users to select various options. Unfortunately, the only inputs that shiny seems to see are ones that have been displayed in the table. So if I have multiple pages, I'm only able to see the first 10 inputs.
In the example below, I've printed all of the inputs that I can see registered above the datatable object. At the moment, I only see the first 10 inputs (A - J). I'd like to be able to see all 26 when the table first loads (without having to toggle through the pages).
In my actual application, I have multiple columns of checkboxes, so row selection wouldn't be sufficient. Any tips or suggestions on how to register all 26 inputs at once?
1library(shiny)
2library(DT)
3
4shinyInput <- function (FUN, id_base, suffix, label = "", ...)
5{
6 inputId <- paste0(id_base, suffix)
7 args <- list(...)
8 args <- c(list(label = label), args)
9 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
10 rv <- character(length(inputId))
11 for (i in seq_along(rv)) {
12 this_arg <- lapply(args, `[`, i)
13 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
14 rv[i] <- as.character(ctrl)
15 }
16 rv
17}
18
19X <- data.frame(id = LETTERS,
20 selected = sample(c(TRUE, FALSE),
21 size = length(LETTERS),
22 replace = TRUE))
23
24X$IsSelected <-
25 shinyInput(
26 shiny::checkboxInput,
27 id_base = "new_input_",
28 suffix = X$id,
29 value = X$selected
30 )
31
32shinyApp(
33 ui = fluidPage(
34 verbatimTextOutput("value_check"),
35 textOutput("input_a_value"),
36 DT::dataTableOutput("dt")
37 ),
38
39 server = shinyServer(function(input, output, session){
40
41 Data <- reactiveValues(
42 X = X
43 )
44
45 output$value_check <-
46 renderPrint({
47 sort(names(input))
48 })
49
50 output$dt <-
51 DT::renderDataTable({
52
53
54 DT::datatable(X,
55 selection = "none",
56 escape = FALSE,
57 filter = "top",
58 #rownames = FALSE,
59 class = "compact cell-border",
60 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
61 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
62 })
63 })
64)
65
This next example is a bit more complex, but illustrates a bit more of the motivation for the question. It seems the biggest issue is that I would like to utilize buttons such as "select all." Additionally, I'm not processing any actions immediately when a box is interacted with. Instead, the user makes their selections, and the selections are not saved until the "Save Selections" button is clicked.
What is happening is I click on the "Select All" button, and it checks all of the boxes for inputs that have been drawn already. If I've only viewed the first page of the table, it updates only those inputs, and none of the inputs on the next few pages. This is really the behavior I need to change.
1library(shiny)
2library(DT)
3
4shinyInput <- function (FUN, id_base, suffix, label = "", ...)
5{
6 inputId <- paste0(id_base, suffix)
7 args <- list(...)
8 args <- c(list(label = label), args)
9 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
10 rv <- character(length(inputId))
11 for (i in seq_along(rv)) {
12 this_arg <- lapply(args, `[`, i)
13 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
14 rv[i] <- as.character(ctrl)
15 }
16 rv
17}
18
19X <- data.frame(id = LETTERS,
20 selected = sample(c(TRUE, FALSE),
21 size = length(LETTERS),
22 replace = TRUE))
23
24X$IsSelected <-
25 shinyInput(
26 shiny::checkboxInput,
27 id_base = "new_input_",
28 suffix = X$id,
29 value = X$selected
30 )
31
32shinyApp(
33 ui = fluidPage(
34 verbatimTextOutput("value_check"),
35 textOutput("input_a_value"),
36 DT::dataTableOutput("dt")
37 ),
38
39 server = shinyServer(function(input, output, session){
40
41 Data <- reactiveValues(
42 X = X
43 )
44
45 output$value_check <-
46 renderPrint({
47 sort(names(input))
48 })
49
50 output$dt <-
51 DT::renderDataTable({
52
53
54 DT::datatable(X,
55 selection = "none",
56 escape = FALSE,
57 filter = "top",
58 #rownames = FALSE,
59 class = "compact cell-border",
60 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
61 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
62 })
63 })
64)
65# Set up environment ------------------------------------------------
66library(shiny)
67library(DT)
68library(magrittr)
69
70# Example of data coming from the database. -------------------------
71
72set.seed(pi^2)
73
74SourceData <-
75 data.frame(sample_id = 1:25,
76 is_selected = sample(c(TRUE, FALSE), 25, replace = TRUE))
77
78
79# Support Functions -------------------------------------------------
80# These would exist, for example, in an internal package
81
82shinyInput <- function (FUN, id_base, suffix, label = "", ...)
83{
84 inputId <- paste0(id_base, suffix)
85 args <- list(...)
86 args <- c(list(label = label), args)
87 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
88 rv <- character(length(inputId))
89 for (i in seq_along(rv)) {
90 this_arg <- lapply(args, `[`, i)
91 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
92 rv[i] <- as.character(ctrl)
93 }
94 rv
95}
96
97prepareDataForDisplay <- function(Data){
98 Data$is_selected <-
99 shinyInput(shiny::checkboxInput,
100 id_base = "is_selected_",
101 suffix = Data$sample_id,
102 value = Data$is_selected)
103
104 Data
105}
106
107# User Interface ----------------------------------------------------
108
109ui <-
110 fluidPage(
111 verbatimTextOutput("value_check"),
112
113 actionButton(inputId = "btn_saveSelection",
114 label = "Save Selection"),
115 actionButton(inputId = "btn_selectAll",
116 label = "Select All"),
117 actionButton(inputId = "btn_unselectAll",
118 label = "Unselect All"),
119 actionButton(inputId = "btn_restoreDefault",
120 label = "Restore Default (select odd only)"),
121
122 DT::dataTableOutput("dt")
123 )
124
125# Server ------------------------------------------------------------
126
127server <-
128 shinyServer(function(input, output, session){
129
130 # Event Observers -----------------------------------------------
131
132 observeEvent(
133 input$btn_selectAll,
134 {
135 check_input <- names(input)[grepl("is_selected_", names(input))]
136
137 lapply(check_input,
138 function(ci){
139 updateCheckboxInput(session = session,
140 inputId = ci,
141 value = TRUE)
142 })
143 }
144 )
145
146 observeEvent(
147 input$btn_unselectAll,
148 {
149 check_input <- names(input)[grepl("is_selected_", names(input))]
150
151 lapply(check_input,
152 function(ci){
153 updateCheckboxInput(session = session,
154 inputId = ci,
155 value = FALSE)
156 })
157 }
158 )
159
160 observeEvent(
161 input$btn_restoreDefault,
162 {
163 check_input <- names(input)[grepl("is_selected_", names(input))]
164
165 lapply(check_input,
166 function(ci){
167 id <- as.numeric(sub("is_selected_", "", ci))
168
169 updateCheckboxInput(session = session,
170 inputId = ci,
171 value = id %% 2 == 1)
172 })
173 }
174 )
175
176 observeEvent(
177 input$btn_saveSelection,
178 {
179 check_input <- names(input)[grepl("is_selected_", names(input))]
180
181 id <- as.numeric(sub("is_selected_", "", check_input))
182
183 for (i in seq_along(check_input)){
184 SourceData$is_selected[SourceData$sample_id == id[i]] <-
185 input[[check_input[i]]]
186 }
187
188 # At this point, I would also save changes to the remote database.
189
190 DT::replaceData(proxy = dt_proxy,
191 data = prepareDataForDisplay(SourceData))
192 }
193 )
194
195 # Output elements -----------------------------------------------
196
197 output$value_check <-
198 renderPrint({
199 sort(names(input))
200 })
201
202 output$dt <-
203 DT::renderDataTable({
204 SourceData %>%
205 prepareDataForDisplay() %>%
206 DT::datatable(selection = "none",
207 escape = FALSE,
208 filter = "top",
209 class = "compact cell-border",
210 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
211 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
212 })
213
214 dt_proxy <- DT::dataTableProxy("dt")
215
216 })
217
218# Run the application -----------------------------------------------
219
220shinyApp(
221 ui = ui,
222 server = server
223)
224
ANSWER
Answered 2021-Dec-17 at 16:15Here is a workaround based on your addendum (not sure if you need the changes regarding btn_restoreDefault
and btn_saveSelection
), but the general procedure should be clear:
1library(shiny)
2library(DT)
3
4shinyInput <- function (FUN, id_base, suffix, label = "", ...)
5{
6 inputId <- paste0(id_base, suffix)
7 args <- list(...)
8 args <- c(list(label = label), args)
9 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
10 rv <- character(length(inputId))
11 for (i in seq_along(rv)) {
12 this_arg <- lapply(args, `[`, i)
13 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
14 rv[i] <- as.character(ctrl)
15 }
16 rv
17}
18
19X <- data.frame(id = LETTERS,
20 selected = sample(c(TRUE, FALSE),
21 size = length(LETTERS),
22 replace = TRUE))
23
24X$IsSelected <-
25 shinyInput(
26 shiny::checkboxInput,
27 id_base = "new_input_",
28 suffix = X$id,
29 value = X$selected
30 )
31
32shinyApp(
33 ui = fluidPage(
34 verbatimTextOutput("value_check"),
35 textOutput("input_a_value"),
36 DT::dataTableOutput("dt")
37 ),
38
39 server = shinyServer(function(input, output, session){
40
41 Data <- reactiveValues(
42 X = X
43 )
44
45 output$value_check <-
46 renderPrint({
47 sort(names(input))
48 })
49
50 output$dt <-
51 DT::renderDataTable({
52
53
54 DT::datatable(X,
55 selection = "none",
56 escape = FALSE,
57 filter = "top",
58 #rownames = FALSE,
59 class = "compact cell-border",
60 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
61 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
62 })
63 })
64)
65# Set up environment ------------------------------------------------
66library(shiny)
67library(DT)
68library(magrittr)
69
70# Example of data coming from the database. -------------------------
71
72set.seed(pi^2)
73
74SourceData <-
75 data.frame(sample_id = 1:25,
76 is_selected = sample(c(TRUE, FALSE), 25, replace = TRUE))
77
78
79# Support Functions -------------------------------------------------
80# These would exist, for example, in an internal package
81
82shinyInput <- function (FUN, id_base, suffix, label = "", ...)
83{
84 inputId <- paste0(id_base, suffix)
85 args <- list(...)
86 args <- c(list(label = label), args)
87 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
88 rv <- character(length(inputId))
89 for (i in seq_along(rv)) {
90 this_arg <- lapply(args, `[`, i)
91 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
92 rv[i] <- as.character(ctrl)
93 }
94 rv
95}
96
97prepareDataForDisplay <- function(Data){
98 Data$is_selected <-
99 shinyInput(shiny::checkboxInput,
100 id_base = "is_selected_",
101 suffix = Data$sample_id,
102 value = Data$is_selected)
103
104 Data
105}
106
107# User Interface ----------------------------------------------------
108
109ui <-
110 fluidPage(
111 verbatimTextOutput("value_check"),
112
113 actionButton(inputId = "btn_saveSelection",
114 label = "Save Selection"),
115 actionButton(inputId = "btn_selectAll",
116 label = "Select All"),
117 actionButton(inputId = "btn_unselectAll",
118 label = "Unselect All"),
119 actionButton(inputId = "btn_restoreDefault",
120 label = "Restore Default (select odd only)"),
121
122 DT::dataTableOutput("dt")
123 )
124
125# Server ------------------------------------------------------------
126
127server <-
128 shinyServer(function(input, output, session){
129
130 # Event Observers -----------------------------------------------
131
132 observeEvent(
133 input$btn_selectAll,
134 {
135 check_input <- names(input)[grepl("is_selected_", names(input))]
136
137 lapply(check_input,
138 function(ci){
139 updateCheckboxInput(session = session,
140 inputId = ci,
141 value = TRUE)
142 })
143 }
144 )
145
146 observeEvent(
147 input$btn_unselectAll,
148 {
149 check_input <- names(input)[grepl("is_selected_", names(input))]
150
151 lapply(check_input,
152 function(ci){
153 updateCheckboxInput(session = session,
154 inputId = ci,
155 value = FALSE)
156 })
157 }
158 )
159
160 observeEvent(
161 input$btn_restoreDefault,
162 {
163 check_input <- names(input)[grepl("is_selected_", names(input))]
164
165 lapply(check_input,
166 function(ci){
167 id <- as.numeric(sub("is_selected_", "", ci))
168
169 updateCheckboxInput(session = session,
170 inputId = ci,
171 value = id %% 2 == 1)
172 })
173 }
174 )
175
176 observeEvent(
177 input$btn_saveSelection,
178 {
179 check_input <- names(input)[grepl("is_selected_", names(input))]
180
181 id <- as.numeric(sub("is_selected_", "", check_input))
182
183 for (i in seq_along(check_input)){
184 SourceData$is_selected[SourceData$sample_id == id[i]] <-
185 input[[check_input[i]]]
186 }
187
188 # At this point, I would also save changes to the remote database.
189
190 DT::replaceData(proxy = dt_proxy,
191 data = prepareDataForDisplay(SourceData))
192 }
193 )
194
195 # Output elements -----------------------------------------------
196
197 output$value_check <-
198 renderPrint({
199 sort(names(input))
200 })
201
202 output$dt <-
203 DT::renderDataTable({
204 SourceData %>%
205 prepareDataForDisplay() %>%
206 DT::datatable(selection = "none",
207 escape = FALSE,
208 filter = "top",
209 class = "compact cell-border",
210 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
211 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
212 })
213
214 dt_proxy <- DT::dataTableProxy("dt")
215
216 })
217
218# Run the application -----------------------------------------------
219
220shinyApp(
221 ui = ui,
222 server = server
223)
224# Set up environment ------------------------------------------------
225library(shiny)
226library(DT)
227library(magrittr)
228
229# Example of data coming from the database. -------------------------
230
231set.seed(pi^2)
232
233SourceData <-
234 data.frame(sample_id = 1:25,
235 is_selected = sample(c(TRUE, FALSE), 25, replace = TRUE))
236
237
238# Support Functions -------------------------------------------------
239# These would exist, for example, in an internal package
240
241shinyInput <- function (FUN, id_base, suffix, label = "", ...)
242{
243 inputId <- paste0(id_base, suffix)
244 args <- list(...)
245 args <- c(list(label = label), args)
246 args <- lapply(args, function(a) rep(a, length.out = length(inputId)))
247 rv <- character(length(inputId))
248 for (i in seq_along(rv)) {
249 this_arg <- lapply(args, `[`, i)
250 ctrl <- do.call(FUN, c(list(inputId = inputId[i]), this_arg))
251 rv[i] <- as.character(ctrl)
252 }
253 rv
254}
255
256prepareDataForDisplay <- function(Data){
257 Data$is_selected <-
258 shinyInput(shiny::checkboxInput,
259 id_base = "is_selected_",
260 suffix = Data$sample_id,
261 value = Data$is_selected)
262
263 Data
264}
265
266# User Interface ----------------------------------------------------
267
268ui <-
269 fluidPage(
270 verbatimTextOutput("value_check"),
271
272 actionButton(inputId = "btn_saveSelection",
273 label = "Save Selection"),
274 actionButton(inputId = "btn_selectAll",
275 label = "Select All"),
276 actionButton(inputId = "btn_unselectAll",
277 label = "Unselect All"),
278 actionButton(inputId = "btn_restoreDefault",
279 label = "Restore Default (select odd only)"),
280
281 DT::dataTableOutput("dt")
282 )
283
284# Server ------------------------------------------------------------
285
286server <-
287 shinyServer(function(input, output, session){
288
289 # Event Observers -----------------------------------------------
290
291 observeEvent(
292 input$btn_selectAll,
293 {
294 TmpData <- SourceData
295 TmpData$is_selected <- TRUE
296 replaceData(dt_proxy, prepareDataForDisplay(TmpData))
297 }
298 )
299
300 observeEvent(
301 input$btn_unselectAll,
302 {
303 TmpData <- SourceData
304 TmpData$is_selected <- FALSE
305 replaceData(dt_proxy, prepareDataForDisplay(TmpData))
306 }
307 )
308
309 observeEvent(
310 input$btn_restoreDefault,
311 {
312 replaceData(dt_proxy, prepareDataForDisplay(SourceData))
313 }
314 )
315
316 observeEvent(
317 input$btn_saveSelection,
318 {
319
320 check_input <- names(input)[grepl("is_selected_", names(input))]
321
322 id <- as.numeric(sub("is_selected_", "", check_input))
323
324 TmpData <- SourceData
325
326 for (i in seq_along(check_input)){
327 TmpData$is_selected[TmpData$sample_id == id[i]] <-
328 input[[check_input[i]]]
329 }
330
331 # At this point, I would also save changes to the remote database.
332
333 DT::replaceData(proxy = dt_proxy,
334 data = prepareDataForDisplay(TmpData))
335 }
336 )
337
338 # Output elements -----------------------------------------------
339
340 output$value_check <-
341 renderPrint({
342 sort(names(input))
343 })
344
345 output$dt <-
346 DT::renderDataTable({
347 SourceData %>%
348 prepareDataForDisplay() %>%
349 DT::datatable(selection = "none",
350 escape = FALSE,
351 filter = "top",
352 class = "compact cell-border",
353 options = list(preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
354 drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')))
355 })
356
357 dt_proxy <- DT::dataTableProxy("dt")
358
359 })
360
361# Run the application -----------------------------------------------
362
363shinyApp(
364 ui = ui,
365 server = server
366)
367
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in User Interface
Tutorials and Learning Resources are not available at this moment for User Interface