Angular hide inputs in ng-repeat table rows - javascript

How would i hide input elements and replace there value to the table rows , the inputs are dynamically created with push see below code :
view
ID LIKE TO REPLACE THE INPUTS WITH THE VALUE OF INPUTS IN THE TABLE ROWS
<tr class="odd gradeX" ng-repeat="choice in vm.choices">
<td>Add</td>
<td>save</td>
<td>
<div class="form-group">
<div class="input-group">
<input type="text" placeholder="Item Name" class="form-control" ng-model="choice.item_name"/>
</div>
</div>
</td>
<td>
<div class="form-group">
<div class="input-group">
<select data-ng-options='t.value as t.label for t in vm.invoice_item_type' ng-model="choice.item_type" >
</select>
</div>
</div>
</td>
contoller
vm.choices = [];
vm.addNewChoice = function() {
var newItemNo = parseInt(vm.choices.length+1);
vm.choices.push({});
};
vm.saveChoice = function() {
var lastItem = vm.choices.length-1;
------ What to do here ------
};

Ok, the easiest way to do this would be probably something like this:
Add additional field to every choice object saying if it's saved or not
Add two <td>s for every choice, one with plain text and one with input and show/hide them depending on extra parameter' value.
Something like this:
<tr class="odd gradeX" ng-repeat="choice in vm.choices">
<td>Add</td>
<td>save</td>
<td ng-hide="choice.saved">
<div class="form-group">
<div class="input-group">
<input type="text" placeholder="Item Name" class="form-control" ng-model="choice.item_name"/>
</div>
</div>
</td>
<td ng-show="choice.saved">
<div class="form-group">
<div class="input-group">
<input type="text" placeholder="Item Name" class="form-control" ng-model="choice.item_name"/>
</div>
</div>
</td>
<!-- rest of your row goes here -->
</tr>
And in controller:
vm.choices = [];
vm.addNewChoice = function() {
var newItemNo = parseInt(vm.choices.length+1);
vm.choices.push({}); // we don't need to set `saved` property explicitly since undefined will be resolved to false
};
vm.saveChoice = function(choice) {
var lastItem = vm.choices.length-1;
choice.saved=true;
// probably some extra logic related to saving
};
Note that I've added parameter to saveChoice method - you need to know which choice to save.
Also, I think that button for adding new choice should be moved outside of the table - adding new item is not related to any existing item.

Related

only the first row were calculated automatically using jquery

