Angular JS - Having an empty array - html

I have a form that submits data into a function called ng-submit="newBirthday() this pushes data - $scope.bdayname, $scope.bdaydate; into an array called bdaes
My issue is that with all of the tutorials I have seen the array has predefined data is there a way that it can be an empty array that gets filled with data when it is submitted?
app.js:
var app = angular.module('birthdayToDo', []);
app.controller('main', function($scope){
// Start as not visible but when button is tapped it will show as true
$scope.visible = false;
// Create the array to hold the list of Birthdays
$scope.bdays = [{}];
// Create the function to push the data into the "bdays" array
$scope.newBirthday = function(){
$scope.bdays.push({name:$scope.bdayname, date:$scope.bdaydate});
$scope.bdayname = '';
$scope.bdaydate = '';
}
});
HTML:
<body ng-app="birthdayToDo" ng-controller="main">
<div id="wrap">
<!-- Begin page content -->
<div class="container">
<div class="page-header">
<h1>Birthday Reminders</h1>
</div>
<ul ng-repeat="bdays in bdays">
<li>{{bdae.name}} | {{bdae.date}}</li>
</ul>
<form ng-show="visible" ng-submit="newBirthday()">
<label>Name:</label>
<input type="text" ng-model="bdayname" placeholder="Name"/>
<label>Date:</label>
<input type="date" ng-model="bdaydate" placeholder="Date"/>
<button class="btn" type="submit">Save</button>
</form>
</div>
<div id="push"></div>
</div>
<div id="footer">
<div class="container">
<a class="btn" ng-click="visible = true"><i class="icon-plus"></i>Add</a>
</div>
</div>
<script type="text/javascript" src="js/cordova-2.5.0.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>

Okay, there were a few of small issues.
An empty array must have no items; [{}] is an array with one item: an empty object. Changing to [] gets rid of the extra bullet.
The bigger issue was your ngRepeat. You used ng-repeat="bdays in bdays". What ngRepeat does is take an array and allow you to do a "for each" on the array, assigning each value to that temporary local variable. You named them the same. Instead, ng-repeat="bday in bdays" will add the DOM nodes inside of it for each item in bdays, giving you a local variable called bday to use to reference each item.
Inside the ngRepeat template, you used bdae, which doesn't reference anything.
I don't know what app.initialize() is, so I removed it. It was just erroring out in the console.
Here's a fixed Plunker: http://plnkr.co/edit/OFWY7o?p=preview

Related

ng-click according to element ID

