But I have problem when I checked radio button doesn't change ng-model="title"
I changed this code a lot but I can not find a solution. Can someone help, I think there is a problem here in ng-repeat?
Can someone help solve this problem?
I have code:
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field" ng-model="title" value="{{option.title}}" ng-checked="$index == 0" />
{{option.title}}
</label>
<span>{{title}}</span>
</div>
__
var app = angular.module("SampleApp", []);
app.controller("SampleAppCtrl", function($scope) {
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
$scope.title = $scope.dbQuestion[0].title;
});
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
Having a '.' in your models will ensure that prototypal inheritance is in play. So, use
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
app.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{ /*..*/ }];
});
For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.
The DEMO
angular.module("app", [])
.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
</div>
</body>
You need to use $parent.title instead of title, like this :
<input type="radio" name="form-field" ng-model="$parent.title" value="{{option.title}}" ng-checked="$index == 0" />
ng-repeat creates its own scope and in order to assign the value to the parent scope from the child scope we need to use $parent
Related
How can i display a confirmation alert only if i want to change radio button on previous step? So if i confirm my action all steps below should be removed.
I've binded a #change directive to the radio button with a method implementing the expected confirmation alert, but it appears on each change i make.
Here is my fiddle
Thanks for your advices in advance
new Vue({
el: "#app",
data() {
return {
answer: ["1"],
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
},
{
id: "2",
yes_section: "5",
no_section: "1",
name: "Step 2",
},
{
id: "3",
yes_section: "2",
no_section: "4",
name: "Step 3",
},
{
id: "4",
yes_section: "2",
no_section: "4",
name: "Step 4",
},
{
id: "5",
yes_section: "2",
no_section: "4",
name: "Step 5",
},
],
};
},
computed: {
quation() {
return this.answer.map((answer) => {
return this.stepsData.find((step) => step.id === answer);
});
},
},
methods: {
pushAnswer(answer) {
this.answer.push(answer);
},
confirmPopup() {
alert('Are you sure?')
},
},
});
.step {
background: #ccc;
padding: 20px;
margin-bottom: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(step, id) in quation" :key="id" class="step">
<div v-html="step.name"></div>
<div>
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.yes_section"
#click="pushAnswer(step.yes_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
YES {{ step.yes_section }}
</label>
</div>
<div class="legal-aid__step-action_no">
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.no_section"
#click="pushAnswer(step.no_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
NO {{ step.no_section }}
</label>
</div>
</div>
</div>
I would add a property on every stepData that is called isSelected which will be initialized to false and once it was clicked, it will be changed to true.
So you data will look like this:
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
isSelected: false
},
....
]
You will need to change pushAnswer to set isSelected to `true:
#click="pushAnswer(step)"
pushAnswer(answer) {
answer.isSelected = true;
this.answer.push(answer.yes_section);
},
And confirmPopup function will check if the answer is already selcted or not:
#change="confirmPopup(step)"
confirmPopup(step) {
if (step.isSelected) {
alert('Are you sure?')
}
},
Of course you can change anything to your liking, but this is the basic idea
I have recently started learning KendoUI and have come up with this issue. I am trying to include a dropdownlist in kendo grid using MVVM approach. The grid has 3 columns- Checkbox, text and dropdownlist. I want to manually set the dropdownlist value based on whether the checkbox is checked or not. As an example here i am trying to set the Class as 'Class 3' if checkbox is unchecked. Even though index is set to 2, it gets reverted back to the class from the model at the end of the event dataBound. Can anyone help me with this? I need to forcefully set the dropdown index. Thank you.
<script type="text/x-kendo-template" id="checkboxGrid">
<input type="checkbox" data-bind="checked: IsChecked" />
</script>
<script type="text/x-kendo-template" id="ddlGrid">
<input data-role="dropdownlist"
data-auto-bind="true"
data-text-field="name"
data-value-field="id"
data-auto-bind="true"
data-bind="source: actionSource, value: class, events:{dataBound: dataBound }"/>
</script>
<div id="content" >
<div id="my-grid"
data-role="grid"
data-sortable="true"
data-selectable="true"
data-columns='[
{"field": "IsChecked", "title":" ", template: kendo.template($("#checkboxGrid").html())},
{"field": "Name", "title":"Name" },
{"field": "class", "title":"Class", template: kendo.template($("#ddlGrid").html())}
]'
data-bind="source: dataSource">
</div>
</div>
<script>
$(document).ready(function() {
var viewModel = new kendo.data.ObservableObject({
dataSource: [
{ IsChecked: true, Name: "Student 1", class: { name: "Class 1", id:"1" }},
{ IsChecked: false, Name: "Student 2", class: { name: "-Please Select-", id:"999" } },
{ IsChecked: false, Name: "Student 3", class: { name: "-Please Select-", id:"999" }},
{ IsChecked: true, Name: "Student 4", class: { name: "Class 3", id:"3" } }
],
actionSource: [
{ name: "-Please Select-", id:"999"},
{ name: "Class 1", id:"1" },
{ name: "Class 2", id:"2" },
{ name: "Class 3", id:"3" }
],
dataBound: function(e) {
var ddl = e.sender;
var gridRow = $(ddl.element).closest( "tr" );
var checkbox = $(gridRow).find('input[type=checkbox]');
debugger;
if(checkbox.prop("checked") == false){
console.log("Checkbox checked : " + false);
//explicitly trying to set class to 'Class 3'
ddl.select(2);
debugger;
}
//Even though index is set to 2, it gets reverted back to the class from the model at the end of the event
}
});
kendo.bind($('#my-grid'), viewModel);
});
</script>
I have mobile brand list .here based on 1st drop down 2nd dropdown list is coming but .when i select nokia in 1st dropdown ,Lumia 735,Asha 230,Lumia 510 these are coming in 2nd dropdown,in 2nd dropdown i have selected Lumia 735 its working fine but again i have selected Samsung in 1st dropdown here 2nd drop list got changed but already selected Lumia 735 still showing .
expectation:based on 1st dropdown selection 2nd dropdown should come
2.after 1st and 2nd dropdown selection ,when i submit i need to get id,brandname,modelname
angular.module('myApp', ['ui.filters'])
.controller("myCntrl", function ($scope) {
$scope.items= [{
id: "986745",
brandname: "Nokia",
modelname: "Lumia 735",
price: "7500"
}, {
id: "896785",
brandname: "Nokia",
modelname: "Asha 230",
price: "12000"
}, {
id: "546785",
brandname: "Nokia",
modelname: "Lumia 510",
price: "9500"
},
{
id: "144745",
brandname: "Samsung",
modelname: "Samsung 110",
price: "13000"
},
{
id: "986980",
brandname: "Samsung",
modelname: "Galaxy A5",
price: "5500"
},
{
id: "586980",
brandname: "Samsung",
modelname: "Galaxy Note 4 Duos",
price: "5500"
},
{
id: "986980",
brandname: "Samsung",
modelname: "Galaxy A5",
price: "5500"
},
{
id: "586980",
brandname: "Samsung",
modelname: "Galaxy Note 4 Duos",
price: "1000"
},
{
id: "232980",
brandname: "Htc",
modelname: "One X9",
price: "1000"
},
{
id: "456798",
brandname: "Htc",
modelname: "Desire 820",
price: "1000"
}
]
$scope.test = function()
{
console.log($scope.id);
console.log($scope.selectedBrand);
console.log($scope.selectedModel);
}
})
$(function () {
setTimeout(function () {
$("select").select2();
}, 100);
});
//]]>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.full.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.min.css" />
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCntrl">
<form name="addvehicleForm" data-ng-submit="test()" novalidate>
<label>List Of Brand</label>
<label for="singleSelect"> select: </label>
<select ng-model="selectedBrand">
<option ng-repeat="item in items | unique: 'brandname'" value="{{item.brandname}}">{{item.brandname}}</option>
</select>
<select ng-model="selectedModel">
<option ng-repeat="item in items | filter: {brandname: selectedBrand}" value="{{item.modelname}}">{{item.modelname}}</option>
</select>
<div class="padding">
<button class="button button-full button-stable" type="submit" > Save
</button>
</div>
</form>
</div>
</div>
pls run above code and solve the issue
Seems all you want is to clear the model if you change the brand, to do that, just put ng-click on
<select ng-model="selectedBrand">
<option ng-repeat="item in items | unique: 'brandname'" value="{{item.brandname}}"
ng-click="setNull()">{{item.brandname}}</option>
</select>
and in script do something like
angular.module('myApp', ['ui.filters'])
.controller("myCntrl", function ($scope) {
$scope.setNull = function(){
$scope.selectedModel = "";
}
.
.
.
I'm attempting to get at the version data stored inside the server model, however, it's not playing ball.
My assumption is that on load the initial data from the first select is not yet available because it hasn't really been selected (technically speaking). I tried to use trigger('click') whether this would help at all, but it did absolutely nothing. I can't seem to find any answers out there and I have a feeling I maybe tackling it from the wrong end.
edit: Forgot to mention, if I have to restructure my data to allow for this to happen, so be it.
Here's all my code + JSFiddle:
http://jsfiddle.net/h8uoy9xr/3/
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app>
<div ng-controller="MyCntrl">
<div class="selection" ng-repeat="selection in selections">
<select ng-model="server" ng-options="server as server.name for server in servers track by server.id" ng-init="server.id=selection.server"></select>
{{ server | json }}
<select ng-model="version" ng-options="version as version.name for version in server.version track by version.id" ng-init="version.id=selection.version"></select>
</div>
</div>
</div>
JS:
function MyCntrl($scope) {
$scope.servers = [
{
"id": 1,
"name": "server1",
"version":
[
{
id:1,
name: "10.x"
},
{
id:3,name: "12.x"
}
]
},
{
"id": 2,
"name": "server2",
"version":
[
{
id: 2,
name: "1.0"
},
{
id: 3,
name: "2.0"
}
]
}
];
$scope.selections = [
{
server: 2,
version: 3
},
{
server: 1,
version: 3
}
];
}
cascading dropdownlist inside ng-repeat
Here's a working solution of the above problem. I hadn't realized angularjs did things a wee bit differently with the models, but finally it clicked. See below code + fiddle for anyone needing something similar in the future:
Fiddle: http://jsfiddle.net/mmy6z57g/2/
Fiddle: http://jsfiddle.net/mmy6z57g/3/ (added a button to demonstrate how additional servers can be added)
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="test">
<div ng-controller="MyCntrl">
<div class="selection" ng-repeat="xserver in xservers">
<select ng-model="xservers[$index]" ng-options="server as server.name for server in servers track by server.id"></select>
<select ng-model="xversions[$index]" ng-options="version as version.name for version in xservers[$index].version track by version.id"></select>
</div>
</div>
</div>
JS:
var app = angular.module('test', []);
app.controller('MyCntrl', function($scope) {
$scope.servers = [
{
id: 1,
name: "server1",
version:
[
{
id:1,
name: "10.x"
},
{
id:3,
name: "12.x"
}
]
},
{
id: 2,
name: "server2",
version:
[
{
id: 2,
name: "1.0"
},
{
id: 3,
name: "2.0"
}
]
}
];
$scope.xservers = [
{
id: 2,
name: "server2",
version:
[
{
id: 2,
name: "1.0"
},
{
id: 3,
name: "2.0"
}
]
},
{
id: 1,
name: "server1",
version:
[
{
id:1,
name: "10.x"
},
{
id:3,
name: "12.x"
}
]
}
];
$scope.xversions = [
{
id: 3,
name: "2.0"
},
{
id: 3,
name: "12.x"
}
];
});
Could you use your controller and use a .then(); so that it selects the first one and when that is done then it selects the second? User wouldn't see it and it would solve the issue of second one not getting selected.
I have an application that is using angular.js and I'm very new to it. I have a list of checkboxes that gets dynamically created based on a previous selection.
For example, if I have a dropdown of Fruits, the following html will get created:
<input type='checkbox' value="apple">apple</input>
<input type='checkbox' value="banana">banana</input>
<input type='checkbox' value="mango">mango</input>
<input type='checkbox' value="orange">orange</input>
<input type='checkbox' value="pear">pear</input>
<input type='checkbox' value="watermelon">water</input>
However, sometimes the amount of checkboxes that get generated gets more than 20 items, and I want to make use of some unused space.
So I was wondering if it's possible to split a list of checkboxes into two columns instead of one, so that a new column will generate filling up the rest of the checkboxes?
For example: If I have 18 items, instead of one large list of a single column containing 18 checkboxes, the final result will be to have 10 checkboxes in on column, and 8 checkboxes in another column next to it. I want to only have 2 columns as the maximum. Is this possible?
Here is what I have so far, I'm not sure if this is the best way of doing it. Otherwise I'll just make an answer for this question and mark it as such. Logic for splitting the data will be done in code-behind I guess.
example: http://jsfiddle.net/7843b/
Visual representation
X Apple X Pears
X Banana X Watermelon
X Mango
X Orange
The X represents a checkbox.
Seems like these solutions are a bit more complicated than needs to be. Let css handle putting them into columns:
Javascript:
$scope things = ["car", "box", "plant", "dice", "knife", "calendar"];
html:
<div class="checkbox-column" ng-repeat='thing in things'>
<input type="checkbox" /><span>{{thing}}</span>
</div>
in the css display each element with an inline-block and a width around 48%.
.checkbox-column{
display: inline-block;
width:48%;
}
The width of 48% will give it 2 columns. If you want 3 columns, then just use a width of like 30%.
This will also keep the columns aligned when the browser window is adjusted.
Another way is to add column number to each team in the $scope.teams.
http://jsfiddle.net/dkitchen/y5UzD/4/
This splits them into groups of 10...
function TeamListController($scope) {
$scope.teams = [
{ name: "apple", id: 0, isChecked: true, col:1 },
{ name: "banana", id: 1, isChecked: false, col:1 },
{ name: "mango", id: 2, isChecked: true, col:1 },
{ name: "orange", id: 3, isChecked: true, col:1 },
{ name: "pear", id: 4, isChecked: false, col:1 },
{ name: "john", id: 5, isChecked: true, col:1 },
{ name: "paul", id: 6, isChecked: false, col:1 },
{ name: "george", id: 7, isChecked: true, col:1 },
{ name: "ringo", id: 8, isChecked: true, col:1 },
{ name: "roger", id: 9, isChecked: false, col:1 },
{ name: "dave", id: 10, isChecked: true, col:2 },
{ name: "nick", id: 11, isChecked: false, col:2 }
];
}
You can do that at the data source, or you can assign the column number later in the controller.
For example, this bit re-groups them into 8 items per column:
var colCounter = 1;
var colLimit = 8;
angular.forEach($scope.teams, function(team){
if((team.id + 1) % (colLimit + 1) == 0) {
colCounter++;
}
team.col = colCounter;
});
Then in the view, you can filter each repeater by column number:
<div ng-app>
<div ng-controller="TeamListController">
<div class="checkboxList">
<div id="teamCheckboxList">
<div ng-repeat="team in teams | filter: { col: 1 }">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name }}</span>
</label>
</div>
</div>
</div>
<div>
<div id="teamCheckboxList1">
<div ng-repeat="team in teams | filter: { col: 2 }">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name}}</span>
</label>
</div>
</div>
</div>
</div>
This is not so surprising question at all. You can dynamically add the items in either js or else you can do the same in html itself. I am here mentioning how to split dynamically based on the number of items.
function TeamListCtrl($scope) {
$scope.teams = [
{ name: "apple", id: 0, isChecked: true },
{ name: "banana", id: 1, isChecked: false },
{ name: "mango", id: 2, isChecked: true },
{ name: "orange", id: 3, isChecked: true },
{ name: "pear", id: 4, isChecked: false },
{ name: "watermelon", id: 5, isChecked: true }
];
column1 = [];
column2 = [];
$.each($scope.teams, function(index){
console.log("index"+index);
if(index%2==0) {
column1.push($scope.teams[index]);
} else{
column2.push($scope.teams[index]);
}
});
$scope.columns.push(column1);
$scope.columns.push(column2);
}
And you can modify your html code as:
<div ng-app>
<div ng-controller="TeamListCtrl" class="checkboxList">
<div id="teamCheckboxList">
<div ng-repeat='column in columns'>
<div class='someClassToArrangeDivsSideBySide' ng-repeat="team in column">
<label>
<input type="checkbox" ng-model="team.isChecked" /> <span>{{team.name}}</span>
</label>
</div>
</div>
</div>
</div>
</div>