How do I create nested fieldsets with vue-form-generator?
Here is an example with a fieldset around the whole form. I would like to nest a fieldset to group skills and status within the main fieldset? I couldn't find anything in the documentation that explains this.
var vm = new Vue({
el: "#app",
components: {
"vue-form-generator": VueFormGenerator.component
},
data() {
return {
model: {
id: 1,
name: "John Doe",
password: "J0hnD03!x4",
age: 35,
skills: ["Javascript", "VueJS"],
email: "john.doe#gmail.com",
status: true
},
schema: {
groups: [{
legend: "User Details",
fields: [{
type: "input",
inputType: "text",
label: "ID",
model: "id",
readonly: true,
featured: false,
disabled: true
}, {
type: "input",
inputType: "text",
label: "Name",
model: "name",
readonly: false,
featured: true,
required: true,
disabled: false,
placeholder: "User's name",
validator: VueFormGenerator.validators.string
}, {
type: "input",
inputType: "password",
label: "Password",
model: "password",
min: 6,
required: true,
hint: "Minimum 6 characters",
validator: VueFormGenerator.validators.string
}, {
type: "input",
inputType: "number",
label: "Age",
model: "age",
min: 18,
validator: VueFormGenerator.validators.number
}, {
type: "input",
inputType: "email",
label: "E-mail",
model: "email",
placeholder: "User's e-mail address",
validator: VueFormGenerator.validators.email
}, {
type: "checklist",
label: "Skills",
model: "skills",
multi: true,
required: true,
multiSelect: true,
values: ["HTML5", "Javascript", "CSS3", "CoffeeScript", "AngularJS", "ReactJS", "VueJS"]
}, {
type: "switch",
label: "Status",
model: "status",
multi: true,
readonly: false,
featured: false,
disabled: false,
default: true,
textOn: "Active",
textOff: "Inactive"
}]
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
};
}
});
html {
font-family: Tahoma;
font-size: 14px;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
}
pre {
overflow: auto;
}
pre .string {
color: #885800;
}
pre .number {
color: blue;
}
pre .boolean {
color: magenta;
}
pre .null {
color: red;
}
pre .key {
color: green;
}
h1 {
text-align: center;
font-size: 36px;
margin-top: 20px;
margin-bottom: 10px;
font-weight: 500;
}
fieldset {
border: 0;
}
.panel {
margin-bottom: 20px;
background-color: #fff;
border: 1px solid transparent;
border-radius: 4px;
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
border-color: #ddd;
}
.panel-heading {
color: #333;
background-color: #f5f5f5;
border-color: #ddd;
padding: 10px 15px;
border-bottom: 1px solid transparent;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
.panel-body {
padding: 15px;
}
.field-checklist .wrapper {
width: 100%;
}
fieldset {
border: 1px groove #ddd !important;
}
<script src="https://unpkg.com/vue-form-generator#2.1.1/dist/vfg.js"></script>
<link href="https://unpkg.com/vue-form-generator#2.1.0/dist/vfg.css" rel="stylesheet" />
<script src="https://unpkg.com/vue#2.2.1/dist/vue.min.js"></script>
<h1 class="text-center">Demo of vue-form-generator</h1>
<div class="container" id="app">
<div class="panel panel-default">
<div class="panel-heading">Form</div>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</div>
</div>
Here is a simple html example
<fieldset>
<legend>User Details</legend>
<label for="">ID</label>
<input type="text">
<br><label for="">Name</label>
<input type="text">
<br><label for="">password</label>
<input type="password">
<br><label for="">Age</label>
<input type="text">
<br><label for="">Email</label>
<input type="text">
<fieldset>
<legend>User Special Detils</legend>
<br><label for="">Skills</label>
<input type="text">
<br><label for="">Status</label>
<input type="text">
</fieldset>
</fieldset>
EDIT:
I added the simple html demo above
If I'm understanding you correctly then you already have the ability to add a fieldset as you are structuring your schema. Using groups you get the different fieldset you are looking for. If you are looking for dynamic if/then you can use visible which is in the first model below. You can select the model and condition of when your field will show.
Each group is a new fieldset in the html.
This is an older question so I hope you figured this out already.
schema: {
groups: [{
legend: 'Entry',
{model: "enter", type: "radios", label: "Enter", values: ["Yes","No"]),
{model: "entryPrice", type: "input", inputType: "number", label: "Entry Price",
visible(model) {
return model && model.entryType != 'Yes';
}
}
legend: 'newGroup',
{model: "model", type: "text" , label: "Cool Label", inputType: "text"}
}
Related
Exactly as the title says, my overflow-x scrollbar is hidden at the bottom of the overflow y scrollbar. Is there anyway to fix this?
Right now the height and width are coming from the parent .wrapper div, but the overflow-x, while commented out, seems to be automatically set to scroll.
Any advice would be greatly appreciated!
Codesandbox
<template>
<div class="wrapper">
<vue-good-table
style="width: 100%"
class="issue-tracker-style"
:columns="columns"
:rows="rows"
:sort-options="{
enabled: false,
}"
>
<template v-slot:table-row="scope">
<div>
<div>{{ scope.formattedRow[scope.column.field] }}</div>
</div>
</template>
</vue-good-table>
</div>
</template>
<script>
export default {
name: "my-component",
mounted: function () {
let tdElm;
let startOffset;
Array.prototype.forEach.call(
document.querySelectorAll("table th"),
function (td) {
td.style.position = "relative";
//td.style.maxWidth = "unset";
let grip = document.createElement("div");
grip.innerHTML = " ";
grip.style.position = "absolute";
grip.style.top = 0;
grip.style.right = 0;
grip.style.bottom = 0;
grip.style.width = "5px";
// grip.style.background = "red";
grip.style.cursor = "col-resize";
grip.addEventListener("mousedown", function (e) {
tdElm = td;
startOffset = td.offsetWidth - e.pageX;
});
td.appendChild(grip);
}
);
document.addEventListener("mousemove", function (e) {
if (tdElm) {
tdElm.style.minWidth = startOffset + e.pageX + "px";
}
});
document.addEventListener("mouseup", function () {
tdElm = undefined;
});
},
data() {
return {
columns: [
{
label: "Name",
field: "name",
//width: "100px"
},
{
label: "Age",
field: "age",
type: "number",
},
{
label: "Created On",
field: "createdAt",
dateInputFormat: "yyyy-MM-dd",
dateOutputFormat: "MMM do yy",
},
{
label: "Percent",
field: "score",
type: "percentage",
},
{
label: "Name",
field: "name",
},
{
label: "Age",
field: "age",
type: "number",
},
{
label: "Created On",
field: "createdAt",
dateInputFormat: "yyyy-MM-dd",
dateOutputFormat: "MMM do yy",
},
{
label: "Percent",
field: "score",
type: "percentage",
},
{
label: "Name",
field: "name",
},
{
label: "Age",
field: "age",
type: "number",
},
{
label: "Created On",
field: "createdAt",
dateInputFormat: "yyyy-MM-dd",
dateOutputFormat: "MMM do yy",
},
{
label: "Percent",
field: "score",
type: "percentage",
},
],
rows: [
{ id: 1, name: "John", age: 20, createdAt: "", score: 0.03343 },
{
id: 2,
name: "Jane Jacob Johnson OOOO",
age: 24,
createdAt: "2011-10-31",
score: 0.03343,
},
{
id: 3,
name: "Susan",
age: 16,
createdAt: "2011-10-30",
score: 0.03343,
},
{
id: 4,
name: "Chris",
age: 55,
createdAt: "2011-10-11",
score: 0.03343,
},
{
id: 5,
name: "Dan",
age: 40,
createdAt: "2011-10-21",
score: 0.03343,
},
{
id: 6,
name: "John",
age: 20,
createdAt: "2011-10-31",
score: 0.03343,
},
{
id: 3,
name: "Susan",
age: 16,
createdAt: "2011-10-30",
score: 0.03343,
},
{
id: 4,
name: "Chris",
age: 55,
createdAt: "2011-10-11",
score: 0.03343,
},
{
id: 5,
name: "Dan",
age: 40,
createdAt: "2011-10-21",
score: 0.03343,
},
{
id: 6,
name: "John",
age: 20,
createdAt: "2011-10-31",
score: 0.03343,
},
],
};
},
};
</script>
<style lang="scss">
.wrapper {
border: 1px solid red;
width: 400px;
height: 200px;
overflow-y: scroll;
/* overflow-x: scroll; */
}
body {
display: flex;
justify-content: center;
margin-top: 5rem;
}
.issue-tracker-style {
font-family: "Inter";
width: 100%;
.vgt-inner-wrap {
box-shadow: none;
}
td > div {
position: relative;
width: 100%;
height: 100%;
}
td > div > div {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
}
thead {
border: 1px solid #f0f7ff;
}
tr {
background: white;
margin: 0;
height: 32px; // height works like min-height apparently https://stackoverflow.com/questions/19432092/can-i-use-a-min-height-for-table-tr-or-td/37115413
}
td {
min-width: 70px;
overflow: hidden;
white-space: nowrap;
-moz-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
}
tr th {
color: #4859af;
font-weight: 600;
height: 100%;
vertical-align: middle;
padding: 0.5rem 0;
font-size: 13px;
background: #fafafa;
border: 2px solid #efeff0;
text-align: center;
overflow: hidden;
white-space: nowrap;
-moz-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
}
tr td {
padding: 0;
font-size: 13px;
color: #4859af;
background: white;
border: 2px solid #efeff0;
height: 42px;
vertical-align: middle;
}
tr td,
tr th {
text-align: center;
}
/*tr th {
width: 60px !important;
}*/
}
</style>
this css should fix the problem
.wrapper {
border: 1px solid red;
width: 400px;
height: 200px;
overflow: scroll;
}
.vgt-responsive {
overflow: visible!important;
}
The scrollbar hidden at the bottom comes from the .vgt-responsive class.
I am a complete beginner in JS, please help me. How can I create and populate a similar array in JS? Not through const should be done obviously?
const questions = [
{
questionText: 'What is the capital of France?',
answerOptions: [
{ answerText: 'New York', isCorrect: false },
{ answerText: 'London', isCorrect: false },
{ answerText: 'Paris', isCorrect: true },
{ answerText: 'Dublin', isCorrect: false },
],
},
{
questionText: 'Who is CEO of Tesla?',
answerOptions: [
{ answerText: 'Jeff Bezos', isCorrect: false },
{ answerText: 'Elon Musk', isCorrect: true },
{ answerText: 'Bill Gates', isCorrect: false },
{ answerText: 'Tony Stark', isCorrect: false },
],
}
];
Here you go buddy. Make sure you get the questions and answers in the right json format. and console.log them a few times to check how you can access the data inside the json. Once that is clear you can use these classes and the for loops below to get what you want.
Those who have a problem with this answer let me know in the comments.
Edited: I MADE THE NECESSARY CHANGES. You can add a plus button to add more options
class Question {
constructor(question, answers) {
this.question = question;
this.answers = answers;
}
}
class Answer {
constructor(answer, isCorrect) {
this.answer = answer;
this.isCorrect = isCorrect;
}
}
function GetData() {
var question = document.querySelector('#question').value;
var options = document.querySelectorAll('.option');
var checkboxes = document.querySelectorAll('.checkbox');
var result = [];
var answerslist = [];
for (var j = 0; j < options.length; j++) {
const A = new Answer(options[j].value, checkboxes[j].checked)
answerslist.push(A);
}
const Q = new Question(question, answerslist);
result.push(Q);
console.log(result);
}
body {
box-sizing: border-box;
overflow-x: hidden;
font-size: 62.5%;
padding: 5rem;
}
.Inputarea {
width: 70%;
margin: auto;
height: auto;
background-color: gainsboro;
padding: 2rem;
}
input[type="text"] {
width: 60%;
margin: 1rem auto;
border-radius: 0.3rem;
border: none;
}
input[type="text"] :focus {
border: 2px solid mediumpurple;
}
input::placeholder {
color: mediumpurple;
}
button {
width: 30%;
margin: 1rem 15%;
background-color: white;
font-size: 1rem;
color: blueviolet;
border-radius: 0.5rem;
padding: 0.5rem;
font-weight: bolder;
border: none;
}
button:hover {
background-color: blueviolet;
color: white;
transition: all 0.3s ease-in;
}
input[type="checkbox"] {
margin: 1rem 3rem;
}
<div class="Inputarea">
<input id="question" type="text" placeholder="Enter Question">
<input class="option" type="text" placeholder="Enter Option1">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option2">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option3">
<input class="checkbox" type="checkbox">
<input class="option" type="text" placeholder="Enter Option4">
<input class="checkbox" type="checkbox">
<button onclick="return GetData();">Submit</button>
</div>
I have defined component as below:
<template>
<div>
<span style="font-size: 16px">{{label}}</span>
<!-- <label style="font-size: 15px">{{ label }}</label> -->
<input
:class="{input:isSuccess, input_danger:isDanger, input_disabled:isDisabled}"
:style="{width:width}"
:id="id"
:type="type"
:max="max"
:min="min"
:state="state"
:placeholder="placeholder"
:disabled="disabled"
:value="value"
#input="handleInput"
#change="change"
/>
</div>
</template>
<script>
import TransformationVue from '../../pages/Transformation.vue';
export default {
props: {
value: [Number, String],
id: String,
label: String,
min: Number,
max: Number,
type: String,
state: Boolean,
placeholder: [Number, String],
isDanger:{
type:Boolean,
default:false
},
disabled:{
type:Boolean,
default:false
},
width:{
type:String,
default:'100%'
}
},
data() {
return {
minVal:this.min,
};
},
watch:{
disabled:function(){
alert('hello')
}
},
computed:{
isSuccess:function(){
if(this.isDanger == false && this.disabled == false ){
return true
}else {
return false
}
},
isDisabled:function(){
if(this.disabled ==true){
return true
}else{
return false
}
}
},
methods: {
handleInput(e) {
this.$emit("input", e.target.value);
},
change(e) {
if(this.type == 'number'){
if(e.target.value<this.min || e.target.value > this.max){
this.$emit("input", this.minVal)
this.$toast.error("Out of range!, Allowed range is "+this.min+" to" + this.max, { timeout: 6000 });
}else{
this.$emit("change")
}
}else{
this.$emit("change");
}
},
},
};
</script>
<style scoped>
.input {
font-size: 14px;
height: 40px;
border: 1px solid white;
border-radius: 4px;
border-bottom:4px solid #116b9d;
}
.input:hover {
border-bottom:4px solid #93d9ff;
background:rgb(255, 255, 255);
transition: none;
}
.input:focus {
border-bottom:4px solid #93d9ff;
background:rgb(255, 255, 255);
transition: none;
}
.input_danger {
font-size: 14px;
height: 40px;
border: 1px solid white;
border-radius: 4px;
border-bottom:4px solid rgb(255, 180, 180);
}
.input_disabled {
font-size: 14px;
height: 40px;
border: 1px solid white;
border-radius: 4px;
border-bottom:4px solid rgb(177, 177, 177);
}
.input_disabled:focus {
font-size: 14px;
height: 40px;
border: 1px solid white;
border-radius: 4px;
border-bottom:4px solid rgb(177, 177, 177);
}
</style>
in the vue page I have used the component as below:
<template>
<aboveComponent
id='el'
#change="func"
:disabled="true"
/>
</template>
<script>
methods(){
func(){
document.getElementbyID('el').disabled = false
}
</script>
When I directly use the disabled as true or false the component style is updating,
but when I change the disabled property using document.getElementById the disable functionality is working but the components style is not updating.
I'm using a kendo grid and I want to implement an action bar when a user hover the row. I found the example solution. But I'm looking for showing the tooltips at the end of the row instead of the current hover column. So how can I get the last column that user currently stop at?
Add a :last-child to the filter property:
filter: "tbody td:last-child",
Demo:
<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/grid/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.2.513/styles/kendo.default-v2.min.css" />
<script src="https://kendo.cdn.telerik.com/2020.2.513/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.513/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div id="grid"></div>
<script>
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers"
},
pageSize: 20
},
height: 550,
groupable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [{
template: "<div class='customer-photo'" +
"style='background-image: url(../content/web/Customers/#:data.CustomerID#.jpg);'></div>" +
"<div class='customer-name'>#: ContactName #</div>",
field: "ContactName",
title: "Contact Name",
width: 500
}, {
field: "ContactTitle",
title: "Contact Title",
width: 300
}, {
field: "CompanyName",
title: "Company Name",
width: 300
}, {
field: "Country",
width: 300
}]
});
});
$("#grid").kendoTooltip({
position: "right",
callout: false,
filter: "tbody td:last-child",
content: function(e) {
return "<button class='k-button' ><span class='k-icon k-i-trash'></span></button> <button class='k-button'><span class='k-icon k-i-email'></span></button> <button class='k-button'><span class='k-icon k-i-warning'></span></button>";
}
});
</script>
</div>
<style type="text/css">
.customer-photo {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
background-size: 32px 35px;
background-position: center center;
vertical-align: middle;
line-height: 32px;
box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2);
margin-left: 5px;
}
.customer-name {
display: inline-block;
vertical-align: middle;
line-height: 32px;
padding-left: 3px;
}
</style>
</body>
</html>
Dojo
Continuation of what I thought was resolved a couple of months ago:
A new datatable is rendered each time when called in Ajax response [Highcharts]
$(function() {
Highcharts.setOptions({
lang: {
exportData: {
categoryHeader: 'Vulnerability'
}
}
});
$('#container').highcharts({
chart: {
//plotBackgroundColor: null,
//plotBorderWidth: null,
//plotShadow: false,
evsents: {
load: Highcharts.drawTable
},
height: 400,
width: 800,
//marginBottom: 250
},
title: {
text: undefined
},
credits: {
enabled: false
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
showInLegend: true,
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
verticalAlign: 'top',
enabled: true,
color: '#000000',
connectorWidth: 1,
distance: -50,
connectorColor: '#000000',
format: '<br>{point.percentage:.1f} %<br>Count: {point.y}'
}
}
},
exporting: {
showTable: true,
tableCaption: false
},
series: [{
type: 'pie',
name: 'Counts',
data: [{
y: 4,
name: 'high',
}, {
y: 8,
name: 'medium',
}, {
y: 2,
name: 'low'
}]
}]
});
});
.highcharts-data-table table {
font-family: Verdana, sans-serif;
border-collapse: collapse;
border: 1px solid #EBEBEB;
margin: 10px auto;
text-align: center;
position: absolute;
top: 200px;
left: 20px;
}
.highcharts-data-table caption {
padding: 1em 0;
font-size: 1.2em;
color: #555;
}
.highcharts-data-table th {
font-weight: 600;
padding: 0.5em;
}
.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption {
padding: 0.5em;
}
.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) {
background: #f8f8f8;
}
.highcharts-data-table tr:hover {
background: #f1f7ff;
}
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
Overview:
I have a condition where I need to update highcharts datatable every time when the change event is triggered.
http://jsfiddle.net/BlackLabel/s7m0tvpy/
This was working perfectly before in which clicking the update button changes 4,8,2 to 0,0,1.
But quite recently, this is not working.
Is it something that update function has been modified?
Any help would be appreciated.
This issue was due to
https://github.com/highcharts/highcharts/issues/14320
However, it still works in 8.1.2 version.
<script src="https://code.highcharts.com/8.1.2/highcharts.js"></script>
<script src="https://code.highcharts.com/8.1.2/modules/exporting.js"></script>
<script src="https://code.highcharts.com/8.1.2/modules/export-data.js"></script>