Trouble getting ngOptions to work properly in nested select dropdowns - javascript

I have created an angular app which records the attributes for a product which is being created. In the page, I have 2 select dropdowns, the first one for selecting the key of the attribute and the second selects the specific value. The json data for each attribute is as follows:-
{
meta_key :"Weight",
meta_values :[
"10","20","30","40","50"
],
type : "text",
unit:"kgs"
}
Each product can have an array of attributes with the only difference being that instead of meta_values as an array, each attribute in a product will have a single value as meta_value. The JSON representation is as follows:-
{
attributes : [
{
meta_key : "Weight",
meta_value : "20",
unit : "kgs"
},
{
meta_key : "Volume",
meta_value : "200",
unit : "cm*cm*cm"
}
]
}
This is what the page looks like.
My concern is that no matter what I am trying, the second select's values which depend entirely upon the value of the first select dropdown, does not get populated.
The empty second dropdown.
I tried populating the second dropdown with static data and it works fine. But the data does not change when it depends on the selection of the first dropdown. Here is my controller.
$scope.attributes = [];
$scope.product = {
attributes: []
};
$scope.current_user = {};
var attribute = {
meta_key: '',
meta_values: '',
unit: ''
};
AuthService.getCurrentUser(function (user) {
$scope.current_user = user;
$scope.product.created_by = $scope.current_user.id;
});
Attributes.fetchAllAttributes(function (response) {
$scope.attributes = response.message;
$scope.attributes.unshift({meta_key: "Select an attribute"});
console.log("Attributes", $scope.attributes);
});
$scope.addAttributes = function () {
$scope.product.attributes.push(attribute);
console.log($scope.product);
initDropDown($scope.product.attributes.length - 1);
};
$scope.initValues = function (index) {
var selectedValue = $scope.product.attributes[index];
console.log(selectedValue,$scope.product.attributes[index].meta_values);
};
And the html partial.
<div class="row attribute" ng-repeat="attribute in product.attributes track by $index">
<div class="input-field col s12 m4">
<select required md-select
ng-model="product.attributes[$index]"
ng-change="initValues($index);"
ng-options="attribute as attribute.meta_key for attribute in attributes">
</select>
<label>Attribute Name</label>
</div>
<div class="input-field col s12 m4" ng-show="product.attributes[$index].type == 'select'">
<select md-select
ng-options="value as value for value in product.attributes[$index].meta_values"
ng-model="product.attributes[$index].meta_value">
</select>
<label>Attribute Values</label>
</div>
<div class="input-field col s12 m4" ng-show="product.attributes[$index].type == 'text'">
<input type="text" id="{{$index }}" ng-model="product.attributes[$index].meta_value">
<label for="{{$index}}">Attribute Values</label>
</div>
<div class="input-field col s12 m2" ng-show="product.attributes[$index].meta_key != 'Select an attribute'">
<input id="unit" disabled ng-model="product.attributes[$index].unit">
<label for="unit" class="active">Unit</label>
</div>
<div class="input-field col s12 m2">
<a ng-click="remove($index);">
<i class="material-icons waves-effect waves-red red-text">close</i>
</a>
</div>
</div>
I have been trying to figure it for a while now. Have tried a lot solutions. But nothing quite works. How do I solve it? Any help will very appreciated.

Related

How to pass data to method from a vue element iteration

