Right now I am working with AngularJS on a web interface which should have similar behavior like Dev HTTP Client. I can't find a way how to add headers in the way like DHC does.
I'm trying to make it somehow like this, but it isn't working since array is initialized empty:
<div ng-repeat="header in headersCollection.headers">
<input ng-model="header.name" type="text"/> :
<input ng-model="header.value" type="text"/>
</div>
<button type="button" ng-click="addNewHeader()">Add</button>
Headers should be stored inside this object and be available for creating, editing and removing through web interface. Just like in DHC.
$rootScope.headersCollection = {
headers : []
}
Any idea / link / answer are highly appreciated and answered immidiately.
Thank you.
Just make an "empty" header object in the headers collection. See http://jsfiddle.net/e8MEx/
Of course you will want to throw in some validation to make sure they are values before adding another one and potentially add the ability to remove an item:
JavaScript:
var mod = angular.module("myApp", []);
mod.run(["$rootScope", function($rootScope) {
//start the array with one empty value for header
$rootScope.headersCollection = {
headers : [{name: "", value: ""}]
}
}]);
mod.controller("MainController", ["$scope", "$rootScope", function ($scope, $rootScope) {
$scope.headersCollection = $rootScope.headersCollection
$scope.addNewHeader = function () {
//push a new empty value onto the array.
$scope.headersCollection.headers.push({name: "", value: ""});
}
}]);
HTML:
<div ng-app="myApp" ng-controller="MainController">
<div ng-repeat="header in headersCollection.headers">
<input ng-model="header.name" type="text"/> :
<input ng-model="header.value" type="text"/>
</div>
<button type="button" ng-click="addNewHeader()">Add</button>
<p>{{headersCollection.headers}}</p>
</div>
Related
I know there are several similar topics already but I found none that really matches my problem.
When opening my AngularJS app/website I am loading two arrays of objects (both are of the same type). One list contains all possible values (called sources here) and the other list is a selection of elements from the first.
My goal is display all sources as checkboxes. The ones from the second list have to be preselected, the rest not. Now the user can select/deselect checkboxes. If he does so I need to inform the server (with the source.id).
What I got so far:
exampleApp.controller('testController', [ '$scope', '$http', function($scope, $http) {
$scope.sources = [];
$scope.selectedSources = [];
$scope.changeSource = function(source) {...};
})
and
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="??"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
What I can't figure out is how I can get ng-model to preselect the right checkboxes and how to get the new (and old) values to changeSource(). Is there an elegant way of doing that?
Example (Pseudo code only):
Sources = [{id=1, name=test1},{id=2, name=test2}, ...]
SelectedSources = [{id=2, name=test2}]
Now what I need are checkboxes like this:
[ ] test1 [x] test2
where all elements from sources are checkboxes and the ones from selectedsources are preselected. Changes of the selection can be stored in selected sources (as objects) and have to trigger my changeSource() function so that I can inform my server.
Set the selected/unselected state in a property inside each of the objects in Sources array(initialize it based on whats present in selectedArray)
$scope.sources.forEach(function(source) {
source.selected = isSelected(source);
})
function isSelected(selectedSource) {
return !!$scope.selectedSources.find(function(s) {
return s === selectedSource || s.id == selectedSource.id;
})
}
Here's a working plunker link
I didn't understood your question very well, but if i'm not mistaken, you want to fill the second collection only with the selected items from the first one, right? If it's the case, you could turn your second collection into a returning function with a filter of the first inside, as follows:
In your controller:
exampleApp.controller('testController', [ '$scope', '$http', function ($scope, $http) {
$scope.sources = [];
/* ... */
$scope.getSelectedSources = function () {
return $scope.sources.filter(function (val) {
return val.selected;
});
};
})
In your template:
<div ng-repeat="source in sources">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
<div ng-repeat="source in getSelectedSources()">
<input
type="checkbox"
name="source.name"
value="{{source.id}}"
ng-model="source.selected"
ng-change="changeSource(source.id)"
> {{source.name}}
</div>
Hi this may be help you to get new & old value.
$scope.$watch('sources', function (oldval, newval) {
console.log(oldval + newval);
});
I'm generating dozens of forms on my page. Each form has several parameters (not the same for each form). I'm generating my forms as such (simplified):
<div ng-repeat='module in modules'>
<form ng-submit='submitModule(module)'>
<div ng-repeat='arg in module.args'>
<input ng-model='models[module.name][arg.name]' id="{{ arg.name }}">
</div>
</form>
</div>
You can see I'm trying to assign a unique ng-model to each input parameter by using a two dimensional array models[module.name][arg.name].
Because I am planning on submitting this as JSON, the idea was that I could just do models[some_module] in my controller to get the full JSON, and then just post along.
Unfortunately this isn't working, when trying models['test_module'] I get undefined, instead of my object. There are no errors elsewhere in the code, I've tested extensively. The problem comes from the use of multi-dimensional arrays here which is apparently a big no-no.
How should I handle my situation? IE: several forms, several inconsistent parameters, and a need to POST every param together as JSON.
EDIT: For info, my controller looks like:
angular.module('app')
.controller('InputCtrl', function($scope, InputSvc) {
$scope.models = {};
InputSvc.list().success(function(modules) {
$scope.modules = modules;
$scope.models['test_module'] = {}
});
$scope.submitModule = function(module) {
console.log($scope.models['test_module']);
};
});
Perhaps you could give each form a controller so the model is scoped to the form instance rather than the parent:
<div ng-repeat='module in modules'>
<form ng-controller="FormCtrl" ng-submit='submitModule(module)'>
<div ng-repeat='arg in module.args'>
<input ng-model='formData[arg.name]' id="{{ arg.name }}">
</div>
</form>
</div>
Then your FormCtrl would have the submit method and the model:
angular.module('app')
.controller('FormCtrl', function($scope) {
$scope.formData = {};
$scope.submitModule = function(module) {
console.log($scope.formData);
};
});
Here is a Codepen
I'm building an app where users can add items to a list and I decided, for the sake of learning, to use Angular (which I'm very new to). So far, I've been able to successfully add a single item to that list without any issues. Unfortunately, whenever I try to add more than one without a page refresh, I get an error - specifically a "Undefined is not a function."
I've spent more time than I care to think about trying to resolve this issue and I'm hoping an expert out there can give me a hand. Here's what I have so far:
Controllers:
angular.module('streakApp')
.controller('StreakController', function($scope) {
// Removed REST code since it isn't relevant
$scope.streaks = Streak.query();
// Get user info and use it for making new streaks
var userInfo = User.query(function() {
var user = userInfo[0];
var userName = user.username;
$scope.newStreak = new Streak({
'user': userName
});
});
})
.controller('FormController', function($scope) {
// Works for single items, not for multiple items
$scope.addStreak = function(activity) {
$scope.streaks.push(activity);
$scope.newStreak = {};
};
});
View:
<div class="streaks" ng-controller="FormController as formCtrl">
<form name="streakForm" novalidate >
<fieldset>
<legend>Add an activity</legend>
<input ng-model="newStreak.activity" placeholder="Activity" required />
<input ng-model="newStreak.start" placeholder="Start" type="date" required />
<input ng-model="newStreak.current_streak" placeholder="Current streak" type="number" min="0" required />
<input ng-model="newStreak.notes" placeholder="Notes" />
<button type="submit" ng-click="addStreak(newStreak)">Add</button>
</fieldset>
</form>
<h4>Current streaks: {{ streaks.length }}</h4>
<div ng-show="newStreak.activity">
<hr>
<h3>{{ newStreak.activity }}</h3>
<h4>Current streak: {{ newStreak.current_streak }}</h4>
<p>Start: {{ newStreak.start | date }}</p>
<p>Notes: {{ newStreak.notes }}</p>
<hr>
</div>
<div ng-repeat="user_streak in streaks">
<!-- Removed most of this for simplicity -->
<h3>{{ user_streak.fields }}</h3>
</div>
</div>
Could you post the html of StreakController too? Your solution works fine in this fiddle:
http://jsfiddle.net/zf9y0yyg/1/
.controller('FormController', function($scope) {
$scope.streaks = [];
// Works for single items, not for multiple items
$scope.addStreak = function(activity) {
$scope.streaks.push(activity);
$scope.newStreak = {};
};
});
The $scope inject in each controller is different, so you have to define the "streaks" in FormController.
Your problems comes from :
.controller('FormController', function($scope) {
// Works for single items, not for multiple items
$scope.addStreak = function(activity) {
$scope.streaks.push(activity);
^^^^^^
// Streaks is initialized in another controller (StreakController)
// therefore, depending of when is instantiated StreakController,
// you can have an error or not
$scope.newStreak = {};
};
});
A better design would be to implement a StreakService, and to inject that service in the controller you need it. Of course, initializing $scope.streaks in FormController will make your code work, but that's not the responsibility of FormController to initialize this data.
I assume FormController is a nested controller of StreakController, so they share the same scope.
if that works for single object, it should work for mulitiple objects, the problems is you can't just use push to push an array of object to the streaks, you can for loop the array and add them individually or use push.apply trick. I thought the reason of Undefined is not a function. is because the Stack.query() return an element instead of an array of elements so, the method push doesn't exists on the $scope.streaks.
http://jsbin.com/jezomutizo/2/edit
The below code shows a list from firebase and shows a corresponding comment field for each item in the list. The user can make a comment on that item and it will update the comment field for that item in the list. Currently, each time a comment is made, it overwrites the previous one, but I'd like for all comments to be saved.
How do I make it so that every time a comment is added, the previous ones are saved as well?
http://jsfiddle.net/chrisguzman/PS9J2/
indx.html
<div ng-app="MyApp" ng-controller="MyCtrl">
<div ng-repeat="(id,item) in data">
<h2>{{item.title}}</h2>
<input ng-model="item.comment"></input>
<button type="submit" ng-click="CommentAdd(id)">Comment</button>
</div>
</div>
app.js
angular.module('MyApp', ['firebase'])
.controller('MyCtrl',
function MyCtrl($scope, $firebase) {
var furl = "https://helloworldtest.firebaseio.com";
var ref = new Firebase(furl);
$scope.data = $firebase(ref);
$scope.CommentAdd = function (id) {
$scope.data.$save(id);
};
});
The following is the data structure within firebase that is generated
{helloworldtest:
{-JSQhsAnY5zhf0oVKfbb: {title: "nameA", comment:"Second Comment"},
-JSQhsAnY5zhf0oVKfbb: {title: "nameB", comment:"Second Comment"}}
}
However, I'd like to create the following where there is a 'comments' branch that holds all comments.
{helloworldtest:
{-JSQhsAnY5zhf0oVKfbb: {title: "nameA", comments:{-JSQhsAnY5zhf0oVKfbb:{Comment:"Second Comment"},-JSQhsAnY5zhf0oVKfbb:{Comment:"First Comment"}}},
{-JSQhsAnYdfdfdffbb: {title: "nameA", comments:{-JSQhsAnY5zhf0oVKfAb:{Comment:"Another Comment"},-JSQhsAnY5zhf0oVKfbb:{Comment:"First Comment"}}}
}
I've tried to do this by replacing
$scope.data.$save(id);
with
$scope.data.$add(id);
I've also tried using :
$scope.data[id].$add({foo: "bar"})
You are saving the comment into a field called comment. Instead, use a list called comments and utilize push or $add.
<div ng-app="MyApp" ng-controller="MyCtrl">
<div ng-repeat="(id,item) in data">
<h2>{{item.title}}</h2>
<input ng-model="newComment"></input>
<button type="submit" ng-click="addComment(id, newComment)">Comment</button>
</div>
</div>
function MyCtrl($scope, $firebase) {
var furl = "https://helloworldtest.firebaseio.com";
var ref = new Firebase(furl+'/items');
$scope.data = $firebase(ref);
var $comments = $firebase( commentsRef );
$scope.addComment = function (id, newComment) {
ref.child(id).child('comments').push(newComment);
};
});
Also Don't nest data just because you can. Instead, consider putting comments in their own path, items in their own path.
I cannot get at a form value through $scope.form. In the view and Batarang I see that the form object has the right name for all fields, but no values. On the other hand, the value in the actual form field is correct, as is the $scope.mymodel.headline value (see example below).
Why would this happen?
Sample for 1 field follows. Batarang output:
{
mymodel: {
headline: My value
}
form: {
mymodel[headline]: { }
}
}
If I output {{form}} in the view it shows:
mymodel[headline]: { }
Controller code is very simple:
#mymodelCtrl = ['$scope', ($scope) ->
$scope.init = (mymodel) ->
$scope.mymodel = mymodel
]
Much simplified HTML:
<div id="new_mymodel" ng-controller="mymodelCtrl"
ng-init="init({'headline': 'my value'})" class="ng-scope">
<form action="/myurl" id="new_mymodel" method="post" name="form" role="form">
<input id="mymodel_headline" name="mymodel[headline]"
ng-model="mymodel.headline" ng-required="true" type="text">
<input type="submit">
</form>
</div>
UPDATE: At first I thought the accepted answer was wrong, but that was because of a side issue. But it is correct: the issue is that developer console and batarang and view were displaying something wrong, not that the field is empty. I needed to use $scope.form["mymodel[headline]"].$formVaue.
You can get it's value from
$scope.form['mymodel[headline]'].$modelValue
See this.