How can I render a form with form.io using vanilla JS? - formio

I am playing with the form.io demo on CodePen, but it uses Angular. Assuming I have a basic JSON form and an html page not tied to any framework, what is the simplest way to render the form, initializing the form with an optional model, and collecting the model once the form is submitted?
Is there a form.io JavaScript library that does such a thing?
Example form.io JSON form snippet:
{
components: [
{
input: true,
tableView: true,
inputType: "text",
inputMask: "",
label: "First Name",
key: "firstName",

The formio developers provide formio.js for this specific use case. Here is the link

as per their own documentation:
in your index:
<link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="./node_modules/formiojs/dist/formio.form.min.css" />
<script src="node_modules/formiojs/dist/formio.form.min.js"></script>
<div id="formID" class="demo-box">Loading...</div>
then in your js:
let schema = {
components: [
{
input: true,
tableView: true,
inputType: "text",
inputMask: "",
label: "First Name",
key: "firstName"
}]
}
let data = {}
let formio = new Formio.createForm(document.getElementById('formID'), schema, data)
i recommend using this site to build your schema: https://formio.github.io/formio.js/app/sandbox

Related

How can I generate pages in Assemble based on an different json files?

So I have a folder rules that that looks like this:
rule-001.json
rule-002.json
rule-003.json
Each *.json file is of a unified format:
{ name: 'AAA', descriptions: 'BBB' }
How can I generate a pages based on these files in Assemble?
The short answer is that you need to load your JSON data in your Gruntfile and use it to replace the Assemble pages object.
I have written a blog post about generating pages from data, based on the Assemble Blog Theme sample. In both cases, the pages data was stored in a single JSON file.
In your case, you need to load the data from all of JSON files in your Gruntfile, and transform the data into the pages format. You can do this any number of ways, but one simple way would be to write a function in your Gruntfile that does this:
function loadDataPages (jsonFileSpec) {
var path = require("path");
var jsonPaths = grunt.file.expand(jsonFileSpec);
var jsonPages = jsonPaths.map(function (jsonPath) {
var jsonData = grunt.file.readJSON(jsonPath);
var outputFileName = path.basename(jsonPath, path.extname(jsonPath)) + ".html";
var jsonPage = {
"data": jsonData,
"content": "This is the body content for page " + outputFileName,
"filename": outputFileName
};
return jsonPage;
});
return jsonPages;
}
and then you need to load this data object in your Grunt config and pass it to Assemble's pages option:
grunt.initConfig({
assemble: {
data: {
options: {
flatten: true,
layout: "source/templates/layouts/custom-data-layout.hbs",
pages: loadDataPages("source/custom-data/*.json")
},
files: {
"output/custom-data-pages/": ["source/custom-data/index.hbs"]
}
}
}
// ...
});
Here is what the layouts might look like:
custom-data-layout.hbs
<!DOCTYPE html>
<html>
<head>
<title>Custom Data - {{name}}</title>
</head>
<body>
<h1>Custom Data - {{name}}</h1>
<p>{{ description }}</p>
{{> body }}
</body>
</html>
index.hbs
---
layout: false
title: Custom Data Index
---
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each pages }}
<li>{{basename}}</li>
{{/each}}
</ul>
</body>
</html>
Something like this should work for you. You just create separate Assemble tasks and call the main Assemble task with grunt.
https://gist.github.com/davidwickman/a0bf961e3099ea6b9c35

Custom Transition for sap.m.App

I want to write a custom transition for sap.m.Page transitions.
How Do I start off with this?
Exactly I want to know regarding any documentation, How to create a custom transition and register the same so that it can be used in an SAP UI5 Application.
Thanks in Advance
A Sample implementation of custom transition when App navigates. Click on the list item to find the transition. There is no documentaion on it. This is just a hack.
jQuery.sap.require('sap.m.NavContainer');
jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-core');
jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-ui-effect')
jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-effects-core');
jQuery.sap.require('sap.ui.thirdparty.jqueryui.jquery-effects-clip');
sap.m.NavContainer.transitions["custom"] = {
to: function(oFromPage, oToPage, fCallback) {
window.setTimeout(function(){
oFromPage.$().toggle("clip");
oToPage.$().toggle("clip");
fCallback();
},600);
},
back: function(oFromPage, oToPage, fCallback) {
window.setTimeout(function(){
debugger;
oFromPage.$().toggle("clip");
oToPage.$().toggle("clip");
fCallback();
},600);
}
};/* code for transition */
var data = {
names: [
{firstName: "Peter", lastName: "Mueller"},
{firstName: "Petra", lastName: "Maier"},
{firstName: "Thomas", lastName: "Smith"},
{firstName: "John", lastName: "Williams"},
{firstName: "Maria", lastName: "Jones"}
]
};
// create a Model with this data
var model = new sap.ui.model.json.JSONModel();
model.setData(data);
var list = new sap.m.List({
headerText:"Names"
});
list.bindItems({
path : "/names",
sorter : new sap.ui.model.Sorter("lastName"),
template : new sap.m.StandardListItem({
title: "{lastName}",
description: "{firstName}",
type: sap.m.ListType.Navigation,
press:function(evt){
var oBindingContext = evt.getSource().getBindingContext();
page2.setBindingContext(oBindingContext);
app.to("page2","custom");
}
})
});
// create the page holding the List
var page1 = new sap.m.Page("page1",{
title: "List Page",
content : list
});
// create the detail page
var page2 = new sap.m.Page("page2", {
title: "Detail Page",
showNavButton: true,
navButtonPress: function(){
app.back();
},
content : [
new sap.ui.layout.form.SimpleForm({
title: "Details for {firstName} {lastName}",
content: [
new sap.m.Label({text: "First Name"}),
new sap.m.Text({text: "{firstName}"}),
new sap.m.Label({text: "Last Name"}),
new sap.m.Text({text: "{lastName}"})
]
})
]
});
// create a mobile App holding the pages and place the App into the HTML document
var app = new sap.m.App({
pages: [page1, page2]
}).placeAt("content");
// set the model to the App; it will be propagated to the children
app.setModel(model);
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<title>Custom jQuery transition</title>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m,sap.ui.layout"
data-sap-ui-xx-bindingSyntax="complex"
data-sap-ui-theme="sap_bluecrystal"></script>
</head>
<body id="content" class="sapUiBody">
</body>
</html>

Bind results of client side calculations to control (e.g. chart)

If the source for my chart in SAP UI5 is not a model loaded from a server or file, but the result of some calculations (groupings/maths) based on an existing model, how do I correctly bind it to the chart control and use the data?
You first create the outcome of the calculation. Then you transfer it in a new JSON model and use the setData function to pass the results.
Then you bind the control to the new JSON model. I try to make up some dummy code probably located in your controller:
var data = modelWithRawData.getData();
calculationOutput = doComplicatedCalculation(data);
var calculationModel = new sap.ui.model.json.JSONModel(calculationOutput)
myView.setModel(calculationModel, "calculationModel");
And in the path of your bindings you now need to reference the modelName. Eg in an xmlView:
<Chart data="{calculationModel>/PathToRelevantData}">
<!-- more xml -->
Here's a working example using the sap.viz library:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8' />
<script src="resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons,sap.ui.layout,sap.ui.ux3,sap.ui.table,sap.m,sap.viz"
data-sap-ui-theme="sap_goldreflection">
</script>
<script>
var oModel = new sap.ui.model.json.JSONModel({
businessData : [
{text: "A", value: 100},
{text: "B", value: 200},
{text: "C", value: 300}
]
});
//DO SOME ADVANCE CALCULATION WITH THE JSON DATA...
var data = oModel.getData();
data.businessData[0].value += 30;
data.businessData[1].value = data.businessData[1].value * 2;
data.businessData[2].value = data.businessData[2].value - 100;
//END OF SOME ADVANCE CALCULATION WITH THE JSON DATA...
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions : [{axis : 1, name : 'Text', value : "{text}"}],
measures : [{name : 'Value', value : '{value}'},
],
data : {path : "/businessData"}
});
var oBarChart = new sap.viz.ui5.Bar({
title : {
visible : true,
text : 'My bar chart'
},
dataset : oDataset
});
// attach the model to the chart and display it
oBarChart.setModel(oModel);
oBarChart.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
Hope this helps.