I am developing an invoice system in laravel vuejs. I am trying to pass data to the method from a form. In this form, I have used iteration to add/remove input text/select fields. In order to Iterate I have used v-model of these inputs. Now these v-models fail to pass data. When I console, I see they are empty.
I am sharing codes of that form :
For Iteration
<div class="form-group" v-for="(item,k) in inputs" :key="k">
<div class="row mb-2">
<div class="col-md-3">
<select class="form-control" v-model="item.product_id"
#change="getProductCost()">
<option value="">Select Product</option>
<option v-for="(product, i) in products" :key="i" :value="product.id">{{
product.product_name }}</option>
</select>
</div>
<div class="col-md-3">
<input type="text" class="form-control" placeholder="Quantity" v-
model="item.quantity" #keyup="getProductCost">
</div>
<div class="col-md-3">
<input type="text" class="form-control" placeholder="Total" v-
model="item.total">
</div>
<div class="col-md-3">
<span>
<i class="fa fa-minus-circle text-danger" #click="removeElement(k)" v-
show="k || ( !k && inputs.length > 1)"></i>
<i class="fa fa-plus-circle text-success ml-4" #click="addElement(k)" v-
show="k == inputs.length-1"></i>
</span>
</div>
</div>
</div>
From script, I need to pass data (item : {}) to getProductCost() method
export default {
data() {
return {
allerrors : [],
inputs : [{
product_id : '',
quantity : '',
total : '',
}],
item : {
product_id : '',
quantity : '',
total : '',
}
}
},
getProductCost() {
axios.get('/api/product-cost?
product_id='+this.item.product_id+'&&quantity='+this.item.quantity,
this.data).then(response => {
this.data.total_product_price = response.data
})
},
addElement() {
this.inputs.push({
product_id : '',
quantity : '',
total : ''
})
},
removeElement (index) {
this.inputs.splice(index, 1)
},
Well, actually you are overwriting the scope of item in the forloop.
I could imagine, that you just have to rename this line
<div class="form-group" v-for="(item,k) in inputs" :key="k">
to something like this:
<div class="form-group" v-for="(input,k) in inputs" :key="k">
and check for renaming the coresponding references aswell.
Edit 1:
You can look here for the vuejs way to handle dynamic data bindings and adjust it to your case: https://blog.logrocket.com/how-to-make-form-elements-dynamic-in-vue-js/

Cannot create property 'subjects' on number '1' using AngularJs

I want to select multiple subjects across one course but can't do so
I have two dropdown lists one for course selection and one for subjects selection. For multiple selection of the subjects I use the angular-chosen plugin, I can select multiple subjects only in the case when the Course is not selected from the dropdown list. But when I select the Course from the dropdown list then I can't select even one subject from the dropdown list
Following is my AddCourseController.js and related HTML
(function() {
var myApp = angular.module("myApp");
var AddCourseController = function($scope, CourseService, TeacherService) {
var onCourses = function(courses) {
$scope.courses = courses;
}
var onError = function(response) {
$scope.error = true;
$scope.errors = response.data;
};
CourseService.courses().then(onCourses, onError);
TeacherService.getSubjects().then(function(data) {
$scope.subjects = data
});
};
myApp.controller("AddCourseController", AddCourseController);
}());
<div class="form-group">
<label>Select Course</label>
<select ng-model="course" class="form-control"
ng-options="course.IdCourse as course.Name for course in courses track by course.IdCourse">
</select>
</div>
<div class="form-group" ng-class="{ 'has-error' :
addCourseForm.subjects.$invalid && !addCourseForm.subjects.$pristine }">
<label class="pull-left">Select Subjects</label>
<a class="pull-right btn btn-primary btn-xs" data-toggle="modal" data- target="#add-subject">Add Subject</a>
<select chosen multiple class="form-control"
ng-model="course.subjects"
ng-options="subject.IdSubject as subject.Name for subject in subjects">
</select>
<p ng-show="addCourseForm.subjects.$invalid &&
!addCourseForm.subjects.$pristine" class="help-block">Subject is required.
</p>
</div>
Change the course selector to return the entire course object to the ng-model:
<div class="form-group">
<label>Select Course</label>
<select ng-model="course" class="form-control"
ng-options="course ̶.̶I̶d̶C̶o̶u̶r̶s̶e̶ as course.Name for course in courses track by course.IdCourse">
</select>
</div>

How to select rows based on string options in html vue js?

