creating dynamic forms using ng-repeat - javascript

Hello everyone I need to create some dynamic forms so users can configure feeds to their specification.
I have used ng-repeat to do the following:
For each feed a user needs to configure a new tab is created
for each property a feed has a label and input textbox is created.
Markup:
<tabset>
<tab ng-repeat="feed in feeds" heading="{{feed.heading}}">
<form role="form">
<div class="row" ng-repeat="property in feed.properties">
<div class="col-xs-6">
<div class="input-group">
<span class="input-group-addon">
<span>{{property.name}}</span>
</span>
<input type="text" class="form-control" value="{{property.value}}">
</div>
</div>
</div>
</form>
</tab></tabset>
This works just fine with the backing json that I have however I am wondering what the accepted way of capturing the data for this kind of use case, obviously I won't know how many feeds or properties each feed has so I suppose I need to bind this to an array in some way.
The question is how?

use ng-model
<input type="text" class="form-control" ng-model="property.value">
This way the textbox is bound to property.value. angular automatically updates property.value when you change the text in the textbox. You can use it in your JS just like any other variable. That's the beauty of angular.

Related

How to dynamically add waypoints in Angular along with auto complete address?

<div [hidden]="!showWaypoint" #waypoint>
<div class="form-group label-floating">
<label class="control-label">Waypoint</label>
<input type="text" class="form-control search-address" name = "waypoint" placeholder=" " [(ngModel)]="wayPointInput" #stop>
</div>
</div>
I want to clone this entire portion, just like appending when i am clicking on add waypoint. I Dont want to use structural directives like *ngFor.
I have also consoled this
#ViewChild('waypoint') wp;
console.log(this.wp.nativeElement);
but I dont know how to append it along with the change in ngModel name so that after submitting I get a set of data in an array.

Using form data and generating HTML based on it

Looking for something to take data from a form like this one:
<form id="rendered-form" name="rendered-form">
<div class="rendered-form">
<div class="fb-text form-group field-text-1534368808722">
<label class="fb-text-label" for="text-1534368808722">Name</label><input class="form-control" id="text-1534368808722" name="text-1534368808722" type="text">
</div>
<div class="fb-text form-group field-text-1534368811041">
<label class="fb-text-label" for="text-1534368811041">Email</label><input class="form-control" id="text-1534368811041" name="text-1534368811041" type="text">
</div>
<div class="fb-text form-group field-text-1534368811041">
<label class="fb-text-label" for="text-1534368811041">Link</label><input class="form-control" id="text-1534368811041" name="text-1534368811042" type="text">
</div>
</div>
</form>
And insert the data into a HTML template. For example:
<div class="name">FORM TEXT HERE</div>
<div class="email">FORM TEXT HERE</div>
link
I would love to use Vue.js for this if at all possible, I've been playing around with it and this seems like something it would be capable of.
I'm trying to use this to quickly make AMP pages (I know I could do it programmatically, but due to restrictions I cannot at this time). I don't want to have a database, it doesn't need to store this. I just want to be able to insert my data, press a button, and have it spit out HTML or an HTML file based on the template and provided data and be done.
If you already handled the form submit, you can change the content of your divs with js selectors, like this:
document.getElementsByClassName("name")[0].innerHTML = nameFromFormInput;

Several radio button groups in nested ng-repeat, but only last group shows the value

