have you ever created any custom action on your jqGrid?
looking at this example, I realized custom action, even if their tooltip are something similar to a sequence of html space (  ...)
any tips?
EDIT: this is the code I developed:
gridComplete: function () {
if (grid.getGridParam('records') == 0) // are there any records?
DisplayEmptyText(true);
else
DisplayEmptyText(false);
var ids = grid.jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var cl = ids[i];
ae = "<a id='modifica' href='#'><img src='../../../images/edit.png' alt='' width='16' /></a>";
be = " <a id='assegnacamera' href='#'><img src='../../../images/key.png' alt='Assegna Camera' width='16' /></a>";
se = " <a id='cancel' href='#'><img src='../../../images/delete.png' alt='Elimina prenotazione' width='16' /></a>";
ce = " <a id='unassigncamera' href='#'><img src='../../../images/room_unassign.png' alt='Elimina assegnazione camera' width='16' /></a>";
de = " <a id='noshow' href='#'><img src='../../../images/reservationnoshow.png' alt='' width='16' /></a>";
grid.jqGrid('setRowData', ids[i], { act: ae + be + se + ce + de });
}
}
First of all you should include title: false in the column definition to have no standard tooltip. Then you can either define different tilte attributes for separate <a> elements or use cellattr to set custom value on the title attribute of the cell (the <td> element).
Related
I have the following JS and HTML code and I want to disable the button when ajax request is submitting so the user wont be able to double click and disturb the process.
function doReshare(_intPostId) {
if(typeof cLogin === 'undefined')
var cLogin = checkLogin();
if(cLogin!=true)
return;
var date = new Date();
var mainId = _intPostId;
var type = 1;
var active = 0;
var postFinded = 0;
jQuery(".reshare_" + _intPostId).each(function() {
postFinded = 1;
objElement = jQuery(this);
if(objElement.hasClass('sm2_playing') || objElement.hasClass('sm2_paused')) {
// track is active
active = 1;
}
if(objElement.hasClass('is_album')) {
mainId = objElement.closest('div.playlist-box').attr('id').replace('album_', '');
// mainId = objElement.data('mainid');
}
var intLikesCurrentCount = parseInt(objElement.find(".likes_count").first().text(), 10);
if(!objElement.find(".refeed_fct").hasClass("active")) {
if(active)
jQuery('.player-icons.dorepost').addClass('active');
objElement.find(".refeed_fct").addClass("active");
//objElement.find(".likes_count").html("<i class=\"fa fa-heart-o\"></i> " + (intLikesCurrentCount + 1));
} else {
objElement.find(".refeed_fct").removeClass("active");
if(active)
jQuery('.player-icons.dorepost').removeClass('active');
type = 0;
//objElement.find(".likes_count").html("<i class=\"fa fa-heart-o\"></i> " + (intLikesCurrentCount - 1));
}
});
if(!postFinded) {
if(!jQuery(".player-icons.dorepost").hasClass("active")) {
jQuery('.player-icons.dorepost').addClass('active');
} else {
jQuery('.player-icons.dorepost').removeClass('active');
}
}
jQuery("#vowave").append('<img width="1" height="1" src="/reshare/' + mainId + '/' + type + '?time=' + date.getTime() + '" />');
}
and the html
<span class="refeed_fct" onclick="doReshare(10309)">
<i class="fa fa-retweet"></i> <div class="inline hidden-mobile">Repost</div>
</span>
Thank you
Maybe you should set the objElement's onclick listener to an empty function
I am learner in javaScript
How to write required on selectpicker based on
var typeSelectBox = "<select id='depprojsDevice' class='selectpicker'>";
typeSelectBox += "<option value=''> -- SELECT --</option>";
if (arr) {
for (var i in arr) {
typeSelectBox += "<option value='" + arr[i][2] + "'>" + arr[i][0] + " " + arr[i][1] + "</option>";
}
}
typeSelectBox + "</select>";
$('#depprojsDevice_Div').html(typeSelectBox);
$("div#depprojsDevice_Div select[id = 'depprojsDevice']").attr('required','required');
$(function(){
$("#depprojsDevice").prop('required',true);
});
Try This Code
Scenario: User enters a name into a Textbox and result is presented through jQueryUI $("#textboxElement").autocomplete({...}). User selects one of the suggested result (Full Name (username)) and that gets displayed into the #textboxElement. User now clicks on a button named "Permission" which should return a list of permission for the selected user populated into a pre-existing HTML table. Button click should takes user selection, extract only the last username between two parentheses and pass as a parameter for webservice that returns list of Permission object.
Problem: Nothing happens on the page. No error is shown. Other jQUeryUI user controls are all over the page and does not work. Even search does not work with other button click events on the page. The Ajax code gives error (Unexpected ".) Where am I doing things wrong?
jQueryUI code:
$("#showPermission")
.button()
.click(function () {
var username = $('input:text[name=nameSearch]').val();
//extracting a string of text that lies between two (parenthesis) from the end of the string
var result = username.split('(');
for (var i = 1; i < result.length; i++) {
$("#txtSelectedUsername").val(result[i].split(')')[0]);
}
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Search.aspx/GetUserPermission",
data: "{'username':'" + $("#txtSelectedUsername").val() + "'}",
dataType: "json",
success: function (data)
{
$.each(data, function(key, val)
{
var row = $("<tr />");
$("<td />").text(val.username).appendTo(row);
$("<td />").text(val.level).appendTo(row);
$("<td />").text(val.location).appendTo(row);
$("<td />").text(val.role).appendTo(row);
row.appendTo("table.usersPermissionTbl");
});
},
error: function (xhr, textStatus, errorThrown)
{
var errorMessage = "Ajax error: " + this.url + " textStatus: " + textStatus + " errorThrown: " + errorThrown + " xhr.statusText: " + xhr.statusText + " xhr.status: " + xhr.status;
alert(errorMessage);
if (xhr.status != "0" || errorThrown != "abort")
{
alert(xhr.responseText);
}
}
});//end of ajax
});//end of click event
HTML
<table id="usersPermissionTbl" class="ui-widget ui-widget-content">
<thead>
<tr class="ui-widget-header ">
<th>Username</th>
<th>Level</th>
<th>Location</th>
<th>Role</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>
</tbody>
</table>
C# code
public static Permission[] GetUserPermission(string username)
{
List<Permission> allPermission = new List<Permission>();
SqlConnection con = new SqlConnection();
con.ConnectionString = connectionString;
string sqlString = "SELECT username, level, location, role from URTable WHERE username = '" + username + "'";
SqlDataAdapter sadp = new SqlDataAdapter(sqlString, con);
DataSet ds = new DataSet();
sadp.Fill(ds);
foreach (DataTable table in ds.Tables)
{
foreach (DataRow dtrow in table.Rows)
{
Permission permission = new Permission();
permission.userName = dtrow["username"].ToString();
permission.level = dtrow["level"].ToString();
permission.location = dtrow["location"].ToString();
permission.role = dtrow["role"].ToString();
allPermission.Add(permission);
}
}
con.Close();
return allPermission.ToArray();
}
public class Permission
{
public string userName { get; set; }
public string level { get; set; }
public string location { get; set; }
public string role { get; set; }
}
Solution
The following was missing on the C# method as #Saranya has mentioned.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Binding to a table was wrong, so the solution is as below
success: function (data) {
var row;
$.each(data.d, function (key, value) {
row = '<tr>';
row += '<td>' + value.userName + '</td>';
row += '<td>' + value.level + '</td>';
row += '<td>' + value.location + '</td>';
row += '<td>' + value.role + '</td>';
row += '</tr>';
$(row).appendTo("#usersPermissionTbl");
});
String extraction was assiging the result to a textbox which should have been to a variable.
var username = $('input:text[name=nameSearch]').val();
var name
var result = username.split('(');
for (var i = 1; i < result.length; i++) {
name = result[i].split(')')[0];
}
Mark the method in aspx as WebMethod..
I have the controller below with the Methods. One takes a parameter and the other does not.
I want to be able to do a search.
When I click on submit button. Nothing happens. My ajax call is not hit.
If question 1 is solved, I want to be able to type in my search criteria and have it
return data in the existing table used in my index view.
Please assist. New to Ajax and mvc.
public class HomeController : Controller
{
public ActionResult Index()
{
//List<Product> myProductList = GetAllProducts();
//return View(myProductList);
//List<Product> myProductList = GetAllProducts();
return View();
}
public ActionResult About()
{
return View();
}
public List<Product> GetAllProducts()
{
string myConnect = ConfigurationManager.ConnectionStrings["ConnectSir"].ConnectionString;
List<Product> prdResults = new List<Product>();
SqlConnection con = new SqlConnection(myConnect);
SqlCommand cmd = new SqlCommand("select * from products",con);
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Product newProduct = new Product();
newProduct.Id = Convert.ToInt16(reader["Id"]);
newProduct.Name = reader["Name"].ToString();
newProduct.Description = reader["description"].ToString();
newProduct.Price = Convert.ToDecimal(reader["Price"]);
newProduct.UnitsInStock = Convert.ToInt16(reader["UnitsInStock"]);
prdResults.Add(newProduct);
}
}
return prdResults;
}
[HttpPost]
public JsonResult GetAllProducts(string searchName)
{
string myConnect = ConfigurationManager.ConnectionStrings["ConnectSir"].ConnectionString;
List<Product> prdResults = new List<Product>();
string sqlcmd = #"select * from products where name = #name";
SqlConnection con = new SqlConnection(myConnect);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = sqlcmd;
cmd.Parameters.Add("#name", SqlDbType.NVarChar);
cmd.Parameters["#name"].Value = searchName;
cmd.Parameters["#name"].Direction = ParameterDirection.Input;
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Product newProduct = new Product();
newProduct.Id = Convert.ToInt16(reader["Id"]);
newProduct.Name = reader["Name"].ToString();
newProduct.Description = reader["description"].ToString();
newProduct.Price = Convert.ToDecimal(reader["Price"]);
newProduct.UnitsInStock = Convert.ToInt16(reader["UnitsInStock"]);
prdResults.Add(newProduct);
}
}
//return prdResults;
return Json(prdResults);
}
}
*********************************
Html
#model IEnumerable<MvcAjax.Models.Product>
<script src="../../Scripts/jquery-1.10.2.js" type="text/javascript"></script>
<form>
<div>
<input type="text" name="search" id="searchItem" />
<input type="submit" value="Retrieve" id="btnSearch"/>
</div>
<div>
</div>
<table id="items">
<tr>
<th></th>
<th>
Name
</th>
<th>
Description
</th>
<th>
Price
</th>
<th>
UnitsInStock
</th>
</tr>
</table>
<script type="text/javascript">
$('#btnSearch').click(function () {
$.ajax({
url: 'Home/GetAllProducts/',
type: 'POST',
dataType: 'json',
data: { searchName: $('#searchItem').val() }
}).done(function (data) {
if (data && data.length) {
for (var i = 0; i < data.length; i++) {
var newTR = '<tr>';
//create your TR, such as
newTR += '<td>' + data[i].Name + '</td>';
newTR += '<td>' + data[i].Description + '</td>';
newTR += '<td>' + data[i].Price + '</td>';
newTR += '<td>' + data[i].UnitsInStock + '</td>';
//and so on...
newTR += '</tr>';
$('#items > tr:last').append(newTR);
}
}
});
});
</script>
</form>
Send ajax with data and change content type to application/json; charset=utf-8", like this:
$('#btnSearch').click(function () {
$.ajax({
data: '{searchName:' + $('#searchItem').val() + '}'
url: 'Home/GetAllProducts/',
contentType: 'application/json; charset=utf-8"',
type: 'Get',
dataType: 'html'
})
});
Change
data: { Name: mysearchName }
in your ajax call to
data: { searchName: mysearchName }
as your action method is accepting searchName
[HttpPost]
public JsonResult GetAllProducts(string searchName)
{...
}
Let's focus on your first question. Your action is probably not being called because you're using a non-default route. Also, having actions with the same name and verb is not a good practice.
So, let's change your action signature to:
[HttpPost]
public JsonResult GetAllProducts(string searchName)
HttpPost to change the verb, and JsonResult because we want to use your data with javascript, and that's the best approach.
Final change to your action, let's modify the return statement:
return Json(prdResults);
On your view, we must modify the ajax call:
$('#btnSearch').click(function () {
$.ajax({
url: 'Home/GetAllProducts/',
contentType: 'application/html; charset-ut',
type: 'POST',
dataType: 'json',
data: { searchName: $('#searchItem').val()}
});
});
As soon as we get this working, I'll move to the next question.
Now, the 2nd part. We'll add the lines using javascript.
First of all, let's give an id to your table. Let's call it items
<table id="items">
Let's add a handler to your ajax promise:
$('#btnSearch').click(function () {
$.ajax({
url: 'Home/GetAllProducts/',
type: 'POST',
dataType: 'json',
data: { searchName: $('#searchItem').val()}
}).done(function(data){
if(data && data.length){
for(var i = 0; i < data.length; i++){
var newTR = '<tr>';
//create your TR, such as
newTR += '<td>' + data[i].Name + '</td>';
//and so on...
newTR += '</tr>';
$('#items > tr:last').append(newTR);
}
}
});
});
And that's it
For debugging puporses, let's replace the code within done(data){...} with this:
if (data && data.length) {
for (var i = 0; i < data.length; i++) {
var newTR = '<tr>';
//create your TR, such as
newTR += '<td>' + data[i].Name + '</td>';
newTR += '<td>' + data[i].Description + '</td>';
newTR += '<td>' + data[i].Price + '</td>';
newTR += '<td>' + data[i].UnitsInStock + '</td>';
//and so on...
newTR += '</tr>';
alert(newTR);
$('#items > tr:last').append(newTR);
}
}
else{
alert('empty response. Please set a breakpoint at the action and make sure that something is returning');
}
I am using a Mediawiki based website. The site is http://www.DragonFallRPG.com The widget in question is the 'Orion's Dice Box' in the left column of the site.
Not sure if that has any bearing on this but here goes. I have a custom div called 'dice' with a content destination div called 'result'. Below the 'result' div is a form for selecting a number of dice, and the number of sides for those dice. There is a processing script, which is tested working to provide a randomized result as if those dice were thrown. The problem is in the calling of one or more functions, I think. I found the AJAX method for getting the user input via 'get' somewhere on the web and no longer have any idea where it came from. I will include the files below.
dice_header.php (include file for <head> portion of webpage)
<style>
<!--[if IE] -- long buttons / button width in IE fix>
<style>.button{width:1;}</style>
<![endif]-->
</style>
<?php $javafile = dirname(__FILE__).'/ajax_engine.js'; ?>
<script type="text/javascript" src= "<?php echo $javafile ?>" ></script>
<script type="text/javascript">
function submit_dice() {
// Get form values
var no_of_dice = document.getElementById('dice').value;
var no_of_sides = document.getElementById('sides').value;
// Construct URL
<?php $handlerfile = dirname(__FILE__).'/handler.php' ?>
url = '<?php echo $handlerfile; ?>' + '?no_of_dice=' + escape(no_of_dice) + '&no_of_sides=' + escape(no_of_sides);
var xend = url.lastIndexOf("/") + 1;
var base_url = url.substring(0, xend);
alert('Handlerfile URL = ' + url + '\r\n\r\n Escape URL = ' + escape(url) + '\r\n\r\n # of dice = ' + no_of_dice + '\r\n # of Sides = ' + no_of_sides);
alert('url for ajax_get = ' + url);
ajax_get (url, 'result');
}
</script>
The above code is an include in the header of the index.php
The function call for ajax_get seems to be where it breaks down in the process in the above code. I don't know if it requires the http portion of the url or not. I don't know if the escape url is required or not. I'm hesitant to monkey with the script any further without guidance.
The code that follows is the div block for the widget I'm trying to create
dice.php (include file for my widget / div block)
<div id="result" style="text-align:center;
word-wrap: break-word;
width:100px;
font-weight:bold;
font-size:large;
border:1px blue solid;
margin:0;">
<?php
//$filename = dirname(__FILE__).'/ajax_engine.js';
//$handlerfile = dirname(__FILE__).'/handler.php';
if (file_exists($handlerfile)) {
echo "Handler file path OK";
echo 'alert(\'Handler file path = "' . $handlerfile . '"\');';
die();
} else {
echo "BAD handler file path!";
}
?>
</div>
<table border="0" cellspacing="0" cellpadding="0" style="margin:0; padding:0px;" >
<tr>
<td><select name="dice" id="dice" size="1" style="margin:0px;">
<?php
for ($i = 1; ; $i++) {
if ($i > 20) {
break;
}
if ($i == 1) {
echo "<option value=$i selected>$i</option>\n";
} else {
echo "<option value=$i>$i</option>\n";
}
}
?>
</select></td>
<td><select name="sides" id="sides" size="1" style="margin:0px;">
<option value="4">d4</option>
<option value="6">d6</option>
<option value="8">d8</option>
<option value="10">d10</option>
<option value="12">d12</option>
<option value="20" selected>d20</option>
<option value="100">d100</option>
</select>
</td>
</tr><tr>
<td colspan="2">
<input type="button" onclick="submit_dice();" value="Roll Dice" style="width:100px;" />
</td></tr>
</table>
<!--
Psuedo vs. True Random Numbers
http://www.phpfive.net/pseudo-random_php_functions_and_truly_random_number_generators_article2.htm
-->
Next follows the javascript engine I'm using to begin the AJAX functionality... Mediawiki has it's own built in AJAX - but I have no familiarity with it and tried finding a less complicated working version else where that I could tweak - resulting in this headache.
Several alert popup calls made to help with debugging, but I'm lost, and none of these alerts are actually being called... I can't tell why.
// JavaScript Document "javascript_engine.js"
// Get base url
url = document.location.href;
var base_url = "http://";
alert('base_url = ' + base_url);
xend = url.lastIndexOf("/") + 1;
var base_url = url.substring(0, xend);
var ajax_get_error = false;
alert('ajax_engine.js called');
function ajax_do (url) {
// Does URL begin with http?
alert('url.substring(0, 4) = ' + url);
if (url.substring(0, 4) != 'http') {
url = base_url + url;
}
// Create new JS element
var jsel = document.createElement('SCRIPT');
jsel.type = 'text/javascript';
jsel.src = url;
// Append JS element (therefore executing the 'AJAX' call)
document.body.appendChild (jsel);
return true;
}
function ajax_get (url, el) {
// Has element been passed as object or id-string?
if (typeof(el) == 'string') {
el = document.getElementById(el);
}
// Valid el?
if (el == null) { return false; }
alert(url.substring(0, 4));
// Does URL begin with http?
if (url.substring(0, 4) != 'http') {
url = base_url + url;
}
// Create getfile URL
getfile_url = base_url + 'getfile.php?url=' + escape(url) + '&el=' + escape(el.id);
// Do Ajax
ajax_do (getfile_url);
return true;
}
Following is getfile.php
<?php //getfile.php -- used for addressing visual part of code
// Get URL and div
if (!isset($_GET['url'])) { die(); } else { $url = $_GET['url']; }
if (!isset($_GET['el'])) { die(); } else { $el = $_GET['el']; }
// echo 'alert(\'URL in getfile.php = \'); $url';
// Make sure url starts with http
if (substr($url, 0, 4) != 'http') {
// Set error
echo 'alert(\'Security error; incorrect URL!\');';
die();
}
// Try and get contents
$data = #file_get_contents($url);
if ($data === false) {
// Set error
echo 'alert(\'Unable to retrieve "' . $url . '"\');';
die();
}
// Escape data
$data = str_replace("'", "\'", $data);
$data = str_replace('"', "'+String.fromCharCode(34)+'", $data);
$data = str_replace ("\r\n", '\n', $data);
$data = str_replace ("\r", '\n', $data);
$data = str_replace ("\n", '\n', $data);
?>
el = document.getElementById('<?php echo $el; ?>');
el.innerHTML = '<?php echo $data; ?>';
Following is the form processor, generating the random numbers result for the AJAX output/update.
<?php // handler.php
/////////////////////////////////////////////////////////////////
// Random Dice Value Generator v1.0 //
// http://www.dragonfallrpg.com //
// Orion Johnson Copyright 2007 //
// //
// This script is used to create a random number based //
// values from the user's input //
/////////////////////////////////////////////////////////////////
/* double rolldice(int, int)
* - generates a random value based on the numbers passed as an argument
* - maximum iterations = 20 (can be changed in the user form)
* - maximum number of sides per function call = 4, 6, 8, 10, 12, 20, or 100 (can be changed)
*
* Usage: To generate a random total value as if one had thrown that many dice:
* Note: Future revisions may include the ability to add additional lines to the user form
* to mix types of simulated dice being thrown.
*
* array $no_of_dice(x-1); array value "x" taken from user form
* var $no_of_sides; value taken from user form
* var $total_value; sum of values from entire array
* echo $total_value;
*/
// Check variables
if (empty($_GET['no_of_dice'])) {
die ('<span style="color:red;">Number of dice value invalid!</span>');
}
if (empty($_GET['no_of_sides'])) {
die ('<span style="color:red;">Number of sides value invalid!</span>');
}
// seed with microseconds
function make_seed()
{
list($usec, $sec) = explode(' ', microtime());
return (float) $sec + ((float) $usec * 1000003);
}
function rolldice()
{
$total_value = 0; /* sum of values from entire array */
srand(make_seed()); /* seed random number generator // 1,000,003 is a prime number */
/* start loop structure from 0 to $no_of_dice */
for($i = 0; $i < $_GET['no_of_dice']; $i++)
{
$randnum = rand(1, $_GET['no_of_sides']);
$total_value = $total_value + $randnum;
}
/* end loop */
/* print/return results to the screen */
// echo 'Total value for dice: ' + rolldice();
return $total_value;
}
// Taken from http://www.sebflipper.com/?page=code&file=password.php
// for array iteration see also: http://www.php-scripts.com/php_diary/122799.php3
?>
If there is a simpler way to perform a div update with a random result based on form input, I'm all ears. This has been a headache for too long for me. I'm no code-head, just know enough to tinker and make some things work and understand most things when explained.
I haven't read through all the code, but since MediaWiki 1.17.0 there's a feature called ResourceLoader (if you have older version you should upgrade), which you can use for this purpose.
You can make the whole code into an extension to have it organized in a directory (let's say extensions/DiceBox). The DiceBox.php file in that folder would then be along these lines:
<?php
if( !defined( 'MEDIAWIKI' ) ) {
die();
}
$wgExtensionFunctions[] = 'DiceBoxInit';
$wgHooks['SkinTemplateToolboxEnd'][] = 'DiceBoxOnSkinTemplateToolboxEnd';
$wgResourceModules['ext.DiceBox'] = array(
'localBasePath' => dirname( __FILE__ ),
'remoteExtPath' => 'DiceBox',
'scripts' => 'ext.DiceBox.js',
'dependencies' => 'jquery'
);
function DiceBoxInit() {
global $wgOut;
$wgOut->addModules( 'ext.DiceBox' );
}
?>
<?php
function DiceBoxOnSkinTemplateToolboxEnd() {
$sides = array( 4, 6, 8, 10, 12, 20, 100 );
?>
</ul>
</div>
</div>
<div class="portlet" id="p-dicebox">
<h5>Orion's Dice Box</h5>
<div class="pBody">
<div id="dice-result" style="display: none;"></div>
<form id="dice-form">
<select name="no_of_dice">
<?php
for( $i = 1; $i <= 20; $i++ ) {
echo '<option value="', $i, '">', $i, '</option>';
}
?>
</select>
<select name="no_of_sides">
<?php
foreach( $sides as $n ) {
echo '<option value="', $n, '">d', $n, '</option>';
}
?>
</select>
<input type="button" value="Roll Dice" id="dice-roll" />
</form>
<?php
return true;
}
This code outputs the code box HTML in the sidebar and registers the following JavaScript file (ext.DiceBox.js) to be available on the page:
jQuery( document ).ready( function( $ ) {
$( '#dice-roll' ).click( function() {
$.get( mw.config.get( 'wgExtensionAssetsPath' ) + '/DiceBox/handler.php',
$( '#dice-form' ).serialize(), function( data )
{
$( '#dice-result' ).html( data ).append( '<hr />' ).show();
} );
} );
} );
This code simply uses jQuery (which is bundled with MediaWiki as of 1.16.0) to send a request to the server when the button is clicked and displays the result in the box.
In the handler.php file, there's no place where the random number gets output, so you need to add echo rolldice(); before the ?>.
Finally, to make the extensions fully work, add require_once $IP . '/extensions/DiceBox/DiceBox.php'; to the bottom of LocalSettings.php.