I need to add new rows based on the select options.
If my option is "kfc" I need to select a particular row. If my selected option is "cemrt", I need to add another row.
<div class="card-content" v-for="(bok, index) in rules" :key="index">
<div class="row">
<div class="col-md-6">
<div class="form-group label-floating">
<label class="control-label">Booked</label>
<select class="form-control" v-model="bok.name">
<option value="SEENAT">SEENAT</option>
<option value="CEMRT">CEMRT</option>
<option value="KFC">KFC</option>
</select>
</div>
</div>
</div>
<div class="row" v-if="bok.name == SEENAT"> //NOT WORKING FROM HERE
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms(if any)</label>
<input type="text" class="form-control" v-model="bok.data.head" required="">
</div>
</div>
</div>
<div class="row" v-if="bok.name == KFC">
<div class="col-md-4">
<div class="form-group label-floating">
<label class="control-label">Arms(if any)</label>
<input type="text" class="form-control" required="">
</div>
</div>
</div>
</div>
But I am using this code not able to add rows based on the options.
My vue js code is
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}] });
},
},
});
If I use option value as 1,2,3 etc. I am getting the result.
But I need to send SEENAT,CEMRT,KFC as data. How can I able to achieve the result.
Hard to tell. A reproduction on codesandbox would be welcome.
What I can see in your code at a first glance :
1) You forgot quotes around the options keys and thus it expects a constant. The fact you're using double equals instead of triple doesn't help:
v-if="bok.name === 'SEENAT'" // this
v-if="bok.name == SEENAT" // instead of that
2) data should be a function:
data() {
return {
rules: [
{
name: null,
section: null,
data: [{ head: null, value: null }]
}
]
};
},

jQuery result beign overwritten by the info sent from the GET Method [duplicate]

This question already has answers here:
jQuery: Conflict with removeData() executing at inadequate times
(3 answers)
Closed 5 years ago.
I have a modal window used to update or add a new object Store.
This modal is called remotely which information is loaded from a GET method constructed in ASP.NET.
Button that calls the modal:
<div class="btn-group" id="modalbutton">
<a id="createEditStoreModal" data-toggle="modal" asp-action="Create"
data-target="#modal-action-store" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> NEW STORE
</a>
</div>
Html of the modal:
#model Application.Models.ApplicationviewModels.StoreIndexData
#using Application.Models
<form asp-action="Create" role="form">
#await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo: Tiendas") })
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control"
asp-items="#(new SelectList(#ViewBag.ListofDepartment,"DepartmentID","DepartmentName"))"></select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID"
asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))"></select>
</div>
</div>
{... more elements}
</div>
</form>
GET Method:
public IActionResult Create(int? id)
{
List<Department> DepartmentList = new List<Department>();
DepartmentList = (from department in _context.Departments
select department).ToList();
DepartmentList.Insert(0, new Department { DepartmentID = 0, DepartmentName = "-- Seleccione Departamento --" });
ViewBag.ListofDepartment = DepartmentList;
StoreIndexData edit = new StoreIndexData();
List<District> ListofDistrict = new List<District>();
ListofDistrict.Insert(0, new District { DistrictID = 0, DistrictName = "-- PRUEBA --" });
ViewBag.ListofDistrict = ListofDistrict;
return PartialView("~/Views/Shared/Stores/_Create.cshtml");
}
The problem:
I have the following jQuery which asigns a value to DistrictID once the modal opens:
<script type="text/javascript">
var wasclicked = 0;
var $this = this;
$(document).ready(function () {
document.getElementById("modalbutton").onclick = function () {
//is AddNew Store button is hitted, this var = 1
wasclicked = 1;
};
$('#modal-action-store').on('hidden.bs.modal', function () {
//global.wasclicked = 0;
wasclicked = 0;
$(this).removeData('bs.modal');
});
$('#modal-action-store').on('shown.bs.modal', function (e) {
console.log($('#DistrictID').length);
//if wasclicked equals 1 that means we are in the AddNew Store scenario.
if (wasclicked == 1) {
//a default value is sent to District dropdownlist
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
};
});
});
</script>
The problem right now is that after this line jQuery is executed, the value that was assigned to DistrictID gets overwritten by :
ViewBag.ListofDistrict = ListofDistrict; //"-- PRUEBA --"
And this line is lost:
var items = "<option value='0'>-- Seleccione Distrito --</option>";
What I suspect is that the information coming from the Controller overwrites any result from jQuery over the in the modal.
After debugging I have identified three diferent moments:
Moment 1: First time we open the modal
The modal hasn't opened yet and the jQuery executes
For this reason it does not identify DistrictID
The result from the GET Action fills the modal's inputs.
Moment 2 - Part 1: Second time we open the modal
This time the modal opens before the jQuery is executed
The DistrictID has the value from the GET Method before we assign the value from jQuery
Moment 2 - Part 2: When the value from jQuery is assigned
The value from jQuery is assigned to DistrictID
This value will be overwritten by the result of the GET Action
Question:
Can anyone explain or help me understand what might be causing this? What else can I do to identify the reason behind this?
Try to replace your code:
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
by
var items = "<option value='0'>-- Seleccione Distrito --</option>";
var currentItems = $('#DistrictID').html();
$('#DistrictID').html(items + currentItems)
Hope this helps you :)
Trying moving the assigning of html to districtID from your main view to the document.ready of modal popUp view.
#model Application.Models.ApplicationviewModels.StoreIndexData
#using Application.Models
<form asp-action="Create" role="form">
#await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo: Tiendas") })
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control"
asp-items="#(new SelectList(#ViewBag.ListofDepartment,"DepartmentID","DepartmentName"))"></select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID"
asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))"></select>
</div>
</div>
{... more elements}
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
//if wasclicked equals 1 that means we are in the AddNew Store scenario.
if (wasclicked == 1) {
//a default value is sent to District dropdownlist
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
}
});
</script>
PS: Default option can be also be used. refer the below code.
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID" asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))">
<option value='0'>-- Seleccione Distrito --</option>
</select>
</div>
</div>