So I have a ng-repeat iterating through an array that contains the elements form an API. Through the ng-repeat , I print out the same number of div(s) containing the names of some properties as the number of property present in the API in different objects. Now the next step that I want is that when I click on any property Name div, another screen is opened up which has the details of the property ( details are then fetched from the API which I can do). What I am not able to do is how to use the ng-click that it goes to the details screen but according the property that is clicked. I know that somehow I need to pass the property ID in ng-click and lead it to a different screen. Can't figure out how. Kinda am new to Angularjs so can someone help?
<div ng-repeat="prop in propertyDetails" class="propertyCard"
ng-click="Something here which I cant figure out ">
<p class="propSummaryName">{{ prop.name }}</p>
<div>
Now when the divs are created for the different properties when I click on one of them a new screen comes and then I show there what I want to show for the property.
PS- for property ID : prop.id
Use can directly write function call.
<div ng-repeat="prop in propertyDetails" class="propertyCard"
ng-click="propDetails(prop.id)">
<p class="propSummaryName">{{ prop.name }}</p>
$scope.showDetails(propId) {
// do want ever you want to };
If you want to show property details on another screen then you can use
modal or routing.
hey it's Simple You can call the #scope function in the ng Click and inside the function call the reset service and then open the popup
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body ng-app="myApp" ng-controller="test">
<div ng-init="loadData()">
<div ng-repeat="prop in propertyDetails" class="propertyCard"
ng-click="openMyPopUp(prop)">
<p class="propSummaryName">{{ prop.name }}</p>
<div>
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
Name : {{popupData.name}}
Id : {{popupData.id}}
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
<script type="text/javascript">
var app = angular.module('myApp', []);
app.controller('test', function($scope, $http) {
var popup = angular.element("#myModal");
//for hide model
popup.modal('hide');
var url = 'your-url.com/rest/api'
$scope.loadData = function(){
$http.get(url).then(function(res){
$scope.propertyDetails = res.data;
});
}
$scope.openMyPopUp= function(data) {
$http.get(url + '?id=' + data.id).then(function(res){
$scope.popupData = res.data;
});
//for show model
popup.modal('show');
}
});
</script>
If you need to rederct to another page mean you can do like this
var url = "http://" + $window.location.host + "/Account/Login";
$log.log(url);
$window.location.href = url;
inside this function

Angular 2 create dynamic formcontrol that contains formarray

I have a reactive input form with a dynamic amount of inputs that I need to add form controls to.
The parent control Mammals will contain a variable amount of MammalId's, and each MammalId will contain a FormArray of variable length.
I have created typescript code that will generate the form as I described, however, I haven't been able to set my form to my HTML.
And an example of my generated form:
I've tried mapping the form to my html in the following way:
<form [formGroup]="inputForm">
<div *ngFor="let mammal of Mammals; let i = index">
<div *ngFor="let id of mammal.ids; let z = index">
<!-- parent form control -->
<div [formGroupName]="mammals">
<!-- mammals[i].id resolves to 'mammalIdx' -->
<div [formGroupName]="mammals[i].id">
<!-- this should map as the controls Form Array -->
<input [formControlName]="z">
</div>
</div>
</div>
</div>
</form>
But when I try and run this, I get:
Error: Cannot find control with unspecified name attribute
How can I set my html to my form values?
Thank you
The parent control Mammals will contain a variable amount of MammalId's, and each MammalId will contain a FormArray of variable length.
As per my understand the arry you expected may be like this
[
{
"Mammals":[
{
"mammalId":[
{
}
]
}
]
}
]
for that above array the form will be like this
this.inputForm = this.fb.group({
Mammals: this.fb.array([}
mammalId: this.fb.array([{
z: ''
}
])}
])
})
for that above array html should be like this
HTML
<form [formGroup]="inputForm">
<div formArrayName="Mammals">
<div *ngFor="let mammal of inputForm.get('Mammals'); let i = index" [formGroupName]="i">
<div formArrayName="mammalId">
<div *ngFor="let id of mammal.get(mammalId); let z = index" [formGroupName]="z">
<!-- parent form control -->
<!-- mammals[i].id resolves to 'mammalIdx' -->
<!-- this should map as the controls Form Array -->
<input [formControlName]="z">
</div>
</div>
</div>
</div>
</div>
</div>
</form>
It may be helps you

Framework7 formToData not working

