bind multiple inputs to each other in vuejs to change together - javascript

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

Filter more than one element with Ng2SearchPipeModule

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.

AngularJS : Angular copy append $compile does not working

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.

Close previous table row when clicking on another table 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.

vuejs how do I change input value from components

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>

Angular foreach - null values

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 } );
});

Categories

Resources