Dropdowns not bound to ng-model in Angular

Something very basic I am missing but I am not able to figure out . I have three fields in a view , two of them are dropdowns.
<div class="form-group row">
<label for="GroupName" class="col-sm-4 form-control-label">Group Name : </label>
<div class="col-sm-8">
<input ng-model="referenceEdit.groupName" id="GroupName" class="form-control" type="text">
</div>
</div>
<div class="form-group row">
<label for="GroupType" class="col-sm-4 form-control-label">Group Type : </label>
<div class="col-sm-8">
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-options="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" ng-model="referenceEdit.groupType"></select>
</div>
</div>
<div class="form-group row">
<label for="GroupAssignmentMethod" class="col-sm-4 form-control-label">Group Assignment Method : </label>
<div class="col-sm-8">
<select name="selGroupAssignmentMethod" id="selGroupAssignmentMethod" class="form-control" ng-options="assignmentMethod.id for assignmentMethod in referenceEdit.assignmentMethods track by assignmentMethod.value" ng-model="referenceEdit.assignmentMethod"></select>
</div>
</div>
Now in controller , I am getting the results for these drop downs in this way :
var row_details = GroupMembershipReferenceServices.getReferenceDataRow();
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_TYPE).success(function (result) {
$scope.referenceEdit.groupTypes = result;
$scope.referenceEdit.groupype = row_details.grp_typ;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_ASSIGNMENT_METHOD).success(function (result) {
$scope.referenceEdit.assignmentMethods = result;
$scope.referenceEdit.assignmentMethod = row_details.grp_assgnmnt_mthd;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
Problem is values are getting populated , like
and we are displaying the values accordingly. The results are like
[0] {id:"1",value:"Chapter Non-Event"}
[1] {id:"2",value:"NHQ Campaign"}
But the row_details.grp_typ is "NHQ Campaign".
Even though I assign it , the drop down option is not selected accordingly .
Have I to assign it to the value property only ? What am I missing ?
use ng-repeat instead of ng-options
eg:
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-model="referenceEdit.groupType">
<option value="-1">---</option>
<option ng-repeat="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" value="{[{groupType.id}]}"> {[{groupType.value}]} </option></select>

Categories

Resources