I am trying to append an element to the DOM from user text input using AngularJS.
The desired behaviour is:
User types string into input ng-model "newTask"
Presses enter key
Dynamic element is then appended to the DOM
The relevant section of HTML is as follows:
<div class="add-task">
<input type="text" placeholder="Type then press enter to create task" ng-model="newTask" />
</div>
<div class="task-list">
<a class="task"><span class="text">{{ newTask }}</span></a>
</div>
Currently the HTML is instantly updated. How can I bind this event to only happen after enter keypress? The AngularJS UI is also loaded.
Many appreciations,
an AngularJS newbie
Try creating a temp value
Html:
<input type="text" placeholder="Type then press enter to create task" ng-model="tmpTask" ng-keypress="saveTask($event)" />
Your ng-model binds to a tmpTask property. Only when enter is pressed, save it back to newTask
JS:
app.controller('MainCtrl', function($scope) {
$scope.saveTask = function (event){
if (event.keyCode == 13){
$scope.newTask = $scope.tmpTask;
}
}
});
DEMO
html
<form ng-submit="createTask()">
<input type="text" ng-model="newTaskText" />
</form>
<div ng-repeat="task in tasks">{{ task.text }}</div>
controller
$scope.tasks = [];
$scope.createTask = function() {
$scope.tasks.push({
text: $scope.newTaskText
});
};
Since one of the other answers addresses the ng-keypress, I'll offer up the fact you don't need to use the ng-keypress event but can just watch the variable instead which negates the need for enter:
http://plnkr.co/edit/osFGRtpHG46bMyp15mc8?p=preview
app.controller('MainCtrl', function($scope) {
$scope.taskList = [];
$scope.$watch('newTask', function(newVal){
if (newVal=="newTask") {
$scope.taskList.push("Task " + $scope.taskList.length);
$scope.newTask = null;
}
});
});
<body ng-controller="MainCtrl">
<div class="add-task">
<input type="text" placeholder="Type then press enter to create task" ng-model="newTask" />
</div>
{{taskList.length}}
<div class="task-list" >
<a class="task" ng-repeat="task in taskList" ><span class="text">{{ task }} </span></a>
</div>
</body>
Related
I'm creating a to-do list app with angular, pretty simple, but I am having an issue with the checkboxes--- If I click one check box, they all get checked... How can I separate it so it only checks one at a time and then checks to save checked/unchecked boxes?
HTML
<body ng-controller="HomeController as vm"
ng-cloak>
<input type="text" placeholder="To do..."
ng-model="vm.myTask">
<button type="button" ng-click="vm.submitTask()">Submit</button>
</br>
<label ng-repeat="Task in vm.myTasks">
<ul>
<li>
<input type="checkbox" value="{{Task}}"
ng-model="vm.taskList">{{Task}}</li>
</ul>
</label>
homeController.js
//task array
var myTasks = [];
class HomeController {
//submit task from input value
submitTask(){
//push new task into array
myTasks.push(this.myTask);
}
constructor(myTask){
this.myTasks = myTasks;
}
}
angular.module("myapp").controller("HomeController", HomeController);
You have to push the checked tasks in an array and manipulate this array based on checking/unchecking of checkbox.
JS
constructor(myTask,checkedTask){
this.myTasks = myTasks;
this.checkedTask = checkedTask;
}
check(task,indx){
var index = checkedTask.indexOf(task);
if (index > -1)
checkedTask.splice(index, 1);
else
checkedTask.push(task);
}
HTML
<li>
<input type="checkbox" value="{{Task}}"
ng-click="vm.check(Task,$index)" ng-checked="vm.checkedTask.indexOf(Task)>-1">{{Task}}
</li>
Working Plunker: https://plnkr.co/edit/cDrWUteexBgmAug3Pj2S?p=preview
I would prefer it a bit easier. Change your task to be an object with a name and checked-property. Bind the checkbox to the checked property of your task. Done.
HTML
<body ng-controller="HomeController as vm"
ng-cloak>
<input type="text" placeholder="To do..."
ng-model="vm.myTask">
<button type="button" ng-click="vm.submitTask()">Submit</button>
<br>
<label ng-repeat="task in vm.myTasks"> <!-- lowercase task -->
<ul>
<li>
<input type="checkbox" value="{{task.name}}" ng-model="task.checked">{{task.name}}</li> <!-- task is now an object, not only a string, so we access the properties name and checked -->
</ul>
</label>
</body>
JS
var app = angular.module("myapp",[]);
var myTasks = [];
class HomeController {
//submit task from input value
submitTask(){
//push new task into array
myTasks.push({name: this.myTask, checked: false}); //create new object and push it into the array
}
constructor(myTask,checkedTask){
this.myTasks = myTasks;
}
}
app.controller("HomeController", HomeController);
Working plunker (based on Vivz plunker):
https://plnkr.co/edit/CUPw165TQGiLusJEWqkr?p=preview
<div class="info-block" ng-app="">
<div ng-controller="Note">
<div class="checkbox">
<label>
<p><b>Primary Publication: </b>
{{ form_widget(form.input_ppubs, { 'attr': {'class': 'valOption'}}) }}
</p>
</label>
</div>
<div ng-repeat="item in items">
<input type="text" placeholder="new input" ng-model="item.primaryPub">
</div>
<button type="button" ng-click="add()">New Item</button>
</div>
I am trying to retrieve the value of the html input field and remove it from input upon a button click
I am able to get the code, but I don't know how to remove the code.
var Note = function($scope){
$scope.items = [];
$scope.add = function () {
//angular way of implementing document.getElementByID();
pub1 = angular.element('#form_input_ppubs').val();
$scope.items.push({
primaryPub: pub1
});
};
}
You don't have to retrieve your items like this. It's ugly and not the angular way. angular.element('#form_input_ppubs').val();
Instead, simply reference it in your input using ngModel.
Declare it in your scope.
$scope.inputItem = null;
HTML
<input ng-model="inputItem " />
Use it in your function:
$scope.addItem = function(item) {
$scope.items.push(item);
//reset the model
$scope.inputItem = null;
}
Call it using ng-click
<button type="button" ng-click="addItem(inputItem)">Add Item</button>
If you do:
console.log($scope.items);
You should see an entry for primaryPub, the model for your input. Then you can target it by nulling the model, so:
$scope.items.primaryPub = null;
However you're using this inside an ng-repeat:
<div ng-repeat="(i, item) in items">
<input type="text" placeholder="new input" ng-model="items[i].primaryPub">
</div>
So your console.log (if you have more than one item in 'items') should show an array-like structure for primaryPub.
I want dynamic input in my form so that user can add many input as much he wants
Same time I want to display the value of it..
Example:
Suppose i have one input
Customer: <input type="text" ng-model="name"/> <!--first input>
<a>Add more</a>
I can easily get value for it
All customers <p ng-bind="name"></p>
BUT if users add one more customer name input, Then how can i show that value
Under "All customers tag"
All customers <p ng-bind="name"></p> // Customer1,Customer1 name here
Use an array of objects on scope in conjunction with a ng-repeat. The button will then add to the array.
View:
<p ng-repeat="item in array">Name: <input type="text" ng-model="item.name" ></p>
<button ng-click="add()">Add</button>
<p>All customers</p>
<p ng-repeat="item in array">{{item.name}}</p>
Js:
app.controller('MainCtrl', function($scope) {
$scope.array = [];
$scope.add = function () {
$scope.array.push({ name: ''});
}
$scope.add();
});
Plunkr
You have to create array.
In your controller
$scope.inputs = [];
$scope.add = function() {
$scope.inputs.push({value: ''});
}
$scope.add();
now in HTML
<div ng-repeat="input in inputs">
<input type="text" ng-model="input.value" />
</div>
<button ng-click="add()">Add</button>
This is raw concept of how that might be done.
Update
Added plunker example
http://plnkr.co/edit/bHLXCjsP46GiixysZZ83?p=preview
Suppose I have following angularjs template
<script type="text/ng-template" id="tmp">
<li>
{{firstname}} {{lastname}}</li>
</script>
and I have two textboxes and a save button like
<input name="firstname" type="text"/>
<input name="lastname" type="text"/>
<button name="save" text="save"/>
when user enters values in firstname and lastname textboxes and press on save button I want these two values to be passed to the template and resultant html should be appended to an existing ul. How can I do it with angular?
You could create a directive to dynamically compile your template and append it to the ul when someone hits the save button, but that's basically the whole purpose of ng-repeat.
Here's how it can work with an ng-repeat instead:
angular.module('main', []);
angular.module('main').controller('MainCtrl', function ($scope) {
$scope.names = [];
$scope.save = function () {
$scope.names.push({first: $scope.firstname, last: $scope.lastname});
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="main" ng-controller='MainCtrl'>
<input name="firstname" type="text" ng-model='firstname'/>
<input name="lastname" type="text"ng-model='lastname'/>
<button name="save" text="save" ng-click='save()'>save</button>
<ul>
<li ng-repeat='name in names'>{{name.first}} {{name.last}}</li>
</ul>
</div>
I have a collection of items in $scope.data with fields "id","name" & "age", that are being displayed in the view using ng-repeat directive.
For each set of items, there is a corresponding "edit button".
I want to be able to access values for the particular set of items for which edit button was pressed.
Html:
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<form ng-submit="submit()">
<input type="text" ng-model="i.id"/>
<input type="submit" value="Edit" />
</form>
</div>
</div>
Script:
function Ctrl($scope)
{
$scope.data = [
{id:1,name:"Alex",age:22},
{id:2,name:"Sam", age:28}
];
$scope.submit = function() {
//access id of user for which edit was clicked
};
}
What is the right way to do this?
Instead of a form, I would suggest you just use a button:
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<input type="text" ng-model="i.id"/>
<button ng-click="submit(i)">Edit</button>
</div>
</div>
Just send i into the button click event (I suppose you could use form if you need validation, but your example doesn't seem to need it).
Your submit function then changes to:
$scope.submit = function(selectedItem) {
// here you now have access to selected item
};
Try this:
HTML:
<form ng-submit="submit(i.id)">
JavaScript:
$scope.submit = function(userId) {
// you have userId
};
One option is to just use an ng-click within a button that calls your submit passing in i
<div ng-controller="Ctrl">
<div ng-repeat="i in data">
Name: {{i.name}}
Age: {{i.age}}
<button ng-click="submit(i);">edit</button>
</div>
</div>
and the function:
$scope.submit = function(i) {
console.log(i);
//access id of user for which edit was clicked
};
Here's a fiddle of that working: http://jsfiddle.net/pRAcP/