I am working on a web app that displays a prompt based on which field the user has in focus or not. I have a few different scripts of text that I want to display at these different points.
What I would like to do is display the scope data in those strings when they are displayed. Right now everything gets rendered as text. Here is what I am doing. In the view. (Ignore my poor use of ng-init I will change this to a controller.)
<div><p>Full Name</p><input placeholder="Name" name="personal.name" ng-model="personal.name" ng-model-options="{ updateOn: 'default blur' }" class="medium" type="text"/></div>
<div><p>Address</p><input class="long" type="text" ng-model="personal.address" ng-model-options="{ updateOn: 'default blur' }" placeholder="Address"/></div>
<div><p>Phone</p><input placeholder="Phone" ng-model="personal.phone" type="phone" ng-model-options="{ updateOn: 'default blur' }" only-digits/></div>
<div ng-init="script()">
<div ng-repeat="scripts in script">
<div ng-show="{{scripts.element}}" ng-hide="true" class="alert-bar">
<div class="wrapper">
<div ng-bind="scripts.script"></div>
</div>
</div>
</div>
</div>
and the controller again ignore the data in this I will store this later.
$scope.script = function(){
$scope.script = [
{
'element': "personal.name",
'script': '{{personal.name}} welcome to SOCU\'s loan application.'
},
{
'element': "personal.address",
'script': '{{personal.name}}, please enter your full current address.'
},
{
'element': "personal.phone",
'script': '{{personal.name}}, please enter your current phone number, with the area code.'
}
];
}
Everything works except I cannot get the name to show up. I know that I shouldn't use the double curly brackets here. I've also tried getting the data directly from the $scope but I don't see any personal data there.
You can't do bindings in your controller as they are dedicated to view only.
Since you iterate the script array you can just access the elements of object by,
{{scripts.element + scripts.script}}
Handlebar syntax should work for div element. Have an array structure as given below,
$scope.script = [{
element: 'Person name',
script: 'Your script'
}];
In your div,
<div ng-init="script()">
<div ng-repeat="scripts in script">
<div ng-show="{{scripts.element}}" ng-hide="true" class="alert-bar">
<div class="wrapper">
<div>
{{ scripts.element + " , " + scripts.script }}
</div>
</div>
</div>
</div>
</div>
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'm pretty new to Vue.js and while I've figured most of the problems I'm hitting out, I can't get my head around this one.
I'm displaying a list of posts based on API output, and want to have a comments box for each post. Posting to the API is working fine and it adds it without a problem, but because I'm using the same v-model for each input in the loop any text entered is replicated throughout all other matching inputs due to the binding.
<div class="row" v-if="">
<div class="col-md-11">
<input type="text" class="form-control" value="" title=""
placeholder="Add comments here.." v-model="note.note">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default" style="margin-left: -1.5rem" v-on:click="addNote(task.id)">Add Comment</button>
</div>
</div>
JS:
addNote: function (id) {
if (this.note.note) {
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
this.$http.post('api/note/create/' + id, this.note).then(function (response) {
this.fetchTaskList();
});
}
}
Screenshot:
Is there a different directive I should be using? Or is there another way around this?
You can do this by using index in v-for and then binding each box to the notes comment like so:
<!-- use index, so we know where we are in the loop -->
<div v-for="(note, index) in notes">
{{ note.note }}
<!-- Bind to the comment at the given index -->
<input v-model="notes[index].comment" />
</div>
Now you just need to set that up in data:
data: {
notes: [
{note: 'note 1', comment: ''},
{note: 'note 2', comment: ''},
{note: 'note 3', comment: ''}
]
}
Here's the JSFiddle: https://jsfiddle.net/efxzmq9s/
I have a ember-app-kit application. For the form I am using ember default views. But for form validations I have came across with this lib which everyone highly recommends. Ember Validations By Docyard . But I am not sure how to implement the same with my eak set-up.
Questions that I have:
1. Where should I add validations ?
2. What to declare when defining validations?
3. Errors how to show them on focus out or even on submit button ?
Say for example I have a sign up form and I want to validate firstname lastname, email, password, gender(select options) . How should I go about it ?
If possible please clarify the queries with a JSbin.
Validations should go to controller, unless your working with dyanmic formsets, which can be duplicated. Also u have to wrap ControllerObject into this
var AddController = Ember.ArrayController.extend(Ember.Validations.Mixin, {}
To start validation u have to make new Object named validations
You have to add input value to be validated
validations: {
newFirstname:{
format: { with: /^[A-Za-z-]{2,16}$/, allowBlank: true, message: 'Enter valid name.' }
},
newFamilyname: {
format: { with: /^[A-Za-z-]{3,16}$/ , message: 'Required field lastname.' }
}
},
Showing errors.
<div class="row">
<div class="col-md-6 col-xs-4">
<label>First name: </label>
{{input type="text" placeholder="First name" value=newFirstname class="form-control"}}
{{#if errors.newFirstname}}
<span class="error errorForValidation"><span class="glyphicon glyphicon-warning-sign"></span> {{errors.newFirstname}}</span>
{{/if}}
</div>
<div class="col-md-6 col-xs-4">
<label>*Last name: </label>
{{input type="text" placeholder="Family name" value=newFamilyname class="form-control"}}
{{#if errors.newFamilyname}}
<span class="error"><span class="glyphicon glyphicon-warning-sign"></span> {{errors.newFamilyname}}</span>
{{/if}}
</div>
</div><!--end row-->
Showing button when validation is flawless
<button type="submit" class="btn btn-primary" {{bind-attr disabled="isInvalid"}}{{action 'GetData'}}>Create</button>
JSBIN : http://emberjs.jsbin.com/iDeQABo/17/edit
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';
});
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);