Angular ng-repeat ignoring nested ng-if - javascript

Howdie do,
I'm attempting to only display an option if the code that the client used to login, matches the $scope.code in the controller.
The HTML should then display the option that matches the code the client logged in with.
View:
<div class="">
<select id="customer-dd" ng-model="selectedCustomer" ng-repeat="(group, msg) in codes">
<option value="">select...</option>
<div ng-if=" 'group' == 'code' ">
<option value="{{ group }} ">{{ msg }}</option>
</div>
</select>
</div>
Controller:
$scope.code = dataFactory.getCode();
$scope.codes = {
'ABC': 'First option',
'DEF': 'Second option'
}
There should only be one option showing as a client can't login with more than one code at a time
However, when I run this, I keep getting two input boxes instead of just the one that matches the code.
Is there something I'm missing here?
* UPDATE *
I've updated the code to the following and multiple options are still being printed:
<div class="">
<select id="customer-dd" ng-model="selectedCustomer" ng-repeat="(group, msg) in codes">
<option value="">select...</option>
<div ng-if=" group == code ">
<option value="{{ group }} ">{{ msg }}</option>
</div>
</select>
</div>
* UPDATE *
#ieaglle Removing the div allowed the if statement to excecute. The updated HTML is now:
<div class="">
<select id="customer-dd" ng-model="selectedCustomer" ng-repeat="(group, msg) in codes">
<option value="">select...</option>
<option ng-if=" group == code " value="{{ group }} ">{{ msg }}</option>
</select>
</div>
THANKKKK UUUU!!!

Try using ng-options instead with a filtered object.
http://jsfiddle.net/joshdmiller/hb7lu/
HTML:
<select ng-model="selectedCustomer" ng-options="msg for (group, msg) in filterObjsByProp(codes)"></select>
JS:
$scope.code = 'ABC';
$scope.codes = {
'ABC': 'First option',
'DEF': 'Second option'
};
$scope.filterObjsByProp = function (items) {
var result = {};
angular.forEach(items, function (value, key) {
if (key === $scope.code) {
result[key] = value;
}
});
return result;
}
Although this is overkill, since an object cannot have multiple properties with the same name, so you will only ever have 1 option in the select. As such, maybe a select is not the best option here, or maybe an array with key/value objects is better.

Change your HTML to this.
Notice the change in the ng-if statement.
<div class="">
<select id="customer-dd" ng-model="selectedCustomer">
<option value="{{ group }}" ng-repeat="(group, msg) in codes">select...
<div ng-if=" group == code ">
{{ msg }}
</div>
</option>
</select>
</div>

Related

Creating a dropdown that dynamically creates another dropdown in Laravel

