I'm fairly new to angular, so hopefully this is a super simple question for someone to nail.
I have a form (cut down version below) that I want to be able to have a live preview being shown as the user fills in the form.
All was going well with standard fields, however I've hit a roadblock with <select> fields.
<div ng-app="jobcreate">
<div class="row fullWidth" ng-contoller="JobCtrl">
<div class="medium-6 columns">
<form method="POST" action="http://localhost:3030/job/create" accept-charset="UTF-8">
<label for="title">Enter a title</label>
<input placeholder="title" id="title" required="required" ng-model="job.title" name="title" type="text" />
<br />
<label for="title">Pick template</label>
<select ng-model="job.template" ng-options="template.Name for template in templates" name="template"></select>
</form>
</div>
<div class="medium-6 columns">
<div class='job-detail {{ job.template || "default" }}'>
<h2>{{ job.title || "Enter a title"}}</h2>
<h2>{{ job.template || "Pick a template"}}</h2>
<pre>Templates: {{templates | json}}</pre>
</div>
</div>
</div>
</div>
And here is the js:
angular.module('jobcreate', []).controller('JobCtrl', function($scope) {
$scope.templates = [
{ID:'default', name:'Default'},
{ID:'obnoxious', name:'Obnoxious'}
];
});
I have a jsfiddle here so you can see it in action: http://jsfiddle.net/2m8jm/4/
As you can see, entering something in the title field works as intended, but I'm struggling to get the contents of the $scope.colors to fill in the select field
In your fiddle : http://jsfiddle.net/2m8jm/4/, you have choosed templates as an data array for ng-options but there is not scope variable named templates in the controller JobCtrl. I have renamed $scope.colors to $scope.templates and modified the ng-options bit - ng-options="template.ID as template.name for template in templates".
Here is a working plunker : http://plnkr.co/edit/wsbxkjRqTEU2yfcHOV0D?p=preview
Update
Is there a way to not have the first empty value be in the select field?
Yes, Couple of ways.
1) Initialize job.template with some default value in your markup as :
<label for="title" ng-init="job.template='obnoxious'">Pick template</label>
<select ng-model="job.template" ng-options="template.ID as template.name for template in templates" name="template"></select>
2) Define controller as follows to set default value for job.template inside the controller :
.controller('JobCtrl', function($scope) {
// some other codes
$scope.job = {};
$scope.job.template = 'default';
});
Related
I am currently working on a web application that makes use of :
JQuery
AngularJS
Kendo framework
In particular, I need to implement an auto-complete function using kendo on an input text.
So, my first option, was to select that input text using jquery and then apply the auto-complete to it like this :
$(".autoComplete").kendoAutoComplete({
dataSource: data,
filter: "startswith",
placeholder: "Select country...",
separator: ","
});
Where the auto-complete class is applied to an input element of type text.
However, it seems that this solution is not applicable seen that the input text is generated dinamically as an angular modal :
script type="text/ng-template" id="dialogAddCompany.tpl.html">
<div class="modal-header no-header"></div>
<div class="modal-body">
<div class="row"><div class="col-sm-12 col-md-12"><div class="modal-caption-description-title"><label>{{tab.modal.title}}</label></div><div class="col-sm-12 col-md-12 caption-description"></div></div></div>
<div ng-if="tab.modal.type === 'blackbox'">
<fieldset>
<div class="col-md-12 form-group">
<label class="">Nome compagnia</label>
<input class="autoComplete" />
<input type="text"/>
// rest of the code
Looking on the internet, I found a solution to this problem using event delegation like this :
$("#bubble").on("click", ".autoComplete",function() {
$(".autoComplete").kendoAutoComplete({
dataSource: data,
filter: "startswith",
placeholder: "Select country...",
separator: ","
});
});
Where #bubble is the id of a div that is already present on the page when it's loaded.
However this solution is not working. Any Idea how to solve this ? I have already tried to use a solution using angular like :
<input type="text" kendo-auto-complete k-data-source="data" />
Where data is an array of data.
Thank you for your help!.
Edit :
I forgot to mention that the code I am talking about is inside a template like this :
<script type="text/ng-template" id="dialogAddCompany.tpl.html">
<div class="modal-header no-header"></div>
<div class="modal-body">
<div class="row"><div class="col-sm-12 col-md-12"><div class="modal-caption-description-title"><label>{{tab.modal.title}}</label></div><div class="col-sm-12 col-md-12 caption-description"></div></div></div>
<div ng-if="tab.modal.type === 'blackbox'" ng-controller="aipCompanyController">
<fieldset>
<div class="col-md-12 form-group">
<label class="">Element</label>
<input kendo-auto-complete k-data-source="data"/>
<input type="text" ng-click = "clicked()" kendo-auto-complete k-data-source="data" />
<!--<div ap-textbox ap-options="tab.cfg.textInput.options" ap-class="'form-control'" type="text" ap-value="tab.tabData.prova"></div>-->
If I try to create an input text with autocomple OUTSIDE of this template it works perfectly fine.
With angular you should use the kendo-auto-complete attribute and bind to your data-source like this:
<input kendo-auto-complete ng-model="yourModel" k-data-source="data" />
<p class="demo-hint">Your selection: {{ dataToShow }}</p>
https://demos.telerik.com/kendo-ui/autocomplete/angular
You can try something like this:
HTML:
<div id="example" ng-app="KendoDemos">
<script type="text/ng-template" id="dialogAddCompany.tpl.html">
<div ng-controller="MyCtrl">
<h4>Select Country /e.g. Armenia/</h4>
<input kendo-auto-complete ng-model="country" k-data-source="countryNames" />
<p>Your selection: {{ country }}</p>
</div>
</script>
<a ng-click="currentTemplate='dialogAddCompany.tpl.html'">Load template</a>
<div ng-include src="currentTemplate"></div>
JS:
<script>
angular.module("KendoDemos", [ "kendo.directives" ])
.controller("MyCtrl", function($scope){
$scope.countryNames = [
"Albania",
"Andorra",
"Armenia",
"Austria"];
});
</script>
Here I created a working example: https://dojo.telerik.com/AqEraMib
You can find angular material implementation here:
https://material.angularjs.org/latest/demo/autocomplete
It's easy to understand and implement.
or you can watch this implement yourself:
https://www.youtube.com/watch?v=y4gZMJKAeWs
I have a combo box and I am trying to set the selected value from the controller. How can I do that?
<md-select ng-model="selectedControl" ng-change="changeControl(selectedControl)" required>
<md-option ng-repeat="control in controls" ng-value="control">{{control}}</md-option>
</md-select>
I tried:
$scope.selectedControl = "Test";
Control array:
[{"ControlId":1,"ControlColumn":"Address","ControlText":"AddressTest"},{"ControlId":2,"ControlColumn":"City_State_Zip","ControlText":"CityTest"}]
in your options just pass the index of value<md-option ng-repeat="control in controls" ng-value="control" ng-selected="index == 1">control</md-option>
this will select the scond value in array so you can modify it accoding to your requirement.
problem lies in your data array as you need to select the value itself from the array to be selected in options, try to get proper array or split the data for better control over drop down selection.
Working jsfiddle
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="col-xs-12">
<label class="col-xs-6 control-label">Type:</label>
<div class="col-xs-6">
<select name="type" ng-model="selectedControl" ng-dropdown required ng-change="changeControl(selectedControl)" ng-options="control.ControlText for control in controls">
</select>
</div>
</div>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.controls = [{ 'ControlId': 1, 'ControlColumn': 'Address', 'ControlText': 'AddressTest' }, { 'ControlId': 2, 'ControlColumn': 'City_State_Zip', 'ControlText': 'CityTest' }];
$scope.selectedControl = $scope.controls[1]; // change the value from here
}
I have the following loop in which I'm trying to increment several fields based on the array index each time through the loop.
<div class="individualwrapper" ng-repeat="n in [] | range:4">
<div class="iconimage"></div>
<div class="icontext">
<p>Imagine that you are in a health care facility.</p>
<p>Exactly what do you think this symbol means?</p>
<textarea type="text" name="interpretation_1" ng-model="interpretation_1" ng-required="true"></textarea>
<p>What action you would take in response to this symbol?</p>
<textarea type="text" name="action_1" ng-model="action_1" ng-required="true"></textarea>
</div>
</div>
I'd like to do something similar to this"
ng-model="interpretation_{{$index + 1}}"
Angular is not rendering that value though? What would be the best way to go about adding this kind of logic in the mg-model field?
It becomes an invalid expression with the usage of interpolation with ng-model expression. You need to provide a property name there. Instead you can use an object and use bracket notation.
i.e in your controller:
$scope.interpretation = {};
and in your view use it as:
ng-model="interpretation[$index + 1]"
Demo
angular.module('app', []).controller('ctrl', function($scope) {
$scope.interpretation = {};
$scope.actions = {};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
{{interpretation}} {{actions}}
<div class="individualwrapper" ng-repeat="n in [1,2,3,4]">
<div class="iconimage">
</div>
<div class="icontext">
<p>Imagine that you are in a health care facility.</p>
<p>Exactly what do you think this symbol means?</p>
<textarea type="text" ng-attr-name="interpretation{{$index + 1}}" ng-model="interpretation[$index+1]" ng-required="true"></textarea>
<p>What action you would take in response to this symbol?</p>
<textarea type="text" name="action{{$index + 1}}" ng-model="actions[$index+1]" ng-required="true"></textarea>
</div>
</div>
</div>
I'm trying to render a validation summary on a page using AngularJS. Here's what I have so far:
<div ng-app>
<div ng-controller="ctrl">
<form name="userForm">
<fieldset>
<legend>User Info</legend>
<p><label>Name: <input type="text" required ng-maxlength="15" name="name" ng-model="name" /></label></p>
<p><label>Age: <input type="number" required name="age" ng-model="age" /></label></p>
<p><label>Favorite Color: <input type="text" required name="favColor" ng-model="favColor" /></label></p>
<p><input type="button" value="Submit" ng-click="submitForm()" /></p>
</fieldset>
</form>
<div id="validationSummary" ng-show="hasValidationErrors()">
<ul>
<li ng-repeat="error in validationErrors">{{ error }}</li>
</ul>
</div>
</div>
</div>
In my controller, I'm creating an array with all of the errors.
function ctrl($scope) {
$scope.hasValidationErrors = function () {
return $scope.validationErrors && $scope.validationErrors.length > 0;
};
$scope.submitForm = function() {
$scope.validationErrors = [];
for (var property in $scope.userForm) {
if ($scope.userForm.hasOwnProperty(property) && $scope.userForm[property].$invalid) {
$scope.validationErrors.push($scope.userForm[property].$name);
}
}
}
}
The thing I can't figure out is: how can I get more than just the name of each field that is invalid? I've noticed that there is also an $error property on each field. Outputting this instead of $name gives me the following:
{"required":true,"maxlength":false}
{"required":true,"number":false}
{"required":true}
So I can get the field name, and I can get an object that describes what is wrong with that particular field. How can I define an error message, so that if a field is required it will output "{name} is required"? It seems like this could be a data- attribute on the input element itself, although I don't know how I would access that attribute.
Of course, it's also possible that I'm making things entirely too difficult on myself. Is there a better way to approach this while staying in the "AngularJS" world?
Here's a link to the jsFiddle I've been working on.
A far easier and cleaner way is demonstrated here
Simply put (where form1 is your form name attribute):
<ul>
<li ng-repeat="(key, errors) in form1.$error track by $index"> <strong>{{ key }}</strong> errors
<ul>
<li ng-repeat="e in errors">{{ e.$name }} has an error: <strong>{{ key }}</strong>.</li>
</ul>
</li>
</ul>
A totally dynamic validation summary based on AngularJS 1.5.7 with ngMessages using field names that the user recognizes
A template with error messages:
<script type="text/ng-template" id="error-messages">
<span ng-message="required">This field is required.</span>
<span ng-message="email">Please enter a valid email.</span>
</script>
Display of the error summary (here for a form named "candidateForm"):
<div data-ng-if="candidateForm.$submitted && candidateForm.$invalid">
Please correct these fields and then try to send again:
<ul>
<li data-ng-repeat="field in candidateForm" data-ng-if="candidateForm[field.$name].$invalid">
<div>
{{ getValFieldName(field) }}
<span data-ng-messages="candidateForm[field.$name].$error" role="alert">
<span data-ng-messages-include="error-messages"></span>
</span>
</div>
</li>
</ul>
</div>
A helper function to get the name of the label associated with the input field (instead of displaying input field names or "internal ID codes" to users):
$scope.getValFieldName = function (field) {
return $("label[for=" + field.$name + "]").text(); // to get label associated with input field
// return $("#" + field.$name).attr("placeholder"); // to get placeholder of input field
};
You can reuse this set of standard error messages on multiple forms, ngMessages ensure only one error displayed per field, and looks like the fields are listed in the order they appear in the HTML.
Should probably be made into a directive instead of the jQuery-style helper function, and might even want to add a click-handler on each error message to scroll to the input field with the error. Maybe another will run with that idea?
Use below line to get values of every text box
var value = $scope.userForm[property].$name;
var vl =$('*[name="' + value + '"]').data('required-message')
$scope.validationErrors.push(vl);
I'm using Angular for a SPA I'm working on. I have an array which contains objects for each user on my site. I have an ng-repeat to add all the users to my dropdown list. I'm trying to figure out how do I display specific user information in an input box based on the selected user from the drop down?
<select id="entityDropDown" ng-options="user.name for user in users" ng-change="userInfo(user)"></select>
<div>
<label for="entityId">ID: </label>
<input type="text" id="entityId" disabled ng-model="{{user.id}}"/>
</br>
<label for="entityDomain">Domain: </label>
<input type="text" id="entityDomain" disabled ng-model="{{user.domain}}"/>
</div>
app.controller('userCtrl',
function userCtrl($scope,siteCollection){
$scope.users = siteCollection.getUsers();
}
);
K I solved the issue.
First of all, this ng-model="{{user.domain}}" isn't how you use ng-model. I had to change them to remove the curly braces ng-model="user.domain".
I modified the select as such:
<select id="entityDropDown"
ng-model="selectedUser"
ng-options="user as user.name for user in users"
ng-change="userInfo(selectedUser)">
</select>
This is my controller function:
spApp.controller('userCtrl',
function userCtrl($scope,siteCollection){
$scope.users = siteCollection.getUsers();
$scope.selectedUser = {};
$scope.userInfo = function(user) {
$scope.selectedUser = user;
};
}
);
Basically the controller gets all my users and puts it in a user object. The select goes through each user and generates the options. When the selected option changes, the ng-change passes the selected user object to the userInfo function and the html populates with that objects information.
you can append ng-model="selectedUser" to your select and in your userCtrl
<!-- template.html -->
<select id="entityDropDown" ng-options="user as user.name for user in users" ng-model="selectedUser">
</select>
<div class="user-info" ng-show="selectedUser">
<p> {{selectedUser.name}}</p>
<!-- ... -->
</div>
in your controller
// controller.js
function userCtrl($scope, siteCollection){
$scope.users = siteCollection.getUsers();
$scope.$watch('selectedUser', function(oldVal, newVal) {
if (oldVal === newVal) return;
//do something like call JSON if need it
});
}
When the <select> changes the $scope.selectedUser changes to selected value. later you can use the selectedUser variable like holder for your show the info into other place like in the div.user-info or you can use $scope.$watch('selectedUser'... for fire other behavior like call a services or whatever
using your template
<select id="entityDropDown" ng-options="user in users" ng-model="selectedUser">
<!-- <option ng-repeat="user in users">{{user.name}}</option> -->
</select>
<div>
<label for="entityId">ID: </label>
<input type="text" id="entityId" disabled ng-model="selectedUser.id"/>
</br>
<label for="entityDomain">Domain: </label>
<input type="text" id="entityDomain" disabled ng-model="selectedUser.domain"/>
</div>