Create object from Form inputs to pass to controller method - javascript

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

Related

Send js object into html form

I would like to fill an hidden field of my html form with an object from JS.
This is my form
<form id="form_infos">
<label for="title">Titre:</label><input type="text" name="title" id="title_input"/>
<input id="event" type="hidden"/>
<input type="submit" value="Enregistrer" />
</form>
Js side
element.click(function() {
$("#title_input").attr({value :event.title});
$("#event").attr({value :event});
});
This js part is minimized, but as you can see, event is an object with many field such as title. I could get all the field one by one. But they are too many of them and I need to have the full object.
The issue is, doing this, I'm only getting the string [object Object] into my var event when I treat the form and not the object himself.
Thanks for help.
PS: I can't use JSON.stringify on event because I have circular references.

AngularJS ng-repeat input

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">

Angular1: How to reflect ng-model errors on another element?

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.

How to append additional sets of fields to html form

Example: let's say we have a form with 3 fields: pc, part_id, part_details. Sometimes you will want to add additional parts to database when adding pc, so part_id and part_details should be duplicated(part_id and part_details should be corresponding). What I want is the best way to append this two fields to the form?
I know if you just want to duplicate one field you can name the field like this:
<input type="text" name="part_id[]">
Then we can easily get the post data as array. But now we are duplicating more than one field, if we use the approach above at the post end the two/multiple arrays will not be relevant. The approach described here seems to be a good one http://www.quirksmode.org/dom/domform.html, but the fact that names are changing all the time makes it complicated to use the post data as well.
There is another possible approach described here Multiple Forms With Input Fields With The Same Name Attribute? Good Or Bad? . It gives an idea to duplicate the entire form. I am not sure if I understand it correctly, but when I try putting two identical forms in the same page and submit one of them, only data from this form will be submitted, the other one will be ignored. Also it is not suitable for my scenario as not all the fields should be duplicated.
So what is the best way to accomplish this duplicating job?
In the link you gave, they didn't duplicate the form, just the elements inside the form which is fine. If all you are adding is multiple parts to a single PC then there shouldn't be a problem. The parts will be linked via array indices (you can rely on the ordering).
The first instance of part_id[] will correspond to the first instance of part_details[]. This should be distinguishable in your server-side language. In PHP for instance, part_details[2] will correspond to part_id[2] etc.
You can use another level of indexing:
<input type="text" name="pc" />
<!-- First part -->
<input type="text" name="parts[0][part_id]" />
<input type="text" name="parts[0][part_details]" />
<!-- Duplicate part -->
<input type="text" name="parts[1][part_id]" />
<input type="text" name="parts[1][part_details]" />
<!-- Another duplicate part -->
<input type="text" name="parts[2][part_id]" />
<input type="text" name="parts[2][part_details]" />
The fields for each part (id and details) can be easily generated using jQuery.

Is using ng-init for bind once valid in angular js?

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

Categories

Resources