I need to pass the data in the given format.
rules : [{
name:null,
section:null,
data : [{head:null,value:null}]
}],
This is the problem I am facing. Hope somebody could help me sort out a solution. The snippet is given. I need to pass data in the format given above. If another array is needed inside rules[], it is also fine
Is another array needed for head and value inside data[]. This will be also fine, if needed. Hoping for a help. Please help me to have a solution.
Please change the select to read the issues
addForm = new Vue({
el: "#addForm",
data: {
rules: [{
name: null,
section: null,
data: [{
head: null,
value: null
}]
}],
},
methods: {
addNewRules: function() {
this.rules.push({
name: null,
section: null,
data: [{
head: null,
value: null
}]
});
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<select class="form-control" v-model="bok.name">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.data[0].head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.data[0].head" multiple="">
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.data[0].head == 1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
</div>
<div class="row" v-if="bok.data[0].head == 2">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="">
</div>
</div>
</div>
</div>
<a @click="addNewRules">Add Another Rule</a>
</div>
Using Props To Share Data From Parent To Child # VueJS props are the simplest way to share data between components. Props are custom attributes that we can give to a component. Then, in our template, we can give those attributes values and — BAM — we're passing data from a parent to a child component!
Given a form input, V-model listens to any input events or updates on the view. It then updates the data model property with the new value. It also updates the view template if there is a change in the data model. This is called two-way data binding.
It provides two-way data binding by binding the input text element and the value binded to a variable assigned.
My approach is basically change the type of the data[0].head
and data[0].value
depending on the options you selected.
So for example, if you select Rule,2012
, then data[0].head
would be an object
with item
and qty
as its items. And if you select Act,1961
, data[0].head
would be an array
of numbers (e.g. ['1', '2']
) and data[0].value
would be an object
with area_1
and area_2
or number
and model
or all the four items.
See and try the code snippet to see the code I added/changed.
(Or compare your code with mine and you'd see the changes.)
addForm = new Vue({
el: "#addForm",
data: {
rules: [{
name: null,
section: null,
data: [{
head: null,
value: null
}]
}],
},
methods: {
addNewRules: function() {
this.rules.push({
name: null,
section: null,
data: [{
head: null,
value: null
}]
});
},
removeRuleDataValueProps: function(i) {
var d = this.rules[i].data[0];
if (jQuery.inArray('1', d.head) < 0) {
Vue.delete(d.value, 'area_1');
Vue.delete(d.value, 'area_2');
}
if (jQuery.inArray('2', d.head) < 0) {
Vue.delete(d.value, 'number');
Vue.delete(d.value, 'model');
}
},
_setRuleDataHeadDataType: function(i) {
var d = this.rules[i].data[0],
h = d.head,
_h = d._head,
_restore = true;
if (undefined === _h) {
d._head = h;
_restore = false;
}
switch (this.rules[i].name) {
case 'Rule,2012':
var a = Array.isArray(h);
if (a || null === h || 'object' !== typeof h) {
Vue.set(d, 'head', {});
}
break;
case 'Act,1961':
if (!Array.isArray(h)) {
Vue.set(d, 'head', []);
}
break;
default:
if (_restore && undefined !== _h) {
d.head = _h;
}
break;
}
},
_setRuleDataValueDataType: function(i) {
var d = this.rules[i].data[0],
v = d.value,
_v = d._value,
_restore = true;
if (undefined === _v) {
d._value = v;
_restore = false;
}
switch (this.rules[i].name) {
case 'Act,1972':
case 'Act,1961':
var a = Array.isArray(v);
if (a || null === v || 'object' !== typeof v) {
Vue.set(d, 'value', {});
}
if (_restore) {
this.removeRuleDataValueProps(i);
}
break;
default:
if (_restore && undefined !== _v) {
d.value = _v;
}
break;
}
},
setRuleDataType: function(i, k) {
if (this.rules[i] && this.rules[i].data[0]) {
if (!k || 'head' === k) {
this._setRuleDataHeadDataType(i);
}
if (!k || 'value' === k) {
this._setRuleDataValueDataType(i);
}
}
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<h3>Try the different options and see the JSON output changes.</h3>
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<!-- Here we change the type of `bok.data[0].head` depending on the selected option. -->
<select class="form-control" v-model="bok.name" @change="setRuleDataType(index)">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
<!--</div>-->
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<!-- Here, `bok.data[0].head` is expected to be a `string`. -->
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.data[0].head" @change="setRuleDataType(index, 'value')" required="">
</div>
</div>
</div>
<!-- Here, `bok.data[0].head` is an `object` with 'item' and 'qty'. -->
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.data[0].head.item" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.data[0].head.qty" required="">
</div>
</div>
</div>
<!-- Here, `bok.data[0].head` would be an array of numbers. -->
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.data[0].head" @change="removeRuleDataValueProps(index)" multiple="">
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="jQuery.inArray('1', bok.data[0].head) > -1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.area_1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.area_2">
</div>
</div>
</div>
<div class="row" v-if="jQuery.inArray('2', bok.data[0].head) > -1">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.number">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="" v-model="bok.data[0].value.model">
</div>
</div>
</div>
<h3>The JSON value of <code>bok</code></h3>
<textarea rows="3" cols="75%" readonly>{{ JSON.stringify(bok) }}</textarea>
</div>
<a @click="addNewRules">Add Another Rule</a>
</div>
My opinion,
Based on the HTML you provied, create one data property=ruleTemplate (it makes sure v-model with related form controls).
When add new rules, push one clone of the template to the rules
When you need the data, just convert the rules to the specific format like
this.getFormattedRules
in below demo.
Below is the demo:
addForm = new Vue({
el: "#addForm",
data: {
ruleTemplates: {
name: '',
section: '',
subMenu: {
'Act,1972': '',
'Rule,2012': {'item': '','qty': ''},
'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
}
},
rules: [{
name: '',
section: '',
subMenu: {
'Act,1972': '',
'Rule,2012': {'item': '','qty': ''},
'Act,1961': {'head':[], options:{'option1':'', 'option2':''}}
}
}
],
},
computed: {
formatedJson: function () {
let handler1972 = function (data) {
return [{'head': 'Arms', 'value': data}]
}
let handler2012 = function (data) {
return [{'head': 'item', 'value': data.item},{'head': 'qty', 'value': data.qty}]
}
let handler1961 = function (data) {
return [{'head': 'option1', 'value': data.options.option1},{'head': 'option1', 'value': data.options.option2}]
}
let handlers = {'Act,1972': handler1972, 'Rule,2012': handler2012, 'Act,1961': handler1961
}
return this.rules.map((rule) => {
let formatedRule = new Object()
// convert the rule to the specific format
formatedRule.name = rule.name
formatedRule.section = rule.section
handler = handlers[rule.name]
formatedRule.data = handler ? handler(rule.subMenu[rule.name]) : []
return formatedRule
})
}
},
methods: {
addNewRules: function() {
this.rules.push(Object.assign({},this.ruleTemplates))
}
}
})
.show-format {
position:absolute;
top:2px;
right -4px;
background-color:gray
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="addForm">
<div class="show-format">Format: {{formatedJson}}</div>
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<p>This is the first part which is fine for me</p>
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Act</label>
<select class="form-control" v-model="bok.name">
<option value="Act,1972">Act,1972</option>
<option value="Rule,2012">Rule,2012(CEMR)</option>
<option value="Act,1961">Act,1961</option>
</select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Section</label>
<input type="text" class="form-control" v-model="bok.section">
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1972'">
<p>When selecting Act,1972 is here rules.data.head. Fine for me</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms</label>
<input type="text" class="form-control" v-model="bok.subMenu['Act,1972']" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Rule,2012'">
<p>When Selecting Rule,2012 HOW TO PASS values rules.data.head in this case . There are two input fields here???</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Item</label>
<input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['item']" required="">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Quantity Seized</label>
<input type="text" class="form-control" v-model="bok.subMenu['Rule,2012']['qty']" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == 'Act,1961'">
<p>When selecting Act,1931 Its a select option, I need to select multiple options from here and pass values as rules.data.head. //After I select multiple options I have input fields corresponding to the options. This to be send as rules.data.value.. How
to do this?</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Select</label>
<select class=" form-control" v-model="bok.subMenu['Act,1961'].head" >
<option value="1">life</option>
<option value="2">Enment</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.subMenu['Act,1961'].head == 1">
<p>If option is 1, i should display this and pass value as rules.data.value . HERE THERE ARE TWO INPUT FIELDS How to pass the values</p>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area1</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Area2</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
</div>
</div>
</div>
<div class="row" v-if="bok.subMenu['Act,1961'].head == 2">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">No.</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option1">
</div>
</div>
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Model</label>
<input type="text" class="form-control" required="" v-model="bok.subMenu['Act,1961'].options.option2">
</div>
</div>
</div>
</div>
<a @click="addNewRules" style="background-color:green">Add Another Rule</a>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With