I'm fairly new to Laravel (and I love it!) I'm trying to do something a bit complicated: Creating a drop-down menu that upon selection of an option -will display a second drop-down menu that will give further options dynamically based on the previous selection.
My controller looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Manufacturer;
use App\GearCategory;
use App\SubCategory;
use App\GearItem;
class GearItemController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create(Manufacturer $manufacturers, GearItem $gearItem, GearCategory $gearCategory, SubCategory $subCategory)
{
// dd($gearCategory->all());
$catNum = 6; // <-- needs to be equal to the dispaly div name. Hard coded as 6 for test purposes.
$gearCategory = $gearCategory->all();
$subCategory = $subCategory::where('gear_categories_id', $catNum)->get();
$manufacturers = $manufacturers->all();
return view('gearitem.create', compact('gearCategory'), compact('subCategory'), compact('manufacturers'), compact('gearItem'));
}
}
My blade looks like this:
<div class="card-header">
<h3>Add a new gear Item</h3>
</div>
<div class="container">
<select name="gear_categories_id" id="gear_categories_id" class="custom-select mb-3 mt-3"
onchange="selector('display_div', this)">
<option value="" selected>Choose category</option>
#foreach ($gearCategory as $category)
<option id="cat_selector" value="{{ $category->id }}"
{{ (old("gear_categories_id") == $category->id ? "selected" : "") }}>{{ $category->name }}
</option>
#endforeach
</select>
</div>
<script>
"use strict"
function selector(divId, element) {
console.log(element.value);
document.getElementById(divId).setAttribute("name", element.value)
}
</script>
<div class="display_div container" id="display_div" name="">
<select name="sub_categories_id" id="sub_categories_id" class="custom-select mb-3 mt-3"
onchange="selector('display_div', this)">
<option value="" selected>Choose item's type</option>
#foreach ($subCategory as $scategory)
<option id="cat_selector" value="{{ $scategory->id }}"
{{ (old("sub_categories_id") == $scategory->id ? "selected" : "") }}>{{ $scategory->name }}
</option>
#endforeach
</select>
</div>
(Sorry for using vanilla JS i haven't gotten into Vue yet...) I'm trying to pass the name of the "display_div" onto the $catNum variable in the controller (set to "6" just to test if it works but should be set to whatever the user is choosing on the first dropdown) The values of the 'gear_categories_id' appear as a foreign key in the SubCategory model and if i'll manage to feed these values to the second dropdown it would work. I've been struggling for hours with it and I can't figure it out... Please help and sorry for being such a n00b.
You can use an AJAX request on change of the parent category drop-down to populate the subcategories. See the code below. I have added a second route to get subCategories for a specific categoryID.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Manufacturer;
use App\GearCategory;
use App\SubCategory;
use App\GearItem;
class GearItemController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function create(Manufacturer $manufacturers, GearItem $gearItem, GearCategory $gearCategory, SubCategory $subCategory)
{
// dd($gearCategory->all());
$catNum = 6; // <-- needs to be equal to the dispaly div name. Hard coded as 6 for test purposes.
$gearCategory = $gearCategory->all();
$subCategory = $subCategory::where('gear_categories_id', $catNum)->get();
$manufacturers = $manufacturers->all();
return view('gearitem.create', compact('gearCategory'), compact('subCategory'), compact('manufacturers'), compact('gearItem'));
}
public function getSubCategories($categoryID) {
return SubCategory::where('gear_categories_id', $categoryID)->get();
}
}
Route::get('/sub-categories/{categoryID}', 'GearItemController#getSubCategories');
<div class="card-header">
<h3>Add a new gear Item</h3>
</div>
<div class="container">
<select name="gear_categories_id" id="gear_categories_id" class="custom-select mb-3 mt-3"
onchange="selector('display_div', this)">
<option value="" selected>Choose category</option>
#foreach ($gearCategory as $category)
<option id="cat_selector" value="{{ $category->id }}"
{{ (old("gear_categories_id") == $category->id ? "selected" : "") }}>{{ $category->name }}
</option>
#endforeach
</select>
</div>
<script>
"use strict"
function selector(divId, element) {
console.log(element.value);
document.getElementById(divId).setAttribute("name", element.value);
fetch('/sub-categories/')
.then(res => res.json())
.then(subCategories => {
var options = subCategories.reduce( (opts, cat) =>
`${opts}<option value="${cat.id}">${cat.name}</option>`, "");
document.getElementById("sub_categories_id").innerHTML = `<option value="" selected>Choose item's type</option>${options}`;
});
}
</script>
<div class="display_div container" id="display_div" name="">
<select name="sub_categories_id" id="sub_categories_id" class="custom-select mb-3 mt-3"
onchange="selector('display_div', this)">
<option value="" selected>Choose item's type</option>
</select>
</div>

Access value of option in select and pass it to function - Angular 5

