Hi I'm using the Adaptive card SDK in a web page, using a Sample Card like this:
var card = {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Present a form and submit it back to the originator"
},
{
"type": "Input.Text",
"id": "firstName",
"placeholder": "What is your first name?"
},
{
"type": "Input.Text",
"id": "lastName",
"placeholder": "What is your last name?"
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Action.Submit"
}
]};
and rendering using the usual rubric. I'd like to get the inputs back with the submit so I tried this
// Set the adaptive card's event handlers. onExecuteAction is invoked
// whenever an action is clicked in the card
adaptiveCard.onExecuteAction = function (action) { console.log(action.toJSON()) }
which just gives me:
Object title: "Action.Submit" type: "Action.Submit" __proto__: Object
How do I get the values of the input fields on the submit action?
TIA for any comments, advice and answers
You can use the data property of the action object just like this:
adaptiveCard.onExecuteAction = function (action) {
alert(`Hello ${action.data.firstName} ${action.data.lastName}`);
}
Here's a full jsfiddle.
There are many other interesting properties on the action object, but I haven't found good documentation.
However, the source code of the adaptive card visualizer contains some usage examples.
I have a table using DataTables , it contains a large number of rows and so this causes the page to load very slowly as i assume the browser waits till the table is filled before displaying the page.
I would like to only load one page of the table (10 rows), and only show further data when the user browses through the table, showing a loading sign would be great too.
I have researched and heard of a DataTables function called 'deferRender' which is supposed to do what i need, but i can't get it to work with my table.
My table has 8 columns + the html is generated using PHP that builds the table from data in a text file:
<?php
$tdcount = 1; $numtd = 8; // number of cells per row
$str = "<table id=\"table1\" class=\"table1 table table-striped table-bordered\">
<thead>
<th>1</th>
<th>2</th>
<th>3</th>
<th>4</th>
<th>5</th>
<th>6</th>
<th>7</th>
<th>8</th>
</thead>
<tbody>
";
$f = fopen("tabledata.txt", "r");
if ( $f === FALSE ) {
exit;
}
while (!feof($f)) {
$arrM = explode(",",fgets($f));
$row = current ( $arrM );
if ($tdcount == 1)
$str .= "<tr>"; $str .= "<td>$row </td>";
if ($tdcount == $numtd) {
$str .= "</tr>";
$tdcount = 1;
} else {
$tdcount++;
}
}
if ($tdcount!= 1) {
while ($tdcount <= $numtd) {
$str .= "<td> </td>"; $tdcount++;
} $str .= "</tr>";
}
$str .= "</tbody></table>";
echo $str;
I then use the following code to turn it into a datatable:
<script>
$(document).ready(function() {
$('#table1').basictable({
forceResponsive: false
});
$('#table1').DataTable( { "order": [[ 0, "desc" ]] } );
});
</script>
I have read the instructions here: https://datatables.net/examples/server_side/defer_loading.html
and know i need to add parameters to the JS:
"processing": true,
"serverSide": true,
"ajax": "scripts/server_processing.php",
"deferLoading": 57
and use a server_processing script, however the example only shows how to use it when connecting to a DB, and not when the data is loaded from a text file with php.
How can i acheive this?
This will focus purely on the DataTables aspects of a "server-side" solution. How you write the server-side logic needed to support it is out of scope for this answer. But I hope these notes will at leasst clarify what that logic needs to be, and how you can approach it.
Assumptions
Assume you have a text file containing 1,000 rows of data like this (or a million - but too many rows to send to the browser and to DataTables, all at once). The text file is a simple pipe-delimited file, with three fields:
id|name|description
1|widget_1|This is a description for widget 1
2|widget_2|This is a description for widget 2
3|widget_3|This is a description for widget 3
...
1000|widget_1000|This is a description for widget 1000
You want to send 10 items at a time to DataTables, using server-side processing.
Your data maps to a simple JSON structure, like this - an array of objects (each object is one record):
[
{
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
},
{
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
},
... // more records...
]
The DataTable Definition
Your datatable definition looks like this - it is deliberately very simple, at this stage:
<body>
<div style="margin: 20px;">
<table id="demo" class="display dataTable cell-border" style="width:100%">
</table>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#demo').DataTable({
serverSide: true,
ajax: {
url: 'http://localhost:7000/data',
type: 'POST'
},
columns: [
{ title: 'ID',
data: 'id' },
{ title: 'Name',
data: 'name' },
{ title: 'Description',
data: 'description' }
]
});
});
</script>
</body>
Initial Response
When the web page is first displayed, it will send an initial POST request to the URL (http://localhost:7000/data), and it will expect to receive a JSON response from the web server, containing the data to be displayed.
Because DataTables is using serverSide: true, DataTables will expect the JSON to have a specific structure, as described here.
Specifically, the server has to add all of the mandatory fields (draw, recordsTotal, recordsFiltered, and data) to the JSON it sends to DataTables.
In our case it would look like this - note that it is just our previously mentioned JSON structure, with a few extra metadata fields added:
{
"draw": 1,
"recordsTotal": 1000,
"recordsFiltered": 1000,
"data": [{
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
}, {
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
}, {
"id": 3,
"name": "widget_3",
"description": "This is a description for widget 3"
}, {
"id": 4,
"name": "widget_4",
"description": "This is a description for widget 4"
}, {
"id": 5,
"name": "widget_5",
"description": "This is a description for widget 5"
}, {
"id": 6,
"name": "widget_6",
"description": "This is a description for widget 6"
}, {
"id": 7,
"name": "widget_7",
"description": "This is a description for widget 7"
}, {
"id": 8,
"name": "widget_8",
"description": "This is a description for widget 8"
}, {
"id": 9,
"name": "widget_9",
"description": "This is a description for widget 9"
}, {
"id": 10,
"name": "widget_10",
"description": "This is a description for widget 10"
}]
}
It is the server's responsibility to build this JSON - the first 10 records of the server's data set. The server also tells DataTables that it has a total of 1,000 records, and that it has not filtered out any data (yet) - hence there are also a total of 1,000 records after filtering.
DataTables needs all of this information, so it knows how many pagination buttons to display, and what pagination data to show.
Note that it is entirely the server's responsibility to do all this work - that's why it's called "server-side" processing.
The client (browser) only has 10 records to render - so that happens quickly.
(I just noticed that the screenshot mentions "500 records" - that's a mistake in my server-side code - there is no filter, so I need to fix that).
Subsequent Requests
When a user clicks on a page navigation button (e.g. page "4"), that triggers a new request from DataTables to the server. DataTables builds this request automatically, using the fields described here.
The request is sent as form data.
In our example, the request looks like this:
"Form data": {
"draw": "5",
"columns[0][data]": "id",
"columns[0][name]": "",
"columns[0][searchable]": "true",
"columns[0][orderable]": "true",
"columns[0][search][value]": "",
"columns[0][search][regex]": "false",
"columns[1][data]": "name",
"columns[1][name]": "",
"columns[1][searchable]": "true",
"columns[1][orderable]": "true",
"columns[1][search][value]": "",
"columns[1][search][regex]": "false",
"columns[2][data]": "description",
"columns[2][name]": "",
"columns[2][searchable]": "true",
"columns[2][orderable]": "true",
"columns[2][search][value]": "",
"columns[2][search][regex]": "false",
"order[0][column]": "1",
"order[0][dir]": "asc",
"start": "30",
"length": "10",
"search[value]": "",
"search[regex]": "false"
}
These fields tell the server everything it needs to know, so it can prepare the correct response.
In our case the most important fields are these:
"start": "30",
"length": "10"
Start at row 30, and provide 10 records.
It is, again, the server's responsibility to prepare a JSON response which accurately reflects the requested data.
In our case this means the server needs to have logic to read through the text file to the correct starting point (data row 31 - remember the offset starts at zero), and 10 rows in total (rows 31 through 40).
Other fields in the above request from DataTables describe how the data is to be sorted, and filtered. In our case there is no filter "search[value]": "", - and the data is to be sorted by the first column in ascending order.
Final Notes
I have deliberately not described the following:
1) How your server-side code handles the creation of the JSON responses it sends back to DataTables;
2) How your server-side code parses the form requests it receives from DataTables.
That all depends entirely on what your server-side technology is. DataTables doesn't care. It's just passing JSON messages - it is decoupled from the server-side implementation - as it should be.
Regarding the "defer render" option described here, that is an enhancement you may choose to add if you feel you need it. But I would recommend getting a more basic server-side implementation working first.
Not particulary relavant to any language, but I used Node.js as an example to make a minimum working project for what's explained above:
The data: (put this at the root of where you have the working directory of node.js service)
[ { "id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
},{ "id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
},{ "id": 3,
"name": "widget_3",
"description": "This is a description for widget 3"
},{ "id": 4,
"name": "widget_4",
"description": "This is a description for widget 4"
},{ "id": 5,
"name": "widget_5",
"description": "This is a description for widget 5"
},{ "id": 6,
"name": "widget_6",
"description": "This is a description for widget 6"
},{ "id": 7,
"name": "widget_7",
"description": "This is a description for widget 7"
},{ "id": 8,
"name": "widget_8",
"description": "This is a description for widget 8"
},{ "id": 9,
"name": "widget_9",
"description": "This is a description for widget 9"
},{ "id": 10,
"name": "widget_10",
"description": "This is a description for widget 10"
},{ "id": 11,
"name": "widget_11",
"description": "This is a description for widget 11"
},{ "id": 12,
"name": "widget_12",
"description": "This is a description for widget 12"
},{ "id": 13,
"name": "widget_13",
"description": "This is a description for widget 13"
},{ "id": 14,
"name": "widget_14",
"description": "This is a description for widget 14"
},{ "id": 15,
"name": "widget_15",
"description": "This is a description for widget 15"
},{ "id": 16,
"name": "widget_16",
"description": "This is a description for widget 16"
},{ "id": 17,
"name": "widget_17",
"description": "This is a description for widget 17"
},{ "id": 18,
"name": "widget_18",
"description": "This is a description for widget 18"
},{ "id": 19,
"name": "widget_19",
"description": "This is a description for widget 19"
},{
"id": 20,
"name": "widget_20",
"description": "This is a description for widget 20"
}]
The HTML: (put this under your working directory/public)
<!DOCTYPE html>
<html>
<body>
</head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.13.1/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.js"></script>
</head>
<div style="margin: 20px;">
<div id = 'pageinfo' style='display:none'></div>
<table id="demo" class="display dataTable cell-border" style="width:100%"></table>
</div>
<script type="text/javascript">
$(document).ready(function() {
var table = $('#demo').DataTable({
serverSide: true,
ajax: {
url: 'http://localhost:3000/data',
data: $('#pageinfo').text(), //post pagination parameters to server
type: 'POST'
},
columns: [
{ title: 'ID',
data: 'id' },
{ title: 'Name',
data: 'name' },
{ title: 'Description',
data: 'description' }
],
lengthMenu: [5, 10, 20],
pageLength: 5
});
function getinfo(){
var info = table.page.info();
return info;
}
$('.dataTables_wrapper').on('click',function(e){
var info = table.page.info();
$('#pageinfo').text(JSON.stringify(info)) //get the pagination parameters
})
});
</script>
</body>
<html>
And the server:
const fs = require('fs');
const data = JSON.parse(fs.readFileSync("data.json", 'utf8'));
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
app.use('/static', express.static(__dirname + '/public')); //directory for static html docs
app.post('/data', function(req, res){
var resp = {"recordsTotal": 20,"recordsFiltered": 20,"start":0,"length":5}
if(req.body.start){
resp.draw = JSON.parse(req.body.draw);
resp.data = data.slice(JSON.parse(req.body.start),
JSON.parse(req.body.start)+JSON.parse(req.body.length));
}else{
resp.draw = 1;
resp.data = data.slice(resp.start,resp.start+resp.length);
}
res.end(JSON.stringify(resp))
})
app.listen(3000, function () {
console.log('listening on port 3000');
});
Then you'd be able to just start the server, and browse the result at http://localhost:3000/static/dtable.html
Read through these codes, or probably dig in to a few intermediate outputs, and you'll have a better idea of how DataTable works under a minimum setup for server-side processing.
So I'm trying to follow what I've found in the API and examples from the vue.js page but it doesn't seem to be working out.
I have this component
Vue.component('project', {
data: function () {
return {
title: "Sketch",
desc: "Zoe Beauty is an online store web application that sells different types of makeup from many brands in " +
"the market. It works with a nodeJs server and Handlebars templating to create the front end. The app is " +
"created under the slogan “Just Shine”, Most feedback in the app is elusive to this slogan and so is it's " +
"graphic style. The user can filter the items by many different things such as a type of product, brand, price, " +
"rating, etc. Also, they can add items to their cart.",
links: [{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}]
,
img: "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/projects%2Fzoe.png?alt=media&token=b0255dda-51f9-4958-8f7b-af978cc9b790"
}},
template: `
<div class="each-project">
<img src="https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/projects%2Fzoe.png?alt=media&token=b0255dda-51f9-4958-8f7b-af978cc9b790"
alt="" class="pic-project">
<h3 class="purple title-project">{{title}}</h3>
<p class="project-desc">{{desc}}</p>
<div class="links-container" v-for="link in links">
<a :href="link.link" class="link-container"><img
:src='link.logo' alt='link.key' class='link-img'></a>
</div>
</div>
`
});
The :src and :href in the v-for: link in links are not displaying anything, and when I inspect the element it is literally showing 'link.logo' instead of the actual link
how can I mix v-for and v-bind correctly?
first your array just contains 1 element, and that element was an object so just remove the []
links: {
"github": {
"link": "https://...",
"logo": "https://..."
},
"web": {
"link": "https://...",
"logo": "https://..."
}
}
look https://codepen.io/maoma87/pen/JaWQEq?editors=0010
Your links array contains only 1 element?
links: [{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}]
If it's, you can loop like this:
<div class="links-container" v-for="(linkValue, key) in links[0]">
<a :href="linkValue.link" class="link-container"><img
:src='linkValue.logo' alt='key' class='link-img'></a>
</div>
Your v-for should once read array one element.
Links object a element like this
{
"github": {
"link": "https://github.com/booleanaVillegas/juliana-villegas-taller-uno",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/github.svg?alt=media&token=83edf83c-cd80-43fa-bedd-a2348ff23b3e"
},
"web": {
"link": "https://enigmatic-shelf-33047.herokuapp.com/",
"logo": "https://firebasestorage.googleapis.com/v0/b/booleana-s-portafolio.appspot.com/o/web.svg?alt=media&token=b5e092a2-beb3-4c72-a329-8e402e82032f"
}
}
So your v-for like this
<div class="links-container" v-for="link in links">
<a :href="link.github.link" class="link-container">
<img :src='link.github.logo' alt='link.key' class='link-img'>
</a>
<a :href="link.web.link" class="link-container">
<img :src='link.web.logo' alt='link.key' class='link-img'>
</a>
</div>
I am creating online resume with a free template I downloaded.
This template uses bootstrap and displays a progress-bar of my skills.
But now I would like these skills to be changed dynamically using JSON.
I created my file :
var Skills = [
{
"title": "Skill 1",
"description": "Skill 1 description",
"value": 100
},
{
"title": "Skill 2",
"description": "Skill 2 description",
"value": 100
}];
So it's easy to display it but I would like to format it using the template.
This is an example from the template :
<div class="progress-item">
<span class="progress-title">Skill 1</span>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="62" aria-valuemin="0" aria-valuemax="100" style="width: 62%"><span class="progress-percent"> 62%</span>
</div>
</div>
</div>
How to do make title from JSON be linked to class="progress-title"
I did a fiddle : https://jsfiddle.net/de6f9qwo/37/
Thanks in advance for the help !
progress-bar preview
you asked very general question with many different answers,
but the answer to your problem with your open div is something like this :
var Skills = [
{
"title": "Skill 1",
"description": "Skill 1 description",
"value": 100
},
{
"title": "Skill 2",
"description": "Skill 2 description",
"value": 100
}];
$.each(Skills, function (title, val) {
var $div_item = $('<div class="progress-item"></div>');
$div_item.append("<span class='progress-title'>" + val.title + "</span>");
$('.progress-wrapper').append($div_item);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress-wrapper"></div>
but the real solution for templating is rather a good library like these
https://www.creativebloq.com/web-design/templating-engines-9134396
or read this JavaScript equivalent to printf/string.format to make a proper way of doing it manually.
I am building a website to help operator of my team to generate a data source config.
Since there are many options need to be handled. I design an common solution to render the page: parse a config file(maybe, xml or json format) to html with some rules. Maybe something like below:
{
"data_type": {
"title": "Data type",
"description": "Select what type do you want.",
"fields": [{
"title": "promotion",
"description": "data from promotion center"
"type": "redio",
"default": true,
"value": "p",
"name": "dtype"
}, {
"title": "brands",
"description": "data from brands center"
"type": "redio",
"default": false,
"value": "b",
"name": "dtype"
}]
}
}
then it can be parsed as:
<div class="form-control-group">
<h3>Data type</h3>
<p>Select what type do you want.</p>
<div class="form-control-filed">
<input type="redio" name="dtype" value="p" show="dtype" checked />
<p>data from promotion center</p>
</div>
<div class="form-control-filed">
<input type="redio" name="dtype" value="b" />
<p>data from brands center</p>
</div>
</div>
This step is easily to implement. But since there are some cases like. When I click redio A, I wanna hide the checkbox B. After I unchecked Checkbox C, I wanna show up the input D. I have no idea about how to design the config file to describe the logic about different fields.
So, the key point is, I wanna parse the html by a json snippet. Then maybe there are some symbols to mark the behavior of each form field, I can use my common js to bind events to handle the show/hide, focus/blur or something else logic. Like the attribute show, I can use my common js function to detect it and bind click event to that radio button, and show up the element with name="dtype" after this radio is clicked.
I am not sure if it is a good solution and how to design an reasonable json structure.
Hope any one can provide some suggestions. Thanks in advance.
I've given up for this case. For my requirement, I use a json file to config the information of the form field with a behavior definition to describe show/hide functionality.
{
"xxx": {
"title": "Price mode",
"description": "group_description",
"fields": [{
"title": "",
"type": "select",
"name": "price_mode",
"value": [{
"text": "Store with product",
"value": 1,
"default": true,
"behaviors": {
"show": "name1|name2|name3",
"hide": ""
}
}, {
"text": "Product",
"value": 2,
"default": false,
"behaviors": {
"show": "",
"hide": "name1|name2|name3"
}
}],
"require": true,
"rule": ""
}]
}
}
Codes of server side will parse this config and render as html snippet with special attribute storing behavior definition, then use javascript functions handle these attributes and care about the behavior after doing something like click the radio button or change the value of select list.