AngularJS - how to add dynamic ng-model - javascript

I'm working with a form and would like to add ng-model on dynamic input elements. I have a scope variable defined as:
$scope.formData = {};
On the page there are a couple of drop-down lists that users can choose an option from and based on those options we are appending some input fields to form body.
formBody.append('<input ng-model="formData.'+obj.Title+'" type="number"></input></br>');
This is not working for me because I'm assuming once the controller runs it can't register any new ng-model. Is there way to add dynamic ng-model or there is a different approach to what I'm trying to do (i.e. build predefined views that can be loaded on the page)?
EDIT:
I have created a jsfiddle that outlines what I'm trying to do - http://jsfiddle.net/k5u64yk1/

If you need to dynamically add html with dynamic bindings that cannot be encapsulated into ng-repeat, ng-if, etc, you have to call $compile on the template once it has been modified to alert AngularJS that it has to reparse the template and initiate a new digest cycle. This will pick up any new ng-model bindings and appropriately tie them to your scope.
HTML:
<div ng-app="MyApp" ng-controller="MyCntrl">
<button ng-click="addInput()">Add Input</button>
<div id="form">
input would go here.
</div>
</div>
JS:
By placing your add input inside of a click event, you avoid an infinite compile loop. Note that this currently resets the state of your form, so if you wanted to work around that you'd need to capture your form state and restore it after compile.
$scope.addInput = function () {
var aForm = (angular.element(document.getElementById('form')));
if ($scope.data["Digital Conversation"][0].MetricType.Title === "Number") {
aForm.append(
'<input ng-model="formData.' +
$scope.data["Digital Conversation"][0].Title.Title +
'" type="number"></input>');
}
$compile(aForm)($scope);
}
You can find the working jsfiddle here: http://jsfiddle.net/k5u64yk1/

Related

How to append html from typescript file and perform functionality on it in angular2

I am working on angular2 application.
I am getting one issue when I am appending date field from typescript the field was generated and looking perfect but the functionality I have performed on field click was not working(date picker will open on click on field and event icon).
HTML
<div id="specific_dates_container" class="field_area">
</div>
TYPESCRIPT
let count = document.querySelectorAll('.specific-date').length;
count += 1;
this.addCouponForm.addControl('specific_date'+count, new FormControl());
let html = "<div class='specific-date' id='specific_date"+count+"'><input placeholder='MM/DD/YYYY' ngx-mydatepicker [options]='calendarOptions' #sd"+count+"='ngx-mydatepicker' formControlName = 'specific_date"+count+"' (click)='sd"+count+".toggleCalendar()' readonly><i class='material-icons' (click)='sd"+count+".toggleCalendar()'>event</i></div><br>";
$("#specific_dates_container").append(html);
You need to change your approach towards this
It seems you are tying to create controls dynamically
To do that you need to follow this link
How to dynamically add and remove form fields in Angular 2

Dynamically how to make checkbox check/uncheck in angularjs controller using ng-click

I am new to Angular JS. When the user check/uncheck on a check box, I am calling a function in a controller using ng-click. I am passing $event to the function in controller. Using the $event, I am able to get the srcElement inside the controller function. Now I would like to set the previous check/uncheck value to the check box based on certain conditions.
$scope.isAccessChanged = function(event){
if (some condition) {
var elem = angular.element(event.srcElement);
/** here how to set the elem value back to whatever it was before.*/
}
};
Lets say you have check box like
<input ng-model="form.isSelected" type="checkbox">
All you need to do is:
$scope.form.isSelected = !$scope.form.isSelected;
Avoid DOM manipulation and limit jQuery use as much as possible in angular.
I recommend using jQuery only in directives to make it less of an available option.
Try this out:
<input type="checkbox" ng-model="foShizzle" ng-click="isAccessChanged()"/>
$scope.isAccessChanged = function(event){
if(some condition){
$scope.foShizzle = !$scope.foShizzle; // This will reverse the user's decision
}
}

Making Meteor reactive for html elements