i have this table that has a column for the edit button. a modal will pop up and the data from the row selected will show when the button is clicked.
so on my edit modal, i have 3 textboxes: Quantity, Consumed, and Available.
$('#edit-quant').keyup(function() {
var quant;
var consumed;
quant = parseFloat($('#edit-quant').val());
consumed = parseFloat($('#edit-consumed').val());
avail = quant - consumed || 0;
$("#edit-avail").val(avail);
});
$('#edit-consumed').keyup(function() {
var quant;
var consumed;
quant = parseFloat($('#edit-quant').val());
consumed = parseFloat($('#edit-consumed').val());
avail = quant - consumed || 0;
$("#edit-avail").val(avail);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="input-group mb-3">
<span class="input-group-text" style="color: #008080"><label>Quantity</label></span>
<input class="form-control" type="text" id="edit-quant" name="edit-quant" placeholder="Quantity" value="2"></i>
<span class="input-group-text" style="color: #008080"><label>Consumed</label></span>
<input class="form-control" type="text" id="edit-consumed" name="edit-consumed" placeholder="Consumed" value="3">
<span class="input-group-text" style="color: #008080"><label>Available</label></span>
<input class="form-control" id="edit-avail" type="text" name="edit-avail" placeholder="Available" value="4" readonly>
</div>
and when i try to change the values of the Quantity and Consumed and calculates its Available. only the first row of the table were working. the proceeding rows remains the same. how can i fix this?
I assume you have these repeated. You should not have an id attribute that is the same on any two or more elements on the same page. When you select an element by its id, the first element found with that value is going to be returned.
What you can do is make these into classes, then to get the fields, you can find the .closest(".input-group") which is wrapping all of your fields. From there, you can pull any of the fields by their given class. Alternatively, just use the name attribute on the fields and get rid of the id all together.
<div class="input-group mb-3">
<span class="input-group-text" style="color: #008080"><label>Quantity</label></span>
<input class="form-control" type="text" name="edit-quant" placeholder="Quantity" value="{{$med->med_quantity}}" ></i>
<span class="input-group-text" style="color: #008080"><label>Consumed</label></span>
<input class="form-control" type="text" name="edit-consumed" placeholder="Consumed" value="{{$med->med_consumed}}">
<span class="input-group-text" style="color: #008080"><label>Available</label></span>
<input class="form-control" type="text" name="edit-avail" placeholder="Available" value="{{$med->med_available}}" readonly>
</div>
I've removed the id attributes from the three fields. Now, when our event triggers, we'll find the group (parent DIV), and get each field with .find().
$('input[name = "edit-quant"], input[name = "edit-consumed"]').keyup(function()
{
var $group = $(this).closest('.input-group');
var quant = parseFloat($group.find('input[name = "edit-quant"]').val());
var consumed = parseFloat($group.find('input[name = "edit-consumed"]').val());
$group.find('input[name = "edit-avail"]').val(quant - consumed || 0);
});
Untested, but should work for you, or at least get you on the right track.

Use data of ng-repeat

I can display a table of users from my database on my web application using ng-repeat. I can add and delete directly from the web application but now I'm trying to update informations about those users. I would like to click on a button on the row of the user (each rows display informations for one user, 1 row = 1 user) when I clicked on this button I would like to make a form with input fields filled with actual values.
I can only get informations about my users by clicking on this button but I don't know how to "send" informations to this form.
My table of users :
<tr ng-repeat="user in users">
...
</tr>
But something like this is not working at all :
<form>
<label>Name</label>
<input type="text" id="up_name" ng-model="user.name"/>
<label>Age</label>
<input type="text" id="up_age" ng-model="user.age"/>
...
</form>
If you are using this synthax, your form have to be in your ngRepeat. It is not the best way to do it, as you will have a form for user.
I would suggest you something different. In your controller, set an edit() function:
$scope.edit = function(user) {
$scope.editedUser = user;
}
When clicking a user in your table, call the edit() function:
<tr ng-repeat="user in users" ng-click="edit(user)">
...
</tr>
You can now edit in the form the editedUser object:
<form ng-if="editedUser">
<label>Name</label>
<input type="text" id="up_name" ng-model="editedUser.name"/>
<label>Age</label>
<input type="text" id="up_age" ng-model="editedUser.age"/>
...
</form>
What you can do is the following :
<tr ng-repeat="user in users" ng-init="selectedUser = null">
<td> {{ user.name }}</td>... <td ng-click="selectedUser = user"> edit </td>
</tr>
<div ng-if="selectedUser">
<form>
<label>Name</label>
<input type="text" id="up_name" ng-model="user.name"/>
<label>Age</label>
<input type="text" id="up_age" ng-model="user.age"/>
...
</form>
</div>
I think that you are talking about a sort of master-detail ui pattern.
Here it is a public plunker that will solve that kind of problem
Insert the both input and span HTML directive in <td> and use ng-switch : ng-switch-when & ng-switch-default to display only one field.
<td class="sorting_1" ng-switch="mode">
<input type="text" class="form-control small" ng-switch-when="edit" id="edit" ng-model="edit.username">
<span ng-switch-default id="item.username">{{item.username}}</span>
</td>
You need to write a custom directive for it.Reason for writing custom directive is the value of ng-switch will associate with individual instead of global.
In the last <td> tag add : which will contain edit and update buttons:
<td ng-switch="mode">
<button class="btn btn-success btn-xs edit" ng-switch-when="edit" ng-
click="updateItem(edit, index)">
<i class="fa fa-floppy-o"></i>
</button>
<button class="btn btn-success btn-xs" ng-switch-default ng-
click="editItem(item)">
<i class="fa fa-pencil-square-o "></i>
</button>
</td>
JS
$scope.editItem = function(oldData) {
$scope.edit = angular.copy(oldData);
$scope.mode = "edit";
}
$scope.updateItem = function(data, index) {
$scope.$emit('update', data, index);
$scope.mode = "default";
}
The value of input-box will be updated using
$scope.edit = angular.copy(oldData); into editItem() function.
With the use of event emitters modify the main object.
$scope.$on('update', function(event, data, index) {
angular.copy(data, $scope.items[index]);
});
use angular.copy to deep clone value instead of passing value as a reference.
Check http://codepen.io/sumitridhal/pen/YVPQdW

Angularjs: Dynamic Input in a single array for row

I'm a newbie and I need some help for something you'll maybe find too easy.
I want to add with a single button different inputs at the same time.
I don't know how to manage.
This is what I'm doing, and I'm blocked.
I'll thank you your ideas.
So, my form shows each name and an input box for entering the age of that person (We don't know how many persons are in 'people').
And in the end, an 'submit' button that calls the showAll() function.
And then, I just want to show the content of the array in console.log
A Form like this:
Form with only 3 people
HTML:
<form name="myForm3">
<div class="form-group row" ng-repeat="person in people track by $index">
<label for="player" class="col-xs-3 col-form-label text-right">{{ person.name }}</label>
<div class="col-xs-2">
<input class="form-control" type="text" ng-model="person.age[$index]" required>
</div>
</div>
<button type="submit" class="btn btn-success btn-lg" ng-click="showAll()" >Show all</button>
</form>
controller.js:
$scope.person = [];
// POST
$scope.showAll = function() {
for (var i=0; i < person.length; i++){
console.log('person: ' + {{ $scope.person[i] }} );
}
}
you can hide the inputs by using ng-if or ng-hide and show them on showAll by setting that variable used by those to true or false:
<div class="col-xs-2" ng-if="person.show">
<input class="form-control" type="text" ng-model="person.age[$index]" required>
</div>
And in showAll:
$scope.showAll = function() {
for (var i=0; i < $scope.people.length; i++) {
$scope.people[i].show = true;
}
};

AngularJS: ng-model not clearing input

I have a dynamic input for CPFs (Brazilian 'social security' number).
Every time I enter one CPF, another input should be displayed, and so on..
But for some reason, the ng-model is not being cleared after the CPF is added.
Here's my HTML (inside a directive with isolate scope):
<div ng-repeat="cpf in cpfs" class="field-input">
<input type="text" class="field" ng-model="cpf.number" required>
<label>added CPF</label>
</div>
<div class="field-input">
<input type="text" class="field" ng-model="cpf.number" required>
<label>add new CPF</label>
<button ng-click="addCpf(cpf)" class="btn btn-primary">add</button>
</div>
Here's my controller (inside a directive with isolate scope):
$scope.cpfs = [];
$scope.addCpf = function(cpf) {
$scope.cpfs.push(angular.copy(cpf));
delete $scope.cpf;
};
instead of delete $scope.cpf; use $scope.cpf.number = "";
we can't delete an model, we have to set it to blank, because its linked with our View part

How to clear Input data from within JQuery Div

I have a simple form users can fill out and also add a new form to add multiple entries.
Everything works fine except when I enter data in the first set of inputs and click create new memberships it will take the data from the form and put it in the text boxes.
How can I stop that?
http://jsfiddle.net/811yohpn/2/
I have tried a couple different ways.
$('#education').find('input:text').val('');
$('#education: input').val('');
However that will clear all entries.
Call find on the newDiv, instead of all inputs within #education.
Updated fiddle
newDiv.find('input:text').val('');
var ed = 1;
function new_education() {
ed++;
var newDiv = $('#education div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete Education ' + ed + ' </a>';
newDiv.find('tr:first th').text('Education ' + ed);
newDiv.append(delLink);
newDiv.find('input:text').val(''); // <----------- added this
$('#education').append(newDiv);
}
function deled(eleId) {
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('education');
parentEle.removeChild(ele);
//ed--;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<legend>Education</legend>
<div id="education">
<div id="1">
<table border=3>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Education 1</th>
</tr>
<tr>
<td>
<label>School Name</label>
<input type="text" name="schoolname[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Type</label>
<input type="text" name="degreetye[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Field</label>
<input type="text" name="degreefield[]" maxlength="30" size="30"/>
</td>
</tr>
</table>
</div>
</div>
<br/><a class="js-addNew btn btn-info" href="javascript:new_education()"> Add New Education </a>
You need to clear the inputs under the cloned element
newDiv.find('input').val('')
Demo: Fiddle
Your selectors are selecting all input elements within the #education container, that is not what you want. The newDiv variable refers to the newly created element so you can use that to find the input elements within in and then clear it

Categories