Angular js: Adding list of nested array properties - javascript

Please help: hitting my head all the way,I am a new-bee to angular js, building a Quiz Application using angular js,
I have an issue adding array of nested properties to my controller
jsfiddle link showing the issue:
STEP BY STEP SCENARIO
I want to add a question
each question has 4 options, out of which 1 is selected as right
I am able to get the UI but binding is not working for Options
html is as below:
<div ng-app>
<div class="new-question-container" ng-controller="newQuestionController">
<h3>Add New Question</h3>
<form class="new-question-form" novalidate name="newQuestionForm" data-ng-submit="save()">
<div>
<label for="QuestionDescription">Quesiton Description</label>
<input type="text" name="QuestionDescription" data-ng-model="newQuestion.QuestionDescription" required />
</div>
Options<br/>
<div ng-repeat="i in [1,2,3,4]">
<label for="options[i].OptionDescription">Option {{i}}</label>
<input name="options[i].OptionDescription" type="text" data-ng-model="options[i].OptionDescription" required />
Is right answer:
<input type="radio" data-ng-model="options[i].IsAnswer" name="newQuestion" ng-value="true" />Yes
<input type="radio" data-ng-model="options[i].IsAnswer" name="newQuestion" ng-value="false" />No
</div>
<input type="submit" class="btn btn-primary" value="Add Question" data-ng-disabled="newQuestionForm.$invalid" />
Cancel
</form>
</div>
</div>
angular script as below
function newQuestionController($http, $scope, $window) {
$scope.newQuestion = {};
$scope.options = [{}];
$scope.save = function () {
$scope.newQuestion.Options.push(options);
alert($scope.newQuestion.QuestionDescription);
}
}

You have to initialize you $scope correct like this:
$scope.options = [{},{},{},{}];
and change the ng-repeat array to start from 0:
ng-repeat="i in [0,1,2,3]"
Here you can find a working example

Related

How to replicate input fields on click of button angular2

