I develop the app that uses datatables to visualize certain statistics data.
I receive from API the data in the following format:
{
"data": [{
"companyName": "company1",
"growth": 15
},
{
"companyName": "company2",
"growth": -8
},
{
"companyName": "company3",
"growth": 23
}]
}
Which is essentially a company name and its year over year revenue growth figure (%).
What I would like to implement is an MS Excel-like conditional formatting feature that displays colored bars inside percentage cells (color of the bar is red for negative and green for positive values and its size is normalized to minimal/maximal value and column width).
So far, my HTML is:
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js" charset="utf8"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
<table id="revenue-growth"></table>
And jQuery:
$('#revenue-growth').DataTable({
ajax: {
url: 'https://192.168.0.1/revenue',
method: 'GET',
dataSrc: 'data'
}
dom: 'Bfrtip',
pageLength: 50,
order: [0, 'asc']
columDefs: [{
targets: 0,
data: 'companyName',
title: 'Company Name'
}, {
targets: 1,
data: 'growth',
title: 'YoY revenue growth, %'
}
]
})
So, my question is: is there a way to implement such feature from the ground up, or, maybe, there's already plug-in that does exactly this?
I didn't find anything matching my request here, at stackoverflow, nor I was able to identify DataTables API methods that may solve my problem, so I would really appreciate that if you could point me to the right direction.
You could use the render-callback to create bars inside the cells in the growth-column.
You have to find the maximum growth inside the dataset.
In the render-callback:
2.1. check if the growth is negative or positive.
2.2. calculate bar width-% based on the growth and the maximum.
2.3. create and append the elements based on these information.
Here is an simple example:
$(document).ready(function() {
const dataSet = [
{ companyName: "Company A", growth: -12 },
{ companyName: "Company B", growth: 31 },
{ companyName: "Company C", growth: 7 },
{ companyName: "Company D", growth: 0 },
{ companyName: "Company E", growth: -29 },
{ companyName: "Company F", growth: 23 },
];
// Get absolute maximum value of grwoth from dataset
const maxGrowthValue = Math.max.apply(Math, dataSet.map(function(item) { return Math.abs(item.growth); }));
const table = $('#example').DataTable({
data: dataSet,
columns: [
{
data: 'companyName',
title: "Company Name",
},
{
data: 'growth',
title: "YoY revenue growth, %",
// Custom render the cell of the growth-column
render: (data, type, row, meta) => {
const isPositive = (Number(data) > 0);
const barWidth = 100 / maxGrowthValue * Math.abs(Number(data)) * 0.5;
const $growthBarContainer = $('<div>', {
class: "growth-bar",
});
const $growthBar = $('<div>', {
class: "bar bar-" + (isPositive ? 'positive' : 'negative'),
});
$growthBar.css({
width: barWidth.toFixed(2) + '%',
});
$growthBarContainer.append($growthBar);
$growthNumber = $('<div>', {
class: "growth-number",
});
$growthNumber.text(data + '%');
$growthBarContainer.append($growthNumber);
return $growthBarContainer.prop("outerHTML");
},
},
],
});
});
.growth-bar {
display: inline-block;
width: 120px;
height: 12px;
position: relative;
background-color: #eee;
border: 1px solid #424242;
}
.growth-bar > .bar {
width: 0%;
height: 100%;
position: absolute;
}
.growth-bar > .bar.bar-negative {
right: 50%;
background-color: red;
}
.growth-bar > .bar.bar-positive {
left: 50%;
background-color: green;
}
.growth-bar > .growth-number {
position: absolute;
top: 1px;
right: 2px;
color: #fff;
/* shadow for better readability */
text-shadow: 0px -1px 0px rgba(0,0,0,.5), 0px 1px 0px rgba(0,0,0,.5), -1px 0px 0px rgba(0,0,0,.5), 1px 0px 0px rgba(0,0,0,.5), 0px 0px 1px rgba(0,0,0,.25), 0px 0px 2px rgba(0,0,0,.5), 0px 0px 3px rgba(0,0,0,.75);
font-size: 10px;
line-height: 12px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="example" class="display" style="width:100%"></table>
Related
i am using prime faces pie chart and i have pie chart, tooltip on hovering piechart and legends.
i am trying to develop custom legends like if i hover or click on legends a tool tip should display on corresponding pie chart part.
since i am new to plots am not able to find a solution. please help me how to add tool tip effect for legends
Note: tooltip will display hovering piechart but need hovering on legends
piechart:
PrimeFaces Code:
<p:pieChart id="countries" value="#{chartController.pieChartModel}" extender="toolExt" seriesColors="33CC66,FFCC00,0000CC,FF0099,00CCCC,660099,00FF00,FF6600,003300,00FFFF" style="width:440px;height:296px;background-color: white; border: 2px inset #8B8378; padding: 2px; -moz-border-radius: 5px;-webkit-border-radius: 5px;-webkit-box-shadow: 0 3px 9px #666;" >
javascript for extender:
Note: extender property used in piechart tag to add custom data
<script>
function toolExt() {
this.cfg.highlighter = {
show:true,
tooltipLocation: 'se',
tooltipAxes: 'pieref',
tooltipAxisX: 20000,
tooltipAxisY: 20000,
useAxesFormatters: false,
formatString:'Accumulated Cost to %s: %s',
},
this.cfg.legend = {
show : true,
fontSize: '100px',
rowSpacing: '1px',
textColor: '000000',
},
this.cfg.seriesDefaults={
renderer: jQuery.jqplot.PieRenderer,
rendererOptions : {
sliceMargin: 3,
padding : 1,
diameter : 170,
}
},
this.cfg.grid = {
drawBorder: false,
shadow: false,
background: "white"
};
this.cfg.redraw;
}
</script>
java code
Note: i used sample code, in actual code data comefrom db and it will set upto 10 series
public class ChartController
{
private PieChartModel pieChartModel;
public ChartController()
{
pieChartModel = new PieChartModel();
pieChartModel.set("JAPAN", 102);
pieChartModel.set("AFGANISTAN", 36);
pieChartModel.set("UNITED STATE", 33.6);
pieChartModel.set("PAKISTAN", 20.5);
}
public PieChartModel getPieChartModel()
{
return pieChartModel;
}
}
i tried renderOptions but it didn't worked
please help me how to display tool-tip on piechart while mouse hover/clicking on legends.
Thanks
using amcharts able to render tool tip using legends.
Java Script Code
roboCallCountryCost.js
AmCharts.ready(function() {
var costCountriesData = document.getElementById('roboCallDashboard:CCpieval').value;
var CCchart = AmCharts.makeChart("CCpiediv", {
"type": "pie",
"theme": "none",
"labelsEnabled":"false",
"radius":100,
"hideBalloonTime":60,
"fontSize":10,
"marginBottom":5,
"marginTop":5,
"pullOutDuration": 0,
"pullOutRadius": 0,
"legend": {
"markerType": "square",
"position": "right",
"marginLeft": 30,
"autoMargins": true,
"markerDisabledColor":"#00CCFF",
"markerLabelGap":5,
"markerSize":13,
"verticalGap":2,
"horizontalGap":2,
"spacing":5,
},
"dataProvider":eval(costCountriesData),
"valueField": "countryCost",
"titleField": "countryName",
"balloonText": "<b><span style='font-size:14px'>Accumulated Cost to [[title]]: [[value]]</span></b>",
colors:["#33CC66","#FFCC00","#0000CC","#FF0099","#00CCCC","#660099","#00FF00","#FF6600","#003300","#00FFFF"],
labelsEnabled:false,
});
});
"PrimeFaces Code:"
<h:form id="roboCallDashboard">
<script src="amcharts.js" type="text/javascript"></script>
<script src="pie.js" type="text/javascript"></script>
<script src="roboCallCountryCost.js" type="text/javascript"></script>
<h:panelGrid columns="1" width="100%" styleClass="dashboardContentTable" headerClass="dashboardTableHeader" style="height:337px">
<div id="CCpiediv"/>
<h:inputHidden id="CCpieval" value="{chartController.pieChartModel}" />
</h:panelGrid>
</h:form>
CSS:
#CCpiediv {
width : 440px;
height : 296px;
border: 2px inset #8B8378;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 0 3px 9px #666;
-moz--box-shadow: 0 3px 9px #666;
-o-box-shadow: 0 3px 9px #666;
box-shadow: 0 3px 9px #666;
background-color: white;
}
.amChartsLegend {
max-width: 130px;
overflow-x: scroll !important;
top: 2px !important;
height: 230px !important;
}
JAVA Code
ChartController.java
public String getPieChartModel() {
StringBuilder buf = new StringBuilder("[");
buf.append("{");
buf.append("countryName: ").append("\""+"AFGANISTAN"+"\"").append(",");
buf.append("countryCost: ").append("102").append(",");
buf.append("},");
buf.append("{");
buf.append("countryName: ").append("\""+"JAPAN"+"\"").append(",");
buf.append("countryCost: ").append("36").append(",");
buf.append("},");
buf.append("{");
buf.append("countryName: ").append("\""+"UNITED STATE"+"\"").append(",");
buf.append("countryCost: ").append("33.6").append(",");
buf.append("},");
buf.append("{");
buf.append("countryName: ").append("\""+"PAKISTAN"+"\"").append(",");
buf.append("countryCost: ").append("20.5").append(",");
buf.append("},");
buf.append("]");
return buf.toString();
}
I use Xampp to try GrapesJS, I downloaded GrapesJS from github then copied the rources to my HTDOCS folder, grap my Browser then hit Localhost :) it works, something like Web Builder appear and works as well, but how can I save the Edited Website using PHP ?,
I use intact INDEX.HTML found from GrapesJs github, only change it name to INDEX.PHP to work with PHP, so this is the codes I've been using
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GrapesJS</title>
<link rel="stylesheet" href="dist/css/grapes.min.css">
<script src="dist/grapes.min.js"></script>
<style>
body,
html {
height: 100%;
margin: 0;
}
</style>
</head>
<body>
<div id="gjs" style="height:0px; overflow:hidden;">
<div class="panel">
<h1 class="welcome">Welcome to</h1>
<div class="big-title">
<svg class="logo" viewBox="0 0 100 100">
<path d="M40 5l-12.9 7.4 -12.9 7.4c-1.4 0.8-2.7 2.3-3.7 3.9 -0.9 1.6-1.5 3.5-1.5 5.1v14.9 14.9c0 1.7 0.6 3.5 1.5 5.1 0.9 1.6 2.2 3.1 3.7 3.9l12.9 7.4 12.9 7.4c1.4 0.8 3.3 1.2 5.2 1.2 1.9 0 3.8-0.4 5.2-1.2l12.9-7.4 12.9-7.4c1.4-0.8 2.7-2.2 3.7-3.9 0.9-1.6 1.5-3.5 1.5-5.1v-14.9 -12.7c0-4.6-3.8-6-6.8-4.2l-28 16.2"/>
</svg>
<span>GrapesJS</span>
</div>
<div class="description">
This is a demo content from index.html. For the development, you shouldn't edit this file, instead you can
copy and rename it to _index.html, on next server start the new file will be served, and it will be ignored by git.
</div>
</div>
<style>
.panel {
width: 90%;
max-width: 700px;
border-radius: 3px;
padding: 30px 20px;
margin: 150px auto 0px;
background-color: #d983a6;
box-shadow: 0px 3px 10px 0px rgba(0,0,0,0.25);
color:rgba(255,255,255,0.75);
font: caption;
font-weight: 100;
}
.welcome {
text-align: center;
font-weight: 100;
margin: 0px;
}
.logo {
width: 70px;
height: 70px;
vertical-align: middle;
}
.logo path {
pointer-events: none;
fill: none;
stroke-linecap: round;
stroke-width: 7;
stroke: #fff
}
.big-title {
text-align: center;
font-size: 3.5rem;
margin: 15px 0;
}
.description {
text-align: justify;
font-size: 1rem;
line-height: 1.5rem;
}
</style>
</div>
<script type="text/javascript">
var editor = grapesjs.init({
showOffsets: 1,
noticeOnUnload: 0,
container: '#gjs',
height: '100%',
fromElement: true,
storageManager: { autoload: 0 },
styleManager : {
sectors: [{
name: 'General',
open: false,
buildProps: ['float', 'display', 'position', 'top', 'right', 'left', 'bottom']
},{
name: 'Flex',
open: false,
buildProps: ['flex-direction', 'flex-wrap', 'justify-content', 'align-items', 'align-content', 'order', 'flex-basis', 'flex-grow', 'flex-shrink', 'align-self']
},{
name: 'Dimension',
open: false,
buildProps: ['width', 'height', 'max-width', 'min-height', 'margin', 'padding'],
},{
name: 'Typography',
open: false,
buildProps: ['font-family', 'font-size', 'font-weight', 'letter-spacing', 'color', 'line-height', 'text-shadow'],
},{
name: 'Decorations',
open: false,
buildProps: ['border-radius-c', 'background-color', 'border-radius', 'border', 'box-shadow', 'background'],
},{
name: 'Extra',
open: false,
buildProps: ['transition', 'perspective', 'transform'],
}
],
},
});
editor.BlockManager.add('testBlock', {
label: 'Block',
attributes: { class:'gjs-fonts gjs-f-b1' },
content: `<div style="padding-top:50px; padding-bottom:50px; text-align:center">Test block</div>`
})
</script>
</body>
</html>
thanks for your help
This way worked for me.
First added a Save button to grapesjs panel.
editor.Panels.addButton('options',
[{
id: 'save-db',
className: 'fas fa-save',
command: 'save-db',
attributes: {
title: 'Save Changes'
}
}]
);
Then added a command for save button.
editor.Commands.add('save-db', {
run: function(editor, sender) {
sender && sender.set('active', 0); // turn off the button
editor.store();
//storing values to variables
var htmldata = editor.getHtml();
var cssdata = editor.getCss();
$.post("save.php", {
//you can get value in post by calling this name
"htmldata": htmldata,
"cssdata": cssdata,
success: function(data) {
alert(data);
console.log("Success");
},
});
}
});
In save.php
$editor_html_content = $_POST['htmldata'];
$editor_css_content = $_POST['cssdata'];
editor.on('component:add', options => {
var html = editor.getHtml();
var css = editor.getCss();
function create () {
$.ajax({
url:base_url+"/savepagedata.php",
type: "post",
data: {html_data: html , css_data:css },
success:function(result){
console.log(result);
}
});
}
});
I'm trying to display this array of objects based on highest to lowest rating of each item. It works fine using the method on the v-for, but I would really like to display the list of objects in the order they appear initially and THEN call a function that displays them by highest to lowest rating.
When I have it set as v-for="item in items" and then try to call the method on a button, such as #click="rated(items)", nothing happens. Why would I be able to display the array initially on the v-for with the method attached, but not on a click event?
const items = [
{
name: "Bert",
rating: 2.25
},
{
name: "Ernie",
rating: 4.6
},
{
name: "Elmo",
rating: 8.75
},
{
name: "Rosita",
rating: 2.75
},
{
name: "Abby",
rating: 9.5
},
{
name: "Cookie Monster",
rating: 5.75
},
{
name: "Oscar",
rating: 6.75
}
]
new Vue({
el: "#app",
data: {
items: items
},
methods: {
rated: function(items) {
return items.slice().sort(function(a, b) {
return b.rating - a.rating;
});
},
sortByRating: function(items) {
return items.slice().sort(function(a, b) {
return b.rating - a.rating;
});
}
}
});
#app {
display: flex;
flex-flow: row wrap;
margin-top: 3rem;
}
.item {
flex: 1;
margin: .5rem;
background: #eee;
box-shadow: 0px 2px 4px rgba(0,0,0,.5);
padding: 1rem;
min-width: 20vw;
}
.toggle {
position: absolute;
top: 10px;
left: 10px;
padding: .5rem 1rem;
background: DarkOrchid;
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="item in rated(items)"
class="item">
<p>{{item.name}}</p>
<p>{{item.rating}}</p>
</div>
</div>
Try to rewrite the array for the result returned by the method, like this.
#click="items = rated(items)
and, inside v-for you can keep using items.
Again, I am making a game but yet I ran into another problem. I have a set of actions a player can do, until they run out of energy. The problem I have is this: When they choose an action, it prompts for another action. Yet, when they type anything into the prompt, it closes itself. I know one solution: Copy and paste the code and basically make the code 6x larger by repeating code. But I wanna know if it's possible to: How can I make it so I can rollback a case in a switch-statement to repeat itself, but keep the current stats? Here's my JavaScript (currently not finished)
var merchants = [{
name : 'Weapons Merchant',
items : [
{type: "weapon", cost: 250, name: "Claymore"},
{type: "weapon", cost: 75, name: "Dagger"},
{type: "weapon", cost: 350, name: "Magic Staff"},
{type: "weapon", cost: 150, name: "Sword"},
{type: "weapon", cost: 125, name: "Bow"},
{type: "weapon", cost: 125, name: "Crossbow"},
{type: "weapon", cost: 5, name: "Arrow"},
{type: "weapon", cost: 15, name: "Bolt"}
]
}, {
name : 'Armor Merchant',
items : [
{type: "clothing", slot: "head", name: "Helmet"},
{type: "clothing", slot: "head", name: "Hood"},
{type: "clothing", slot: "chest", name: "Chestplate"},
{type: "clothing", slot: "chest", name: "Tunic"},
{type: "clothing", slot: "chest", name: "Robe"},
{type: "clothing", slot: "leggings", name: "Legplates"},
{type: "clothing", slot: "leggings", name: "Leggings"},
{type: "clothing", slot: "leggings", name: "Undergarments"},
{type: "clothing", slot: "feet", name: "Boots"},
{type: "clothing", slot: "feet", name: "Armored Boots"}
]
}, {
name: 'Material Merchant',
items: [
{type: "material", name: "Leather", cost: 25},
{type: "material", name: "Iron", cost: 50},
{type: "material", name: "Steel", cost: 75},
{type: "material", name: "Mythril", cost: 100},
{type: "material", name: "Dragonbone", cost: 200}
]
}];
function findMerchant(merchants, name) {
return find(merchants, function(merchant) {
return merchant.name === name;
});
}
function findItem(merchant, type, name) {
return find(merchant.items, function(item) {
return item.type === type && item.name === name;
});
}
function findWithParams(arr, parameters) {
return find(arr, function(item) {
for (var parameter in parameters) {
if (item[parameter] !== parameters[parameter]) {
return false;
}
return true;
}
});
}
function find(arr, predicateFn) {
var found = null;
arr.forEach(function(item, index, items) {
if (predicateFn.apply(undefined, arguments)) {
found = item;
return true;
}
return false;
});
return found;
}
function fight() {
var armorMerchant = findMerchant(merchants, 'Armor Merchant');
var weaponMerchant = findMerchant(merchants, 'Weapons Merchant');
var materialMerchant = findMerchant(merchants, 'Material Merchant');
var energy = 100;
var day = 3;
var money = 1000;
var armor = ['Mythril Chestplate', 'Mythril Legplates', 'Leather Hood'];
var weapon = [];
var intro = prompt("You are a hero who saved your town from a dragon attack years ago. You had fun murdering that dragon, but sadly no dragon has attacked since. Just when all hope is lo, you hear the sirens ring through the city. You know what that means. Do you PREPARE, or IGNORE THE SIRENS?").toUpperCase();
switch(intro) {
case 'PREPARE':
if(intro === "PREPARE") {
var decision1 = prompt("You decided to " + intro + ". You need to choose what you will do. Keep in mind, the more activities you do, the less energy you have! You only have 3 days to prepare! What do you do? Do you SEARCH ARMOR STAND, SEARCH WEAPON STAND, GO TO MERCHANT, FIGHT DRAGON, TRAIN, or SLEEP?").toUpperCase();
if(decision1 === "SEARCH ARMOR STAND" && energy >= 5) {
energy -= 5;
prompt("You check your armor rack, but happen to stub your toe on the way. You now have " + energy + " energy. You manage to check your armor rack, and you currently have: " + armor + " on your rack. What do you do now? SEARCH ARMOR STAND, SEARCH WEAPON STAND, GO TO MERCHANT, FIGHT DRAGON, TRAIN, or SLEEP?")
}
else {
alert("You don't have enough Energy!");
}
if(decision1 === "SEARCH WEAPON STAND" && energy >= 10) {
energy -= 10;
prompt("You go downstairs to search your weapon stand. Your weapon stand includes: " + weapon + ". On your way back up, you cut your finger on the broken piece of glass. You now have " + energy + " energy. What do you do now? SEARCH ARMOR STAND, SEARCH WEAPON STAND, GO TO MERCHANT, FIGHT DRAGON, TRAIN, or SLEEP?")
}
}
}
}
#import url(http://fonts.googleapis.com/css?family=Permanent+Marker);
html, body {
background: #000;
margin: 0;
padding: 0;
}
#wrap {
width: 760px;
margin-left: auto;
margin-right: auto;
}
.container {
position: relative;
top: 50px;
margin-left: auto;
margin-right: auto;
width: 570px;
height: 350px;
border: 6px ridge orange;
padding: 0;
}
.container img {
position: absolute;
bottom: 0px;
width: 570px;
height: 350px;
z-index: -1;
}
p.intro {
color: black;
text-shadow:
-1px -1px 0 #FFF,
1px -1px 0 #FFF,
-1px 1px 0 #FFF,
1px 1px 0 #FFF;
}
h2.header {
text-shadow:
-1px -1px 0 #FFA500,
1px -1px 0 #FFA500,
-1px 1px 0 #FFA500,
1px 1px 0 #FFA500;
}
.box {
float: left;
min-width: 567px;
min-height: 350px;
}
.box h2 {
font-family: 'Permanent Marker', cursive;
font-size: 200%;
text-align: center;
}
.box p {
font-family: 'Permanent Marker', arial;
text-align: center;
}
.box a {
position: absolute;
left: 165px;
display: inline-block;
border: 3px groove #000;
border-radius: 5px;
background: red;
margin-left: auto;
margin-right: auto;
width: 225px;
height: 75px;
font-family: 'Permanent Marker', cursive;
color: #FFA500;
text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
text-align: center;
}
.battles img {
}
<html>
<body>
<div id="wrap">
<div class="box">
<div class="container">
<h2 class="header">Dragon Slayer - REBORN!</h2>
<p class="intro">You are a hero who saved your town from a dragon attack years ago. You had fun murdering that dragon, but sadly no dragon has attacked since. Just when all hope is lost, you hear the sirens ring through the city. You know what that means.</p>
<br>BEGIN!
<img class="scenario" src="http://www.thegaminghideout.com/school/stage1.png">
<div class="battles">
</div>
</div>
</div>
</div>
</body>
</html>
THINGS TO NOTE
If possible, when the case rolls back to the previous prompt/step, it should keep the current energy/day variable, too.
If possible, can it just go back to the previous prompt?
If not possible, how can I shorten the code as much as possible to make it meet my requirement?
I have a Dgrid that shows some data, say DataDgrid. I'd like to add a select control based on another Dgrid, say SelectDgrid, inside one of the cells in the main DataDgrid.
To add the select I am following this example: http://dojofoundation.org/packages/dgrid/tutorials/drop_down/
I have prepared a JSFiddle that shows that it works:
http://jsfiddle.net/amiramix/qqezJ/
Now, when I try to add the select it shows inside the table cell instead of floating over the main DataGrid. Please check this JSFiddle (click Edit to add the select to the main DataGrid):
http://jsfiddle.net/amiramix/qqezJ/5/
I guess its down to some CSS not being set properly. I tried to fiddle with z-index but without any results. Any help would be greatly appreciated.
Adding the code below to dismiss stackoverflow's warnings:
HTML:
<button id="editButton" type="button">Edit</button>
<div id="grid"></div>
CSS:
#grid {
line-height: 30px;
}
.mySelect {
border: 1px solid #b5bcc7;
background-color: #ffffff;
height: 17px;
/* Make this position: relative so our arrow is positioned within */
position: relative;
padding: 0;
}
.mySelect .label {
line-height: 17px;
vertical-align: middle;
}
.mySelect .arrow {
/* Position the arrow on the right-hand side */
position: absolute;
top: 0;
right: 0;
/* Use claro's arrow image */
background-image: url("https://ajax.googleapis.com/ajax/libs/dojo/1.8.1/dijit/themes/claro/form/images/commonFormArrows.png");
background-position: -35px 70%;
background-repeat: no-repeat;
/* 16x16 with a white border and a gray background */
width: 16px;
height: 16px;
border: 1px solid #ffffff;
border-top: none;
background-color: #efefef;
}
.mySelect .dgrid {
position: absolute;
top: 17px;
left: -1px;
width: 100%;
display: none;
}
.mySelect .opened {
display: block;
}
JavaScript:
require([
"dojo/_base/declare",
"dojo/on",
"dgrid/OnDemandList",
"dgrid/OnDemandGrid",
"dgrid/Selection",
"dgrid/Keyboard",
"dojo/store/Memory",
"dojo/dom",
"dojo/dom-construct",
"dojo/dom-class",
"put-selector/put",
"dojo/domReady!"
], function(declare, on, List, OnDemandGrid, Selection, Keyboard, Memory, dom, domConstruct, domClass, put) {
var store = new Memory({
identifier: "id",
data: [
{
id: 0,
name: "One",
color: "blue",
value: 1},
{
id: 1,
name: "Two",
color: "red",
value: 2},
{
id: 2,
name: "Three",
color: "green",
value: 3},
{
id: 3,
name: "Four",
color: "orange",
value: 4}
]
});
var dataStore = new Memory({
identifier: "id",
data: [
{
id: 0,
name: "OneOne",
value: "OneTwo"},
{
id: 1,
name: "TwoOne",
value: "TwoTwo"}
]
});
var DropDown = declare([List, Selection, Keyboard]);
var Grid = declare([OnDemandGrid, Keyboard]);
var newGrid = new Grid({
store: dataStore,
columns: {
name: {
label: "Name"
},
value: {
label: "Value",
renderCell: function(object, value, td, options) {
put(td, "div#id-" + object.id, object.name);
}
}
}
}, "grid");
on(dom.byId("editButton"), "click", function(e) {
var ref = dom.byId("id-0");
ref.innerHTML = "";
put(ref, "#select.mySelect");
put(ref, "div.label.button", "choose...");
put(ref, "div.arrow.button");
var dropDown = new DropDown({
selectionMode: "single",
store: store,
renderRow: function(item) {
return domConstruct.create("div", {
innerHTML: item.name,
style: {
color: item.color
}
});
}
});
domConstruct.place(dropDown.domNode, "select");
dropDown.startup();
var open = false;
on(dom.byId("select"), ".button:click", function(e) {
open = !open;
domClass[open ? "add" : "remove"](dropDown.domNode, "opened");
});
});
});
You could use the editor plugin with a FilteringSelect. See: https://github.com/SitePen/dgrid/wiki/editor