I have a page where I want to update a form with several radio buttons. I query an api, and use the returned array of objects to populate the current values for the radio buttons. The problem that I have is that only the last set of radio buttons actually shows the value. This is the code that I have (I am using [[ and ]] for the start and end symbols for angular):
<fieldset data-ng-repeat="s in sections">
<div class="form-group">
<div class="col-md-12">
<h2>[[ s.section.name ]]</h2>
</div>
</div>
<!-- Field Item -->
<div class="form-group m-b-20 bg-light" data-ng-repeat="f in s.fields">
<div class="col-md-12 m-b-30">
<h4>[[ f.field.name ]]</h2>
<input type="text" data-ng-model="f.comments" class="form-control input-md underline" placeholder="Comments">
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="pass" class="form-control" data-ng-model="f.field_condition">
<label class="eval-pass"><i class="fa fa-check-circle green"></i> Pass</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="fail" class="form-control" data-ng-model="f.field_condition">
<label class="eval-fail"> <i class="fa fa-exclamation-circle red"></i> Fail</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="n/a" class="form-control" data-ng-model="f.field_condition">
<label class="eval-na"> <i class="fa fa-circle blue"></i> N/A</label>
</div>
<div class="col-sm-3">
<input type="radio" name="section-[[s.section.section_id]]-field-[[f.field.field_id]]" value="caution" class="form-control" data-ng-model="f.field_condition">
<label class="eval-caution"><i class="fa fa-exclamation-triangle yellow"></i> Caution</label>
</div>
</div>
[[ f.field_condition ]]
<hr>
</fieldset>
So basically, I have several sections, and each section has several fields. Each field has it's own radio button group (I am using the section and field ids to name the radio group). What I currently see is only the last field in each section actually shows the selected radio button. The other fields don't have any selection, even though the value for ng-model definitely does (I am showing the value of f.field_condition just to make sure there is a value).
For each field, I can see that the model is set. And if I select a value manually, I can see that the model changes, so it seems to me that the model is setup correctly. I just don't know why it won't initially show as selected for all rows but the last one.
I should also mention that if I save the form even with the missing radio button selections, the database is updated properly (it doesn't set the values to null, and if I manually change the selected value, it is updated in the db as well).
Does anyone have any ideas? Thanks!
EDIT
Here is a fiddle for this, although, it is working as expected in the fiddle. http://jsfiddle.net/dq8r196v/367/
I tried using the static data that I used in the fiddle, but I am still having the same problem. Does anyone know if this could be a CSS problem? The radio buttons are styled, and I didn't write the HTML or CSS.
UPDATE
I am still having this issue, so I built a new angular app and only used the code that is included in the fiddle that I have created. I am having the same problem with this new app, even though the same code works in the fiddle. I really don't understand what's happening here, but if anyone could shed some light, I would really appreciate it.
I have literally copied and pasted the code from my fiddle into a new angular app, and only the last group of radio buttons in each section is showing the value in the app.
Here is my complete code for the new angular app if someone else wants to try it out and see exactly what is happening: https://pastebin.com/qSR33yfM
I created the app on a single page for simplicity.
Here is the link to a pastebin with the exact json that I am using in my app: https://pastebin.com/utfVVQfT
I fixed the problem you're having by simply adding an array of objects ($scope.values) representing the different radio button options, and using an ng-repeat to create your radio buttons. See the following for the updated code: https://pastebin.com/s3hNzaXX
I know there are semantics around ng-repeat creating new $scopes, and imagine there is a conflict in scopes with your nested ng-repeats where it's binding to the radio buttons incorrectly and at a scope different than you want (the section level ng-repeat).
To confirm this suspicion, you could convert all of your interpolations in the code to use functions and console.log s and f at different points and confirm that field_condition is being set at a level you didn't intend.
Either way, it' best practice to create your radio buttons through data (and using ng-repeat), as is done with the $scope.values array, and a good side effect to doing this is not only can you update the different value options using data through AJAX or however you would like, but you won't have weird angular scoping issues as you're experiencing in your current code above.

How to check in real time if a input field matches another variable with angular.js

I have a ng-repeat that loops through an object and displays a list of strings and input fields, example below. I need to set up a real-time verification for these input fields. The input field should be equal to the barcode string. If a user types in a string that IS NOT equal to the barcode string than angular should prompt the user that it must equal the barcode string and clear the input field. Is this possible with angular? I’ve accomplished similar tasks with jQuery.. could I combine some jQuery and Angular to achieve this verification? I'm new with angular.js so any help is greatly appreciated.
HTML:
<div ng-repeat="(index, val) in barcodes.barcodes track by $index">
<div class="form-group row" ng-show="barcodes.barcodes[index]">
<label class="col-sm-3 form-control-label" style="margin-top: 5px"> {{ barcodes.adaptors[$index] }} </label>
<label class="col-sm-3 form-control-label" style="margin-top: 5px"> {{ barcodes.barcodes[index] }} </label>
<div class="col-sm-6">
<input type="email" class="form-control" placeholder="Barcode">
</div>
</div>
</div>
Example bars Object:
var bars = {
"adaptors": ["506-704", "505-703", "503-702", "508-701", "507-705", "502-706", "504-707", "501-708"],
"barcodes": ["11-11-1111","11-11-2222","11-11-3333","11-11-4444","X","X","X","X"];
}
if you want real time...watcher may be what you're looking for. But watcher is not efficient.
What would be best is to use the ng-change directive. This way, every time a user types, it will trigger the function passed to the ng-change directive. This can allow you to handle logic inside a function and react however you want.
https://docs.angularjs.org/api/ng/directive/ngChange

How to clone form fields without their values?

How to clone following html without persisting the field values?
<form method=POST action="/url">
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[1][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[1][body]" placeholder="Possible answer">
</div>
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[2][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[2][body]" placeholder="Possible answer">
</div>
. . .
<button type="submit">Submit</button>
</form>
I can see only 3 possible choices here. However, all of them come with major flaws:
.clone() the .form-field normally and reset the field values.
Problem: resetting all the values one by one is cumbersome and is not a future-proof solution. For example, if more fields are added into the .form-group, their values will need to be cleared separately.
Include a hidden .form-group as a template on the page.
Problem: as you see, the input fields contain enumerated names like: answer[1][body]. It is convenient to clone the last .form-group and just increment the value by 1. Cloning the templated .form-group will be lacking this flexibility.
Read the fields as raw html and transform them into JQuery object
Problem: this seems to be a clear solution to me, however I couldn't get it working. The code $.parseHTML($('.form-group').html()) does not return a valid JQuery object, which I need to use .find() and other methods on.
What will be an effective and elegant solution to this problem?
Try this code:
$("button").click(function(){
var t = $("form").clone().appendTo("#clonedForm");
$(t).find("input[type=checkbox],input[type=text], textarea").removeAttr("checked").val('');
});

Categories