I'm facing the problem to replicate input fields onclick of a button
*I have few input fields and i can fill the data in that
*After filling the input fields i have a different data set to add so i need same fields.
*If i press button (addMore) the fields should replicate and it should allow me to add one more set of data.
*There should be one button(remove) that will help me to remonessessaryve those replicated fields if its not necessary.
I have tried this in angular ..and I'm sharing my sample code and plunker plz help me out
template.ts
<div class="card">
<input type="text" id="name" value="" class="form-control">
<label for="form1">Name</label>
<input type="text" id="mobile" value="" class="form-control">
<label for="form1">Mobile</label>
</div>
<button type="button" title="Add"class="btn btn-sm"
(click)="addMore">Add</button>
test.component.ts
export class App {
addMore() {
//function to replicate the form input fields
}
plunker link :- http://plnkr.co/edit/GCCnoMkLynpELwaYX11m?p=preview
You're looking for generating dynamic inputs using ngFor
You can initially create an array with initial value as follows,
inputelements = [{name: '',mobile:''}];
on click of addmore button you can push more elements and those will be rendered using ngFor
Template code will be,
<div class="card" *ngFor="let word of inputelements; let in=index" class="col-sm-3">
<div class="form-group">
<label for="form1">Name</label>
<input type="text" [(ngModel)]="inputelements[in].name" class="form-control" required>
<label for="form1">Mobile</label>
<input type="text" [(ngModel)]="inputelements[in].mobile" class="form-control" required>
</div>
</div>
<br>
<button type="button" title="Add"class="btn btn-sm pull-right"
(click)="addMore()">Add</button>
WORKING DEMO
Keep the track of the inputs with an array and add/remove with js :
inputs = [];
add() {
this.inputs.splice(0,0,this.inputs.length+1);
}
DEMO

Angularjs, radio button selection to present selective div (having input) not working

Requirement : selection of radio buttons should bring their respective input boxes.
Below is the part of my html and controller. I am using ng-change to invoke the function written in controller. The function in controller just shows the div using jquery.
fyi, My template is rendering and I don't see any error on console and functions in controller are getting invoked too.
Issue - On the click on radio button, respective div is is not rendering.
Any hints are highly appreciated.
<div ng-app="app" ng-controller="FestCtrl">
<form name="addForm" class="form-horizontal" ng-submit="submitForm(fest)">
<!-- Options to user to either enter a new role OR select from an existing one's -->
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="options" id="option1" autocomplete="off" ng-model="value" ng-change="newfest()"> New
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option2" autocomplete="off" ng-model="value" ng-change="existingfest()"> Existing
</label>
</div>
<br>
<br>
<!-- Respective input will be presented depending on above selection-->
<div id="addNewDiv" class="form-group">
<label class="control-label" for="InputId">New</label>
<input required type="text" class="form-control" id="groupIdInput" placeholder="Insert new fest" ng-model="fest.role">
</div>
<div id="selectExistingDiv" class="form-group">
<label for="select1">Select</label>
<select ng-model="fest.role" class="form-control" id="select1" ng-options="val for val in festArray">
<option value="">Select</option>
</select>
</div>
</form>
</div>
var app = angular.module('App');
app.controller('FestCtrl', ['$scope', '$state', function($scope, $state) {
$(function() {
$("[data-hide]").on("click", function() {
$(this).closest("." + $(this).attr("data-hide")).hide();
});
});
$("#addNewDiv").hide();
$("#selectExistingDiv").hide();
$scope.newRole = function() {
$("#addNewDiv").show();
}
$scope.existingRole = function() {
$("#selectExistingDiv").show();
}
}]);
One of the key problems you're facing in this case is a result of your use of jQuery in combination with Angular. Among other problematic areas, (which are discussed in this question Is that a good practice to use jQuery with AngularJS?) you are interacting with a polluted global scope by referencing the $. Angular uses a lot of $ prefixed methods in it's namespace.
Inside your angular controller, you won't even have a reference to the Window object which is what jQuery attaches it's namespace ($) to. In Angular, if you need a reference to the window object, you can use the $window provider https://docs.angularjs.org/api/ng/service/$window.
Lastly on the subject of using jQuery in combination with angular, there are certainly instances where you need to touch the DOM. Angular's paradigm for handling this is called directives. Directives aren't incredibly easy to understand, and are out of scope of this answer, but I encourage you to read more about them here -> https://docs.angularjs.org/guide/directive.
Here's a working example of how this could work.
function FestController($scope) {
$scope.state = {
selected: 0,
fest: {
role: ""
}
};
}
angular.module("bacon", []);
angular.module("bacon").controller("FestController", FestController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="bacon" ng-controller="FestController">
{{state.selected}}
<input type="number" ng-model="state.selected" />
<form class="form-horizontal" id="addForm" name="addForm" ng-submit="submitForm(fest)">
<!-- Options to user to either enter a new role OR select from an existing one's -->
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input autocomplete="off" id="option1" name="options" ng-model="state.selected" ng-value="0" type="radio"> New</label>
<label class="btn btn-primary">
<input autocomplete="off" id="option2" name="options" ng-model="state.selected" ng-value="1" type="radio"> Existing</label>
</div>
<!-- Respective input will be presented depending on above selection-->
<div class="animate-switch-container" ng-switch="state.selected">
<div class="form-group" id="addNewDiv" ng-switch-when="0">
<h1>
{{state.fest.role}}
</h1>
<label class="control-label" for="InputId">New</label>
<input class="form-control" id="groupIdInput" ng-model="state.fest.role" placeholder="Insert new fest" required="" type="text">
</div>
<div class="form-group" id="selectExistingDiv" ng-switch-when="1">
<label for="select1">Select</label>
<select class="form-control" id="select1" ng-model="state.fest.role" ng-options="val for val in festArray">
<option value="">
Select
</option>
</select>
</div>
</div>
</form>
</div>
You can see that I've completely removed any reference to jQuery, and any reference to direct DOM manipulation.
I've chosen to use the ng-switch built-in angular directive which you can read up on here https://docs.angularjs.org/api/ng/directive/ngSwitch
Moving the state into an object attached to $scope inside the controller allows those values to be referenced in the template and allows two-way binding to work.
I did also remove your functions on the controller to emphasize the two-way binding using the switch directive. Stuff happens when those values are updated on $scope. Whether you choose to rely on this specific implementation or not is a matter of preference and architecture, but this is one way you can accomplish your task.
newfest and existingfest methods does not exists in your controller. You have:
$scope.newRole = function() {
$("#addNewDiv").show();
}
$scope.existingRole = function() {
$("#selectExistingDiv").show();
}
change
<input type="radio" name="options" id="option1" autocomplete="off" ng-model="value" ng-change="newfest()">
to
<input type="radio" name="options" id="option1" autocomplete="off" ng-model="value" ng-change="newRole()">

Dynamic ng-model for input AngularJs

I have a problem. When I use static template on render page
<form name="AddArticle" ng-submit="addArticle()" class="form add-article">
<input type="text" value="first" init-from-form ng-model="article.text[0]" />
<input type="text" value="second" init-from-form ng-model="article.text[1]" />
</form>
And when I do submit form, I get data:
{text : {0: "first", 1: "second"}}
But I have dynamic moment. By clicking I add dynamic input
$(".button").click(function(){
$('.form').append('<input ng-model="article.info" init-from-form type="text" />');
})
Ok. All appended, but by submit I still get data without dynamic input.
Tell me please, how to get all fields form???
Number one, don't mix jQuery like that when you can use angular. Try something like this:
view
<form name="AddArticle" ng-submit="addArticle()" class="form add-article">
<p ng-repeat="object in data track by $index">
<input type="text" ng-model="object.text" />
</p>
</form>
<button ng-click="addInput()">
add
</button>
{{data}}
</div>
controller
angular.module("app", [])
.controller("testCtrl", function($scope) {
$scope.data = [];
$scope.addInput = function() {
$scope.data.push({});
}
})
https://jsfiddle.net/pntd3kaf/

how to serialize div in angular on load?

I am using angular js version 1.2.
Basically i am creating object in server based on screen to do this i need to pass to server
how can i convert a 'div' onload of screen to json using angularjs?
html looks likes this:
<div id="settingsholder" ng-controller="MyCtrl">
<input ng-model="user.firstName" />
<input ng-model="user.lastName" />
<input type="button" ng-click="showJson()" value="Object To JSON" />
<hr/>
{{user | json}}
</div>
js :
function MyCtrl($scope) {
$scope.user = { };
}
jsfiddele: http://jsfiddle.net/bpbhat777/2grw1je0/
i want it to be like this
http://jsfiddle.net/bpbhat777/dbg2u5ck/
without setting firstname and lastName .It need not to be firstname and lastName , in screen ng-model may be any object
<div id="settingsholder" ng-controller="MyCtrl">
<input ng-model="user.firstName" ng-init="user.firstName=''" />
<input ng-model="user.lastName" ng-init="user.lastName=''" />
<input type="button" ng-click="showJson()" value="Object To JSON" />
<hr/>
{{user | json}}
</div>
and remove $scope.user = { }; from controller
WITHOUT ng-init
<div id="settingsholder" ng-controller="MyCtrl">
<input ng-model="user.firstName" />
<input ng-model="user.lastName"/>
<input type="button" ng-click="showJson()" value="Object To JSON" />
<hr/>
{{user | json}}
</div>
function MyCtrl($scope) {
$scope.user = {firstName:'',lastName:''};
}
i don't have any idea what the use of it. but if you really need that ng-init might be the option
<div id="settingsholder" ng-controller="MyCtrl">
<input ng-model="user.firstName" ng-init="user.firstName=''" />
<input ng-model="user.lastName" ng-init="user.lastName=''" />
<input type="button" ng-click="showJson()" value="Object To JSON" />
<hr/>{{user | json}}
check the demo fiddle
You are looking for angular.toJson()
https://docs.angularjs.org/api/ng/function/angular.toJson
There are several ways to update $scope on page load. I personally prefer to use init():
$scope.init = function() {
$scope.json = angular.toJson($scope.user);
}
$scope.init();
Fiddle: http://jsfiddle.net/dbg2u5ck/2/
After reading and re-reading your question, it seems to me you want to populate the $scope with pre-loaded html values (an empty string in your case). This is not the way Angular works, please take the time to read this article if you want to populate $scope with html values: Angular js init ng-model from default values

How to add additional form fields using angularjs?

I have researched online on how to create an additional form field. The method I am using comes from this site.
http://mrngoitall.net/blog/2013/10/02/adding-form-fields-dynamically-in-angularjs/
So basically what I am trying to do, is have data inputted in. But I don't know how many data points a certain person would like to put in. So I what to enable it so I can let them put additional points if they wish.
I have this in my tag:
<script>
function AngularCtrl($scope) {
function Controller($scope) {
$scope.master = {};
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
}
$scope.choices = [{id: 'choice1'}];
$scope.addNewChoice = function() {
var newItemNo = $scope.choices.length+1;
$scope.choices.push({'id':'choice'+newItemNo});
};
$scope.showAddChoice = function(choice) {
return choice.id === $scope.choices[$scope.choices.length-1].id;
};
$scope.showChoiceLabel = function (choice) {
return choice.id === $scope.choices[0].id;
}
}
</script>
I then have this in my tag:
<div class="form-group" ng-controller="Controller" data-ng-repeat="choice in choices">
<form novalidate class="simple-form">
Title of Chart: <input type="text" ng-model="chart.title" /><br />
Series Name: <input type="text" ng-model="chart.series" /><br />
Series Data: <input type="text" ng-model="series.data" /><br>
<label for="choice" ng-show="showChoiceLabel(choice)">Choices</label>
<button ng-show="showAddChoice(choice)" ng-
click="addNewChoice()">Add another choice</button>
<input type="text" ng-model="choice.name" name="" placeholder="Enter
a new data point">
<br>
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
</div>
So as you can see, what I have is 4 form fields. I want choices to add a new form field. I have the button, but when I click the button to add another form field; it does not work. It stays the same.
I was wondering if what I have in my tags was off a bit.
Thank you for the help. Been struggling on this for hours.
To expand on my comment:
Directive html:
<label for="choice" ng-show="showChoiceLabel(choice)">Choices</label>
<input type="text" ng-model="choice.name" name="" placeholder="Enter a new data point" />
<br>
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
Primary content:
<div class="form-group" ng-controller="Controller">
<form novalidate class="simple-form">
Title of Chart: <input type="text" ng-model="chart.title" /><br />
Series Name: <input type="text" ng-model="chart.series" /><br />
Series Data: <input type="text" ng-model="series.data" /><br>
<button ng-show="showAddChoice(choice)" ng-click="addNewChoice()">Add another choice</button>
<div choice-editor ng-repeat="c in choices" choice="c"></div>
</form>
I'm very fuzzy on the best practices with directives. it seems like I mix too much into a single directive sometimes, i.e., i'm not sure if you want the ng-repeat and choice attributes on the same element... Maybe someone else can improve this answer. But that should give you some ideas of how to proceed, hopefully.

Categories