So I have a modal box that allows the user to edit / save some data.
I just want to add that unlike other Meteor apps, I don't want to save the data straight away - I want the user to fill in all the fields before hitting save where it will save to the database and send to server etc. This is mainly because I want the user to be able to hit the "cancel" button to revert all changes.
I have a drop down box at the start of the form where depending on the value, fields will be shown or hidden
<select class="form-control" id="ddlNewInputType" placeholder="Enter your input type">
<option value="input">Input</option>
<option value="formula">Formula</option>
</select>
And I have a handlebar around a field like this to determine whether I want to show it
{{#if isFormula }}
<div class="row">
<input type="text"
id="txtNewInputFormula" placeholder="Enter formula">
</div>
{{/if}}
With a helper looking like this
isFormula: ->
$('#ddlNewInputType').val() == 'formula'
However, this doesn't work. Aside from when it first loads onto the page, it never hits isFormula, probably because Meteor doesn't consider any of the HTML elements as reactive so it never re-evaluates when the HTML element changes.
What is a suitable way to get around this? Is it possible to make something reactive explicitly in Meteor? I was also considering putting the dropdown list value into a session variable but that just seems messy because I'm going to need to manage this session variable (remember to clear it when the modal box closes etc.)
Your analysis is correct - a reactive variable needs to be involved in order for your helper to reevaluate after changing the select element. The basic strategy looks like:
Initialize a reactive variable when the template is created.
Whenever the select changes, update the reactive variable.
Read the reactive variable in your helper.
Rather than use a session variable, let's use a ReactiveVar scoped to your template. Here's an example set of modifications:
Template.myTemplate.helpers({
isFormula: function() {
return Template.instance().isFormula.get();
}
});
Template.myTemplate.events({
'change #ddlNewInputType': function (e, template) {
var isFormula = $(e.currentTarget).val() === 'formula';
template.isFormula.set(isFormula);
}
});
Template.myTemplate.created = function() {
// in your code, default this to the current value from
// your database rather than false
this.isFormula = new ReactiveVar(false);
};
Remember that you'll need to also do:
$ meteor add reactive-var
See my post on scoped reactivity for a full explanation of this technique.

inline editing in angularjs save item

I try to avoid any directive as I want to learn more, but I can't get it working on the save part.
partially working code here : http://jsfiddle.net/U3pVM/3789/
is it good to avoid using $index? because I use a lots of this
$scope.saveEditedTask = function(i){
this.editable = false;
}
change text field to
<input ng-show="editable" type="text" ng-model="task.name"/>
Plunker
You were not using the angular directive ng-model which bi-directionally binds the field to object.

Angular ng-model bound from nested ng-repeat

This must have been already done, and I am missing something about how Angular works on that point.
In short, I have <select ng-model><option ng-repeat/></select> and I don't know how to give it a default value at page load.
View:
<div ng-ctrl="MyCtrl">
<form ng-submit="submitChoice()">
<select ng-model='choice'>
<option ng-repeat='choice in choices' value='{{choice.id}}'>{{choice.id}}</option>
</select>
</form>
</div>
Way 1: When user updates the view (select the 'choice' he wants), the $scope used in MyCtrl gets it and I can perform whatever I want with it:
Way 2: But if, the other way round, I want to programmatically set the default value for the choices from the controller (at start), it can't change the value displayed:
function MyCtrl ($scope) {
$scope.submitChoice = function() {return;}; // Way1: OK!
$scope.choice = choice4; // Way2: Doesn't change the view!!
}
I guess it's because each element in ng-repeat has its own scope (fyi if I hardcode options in view instead of a ng-repeat, it works well).
In way 1 the inner scope selected by the use emits choice to the upper scope, if I understand well. But I have no idea how to do way 2.
Is it doable in a simple way? Is a directive necessary?
You would be better off using the ng-options directive with the select directive. Using select + ngRepeat has all sort of limitations and is better avoided. Is there any particular reason for generating options with ngRepeat?
If you could share more code (especially the structure of your data model) I might be able to provide more info.

Categories