I have an angularForm and a combobox which is filled with options from the database. I need to get the selected option and pass it to a function on button click
<div class="form-group">
<select class="form-control" formControlName="product" #product>
<option *ngFor="let product of products" [value]='product'>{{product.name}}</option>
</select>
</div>
<div class="form-group">
<button (click)="addFeature(name.value, description.value,product.value)" [disabled]="angForm.pristine || angForm.invalid" class="btn btn-primary">Add</button>
</div>
When I click the button and console.log product.value I get [object,object], how to fix this?
addFeature(name, description, product) {
console.log(product);
// this.featureservice.addFeature(name, description,product);
// this.router.navigate(['/features/index']);
// location.reload();
}
UPDATE
The values in the combobox are filled by:
ngOnInit() {
this.getProducts();
}
getProducts() {
this.productservice.getProducts().subscribe(res => {
this.products = res;
})
}
You are getting the whole object, if you need name or description , access it as
addFeature(name, description, product) {
console.log(product.name);
}
EDIT
You can use ngModel and access the variable directly
<select class="form-control" [(ngModel)]="selectedProduct" formControlName="product" #product>
<option *ngFor="let product of products" [value]='product'>{{product.name}}</option>
</select>
and you can access it as,
addFeature() {
console.log(this.selectedProduct);
}
Bind to ngValue instead value of the option tag:
<div class="form-group">
<select class="form-control" formControlName="product" #product>
<option *ngFor="let product of products" [ngValue]='product'>{{product.name}}</option>
</select>
</div>
See Differences between value and ngValue in Angular 5 for more info.
I don't get your doubt precisely but try to change your select tag to something like so:
<select class="form-control" formControlName="product" #product>
<option *ngFor="let product of products" [value]='product.value'
{{product.name}}
</option>
</select>
I found the solution myself
<select class="form-control" [(ngModel)]='selectedOption' formControlName="product" #product>
<option *ngFor="let product of products" [ngValue]='product'>{{product.name}}</option>
</select>
<button (click)="addFeature(name.value, description.value,selectedOption.name)" [disabled]="angForm.pristine || angForm.invalid" class="btn btn-primary">Add</button>

If Dropdown Selected, push into one array, otherwise, push into a different one

