I am working on a E-learning shiny web application which lets students learn R functions easily. The user should be able to drag and drop grids into the blanks provided to answer a particular question syntactically. I have written the HTML file, including the styling and javascript in it. I have used the "includeHTML("index.html")" function to include the HTML file to the ui.R part of the application. Now, I need to implement communication between the ui.R and server.R in such a way that when the user drags and drops all the grids in the desired blanks and clicks the "Submit" button, the concatenated version of the function needs to go to the server side, R interpreter needs to evaluate the statement and then send back the output which needs to be displayed to the user. How do I send the concatenated message from webpage to server.R? Evaluate the function? And how do I send back the output back to the web page?
Example: Q. Write a function in R for sum of two digits:
sum, diff, mean, median, etc
1,2,3,4,5...
( ) . , / : " ' { } ( )
My HTML, CSS and Javascript file is as follows:
<title>E-learning 'R'</title><link rel="stylesheet" href="style.css" />
<script src="index.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<p>The function for sum of any two digits in 'R' syntax is: </p>
<p id="res">
<span class="target" data-accept="right1"></span>
<span class="target" data-accept="right2"></span>
<span class="target" data-accept="right3"></span>
<span class="target" data-accept="right4"></span>
<span class="target" data-accept="right5"></span>
<span class="target" data-accept="right6"></span>
<input type="submit" onclick="showInput();">
<br/>
</p>
<head lang="en">
<meta charset="UTF-8">
<script language="JavaScript">
function showInput() {
console.log(document.getElementById("res").textContent);
document.getElementById('display').innerHTML = document.getElementById("res").textContent;
Shiny.onInputChange("res",value);
}
</script>
<style>
span {
width: 50px;
display: inline-block;
height: 20px;
background: #ffffff;
}
body {
font: 13px Verdana;
background-color: grey;
}
ul.numbers {
list-style: none;
padding: 10px;
background: grey;
}
ul.symbols {
list-style: none;
padding: 10px;
background: grey;
}
ul.functions {
list-style: none;
padding: 10px;
background: grey;
}
ul.numbers li {
display: inline-block;
margin: 0 10px;
padding: 10px;
background: #FFF706;
}
ul.symbols li {
display: inline-block;
margin: 0 10px;
padding: 10px;
background: #18FC7A;
}
ul.functions li {
display: inline-block;
margin: 0 10px;
padding: 10px;
background: #FF99F7;
}
p {
padding: 10px;
color: black;
background-color: #0680FF;
}
#answer span{
width: 100px;
}
.quiz-wrapper {
position: relative;
display: block;
width: 510px;
height: 450px;
}
.quiz-wrapper p.question-description {
background: #19286C;
color: white;
padding: 25px 20px;
}
.quiz-wrapper ul.options {
position: relative;
display: inline-block;
vertical-align: top;
width: 165px;
list-style: none;
border: 1px solid #19286C;
text-align: center;
padding: 0;
margin: 0;
}
.quiz-wrapper ul.options li {
border: 1px solid transparent;
padding: 6px 8px;
}
.quiz-wrapper ul.options li.title {
background: #19286C;
color: white;
}
.quiz-wrapper ul.options li.option {
display: block;
position: relative;
z-index: 50;
font-size: 13px;
}
.quiz-wrapper .answers {
display: inline-block;
width: 335px;
font-size: 13px;
line-height: 20px;
}
.quiz-wrapper .answers .target {
display: inline-block;
width: 110px;
background: lightblue;
margin: 0 3px;
text-align: center;
}
.quiz-wrapper button[type="submit"] {
display: block;
position: relative;
margin: 10px auto;
padding: 10px;
background: #19286C;
border: none;
color: white;
font-size: 16px;
}
.lightbox-bg {
display: none;
position: absolute;
z-index: 100;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.7);
}
.status {
display: none;
position: absolute;
z-index: 110;
text-align: center;
width: 80%;
top: 220px;
left: 47px;
}
.status p {
background: white;
padding: 30px;
}
</style>
<body>
ul class="numbers">
li class="number" data-target="wrong1">0</li>
li class="number" data-target="wrong2">1</li>
li class="number" data-target="right3">2</li>
li class="number" data-target="right5">3</li>
li class="number" data-target="wrong3">4</li>
li class="number" data-target="wrong4">5</li>
li class="number" data-target="wrong5">6</li>
li class="number" data-target="wrong6">7</li>
li class="number" data-target="wrong7">8</li>
li class="number" data-target="wrong8">9</li>
/ul>
ul class="functions">
li class="function" data-target="right1">sum</li>
li class="function" data-target="wrong9">median</li>
li class="function" data-target="wrong10">mean</li>
li class="function" data-target="wrong11">sqrt</li>
li class="function" data-target="wrong12">log</li>
li class="function" data-target="wrong13">min</li>
li class="function" data-target="wrong14">max</li>
li class="function" data-target="wrong15">abs</li>
li class="function" data-target="wrong16">round</li>
li class="function" data-target="wrong17">add</li>
/ul>
ul class="symbols">
li class="symbol" data-target="right2">(</li>
li class="symbol" data-target="right6">)</li>
<li class="symbol" data-target="right4">,</li>
<li class="symbol" data-target="wrong18">.</li>
<li class="symbol" data-target="wrong19">/</li>
<li class="symbol" data-target="wrong20">?</li>
<li class="symbol" data-target="wrong21">+</li>
<li class="symbol" data-target="wrong22">=</li>
<li class="symbol" data-target="wrong23">-</li>
<li class="symbol" data-target="wrong24">*</li>
</ul>
<p id="answer">Message is: <span id = "display"></span> </p>
<script>
$(document).ready(function() {
$("span").droppable({
accept: "ul > li",
classes: {
"ui-droppable-hover": "ui-state-hover"
},
drop: function(event, ui) {
var dragedElement = ui.draggable.text();
$(this).addClass("ui-state-highlight");
$(this).html(dragedElement);
$(this).addClass('matched');
}
});
$("ul li").draggable({
helper:"clone",
revert: "invalid"
});
})
</script>
ui.R:
library(shiny)
shinyUI(fluidPage(
includeHTML("index.html")
))
server.R:
library(shiny)
shinyServer(function(input, output) {
observeEvent(input$res){
eval(res);
print(res);
}
})