I am trying to make comments functionality using Angular js. The problem is that when i want to write a comment for a post, the text is also writing inside other input elements (comments). I write a text inside one input, but it writes it in all inputs
So for example same is happening with this code
<div class="comments" ng-repeat="articles in [1,2,[4,5,6]]">
<div ng-repeat="comments in articles">
<div>
<input type="text" ng-model="$parent.new">
</div>
</div>
if i use new instead of $parent.new i get undefined, but when i use $parent.new and i write in one input, it also writes in other inputs.
The issue is that you are assigning all of the inputs to the same model, so your inputs are all in sync with the same object.
What you need is to assign each input to a different model. I'm guessing you need these models to be dynamic, so you should use an array as your model and track your ng-repeat by $index like so:
<div ng-repeat="comments in articles track by $index">
<div>
<input type="text" ng-model="arr[$index]">
<span ng-if="arr[$index]">
{{arr[$index]}}
</span>
</div>
</div>
Now, in your controller, you can initialize the empty arr like so:
$scope.arr = [];
Now, your inputs will be in sync with $scope.arr depending on the index they were in.
Try out this jsfiddle for an example.
This is because you've giving same model (ng-model="$parent.new") for all of the inputs What you should do to avoid this problem is assign different model to each input element. Something like
<div class="comments" ng-repeat="articles in [1,2,[4,5,6]]">
<div ng-repeat="comments in articles">
<div>
<input type="text" ng-model="comments">
</div>
</div>
Change ng-model of input to
<input type="text" ng-model="comments.comment">
Related
Jquery get values from dynamically generated input texts
This is an example of what I am trying to achieve. Let me put the html code and describe afterwards
<div class="col-xs-3 ">
<label for="pointMap[0]-value">firstkey</label>
<input type="text" id="pointMap[0]-value" name="pointsValueMap[firstkey]" value="value1">
</div>
<div class="col-xs-3 ">
<label for="pointMap[1]-value">secondkey</label>
<input type="text" id="pointMap[1]-value" name="pointsValueMap[secondkey]" value="value2">
</div>
I would like to have all the values of however many of these kinds of input type text id (pointMap[i]-value). Please also suggest if there is a better way than having them an array when collected. My mind is blank on what should I be looping against, in a for loop, I am unable to find a terminating condition (size of these input texts).
Since you are using jQuery. You can use the attribute contains selector. There is whole list of such selectors in jQuery.
You can store values of such inputs in an array like this
var inputStore = []; //Where you want to store the values
$("input[name*=pointsValueMap]").each(function(){ //Will check for inputs with name containing pointsValueMap
inputStore.push($(this).val())
});
I have a directive with the following template
<div>
<span class="label">My Label</span>
<input ng-model="name" required>
</div>
I want the label to be painted red when the input field is invalid.
How can I do that?
Currently I have another directive to sync all the errors from ngModelCtrl to the wrapping div
<div add-all-errors>
...
</div>
And the directive's link function does something like this:
const ngmodel = $element.find('[ng-model]').controller('ngModel');
$scope.$watch(()=>ngmodel.$error, addAllClasses, true);
Where addAllClasses simply makes sure the correct classes appear on the element..
I also tried just adding the same ng-model
<div ng-model="name">
...
</div>
But did not see the classes there..
any better way to do this?
This is why we use the angularjs form... I'm really not sure why people are against using a very handy feature.
I've made a plunker for you.
https://plnkr.co/edit/bGOcQjWzlRq2aTYZUYNm?p=preview
<form name="form">
<span ng-class="{red: form.name.$invalid}">Name:</span>
<input name="name" ng-model="name" required>
</form>
A little more insight of what's going on. form is added to the scope auto magically by angularjs by it's name. In this case, I named it form, however it can be any name.
Now form is an ngForm Object and adds all input field into it by their name attributes. This way we can do form.name to get another object similar to the ngForm Object. We can then use $invalid or $valid properties with ng-class.
ngForm is pretty powerful and is loaded with many cool properties and methods. Just call console.log(scope.form); You will need to put in a method and add it to ng-change to see updates.
I have an array of jobs in my js/controller. Each job object in the array has attributes like jobName, company, city, etc. Is it possible by submitting a form with inputs for the attributes to make it into a job object and then push it into the jobs array in the controller?
So for example, I have a form and I input Software Developer, StackOverflow, NY. Can I wrap the form into an object with the correct attributes and then pass it into the array of jobs in the controller to view it on the view?
Here's my form code so far...
<form name="jobForm" ng-submit="list.addJob(jobForm)">
<div class="form-group" id="test">
<label>Job Name:</label>
<input ng-model="jobName" type="text"/>
</div>
<div>
<label>Company:</label>
<input ng-model="companyDescription" type="text"/>
<div><button type="submit">Enter job entry</div>
</div>
<!-- this is where the live preview is. ng-model in the input binds it to these values -->
<blockquote>
<h4><u>Live Preview</u></h4>
<b>Job Name:</b> {{jobName}}
<div><b>Company:</b>{{companyDescription}}</div>
</blockquote>
</form>
So I want to create a JOB object using the jobName and companyDescription's inputs as the object's name and company attribute. How can I do this? OR am i using a wrong approach. Thank you for the help!
For starters there is a golden rule that ng-model should always be an object property to begin with ... or you can run into lots of child scope problems due to inheritance
So your whole issue is simplified by not using individual scope properties and using one object for all the ng-model in the form to begin with
$scope.job={}
<input ng-model="job.jobName" type="text"/>
<input ng-model="job.companyDescription" type="text"/>
Then when you need to send that to server it is as simple as doing
$http.post(url, $scope.job).then(func....
or pushing to another array
$scope.allJobs.push($scope.job);
$scope.job = {} // reset
Html
<div ng-controller="topicController">
Dashboard | Topics | Users
<h4>{{topic.user_name}} posted a topic</h4>
<h2>{{topic.topic}}</h2>
<h4>Description: {{topic.description}}</h4>
<div ng-controller="postController">
<label>Post Your Answer here</label>
<form>
<textarea name="post" ng-model="new_post.post"></textarea>
<input type='submit' value='Submit' ng-click='addPost(users._id, topic._id, users.name)'>
</form>
<div ng-repeat="x in topic.posts">
<h4>{{x.post}}</h4>
<p>Likes:{{x.up_vote}} Dislikes:{{x.down_vote}}</p>
<ul ng-repeat="i in topic.posts[x].comments">
<li>{{topic.posts[x].comments[i].comment}}</li>
</ul>
<div ng-controller="commentController">
<form>
<textarea name="comment" ng-model="model.comment"></textarea><br>
<input type="submit" value="Submit" ng-click="addComment(users._id, x._id, users.name)">
</form>
</div>
</div>
</div>
</div>
As you can see in the image below, I have all the data popualted, the Topic Object, inside topic Posts, & inside posts Comments.
In my my html i can display the topic content & the posts properly, but having difficulty displaying the comments.
The comments are adding to DB but not showing. I have a ng-repeat to itterate through each comment of each post but its just not showing up. Attaching Image to display the entire object in my console.
Is my ng-repeat wrong ?
Your x is a post object, not an index. So your inner ng-repeat should be
<ul ng-repeat="c in x.comments">
<li>{{c.comment}}</li>
</ul>
You are misunderstanding what x represents inside your ng-repeat for the comments. x is the actual comment object - each item in the comments array on the post. So topic.posts[x] makes no sense. It should just be x.
So, obviously, rename it to comment, instead of x.
Bonus tip: always use track by with your ng-repeat expressions for performance reasons. In your case, it would be track by comment._id.
i have a collection of values whose structure lets assume to be
var a = [{id:1, value:12, name="one"}, {id:2, value:34, name="two"},...]
i wanted to display this in a series of controls so that user can change the values. but with that i also wanted to display original values which obviously shoudn't change.
i found out a way that is working and my code is something like this using ng-init
<div ng-repeat="p in a">
<div class="control-group" ng-if="p.value>0">
<label class="control-label" ng-bind="p.name"></label>
<div class="controls controls-row" ng-init="v=p.value">
<input class="span1" value="{{v}}"/>
<input type="number" ng-model="p.value" class="span2" />
</div>
</div>
</div>
being a complete newbie in angularjs i dont know what implications this might have as i have very little experience in thinking about $watch and performance.
Is it ok to do so?
but with that i also wanted to display original values which obviously shoudn't change.
Use angular.copy(/* array */). It will create new copy (instance) of old array.
BTW a collection must be defined as $scope.a
Demo Fiddle