KendoUI: Unable to bind data to HTML elements from JSON file.

I am new to kendo ui and mvvm, and I'm facing this issue:
I'm having a JSON file in the follow format:
[
{
"Id":1,
"img":"shoes.png"},
{"Id":2,
"img":"books.png"}
}
]
I am reading the file using the sample mentioned online by kendo guys as follows:
var crudServiceBaseUrl = "pro.json";
var viewModel = kendo.observable({
productsSource: new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl,
dataType: "json"
},
update: {
url: crudServiceBaseUrl,
dataType: "json"
},
destroy: {
url: crudServiceBaseUrl,
dataType: "json"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {
models: kendo.stringify(options.models)
};
}
return options;
}
},
batch: true,
schema: {
model: {
id: "Id"
}
}
})
});
kendo.bind($("#form-container"), viewModel);
I am able to bind the data from the data source to a Kendo Control such as a dropdownlist or some other Kendo Control. But when I try binding the data to an HTML Control (mostly an img tag). It stops working and gives an error saying "this.parent" is not a function.
following is the HTML which works:
Select Product: <select data-role="dropdownlist" data-value-field="Id" data-text-field="img"
data-bind="source: productsSource"></select>
However binding to a normal <img> tag does not work. In short I need to bind images based on src value to a div using kendo ui mvvm.
Kindly help me out. Thanks!!
-
Hardik
Currently Kendo MVVM cannot bind a data source to an HTML element. Only Kendo UI widgets can be bound to a kendo.data.DataSource. Using a widget e.g. the ListView would work for a DIV:
<div data-role="listview"
data-template="template"
data-bind="source: productsSource">
</div>
<script id="template" type="text/x-kendo-template">
<img data-bind="attr: { src: img }" />
</script>