I have a screen login in my aplication and to get the form data in framework i need to use formtoData but it wasnt working, so i decided to create another project and copy paste framework docs script but still isnt working.
Index.html(the test project)
<div class="pages navbar-through toolbar-through">
<!-- Page, "data-page" contains page name -->
<div data-page="index" class="page">
<!-- Scrollable page content -->
<div class="page-content">
<form id="my-form" class="list-block">
<ul>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title label">Name</div>
<div class="item-input">
<input type="text" name="name" placeholder="Your name">
</div>
</div>
</div>
</li>
</ul>
</form>
<div class="content-block">
Get Form Data
</div>
</div>
</div>
</div>
js (test project)
// Initialize app
var myApp = new Framework7();
// If we need to use custom DOM library, let's save it to $$ variable:
var $$ = Dom7;
$$('.form-to-data').on('click', function(){
alert("dwdq");
var formData = myApp.formToData('#my-form');
alert(formData);
});
Does anyone know why is it not working? thx in advance.
They changed the function, instead of formToData now is formToJSON
You can use booth:
formtoData or formToJson will return the same value: [object Object]
Just use JSON.stringify() to get the desired result.
$$('.form-to-data').on('click', function(){
var formData = myApp.formToData('#my-form');
var formJSON = myApp.formToJSON("#my-form");
console.log(JSON.stringify(formData));
console.log(JSON.stringify(formJSON));
});
{"name":"Alexandre"}
{"name":"Alexandre"}
Or you can even serialize the form like that:
$$('.form-to-data').on('click', function(){
var formData = $$.serializeObject(myApp.formToJSON($$("#my-form")));
console.log(formData);
});
name=Alexandre
Edit: Framework7 got updated to v4, and now it works this way:
Single Line:
var dados = JSON.stringify(myApp.form.convertToData('#my-form'));
They changed the function again, at least in V2. The new function that works for me is:
var formData = myApp.form.convertToData("#form-id");
var formString = JSON.stringify(formData);
Framework 7 convertToData is ignoring input type text array: for example:
<input type="text" name="no_invoice[]" />
Removing [] doesn't work either.
F7 only take as array checkbox/radio fields, this bug must be solved.
I solved using javascript:
new FormData(your_form);

Show an ngMessage if ngOptions array is empty

Is it possible to use ngMessages to show an error while initializing options of a select element using ngOptions?
For ex. in
<select name="fruitNames" ng-model="fruitName" ng-options="fruit.name for fruit in fruits"></select>
if fruits is empty, I want to show an error message.
You could provide any expression to ng-messages as a kvp, example i am setting boolean value to hasFruits and using the key hasFruits.
<div ng-messages="{noFruits:!fruits.length}" >
<div ng-message="noFruits">Sorry, No fruits available!!</div>
</div>
angular.module('app', ['ngMessages']).controller('ctrl', function($scope) {
$scope.fruits = [];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-messages.js"></script>
<div ng-app="app" ng-controller="ctrl">
<div ng-messages="{hasFruits:!fruits.length}">
<div ng-message="hasFruits">No fruits available!!</div>
</div>
</div>
This however seems a bit weird since you really don't have multiple conditions here (Unlike the way you use ngMessages with $error object), you could just show and hide a div as well instead.

Knockout Clone Whole Item In foreach

I am trying to clone elements when clicking a button. I was trying to use ko.toJS. On page load it works fine, but when I want clone the items, it is unable to bind the items (like, value, Text, etc.).
Here is the HTML:
<div class="stockItems-inner" data-bind="foreach: StockItems">
<div data-bind="if: Type=='Input'">
<div class="stock_container_input">
<input type="text" data-bind="value: Value" />
</div>
</div>
<div data-bind="if: Type=='Radio'">
<div class="stock_container_control">
<div data-bind="foreach: Options">
<div class="stockLbl">
<input type="radio" data-bind="text: Text, checked:$parent.Value, attr:{'id':Id, 'name': $parent.Text, 'value': Value}" />
<label data-bind="attr:{'for':Id}, text: Text"></label>
</div>
</div>
</div>
</div>
</div>
<div class="addItem">
<button type="button" data-bind="click: CloneItem"><img src="images/add.png" alt="" /></button>
</div>
The View Model:
ConfigurationStockViewModel = function() {
var self = this;
this.StockItems = ko.observableArray();
this.ApplyData = function(data){
self.StockItems(data.Items);
}
this.CloneItem = function(StockItems){
self.StockItems.push(ko.toJS(StockItems));
};
};
When clicking the button, an error is thrown: Unable to process binding. I am using JSON data for binding.
Not exactly sure what end result you want without working code, but sounds like you want to clone the last item in array and add to array?
If so, I think you have an error - your add button click binding will never pass anything to the function you defined, since it is outside the foreach. You need something like this:
this.CloneItem = function() {
var toClone = self.StockItems()[self.StockItems().length - 1]
self.StockItems.push(toClone);
};
Here is a simplified example without radio buttons, etc:
http://jsfiddle.net/5J47L/