i want multiple text inputs that when i change one of them i want others to change with the same value too . my inputs are generating in a loop of v-for like below :
<tbody>
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="index" "></variant-item>
</tbody>
and here the input is getting generated :
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
<input type="number" v-model="variant.price" :name="[variantInputName + '[price]']" />
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">#{{ errors.first(variantInputName + '[price]') }}</span></div>
</td>
so with this code if i have 2 products for example the result would be like below :
<td><div class="control-group"><input type="number" name="variants[4344][price]" data-vv-as=""price"" step="any" class="control"> <!----></div></td>
.
.
.
.
<td><div class="control-group"><input type="number" name="variants[4345][price]" data-vv-as=""[price"" > <!----></div></td>
now I want this 2 or multiple inputs change together .
#section('css')
#parent
<style>
.table th.price, .table th.weight {
width: 100px;
}
.table th.actions {
width: 85px;
}
.table td.actions .icon {
margin-top: 8px;
}
.table td.actions .icon.pencil-lg-icon {
margin-right: 10px;
}
</style>
#stop
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.before', ['product' => $product]) !!}
<accordian :title="'{{ __('admin::app.catalog.products.variations') }}'" :active="true">
<div slot="body">
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.before', ['product' => $product]) !!}
<button type="button" class="btn btn-md btn-primary" #click="showModal('addVariant')">
{{ __('admin::app.catalog.products.add-variant-btn-title') }}
</button>
<variant-list></variant-list>
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.controls.after', ['product' => $product]) !!}
</div>
</accordian>
{!! view_render_event('bagisto.admin.catalog.product.edit_form_accordian.variations.after', ['product' => $product]) !!}
<modal id="addVariant" :is-open="modalIds.addVariant">
<h3 slot="header">{{ __('admin::app.catalog.products.add-variant-title') }}</h3>
<div slot="body">
<variant-form></variant-form>
</div>
</modal>
#push('scripts')
#parent
<script type="text/x-template" id="variant-form-template">
<form method="POST" action="{{ route('admin.catalog.products.store') }}" data-vv-scope="add-variant-form" #submit.prevent="addVariant('add-variant-form')">
<div class="page-content">
<div class="form-container">
<div v-for='(attribute, index) in super_attributes' class="control-group" :class="[errors.has('add-variant-form.' + attribute.code) ? 'has-error' : '']">
<label :for="attribute.code" class="required">#{{ attribute.admin_name }}</label>
<select v-validate="'required'" v-model="variant[attribute.code]" class="control" :id="attribute.code" :name="attribute.code" :data-vv-as="'"' + attribute.admin_name + '"'">
<option v-for='(option, index) in attribute.options' :value="option.id">#{{ option.admin_name }}</option>
</select>
<span class="control-error" v-if="errors.has('add-variant-form.' + attribute.code)">#{{ errors.first('add-variant-form.' + attribute.code) }}</span>
</div>
<button type="submit" class="btn btn-lg btn-primary">
{{ __('admin::app.catalog.products.add-variant-title') }}
</button>
</div>
</div>
</form>
</script>
<script type="text/x-template" id="variant-list-template">
<div class="table" style="margin-top: 20px; overflow-x: auto;">
<table>
<thead>
<tr>
<th class="sku">{{ __('admin::app.catalog.products.sku') }}</th>
<th>{{ __('admin::app.catalog.products.name') }}</th>
#foreach ($product->super_attributes as $attribute)
<th class="{{ $attribute->code }}" style="width: 150px">{{ $attribute->admin_name }}</th>
#endforeach
<th class="qty">{{ __('admin::app.catalog.products.qty') }}</th>
<th class="price">{{ __('admin::app.catalog.products.price') }}</th>
<th class="weight">{{ __('admin::app.catalog.products.weight') }}</th>
<th class="status">{{ __('admin::app.catalog.products.status') }}</th>
<th class="actions"></th>
</tr>
</thead>
<tbody>
<variant-item v-for='(variant, index) in variants' :variant="variant" :key="index" :index="index" :variant-price.sync="variantPrice" #onRemoveVariant="removeVariant($event)"></variant-item>
</tbody>
</table>
</div>
</script>
<script type="text/x-template" id="variant-item-template">
<tr>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[sku]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" v-model="variant.sku" :name="[variantInputName + '[sku]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.sku') }}"" v-slugify/>
<span class="control-error" v-if="errors.has(variantInputName + '[sku]')">#{{ errors.first(variantInputName + '[sku]') }}</span>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[name]') ? 'has-error' : '']">
<input type="text" v-validate="'required'" v-model="variant.name" :name="[variantInputName + '[name]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.name') }}""/>
<span class="control-error" v-if="errors.has(variantInputName + '[name]')">#{{ errors.first(variantInputName + '[name]') }}</span>
</div>
</td>
<td v-for='(attribute, index) in superAttributes'>
<div class="control-group">
<input type="hidden" :name="[variantInputName + '[' + attribute.code + ']']" :value="variant[attribute.code]"/>
<input type="text" class="control" :value="optionName(variant[attribute.code])" readonly/>
</div>
</td>
<td>
<button style="width: 100%;" type="button" class="dropdown-btn dropdown-toggle">
#{{ totalQty }}
<i class="icon arrow-down-icon"></i>
</button>
<div class="dropdown-list">
<div class="dropdown-container">
<ul>
<li v-for='(inventorySource, index) in inventorySources'>
<div class="control-group" :class="[errors.has(variantInputName + '[inventories][' + inventorySource.id + ']') ? 'has-error' : '']">
<label>#{{ inventorySource.name }}</label>
<input type="text" v-validate="'numeric|min:0'" :name="[variantInputName + '[inventories][' + inventorySource.id + ']']" v-model="inventories[inventorySource.id]" class="control" v-on:keyup="updateTotalQty()" :data-vv-as="'"' + inventorySource.name + '"'"/>
<span class="control-error" v-if="errors.has(variantInputName + '[inventories][' + inventorySource.id + ']')">#{{ errors.first(variantInputName + '[inventories][' + inventorySource.id + ']') }}</span>
</div>
</li>
</ul>
</div>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[price]') ? 'has-error' : '']">
<input type="number" v-validate="'required|min_value:0.0001'" v-model="variant.price" :name="[variantInputName + '[price]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.price') }}"" step="any"/>
<span class="control-error" v-if="errors.has(variantInputName + '[price]')">#{{ errors.first(variantInputName + '[price]') }}</span>
</div>
</td>
<td>
<div class="control-group" :class="[errors.has(variantInputName + '[weight]') ? 'has-error' : '']">
<input type="number" v-validate="'required|min_value:0.0001'" v-model="variant.weight" :name="[variantInputName + '[weight]']" class="control" data-vv-as=""{{ __('admin::app.catalog.products.weight') }}"" step="any"/>
<span class="control-error" v-if="errors.has(variantInputName + '[weight]')">#{{ errors.first(variantInputName + '[weight]') }}</span>
</div>
</td>
<td>
<div class="control-group">
<select type="text" v-model="variant.status" :name="[variantInputName + '[status]']" class="control">
<option value="1" :selected="variant.status">{{ __('admin::app.catalog.products.enabled') }}</option>
<option value="0" :selected="!variant.status">{{ __('admin::app.catalog.products.disabled') }}</option>
</select>
</div>
</td>
<td class="actions">
<a :href="['{{ route('admin.catalog.products.index') }}/edit/' + variant.id]"><i class="icon pencil-lg-icon"></i></a>
<i class="icon remove-icon" #click="removeVariant()"></i>
</td>
</tr>
</script>
<script>
$(document).ready(function () {
Vue.config.ignoredElements = [
'variant-form',
'variant-list',
'variant-item'
];
});
var super_attributes = #json(app('\Webkul\Product\Repositories\ProductRepository')->getSuperAttributes($product));
var variants = #json($product->variants);
Vue.component('variant-form', {
data: function() {
return {
variant: {},
super_attributes: super_attributes
}
},
template: '#variant-form-template',
created: function () {
this.resetModel();
},
methods: {
addVariant: function (formScope) {
this.$validator.validateAll(formScope).then((result) => {
if (result) {
var this_this = this;
var filteredVariants = variants.filter(function(variant) {
var matchCount = 0;
for (var key in this_this.variant) {
if (variant[key] == this_this.variant[key]) {
matchCount++;
}
}
return matchCount == this_this.super_attributes.length;
})
if (filteredVariants.length) {
this.$parent.closeModal();
window.flashMessages = [{'type': 'alert-error', 'message': "{{ __('admin::app.catalog.products.variant-already-exist-message') }}" }];
this.$root.addFlashMessages()
} else {
var optionIds = [];
for (var key in this_this.variant) {
optionIds.push(this_this.variant[key]);
}
variants.push(Object.assign({
sku: '{{ $product->sku }}' + '-variant-' + optionIds.join('-'),
name: '',
price: 0,
weight: 0,
status: 1
}, this.variant));
this.resetModel();
this.$parent.closeModal();
}
}
});
},
resetModel: function () {
var this_this = this;
this.super_attributes.forEach(function(attribute) {
this_this.variant[attribute.code] = '';
})
}
}
});
Vue.component('variant-list', {
template: '#variant-list-template',
inject: ['$validator'],
data: function() {
return {
variants: variants,
variantPrice:0,
old_variants: #json(old('variants')),
superAttributes: super_attributes
}
},
created: function () {
var index = 0;
for (var key in this.old_variants) {
var variant = this.old_variants[key];
if (key.indexOf('variant_') !== -1) {
var inventories = [];
for (var inventorySourceId in variant['inventories']) {
inventories.push({'qty': variant['inventories'][inventorySourceId], 'inventory_source_id': inventorySourceId})
}
variant['inventories'] = inventories;
variants.push(variant);
} else {
for (var code in variant) {
if (code != 'inventories') {
variants[index][code] = variant[code];
} else {
variants[index][code] = [];
for (var inventorySourceId in variant[code]) {
variants[index][code].push({'qty': variant[code][inventorySourceId], 'inventory_source_id': inventorySourceId})
}
}
}
}
index++;
}
},
methods: {
removeVariant: function(variant) {
let index = this.variants.indexOf(variant)
this.variants.splice(index, 1)
},
}
});
Vue.component('variant-item', {
template: '#variant-item-template',
props: ['variantPrice','index', 'variant'],
inject: ['$validator'],
data: function() {
return {
inventorySources: #json($inventorySources),
inventories: {},
totalQty: 0,
superAttributes: super_attributes
}
},
created: function () {
var this_this = this;
this.inventorySources.forEach(function(inventorySource) {
this_this.inventories[inventorySource.id] = this_this.sourceInventoryQty(inventorySource.id)
this_this.totalQty += parseInt(this_this.inventories[inventorySource.id]);
})
},
computed: {
variantInputName: function () {
if (this.variant.id)
return "variants[" + this.variant.id + "]";
return "variants[variant_" + this.index + "]";
}
},
methods: {
removeVariant: function () {
this.$emit('onRemoveVariant', this.variant)
},
onVariantPriceInput(event) {
this.$emit('update:variantPrice', Number(event.target.value));
},
optionName: function (optionId) {
var optionName = '';
this.superAttributes.forEach(function(attribute) {
attribute.options.forEach(function(option) {
if (optionId == option.id) {
optionName = option.admin_name;
}
});
})
return optionName;
},
sourceInventoryQty: function (inventorySourceId) {
if (! Array.isArray(this.variant.inventories))
return 0;
var inventories = this.variant.inventories.filter(function(inventory) {
return inventorySourceId === parseInt(inventory.inventory_source_id);
})
if (inventories.length)
return inventories[0]['qty'];
return 0;
},
updateTotalQty: function () {
this.totalQty = 0;
for (var key in this.inventories) {
this.totalQty += parseInt(this.inventories[key]);
}
}
}
});
</script>
#endpush
If it is your objective to have a single price which is shared by all variants, then I would advise against having a price property per variant Object. variant.price suggests a price per variant. I would create a separate data property, say variantPrice that would be passed to each instance of the variant-item component.
(As an aside: If there is a single price that is to be shared by all variant-item components then it may be confusing to your users that you render a price input field per variant-item instead of having a single input field.)
One way to synchronize a value with multiple child components, and assuming you are using a version of Vue >= 2.3 and < 3, is to use the .sync modifier.
Your parent component - the one that references the variants Array - would have a new data property for variantPrice. Here is an example where the parent is the root Vue component:
new Vue({
components: {
variantItem: VariantItem
},
data() {
return {
variantPrice: 0,
variants: [
{
inputName: 'VariantOne'
},
{
inputName: 'VariantTwo'
}
]
};
},
el: "#App"
});
The template of the parent (root) would pass variantPrice as a prop to each variant-item instance using the .sync modifier which will bind the value of variantPrice to the update:variantPrice event emitted by the child. The template would look like:
<div id="App">
<variant-item v-for="(variant, index) in variants" :key="index" :variant="variant" :variant-price.sync="variantPrice"></variant-item>
</div>
Next, we must ensure that our VariantItem component takes a variantPrice as a prop and emits the update:variantPrice event when the input field is modified by the user:
const VariantItem = Vue.component('variant-item', {
methods: {
onVariantPriceInput(event) {
this.$emit('update:variantPrice', Number(event.target.value));
}
},
props: {
variant: {
required: true,
type: Object
},
variantPrice: {
required: true,
type: Number
}
},
template: '#VariantItemTemplate'
});
The template for this component would become:
<div>
<label :for="variant.inputName">{{ variant.inputName }}</label>
<input :id="variant.inputName" :name="variant.inputName" :value="variantPrice" #input="onVariantPriceInput" type="number">
</div>
I have created a fiddle for your reference.
Related
I can read the data of one Input Argument with Ng2SearchPipeModule.
Typescript:
public dropdownAuslesen(statustext: number) {
this.nameComp = [];
for (let i = 0; i < this.infoFile.length; i++) {
if (this.infoFile[i]['status'] === statustext) {
this.nameComp.push({
name: this.infoFile[i]['component_Name'],
id: this.componentID[i],
version: this.infoFile[i]['version'],
status: this.getStatusText(this.infoFile[i]['status']),
});
}
}
}
HTML:
<tr *ngFor="let name of this.nameComp | filter: (searchString.valueChanges | async); let i = index">
<td>
<a [routerLink]="['/details', name.id] ">
{{ name.name }}
</a>
</td>
<td>{{ name.version }}</td>
<td [ngStyle]="{'color':name.status === 'geprüft' ? 'green' : 'red' }">{{name.status}}</td>
</tr>
<div class="container mt-4 element1 searchbar inline" id="left">
<input type="text" class="form-control" placeholder="Nach Komponente suchen..." [formControl]="searchString"
autocomplete="on">
</div>
How can I search more than one String in the input field? Maybe with a &?
I expect I can search for example for Sarah & 26.
Here's my angularjs Controller
var $tr = angular.element("#parent" + obj.field_id).find("tbody"),
$nlast = $tr.find("tr:last"),
$clone = angular.copy($nlast);
$clone.find(':text').val('');
var elem = angular.element($clone);
$tr.after($compile(elem)($scope));
When I tried to remove $compile it's working but angularjs does not working at all like validation of fields that's why I need to add a $compile but it doesn't seem working to me , please help me I'm new in angularJS
Here's an example of a simple table built from an object in angularJS. It's not the only way, but it illustrates some basic concepts, and how to add another row.
In the controller
$scope.tabledata = {
header: [{name: "id"}, {name: "name"}, {name: "email"}],
rows: [{
id: 1,
name: "Joe",
email: "joe#1.com"
},
{
id: 2,
name: "Bill",
email: "bill#1.com"
},
{
id: 3,
name: "Sally",
email: "sally#1.com"
}
]
}
// later I want to add another row:
$scope.tabledata.rows.push({
id: 4,
name: "Bob",
email: "bob#1.com"
})
// and like magic, another row is added to the table
The view file:
<table ng-if="tabledata">
<tr>
<th ng-repeat="item in tabledata.header">{{item.name}}</th>
</tr>
<tr ng-repeat="row in tabledata.rows">
<td ng-repeat="(key, value) in row">{{value}}</td>
</tr>
</table>
This is my actual code
<table class="table table-bordered" border="" cellpadding="" cellspacing="" style="background-color:white" id="parent{{form.field_id}}">
<thead>
<tr >
<th ng-repeat="Col in form.GridList">{{Col.field_title}}</th>
</tr>
</thead>
<tbody>
<tr >
<td ng-repeat="gridData in form.GridList">
<div ng-if="gridData.field_type == 'Textbox' && gridData.field_datatype == 'Text'">
<div ng-if="gridData.field_required == 'True'">
<div class="control-group has-feedback">
<div class="Textbox">
<div ng-if="gridData.enable_textformat == 'True'">
<input id="sub{{gridData.field_id }}" name="textinput" ng-model="gridData.value" placeholder="{{gridData.field_textformat}}" type="text" ng-required="{{gridData.field_required | lowercase}} && {{gridData.field_standard | lowercase}} == true" class="col-md-5 rectangle form-control"/>
</div>
<div ng-else>
<input id="sub{{gridData.field_id }}" name="textinput" ng-model="gridData.value" type="text" placeholder="" ng-required="{{gridData.field_required | lowercase}} && {{gridData.field_standard | lowercase}} == true" class="{{gridData.field_required}} col-md-5 rectangle form-control"/>
</div>
</div>
</div>
</div>
<div ng-if="gridData.field_required == 'False'">
<div class="control-group">
<div class="Textbox">
<div ng-if="gridData.enable_textformat == 'True'">
<input id="sub{{gridData.field_id }}" name="textinput" ng-model="gridData.value" placeholder="{{gridData.field_textformat}}" type="text" ng-required="{{gridData.field_required | lowercase}} && {{gridData.field_standard | lowercase}} == false" class="col-md-5 rectangle form-control"/>
</div>
<div ng-else>
<input id="sub{{gridData.field_id }}" name="textinput" ng-model="gridData.value" type="text" placeholder="" ng-required="{{gridData.field_required | lowercase}} && {{gridData.field_standard | lowercase}} == false" class="{{gridData.field_required}} col-md-5 rectangle form-control"/>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
and This is my angularjs controller
function createDataTable(field) {
field.GridList = [{}];
var appendValue = "";
$scope.isread = "";
var row = 1;
var col = "";
try {
$http({
method: 'POST',
url: "DefaultForm.aspx/populaGridView",
data: "{'fieldid':" + field.field_id + "}",
headers: { 'Content-Type': 'application/json; charset=utf-8' }
}).then(function onSuccess(response) {
field.GridList = JSON.parse(response.data.d);
$scope.Tables = JSON.parse(response.data.d);
angular.forEach(field.GridList, function (vals, keys) {
if (vals.field_type == "dropdownList") {
$http({
method: 'POST',
url: "DefaultForm.aspx/populaDD",
data: "{'fieldid':" + vals.field_id + "}",
headers: { 'Content-Type': 'application/json; charset=utf-8' }
}).then(function onSuccess(response) {
try {
vals.Newvalue = [];
vals.Newvalue = JSON.parse(response.data.d);
} catch (err) {
}
}, function myError(response) {
});
}
})
}, function myError(response) {
alert(response.statusText);
});
} catch (err) { console.log("new error " + err.message); }
};
button add new row to the table
$scope.AddRow = function (obj) {
var row = { cells: [] },
se = obj.GridList,
rowLen = se.length;
angular.forEach(se, function (vals) {
row.cells.push({ field_type: vals.field_type });
})
se.push(row);
}
when button is clicked it goes to the 1st row not in 2nd row.
I'm fetching data into the table and on clicking any table row it open a nested colspan inside table row. I want to close previous table row if i click on another table row (Like accordion does )
this is a table body structure
<tbody style="cursor:pointer" v-for="(statement,index) in statements">
<tr #click="statementDetail(index,statement.paper_quality_id.id,statement.paper_brand_id.id,statement.paper_size_id.id,statement.thickness)"
>
<td>{{index+1}}</td>
<td>
{{statement.paper_quality_id.paper_quality}} -
{{statement.paper_size_id.length}} X {{statement.paper_size_id.width}} -
{{statement.paper_brand_id.paper_brand}} -
{{statement.thickness}}
</td>
<td>
<div class="row">
<div
class="col-md-4 text-center"
>{{parseInt((statement.in_total_before - statement.total_out_before)/500)}}</div>
<div
class="col-md-4 text-center"
>{{parseInt((statement.in_total_before - statement.total_out_before)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-4 text-center"
>{{parseInt((statement.total_sheets_in_range)/500)}}</div>
<div
class="col-md-4 text-center"
>{{parseInt((statement.total_sheets_in_range)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-4 text-center"
>{{parseInt((statement.total_outward_range)/500)}}</div>
<div
class="col-md-4 text-center"
>{{parseInt((statement.total_outward_range)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div class="col-md-4 text-center">
{{
parseInt((((statement.in_total_before - statement.total_out_before) + (statement.total_sheets_in_range)) - statement.total_outward_range)/500)
}}
</div>
<div class="col-md-4 text-center">
{{
parseInt((((statement.in_total_before - statement.total_out_before) + (statement.total_sheets_in_range)) - statement.total_outward_range)%500)
}}
</div>
</div>
</td>
</tr>
This the nested table it appears when we click on table row
<tr :id="'show_'+index" v-if = "index = indexData" >
<td colspan="6">
<table class="table table-hover">
<tr>
<th>Date</th>
<th>Opening</th>
<th>Inward</th>
<th>Outward</th>
<th>Balance</th>
</tr>
<tr v-for="(_statement,index) in statements_details" >
<td>{{_statement.date}}</td>
<td>
<div class="row">
<div
class="col-md-3 text-center"
>{{parseInt((_statement.opening.total_in - _statement.opening.total_out)/500)}}</div>
<div
class="col-md-3 text-center"
>{{parseInt((_statement.opening.total_in - _statement.opening.total_out)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div class="col-md-3 text-center">{{parseInt((_statement.inward)/500)}}</div>
<div class="col-md-3 text-center">{{parseInt((_statement.inward)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div class="col-md-3 text-center">{{parseInt((_statement.outward)/500)}}</div>
<div class="col-md-3 text-center">{{parseInt((_statement.outward)%500)}}</div>
</div>
</td>
<td>
<div class="row">
<div
class="col-md-3 text-center"
>{{parseInt((_statement.balance.total_in - _statement.balance.total_out)/500)}}</div>
<div
class="col-md-3 text-center"
>{{parseInt((_statement.balance.total_in - _statement.balance.total_out)%500)}}</div>
</div>
</td>
</tr>
</table>
</td>
</tr>
</tbody>
This is my js file
export default {
data() {
return {
statements: '',
users: [],
ledger_name: '',
paper_details: '',
account_list: false,
//statement Objects
id: '',
start_date: '',
end_date: '',
paper_quality_id: '',
paper_size_id: '',
paper_brand_id: '',
thickness: '',
statements_details: '',
stockIDS: '',
indexData: ''
};
},
created() {
this.fetchData();
},
components: {
appInventoryNavigation: InventoryNavBar,
},
methods: {
// Fetching Ledger Account List
fetchData() {
var vm = this;
axios.get('/ledger/')
.then((response) => {
console.log(response)
vm.users = response.data
}).catch((err) => {
console.log(err)
});
},
//Setting LedgerID In Hidden Input Field
setLedgerID_1(id, name) {
this.account_name = id;
this.account_list = false;
this.id = id;
this.ledger_name = name;
},
call() {
this.account_list = true;
},
//Posting LedgeID
PostLedgerID(e) {
e.preventDefault();
const AccountDetail = {
id: this.id,
start_date: this.start_date + ' 00:00:00.957761',
end_date: this.end_date + ' 00:00:00.957761'
}
var vm = this;
axios.post('/Statement/', AccountDetail)
.then((response) => {
console.log(response)
vm.statements = response.data;
}).catch((err) => {
console.log(err)
});
},
//Show Hide Nested Table
statementDetail(rowid, paper_id, brand_id, size_id, thickness) {
this.indexData = rowid;
alert(this.indexData)
const userDetail = {
account_access_key_id: $('#ledger_id').val(),
start_date: this.start_date + ' 00:00:00.957761',
end_date: this.end_date + ' 00:00:00.957761',
paper_quality_id: paper_id,
paper_brand_id: brand_id,
paper_size_id: size_id,
thickness: thickness
}
axios.post('/StatementDetail/', userDetail)
.then((response) => {
$('#show_' + rowid).toggle();
this.statements_details = response.data;
}).catch((err) => {
console.log(err)
});
}
},
};
Change v-show="indexData === index".
And in your method check if rowid is changed and move this.indexData = rowid; after axios request:
statementDetail(rowid, paper_id, brand_id, size_id, thickness) {
if (rowid !== this.indexData){
const userDetail = {
account_access_key_id: $('#ledger_id').val(),
start_date: this.start_date + ' 00:00:00.957761',
end_date: this.end_date + ' 00:00:00.957761',
paper_quality_id: paper_id,
paper_brand_id: brand_id,
paper_size_id: size_id,
thickness: thickness
}
axios.post('/StatementDetail/', userDetail)
.then((response) => {
$('#show_' + rowid).toggle();
this.statements_details = response.data;
}).catch((err) => {
console.log(err)
});
this.indexData = rowid;
}
}
Good luck.
I have a form which is have hidden input. There is a small list of my data. Just has title and id. This list created by vue component. I want to click this list items then change to hidden input value. Here is my structure.
HTML
<div id="v-account-select">
<form method="post">
{!! csrf_field() !!}
<input type="hidden" name="id" v-model="account_id">
</form>
<account-select :datalist="{{ json_encode($list) }}"></account-select>
</div>
APP.JS
Vue.component("account-select", {
datalist: {
type: Array,
required: true,
},
methods: {
item_id_bind(id) {
this.$emit("#account_id", id);
},
},
template:
'<table class="table table-responsive table-striped table-bordered">' +
"<tbody>" +
'<tr v-for="item in datalist"><td>' +
'<button type="button" class="btn-link" v-on:click="item_id_bind(item.id)">{{item.title}}</button>' +
"</td></tr>" +
"</tbody>" +
"</table>",
});
This is my codes.
Add an event handler.
<account-select #account-change="onAccountChange" :datalist="{{ json_encode($list) }}"></account-select>
In your parent Vue add
methods:{
onAccountChange(id){
this.account_id = id
}
}
And update your component to
methods: {
item_id_bind(id) {
this.$emit("account_change", id)
}
},
Here is a working example.
console.clear()
Vue.component('account-select', {
props: {
datalist: {
type: Array,
required: true
}
},
methods: {
item_id_bind(id) {
this.$emit("account-change", id)
}
},
template:`
<table class="table table-responsive table-striped table-bordered">
<tbody>
<tr v-for="item in datalist" :key="item.id">
<td>
<button type="button"
class="btn-link"
v-on:click="item_id_bind(item.id)">
{{item.title}}
</button>
</td>
</tr>
</tbody>
</table>
`
});
new Vue({
el: "#app",
data: {
datalist: [{
id: 1,
title: "item1"
}, {
id: 2,
title: "item2"
}],
account_id: null
},
methods: {
onAccountChange(id) {
this.account_id = id
}
}
})
<script src="https://unpkg.com/vue#2.2.6/dist/vue.js"></script>
<div id="app">
<div id="v-account-select">
<form method="post">
Current Account id: {{account_id}}
<input type="hidden" name="id" v-model="account_id">
</form>
<account-select #account-change="onAccountChange" :datalist="datalist"></account-select>
</div>
</div>
I am having an issue where when I try to select multiple devices and add them to a group, the array of selected devices($scope.deviceIDs.push) is not getting the values. Can anyone see the issue or suggest a different method. I used http://www.dotnetawesome.com/2015/12/multiselect-dropdown-with-checkbox-in-angularjs.html as template for the service I built.
Here is the angular code.
var MyApp = angular.module('MyApp', ['ui.bootstrap', 'angularjs-dropdown-multiselect']);
MyApp.controller('GroupsController', ['GroupsService', '$scope', '$log', '$uibModal',
function (GroupsService, $scope, $log, $uibModal) {
$scope.groupSelected = [];
$scope.location = '';
$scope.groupguid = '';
$scope.newGroupName = '';
$scope.devicesNotinGroup = [];
$scope.newGroupAddMember = 'false';
$scope.isCollapsed = false;
$scope.groupSelected.GroupID = 0;
$scope.SelectedDevices = [];
$scope.deviceIDs = [];
$scope.dropdownSetting = {
scrollableHeight: '200px',
scrollable: true,
enableSearch: true
}
// Populate Jobs
GroupsService.GetDeviceList().then(function (d) {
$scope.GroupList = d.data;
console.log(d.data)
}, function (error) {
alert('Error!');
});
$scope.showChilds = function (item) {
$scope.grouplist = [];
item.active = !item.active;
console.log("here item=" + item.GroupName + " active=" + item.GroupName.active);
grouplist = item.SubGroup;
};
$scope.showInfoForGroup = function (item) {
console.log("item = " + item + "Count = " + item.DeviceCount);
GroupsService.GetGroupDeviceInformation(item).then(function (d) {
$scope.groupSelected = d.data.devicegroupitem;
//$scope.devicesNotinGroup = d.data.devicesnotingroup;
angular.forEach(d.data.devicesnotingroup, function (value, index) {
$scope.devicesNotinGroup.push({ label: value.HostName, id: value.HostName });
});
//console.log($scope.devicesNotinGroup)
})
}, function (error) {
console.log("item = " +item + "Count = " + groupSelected.DeviceCount);
};
$scope.DeleteDeviceFromGroup = function (deviceguid, groupguid ) {
console.log("DeviceGuid = " + deviceguid + " GroupGuid = " + groupguid);
GroupsService.DeleteDeviceFromList(deviceguid, groupguid).then(function (d) {
$scope.groupSelected = d.data;
})
}
$scope.AddDeviceToGroup = function (hostname, groupguid) {
GroupsService.AddDeviceToGroup(hostname, groupguid).then(function (d) {
$scope.showInfoForGroup(dt.guid);
//$scope.groupSelected = d.data.devicegroupitem;
//$scope.devicesNotinGroup = d.data.devicesnotingroup;
$scope.newGroupAddMember = 'false';
})
}
$scope.SubmitMultipleDevices = function (groupguid){
$scope.deviceIDs = [];
console.log($scope.SelectedDevices);
angular.forEach($scope.SelectedDevices = function (value) {
$scope.deviceIDs.push({ dname: value.HostName, dguid: groupguid } );
});
console.log('device ids ');
console.log($scope.deviceIDs);
var data = { deviceIDs: deviceIDs };
console.log(data);
angular.toJson(data);
GroupsService.SubmitMultiDevicesToGroup(data)
.success(function () {
})
.error(function (error) {
});
}
$scope.CreateGroup = function (groupID, groupName, newGroupAddMember) {
angular.isUndefinedOrNull = function (groupID) {
return angular.isUndefined(groupID) || groupID === null
}
$scope.GroupList = '';
console.log("check value equals" + groupID)
GroupsService.CreateSubGroup(groupID, groupName, newGroupAddMember).then(function (d) {
$scope.GroupList = d.data;
$scope.newGroupName = '';
$scope.newGroupAddMember = false;
})
}
$scope.DeleteGroup = function (groupID) {
$scope.GroupList = '';
GroupsService.DeleteSubGroup(groupID).then(function (d){
$scope.GroupList = d.data;
$scope.newGroupName = '';
})
}
}])
MyApp.factory('GroupsService', function ($http) { // explained about factory in Part2
var fac = {};
fac.GetDeviceList = function () {
return $http.get('/DeviceGroups/getgrouptree')
}
fac.GetGroupDeviceInformation = function (guid) {
return $http.get('/DeviceGroups/GetGroupDeviceInfo?groupguid=' + guid)
}
fac.DeleteDeviceFromList = function (deviceguid, groupguid) {
return $http.get('/DeviceGroups/DeleteDeviceFromGroup?deviceguid='+ deviceguid + "&groupguid=" + groupguid)
}
fac.AddDeviceToGroup = function (hostname, groupguid) {
return $http.get('/DeviceGroups/AddDeviceToGroup?hostname=' + hostname + "&groupguid=" + groupguid)
}
fac.CreateSubGroup = function (groupID, groupName, newGroupAddMember) {
return $http.get('/DeviceGroups/CreateGroup?GroupID=' + groupID + "&groupName=" + groupName + "&AddMember=" + newGroupAddMember)
}
fac.DeleteSubGroup = function (groupID) {
return $http.get('/DeviceGroups/DeleteGroup?GroupID=' + groupID)
}
fac.SubmitMultiDevicesToGroup = function (data) {
return $http.post('/DeviceGroups/AddMultipleDevicesToGroup', data)
}
return fac;
});
Here is the view code:
#model List<NetworkCafe.Models.DeviceGroup>
#{
ViewBag.Title = "Groups";
}
<style>
#clickable:hover {
cursor: pointer;
}
.body-content{padding-top:50px}
.checkbox{padding:0;margin:0;}
.dropdown-menu{overflow:auto !important;}
.form-group div{display:inline-block; margin-right:10px}
</style>
<link rel="stylesheet" href="../Content/font-awesome.min.css">
<div class="container" style="width:90%" ng-app="MyApp" ng-controller="GroupsController">
<div class="col-lg-3">
<div ng-class="dropdown" class="panel panel-warning">
<div class="panel-heading">
Tree List of Groups
</div>
<div class="panel-body">
<script type="text/ng-template" id="tree-structure">
<span>
<span id="clickable" ng-class="{'glyphicon glyphicon-chevron-up':(!dt.AddMembers) && (!dt.active), 'glyphicon glyphicon-chevron-down':(!dt.AddMembers) && (dt.active), 'childElement':(dt.AddMembers)}" ng-click="showChilds(dt)"></span>
<span id="clickable" ng-click="showInfoForGroup(dt.guid)"> {{dt.GroupName}} </span>
</span>
<ul ng-if="dt.AddMembers">
#*<li>Device Count: {{dt.DeviceCount}}</li>
<li>Total Ports: {{dt.TotalPortCount}}</li>
<li>Open Ports: {{dt.OpenPortCount}}</li>
<li>Reserved Ports: {{dt.ReservedPortCount}}</li>
<li>Percent Used: {{dt.PercentUsed}}</li>*#
#*<li><button ng-click="href"</li>*#
</ul>
<ul style="list-style: none" ng-show="dt.active" class="childElement">
<li ng-repeat="dt in dt.SubGroup" ng-include="'tree-structure'">
</li>
</ul>
</script>
</div>
<ul style="list-style: none" ng-class="list-group-item" class="parentList">
<li ng-repeat="dt in GroupList" ng-include="'tree-structure'" style="list-style: none">
</li>
</ul>
</div>
</div>
<div class="col-lg-3">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Group {{groupSelected.GroupName}} Information</h3>
</div>
<div class="panel-body">
<span ng-hide="!groupSelected.AddMembers">
This group has devices and can not have subgroups.
</span>
<table class="table table-striped table-hover" ng-hide="!groupSelected.AddMembers">
<tr>
<td>Device Count: </td>
<td></td>
<td>{{groupSelected.DeviceCount}}</td>
</tr>
<tr>
<td>Total Ports: </td>
<td></td>
<td>{{groupSelected.TotalPortCount}}</td>
</tr>
<tr>
<td>Open Ports: </td>
<td></td>
<td>{{groupSelected.OpenPortCount}}</td>
</tr>
<tr>
<td>Reserved Ports: </td>
<td></td>
<td>{{groupSelected.ReservedPortCount}}</td>
</tr>
<tr>
<td>Percent Used:</td>
<td></td>
<td>{{groupSelected.PercentUsed}}</td>
</tr>
</table>
<span ng-hide="groupSelected.AddMembers">
This group has subgroups and can not have members.<br /><br />
<label>CREATE SUBGROUP</label><br />
<input ng-model="newGroupName" placeholder="Group Name" /><br />
<label>Group Type</label><br />
<input type="checkbox" ng-model="newGroupAddMember" ng-checked="!newGroupAddMember" />Group will be used for Device.<br />
<button type="submit" class="btn btn-success" ng-click="CreateGroup(groupSelected.GroupID, newGroupName, newGroupAddMember)">Submit</button><br />----------------------- <br />
</span>
<span>
<a class="btn btn-danger" ng-click="DeleteGroup(groupSelected.GroupID)">Danger Delete Group </a> <br />
Delete Group. This will delete all subgroups and devices under this group.
</span>
</div>
</div>
</div>
<div class="col-lg-6" ng-hide="!groupSelected.AddMembers">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Device List</h3>
</div>
<div class="panel-body">
<table class="table table-striped table-hover ">
<tr>
<th></th>
<th>Device Name</th>
<th>Total Ports</th>
<th>Open Ports</th>
<th>Reserved Ports</th>
<th>Percent Used</th>
</tr>
<tr ng-repeat="dl in groupSelected.DeviceList">
<td> <i id="clickable" class="fa fa-times" ng-click="DeleteDeviceFromGroup(dl.guid, groupSelected.guid)"></i> </td>
<td>{{dl.DeviceName}}</td>
<td>{{dl.TotalPortCount}}</td>
<td>{{dl.OpenPortCount}}</td>
<td>{{dl.ReservedPortCount}}</td>
<td>{{dl.PercentUsed}}</td>
</tr>
<tr>
<td></td>
</tr>
</table>
#*<ul class="nav navbar-nav">
<li class="dropdown">
----------Add Device from Switch List----------<span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="sl in devicesNotinGroup">
<span>
<i id="clickable" class="fa fa-plus-square" ng-click="AddDeviceToGroup(sl.HostName, groupSelected.guid)"></i> {{sl.HostName}} {{sl.Site}} {{sl.Zone}}
</span>
</li>
</ul>
</li>
</ul>*#
<form class="form-inline" name="myForm" role="form" ng-submit="SubmitMultipleDevices(groupSelected.guid)">
<div class="form-group">
<label>Add Devices to Group: </label>
#* Directive *#
<div ng-dropdown-multiselect="" extra-settings="dropdownSetting" options="devicesNotinGroup" selected-model="SelectedDevices" checkboxes="true"></div>
</div>
<br />
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
#section scripts{
<script src="~/Scripts/angular-1.4.9/ui-bootstrap-tpls-1.1.2.min.js"></script>
<script src="~/Scripts/AngularControllers/DeviceGroupsV2.js"></script>
<script src="~/Scripts/angular-1.4.9/angularjs-dropdown-multiselect.min.js"></script>
<script src="~/Scripts/angular-1.4.9/lodash.js"></script>
}
Your forEach loop is incorrect.
angular.forEach($scope.SelectedDevices = function (value) {
$scope.deviceIDs.push({ dname: value.HostName, dguid: groupguid } );
});
should be :
angular.forEach($scope.SelectedDevices, function (value) {
$scope.deviceIDs.push({ dname: value.HostName, dguid: value.groupguid } );
});