How to get select's value in jqGrid when using <select> editoptions on a column

I have a couple of columns in jqGrid with edittype="select". How can I read the option value of the value currently selected in a particular row?
e.g.: When I provide the following option, how do I get "FE" for FedEx, etc.
editoption: { value: “FE:FedEx; IN:InTime; TN:TNT” }
getRowData() for the rowId/cellname returns only the text/displayed component of the select.
If I set a "change" data event on the column, the underlying fires change events only on mouse clicks, and not keyboard selects (there's numerous references to generic selects and mouse/keyboard issues).
Bottomline, when a new value is selected, I need to know the option value at the time of the change, and also prior to posting to the server.
You have to set the formatter of the column to 'select'
Example from the wiki:
colModel : [ {name:'myname',
edittype:'select', formatter:'select',
editoptions:{value:"1:One;2:Two"}} ...
]
See more here jqgridwiki
I was having the same problem and this worked like a charm
I just solved this question by using setting JqGrid unformat option and use the following function for unformatting cell value.
function Unformat_Select(cellvalue, options, cellobject)
{
var unformatValue = '';
$.each(options.colModel.editoptions.value, function (k, value)
{
if (cellvalue == value)
{
unformatValue = k;
}
});
return unformatValue;
}
The above method will be called everytime when grid need cell data like when you call "getRowData" method. However, my function only support key-paired value edit option. You need to change your data like the following pattern.
editoption:
{
value:
{
FE:'FedEx',
IN:'InTime',
TN:'TNT'
}
}
For more information about unformat option, you can see at the following link.
JqGrid Wiki - Custom Formatter
PS. It's possible to modify my function to support client-side dropdownlist value. But I think it's impossible to apply this function for server-side dropdownlist value.
Update
In the latest jqGrid 3.8.1, I just found some bug when user cancel editing row(or programmatically call "restoreRow" method), jqGrid will create label by using key of data (instead of value of data). I create the following function to fix this issue. For use this, you must it as custom formatter function of this column. This function maps cell value to value of list by comparing key or value.
function JqGridInlineEditor_SelectFormatter(cellvalue, options, rowObject)
{
var temp = '';
$.each(options.colModel.editoptions.value, function (key, value)
{
if (cellvalue == key || cellvalue == value)
{
temp = value;
return false;
}
});
return temp;
}
So, you can send key or value as column data to be rendered by the above custom formatter.
If in case you have requirement where each row has dropdown and it has values like
FE:'FedEx',
IN:'InTime',
TN:'TNT'
Now instead of saving the data to backend on dropdown change event;you want to save data on "Save" button click at row level but want to save dropdwon selected value (TN) not display text(TNT). You can create another hidden field to set selected country code on inline editing of dropdown. Here when user exit after cell inline editing afterSaveCell method will be called and you can set it as mentioned in below code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>http://stackoverflow.com/q/9655426/315935</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/redmond/jquery-ui.css" />
<link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/css/ui.jqgrid.css" />
<style type="text/css">
html, body { font-size: 75%; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/js/i18n/grid.locale-en.js"></script>
<script type="text/javascript">
$.jgrid.no_legacy_api = true;
$.jgrid.useJSON = true;
</script>
<script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.3.1/js/jquery.jqGrid.src.js"></script>
<script type="text/javascript">
//<![CDATA[
/*global $ */
/*jslint devel: true, browser: true, plusplus: true, nomen: true, unparam: true */
$(document).ready(function () {
'use strict';
var listOptions = "CN:Canada; US:United States; FR:France; IN:India";
var mydata = [{
name: "Toronto",
country: "CN",
continent: "North America",
countrycode: "CN"
}, {
name: "New York City",
country: "US",
continent: "North America",
countrycode: "US"
}, {
name: "Silicon Valley",
country: "US",
continent: "North America",
countrycode: "US"
}, {
name: "Paris",
country: "FR",
continent: "Europe",
countrycode: "FR"
}, {
name: "Pune",
country: "IN",
continent: "Asia",
countrycode: "IN"
}]
$("#gvManageMapping").jqGrid({
data: mydata,
datatype: "local",
colNames: ["Name", "Country", "Continent", "countrycode"],
colModel: [{
name: 'name',
index: 'name',
editable: false,
},
{
name: 'country',
index: 'country',
editable: true, edittype: "select", formatter: 'select', editoptions: {
value: listOptions,
}, editrules: { required: true, integer: false }, formatter: "select"
},
{
name: 'continent',
index: 'continent',
editable: false,
},
{
name: 'countrycode',
index: 'countrycode',
editable: false
}],
afterSaveCell: function (rowid, cellname, value) {
var selectedCountryCode, $this;
if (cellname === 'country') {
$this = $(this);
selectedCountryCode = $this.jqGrid("getCell", rowid, 'country');
$this.jqGrid("setCell", rowid, 'countrycode', selectedCountryCode);
}
},
pager: '#pager',
'cellEdit': true,
'cellsubmit': 'clientArray',
editurl: 'clientArray'
});
});
//]]>
</script>
</head>
<body>
<table id="gvManageMapping"><tr><td /></tr></table>
<div id="pager"></div>
</body>
</html>
The documentation for getRowData states:
Do not use this method when you editing the row or cell. This will return the cell content and not the actuall value of the input element
Is the row still being edited when you call getRowData()?
Update
Agreed, jqGrid does not handle <select> very well. In my application I actually was able to get around this by not specifying an edit option (meaning, key/value were both "FedEx"); the translation to ID is then done on the server. This is not the right way to code this, but it worked well enough for my needs at the time.