Im programming an app, and i want to push something in a Array, if a Item of the Dropdown is selected, if its not, then it should push it into another Array.
Heres some Code:
html.js
<label class="item item-input item-select">
<div class="input-label">
Muscle
</div>
<select ng-model="selOption">
<option>Chest</option>
<option>Biceps</option>
<option>Back</option>
<option>Stomach</option>
<option>Legs</option>
<option>Triceps</option>
<option>Shoulders</option>
<option>Traps</option>
</select>
</label>
app.js
$scope.selOption = "Chest";
$scope.createEx = function(){
if($selOption = "Chest")
{
$scope.chestEx.push({title:...., reps:....});
console.log("Test");
};
};
I don't know ionic-framework but in angular code and html need to change.
need to use value="someVlue" in your option tag and compare like if($scope.selOption === "Chest") instead of if($selOption = "Chest")
html:
<select ng-model="selOption"> <!--if you want to call on change value then use ng-change="createEx()"-->
<option value="Chest">Chest</option>
<option value="Biceps">Biceps</option>
<option value="Back">Back</option>
<option value="Stomach">Stomach</option>
<option value="Legs">Legs</option>
<option value="Triceps">Triceps</option>
<option value="Shoulders">Shoulders</option>
<option value="Traps">Traps</option>
</select>
and controller code:
$scope.selOption = "Chest";
$scope.createEx = function() {
if($scope.selOption === "Chest"){
$scope.chestEx.push({title:...., reps:....});
console.log("Test");
}
else {// as you need}
};
Another option is to use the ng-change directive and repeat an array of options like this:
https://jsfiddle.net/kdb9ed7f/
Controller
function Controller($scope) {
var vm = this;
vm.myOptions = [];
vm.options = [
'Chest',
'Biceps',
'Back',
'Stomach',
'Legs',
'Triceps',
'Shoulders',
'Traps'
];
vm.checkOption = checkOption;
function checkOption() {
if (vm.options[vm.selOption] == 'Chest') {
vm.myOptions.push({
name: 'Chest'
});
vm.selOption = null;
}
}
}
HTML
<div ng-controller="Controller as ctrl">
<select ng-model="ctrl.selOption" ng-options="k as v for (k,v) in ctrl.options" ng-change="ctrl.checkOption()">
<option>Select One</option>
</select>
<hr>
<ul>
<li ng-repeat="option in ctrl.myOptions">{{option.name}}</li>
</ul>
</div>

Passing an ng-model value to an object

I have a list made with ng-repeat with options. I'm trying to make it so that when I click an option, the value of the selection will be passed to an object.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" >
<option value="1" ng-repeat="t in klas" ng-model="vakselect">{{ t.Name }}</option>
</select>
$scope.user = {
vak: klas.vakselect,
};
I have small experience with Angular, so I'm not sure how to make it work correctly.
Edit:
I have adjusted my code and user.vak does seem to catch the selectvak field, but now passes it as an array. How do I make it so it's a string in $scope.user? So whenever I log user, I will see a string of vak and then an array of students.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" ng-model="user.vak" ng-options="t.Name as t.Name for t in klas" ng-click="getJSON1()">
$scope.user = {
vak: '',
// klas: klasselect,
student: [$scope.student] -1
};
TLJ and Arnaud are correct.
But answering your initial question, in the select tag, instead of ng-model="vakselect" just use ng-model="user.vak".
Then, when the value of the select changes, the value of user.vak will change automatically.
real code is this : (and nothing to do inside the controller.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" ng-model="user.vak">
<option value="1" ng-repeat="t in klas">{{ t.Name }}</option>
</select>
And you should use ng-options instead of ng-repeat to create your options
https://docs.angularjs.org/api/ng/directive/ngOptions
This will add t.name to an array when you click the option. Take a look at the controller function and the ng-click in the partial.
<select id="selectvak" name="selectvak" class="form-control" multiple="multiple" >
<option value="1" ng-repeat="t in klas" ng-click="add(t.Name)" ng-model="vakselect">{{ t.Name }}</option>
</select>
var string_option;
$scope.add = function(t) {
string_option = t;
console.log(string_option )
}

How to create select option using directives on button click in Angularjs

I want to know how can i duplicate a select tag when i already render it using this lists..
var lists = [{name: "blue"},{name: "green"},{name: "red"},{name: "yellow"}]
and there is a add button to duplicate this select tags.
I created fiddle for this:
http://jsfiddle.net/rdy4e4xx/
I am thinking to used directives for this but i dont know where to start. Thanks guys.
I think you are looking for something like this (Updated):
HTML:
<div ng-controller="ListsCtrl">
{{ mySizes }}
<select ng-model="selectTag.value" ng-repeat="selectTag in selectTags">
<option value="">- - Make Selection - -</option>
<option ng-repeat="size in sizes" value="{{ size.name }}">{{ size.name}}</option>
</select>
<button type="button" ng-click="duplicateSelectTag()">Duplicate Select Tags</button>
Selected values:
<ul ng-repeat="selectTag in selectTags">
<li>{{selectTag.value}}</li>
</ul>
</div>
JS:
var app = angular.module("app",[]);
app.controller('ListsCtrl',function($scope){
$scope.sizes = [{name: "blue"},{name: "green"},{name: "red"},{name: "yellow"}];
$scope.selectTags=[{
value:null
}];
$scope.duplicateSelectTag = function() {
$scope.selectTags.push({});
}
});
Demo
I think you are looking for this
<div ng-controller="ListsCtrl">
{{ mySizes }}
<select ng-model="mySizes">
<option value="">- - Make Selection - -</option>
<option ng-repeat="size in sizes" value="{{ size.name }}">{{ size.name}}</option>
</select>
<button ng-click="dupplicate(mySizes)">Duplicate Select Tags</button>
</div>
var app = angular.module("app",[]);
app.controller('ListsCtrl',function($scope){
$scope.sizes = [{name: "blue"},{name: "green"},{name: "red"},{name: "yellow"}];
$scope.dupplicate = function(mySizes){
$scope.sizes.push({name: mySizes});
};
});

Categories