angularjs ng-repeat determine what item is clicked - javascript

Im loading objects into clickable boxes using ng-repeat.
now i want to return the objects title when the user has clicked its item-box
normally i would put it in a ng-model but since im using ng-repeat the model will be reused in every created box...
i am searching for a way to check the selected objects title. and put it in a ng-model for re-use later on.
code now:
creation of object boxes in html:
<div class="row form-group product-chooser">
<a href="#drop">
<div id="catagories" ng-repeat="catagories in main.catagories" class="col-xs-12 col-sm-12 col-md-4 col-lg-4" value="{{catagories.title}}">
<div class="product-chooser-item">
<img src="{{catagories.image}}" class="img-rounded col-xs-4 col-sm-4 col-md-12 col-lg-12" alt="Catagories">
<div class="col-xs-8 col-sm-8 col-md-12 col-lg-12">
<span class="title">{{catagories.title}}</span>
<span class="description">{{catagories.description}}</span>
<input type="radio" name="product" value="{{catagories.title}}">
</div>
<div class="clear"></div>
</div>
</div>
</a>
</div>
<P>selected is: {{main.CreateProject.ProjectCatagorie}}</P>
contoller js file:
// objects
vm.catagories = [
{
id: 1,
title: 'Mobile and Desktop',
description: 'Full concept design to complete App',
image: '../img/Project/desktop_mobile.png'
},
{
id: 2,
title: 'Desktop',
description: 'Blogs, Webshops, complete full back-end Web-Apps',
image: '../img/Project/desktop.png'
},
{
id: 3,
title: 'Mobile',
description: 'Mobile websites, Apps for Android and/or IOS',
image: '../img/Project/mobile.png'
}
];
//javascript to put the checked prop on the checked box:
//works
$(function(){
$('div.product-chooser').find('div.product-chooser-item').on('click', function(){
// remove selected class form all
$(this).parent().parent().find('div.product-chooser-item').removeClass('selected');
// put checked
$(this).addClass('selected');
$(this).find('input[type="radio"]').prop("checked", true);
// get seleciton
if ($('input[type=radio]:checked').length > 0) {
// do something here
alert($('input[type=radio]:checked').val());
}
// set rest disabled
$('div.product-chooser').not('.selected').addClass('disabled');
});
});
vm.CreateProject = function(){
// selected catagorie
//fails
ProjectCatagorie = $('input[type=radio]:checked').val();
// this model is in the function: CreateProject within the maincontroller.
// function doesnt end here...

You can for example add ngClick directive on every checkbox, and set main.CreateProject.ProjectCatagorie directly:
<input type="radio" name="product" ng-click="main.CreateProject.ProjectCatagorie = catagories">
Demo: http://plnkr.co/edit/awn63n7f1YBO5mOUMLDT?p=preview

ng-repeat does create a new child scope. The trick is to wrap the ng-model value in a object defined in the parent scope and everything works as expected.
<div ng-repeat="catagory in catagories">
<input type="radio" ng-model="selection.catagory" name="product" ng-value="catagory">
</div>
function myCtrl($scope) {
$scope.selection = {catagory : null};
$scope.catagories = [
{
id: 1,
title: 'Mobile and Desktop',
},
{
id: 2,
title: 'Desktop',
},
{
id: 3,
title: 'Mobile',
}
];
}
See https://fiddle.jshell.net/nbg58dto/

Related

Observable inside Observable array that track two elements KO js

Array of 3 radio box and input text that are tied together, selection of radio would dynamically pop text that user can add on top of. I'm able to populate the text box, but can't track changes of both afterward as I need some sort of observable that trace both change and give me the total value of both (e.g. 'File: c:\temp\data.cs'
Here my HTML
<!-- ko foreach: includes -->
<div class="col-md-3 mt-3 offset-3 ">
<input class="col-md-2 " type="radio" value="file:" data-bind="checked: type, attr: { name: name }">File
<input class="col-md-2" type="radio" value="dir:" data-bind="checked: type, attr: { name: name }">Dirs
<input class="col-md-2" type="radio" value="glob:" data-bind="checked: type, attr: { name: name }">Glob
</div>
<div class=" col-md-6 pt-3 ">
<input type="text" class="form-control" required data-bind="attr: { name: name } , value: value">
</div>
<!-- /ko -->
</div>
<div class="col-sm-3 mt-4 mb-4 offset-4" id="firstPath">
<button type="button" class="form-control btn btn-info ml-3" data-bind="click: addInclude">Add new include line</button>
</div>
And my JS
self.includes = ko.observableArray([{
name: "package[][includes][0]",
type: "file:",
value: ko.observable()
}]);
self.addInclude = function () {
self.includes.push({
name: `package[][includes][${includeCounter++}]`,
type: `file`,
value: ko.observable("file")
});
};
How to make the value property in includes observable array track both radio selection + input text value for the related row ?
I tried Ko.Computed but the issue is when initialing the type in includes observable is not define yet for relative row (default value for type is file)
The type member should be observable. So, through subscribe, you can set the value of value each time type changes.
function myViewModel() {
var self = this;
self.includeCounter = 0;
self.includes = ko.observableArray([]);
self.addInclude = function () {
var type = ko.observable('file:');
var value = ko.observable('file:');
type.subscribe((newValue) => {
value(newValue);
}, self);
var item = {
name: `package[][includes][${self.includeCounter++}]`,
type: type,
value: value
};
self.includes.push(item);
};
self.addInclude();
}
var vm = new myViewModel();
ko.applyBindings(vm);

Vue.js - can not add date/timepicker to the html element rendered by vue.js

I have a Vue.js component where there are groups of text fields ( group of a text field labelled "Start" and another text field labelled "To") bound to a Vue array ( s.timespans) .
What I want is, when I add another group of text field by adding element to the ( s.timespans ) array, all the textfields get date/timepicker. But unfortunately, now only the first group of field gets the date/timepicker and the other groups don't. What is the right way of doing this?
Thanks in advance.
<template id="settings">
<div v-for="(k,slot) in s.timespans" class="row mb5">
<div class="col-sm-5">
<label><?php _e( 'From', 'smps' ); ?></label>
<input type="text" class="datepicker form-control" v-model="slot.from">
</div>
<div class="col-sm-5">
<label><?php _e( 'To', 'smps' ); ?></label>
<input type="text" class="datepicker form-control" v-model="slot.to">
</div>
<div class="col-sm-2">
<i class="fa fa-remove"></i>
</div>
</div>
<template>
The Vue js code
Vue.component( 'settings', {
template : '#settings',
data : function () {
return {
s : {
timespans : [
{from : '', to : ''}
]
}
}
},
methods : {
add_timeslot : function () {
Vue.set(this.s.timespans,this.s.timespans.length,{from:'',to:''});
$('.datepicker').datetimepicker();
},
remove_timeslot : function (k) {
this.s.timespans.splice(k,1);
},
},
});
Try this then the DOM will be finished rendering, not before nextTick:
add_timeslot : function () {
Vue.set(this.s.timespans,this.s.timespans.length,{from:'',to:''});
this.$nextTick(function () {
$('.datepicker').datetimepicker();
});
},
when the function in nextTick is executed, the DOM Element will be rendered.

javascript to hide and show the grids based on the radio button selected and click on search button

I am working on angularjs application. Being a newbie facing issues when trying to get the below mentioned scenario.Any suggestions would be helpful.
I want to display one or two angular UI grid's based on the radio button selected at top. When user selects Show one Grid radio button and type Atlanta in From text field and Chicago in To text field and click on SearchLocations button the first angularjs ui grid should be displayed. Similarly when user selects Show two Grids radio button and type Atlanta in From and Chicago in To text field and click on SearchLocations button, two grids should be shown.
Please find the demo here.
HTML code:
<div>
<label>
Show one Grid <input type="radio" name="Passport" ng-click="ShowPassport('Y')" /></label>
<label>Show two Grids <input type="radio" name="Passport" ng-click="ShowPassport('N')" />
</label>
</div>
<div class="row">
<div class="form-group" ng-controller="citiesCtrl">
<label>From</label>
<input type="text" ng-model="places[0]" placeholder="Type Departure City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
<div class="form-group" ng-controller="citiesCtrl">
<label>To</label>
<input type="text" ng-model="places[1]" placeholder="Type Destination City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
</div>
<input type="button" value="SearchLocations" ng-click="submit()">
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>First Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>Second Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
js code:
angular.module('myApp', ['ngAnimate', 'ui.bootstrap','ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.edit','ui.grid.cellNav']);
angular.module('myApp').controller('citiesCtrl',function($scope){
// $scope. places = undefined;
$scope.items = ["Atlanta", "Chicago", "NewYork"];
$scope.selectAction = function() {
console.log($scope.places1);
};
});
/*Controller for searchLocations button*/
angular.module('myApp').controller('searchController', ['$scope', function($scope) {
$scope.places = ['', ''];
$scope.searchValue = '';
$scope.submit = function() {
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
$scope.users = [
{'name' : 'AtlantaChicago',
'show' : true,
'details' : [
{"Travel Date": "10/10/2014", commute:"Bus"},
{"Travel Date": "10/11/2014", commute:"flight"}]
},
{'name' : 'NewYorkChicago',
'show' : true,
'details': [
{"Travel Date": "3/15/2016", commute:"flight"},
{"Travel Date": "10/12/2016", commute:"flight"},
]
}
];
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [
{ name: 'Travel Date', width: '5%'},
{ name: 'Departurecommute', enableFiltering: false, width: '12%' }
],
rowHeight: 20,
enableHorizontalScrollbar:2
};
}]);
You need to change few things in order to get it working as you expected.
If you want to display grids based on radio button selection:
1. you should assign ng-model and value to your radio buttons. Radio buttons in Angular
<label>
Show one Grid
<input type="radio" name="Passport" ng-model="Passport" value=1 ng-click="ShowPassport('Y')" />
</label>
<label>Show two Grids
<input type="radio" name="Passport" ng-model="Passport" value=2 ng-click="ShowPassport('N')" />
</label>
2.Assign the Passport value to another variable on button click. Show hide using Angular
$scope.submit = function() {
$scope.showGrid = $scope.Passport; //Here
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
3.Wrap your grids in a div and assign ng-show attribute
<div ng-show="showGrid==='1'||showGrid==='2'"> //first grid
<div ng-show="showGrid==='2'"> //second grid
4.Now it should work. See the Working plnkr
refer this sample code. you can easily understand
Sample Code
https://codepen.io/SusanneLundblad/pen/iBhoJ

How to hide content with ng-if and a checkbox that's inside a ng-repeat and it's ng-model is an array

I have a list of checkboxes that are created using a ng-repeat, I use those checkboxes to get the IDs of the objects that are inside a list, these objects have a name property and a id property.
this is a object inside my categoryList
category = {
idCategory: 2,
name: 'myName'
};
And this is how I declare my checkboxes.
<div class="form-group">
<label>Select a category</label>
<label class="checkbox-inline" ng-repeat="category in categoryList">
<input type="checkbox" ng-model="idsCategory[category.idCategory]"> {{category.name}}
</label>
</div>
and then in my controller I get the ids like this
var categories= $scope.categoryList;
var idsSelected = [];
//get selected ids
for (var idCategory in categories) {
if (categories.hasOwnProperty(idCategory )) {
if (categories[idCategory ] === true) {
idsSelected .push(idCategory);
}
}
}
but now I want to hide and show some inputs in my HTML, if the user selects a category like "support" I want to show some inputs, but I don't know what condition put inside my ng-if since I declare my checkboxes ng-model like an array of ids like this ng-model="idsCategory[category.idCategory]"
how can I put my ng-if to hide the inputs I tried this but this doesn't work
<div id="b" ng-if="idsCategory.category.name=='Support'">
<div class="form-group">
<label>Support hours:</label>
<input class="form-control" placeholder="support houres">
</div>
</div>
Edited:
If we have HTML:
<div class="form-group">
<label>Select a category</label>
<label class="checkbox-inline" ng-repeat="category in categoryList">
<input type="checkbox" ng-model="idsCategory[category.idCategory]"> {{category.name}}
</label>
</div>
Conroller:
$scope.idsCategory = {};
$scope.categoryList = [{
idCategory: 1,
name: 'categoryA'
}, {
idCategory: 2,
name: 'recreation'
}, {
idCategory: 3,
name: 'develop'
}, {
idCategory: 4,
name: 'Support'
}];
Then we can use following ng-show:
<div id="b" ng-show="idsCategory[4]">
<div class="form-group">
<label>Support hours:</label>
<input class="form-control" placeholder="support houres">
</div>
</div>
See jsfiddle
In checkbox input we have ng-model="idsCategory[category.idCategory]", so idsCategory[4] stores info if category with idCategory = 4 is checked. That's why element with ng-show="idsCategory[4]" will be shown if category with idCategory = 4 is checked.

Dynamically Adding inputs in Angular 1.3.16

My Code is simple and as I searched on net, I guess it is because of angular 1.3.x
I am trying to create dynamic inputs and want to get the value in an array.
HTML:
<div class="row" ng-repeat="item in designFormData.perInstallments track by $index">
<div class="col-md-5">
<label for="">Installment #{{item.sn}}</label>
</div>
<!-- /.col-xs-6 col-sm-4 -->
<div class="col-md-7">
<input type="number" class="form-control" id="" autocomplete="off" ng-model="item.price">
</div>
<!-- /.col-xs-6 col-sm-4 -->
</div>
JS:
for (var i = 0; i < noOfInstallments; i++) {
$scope.designFormData.perInstallments.push({
sn: i+2,
price: ""
});
}
Problem:
The price is not reflecting in perInstallments
designFormData{
perInstallments:
[
{
sn: 2,
price: ""
},
{
sn: 2,
price: ""
}
]
}
values, instead of appearing in perInstallments items, are appearing in child scope of ng-repeat. how to solve this. I have tried adding track by $index as you can see.
Any suggestions.

Categories