I am building a table using angular ng-repeat. I need to have the ability to update or delete each row independently and thus need to validate each row independently.
<tr ng-repeat="item in model.items" >
<td><input type="text" ng-model="item.AccountNumber" ng-maxlength="model.validation.maxAccountLength" /></td>
<td><select ng-model="item.OriginCountry" ng-options="country.Id as country.Name for country in model.OriginCountries"></select></td>
<td><select ng-model="item.DestinationCountry" ng-options="country.Id as country.Name for country in model.DestinationCountries"></select></td>
<td><input type="text" ng-model="item.Zone" ng-maxlength="4" /></td>
<td><button type="button" ng-click="updateItem(item)" class="btn btn-warning" ><i class="fa fa-refresh"></i></button></td>
<td><button type="button" ng-click="removeItem(item)" class="btn btn-danger"><i class="fa fa-trash-o"></i></button></td>
</tr>
Is it possible to validate each row idependently
Try to wrap the row contents with forms and add name attributes to your inputs/selects
<tr ng-repeat="item in model.items" >
<td>
<form name="form">
<input name="account_number" type="text" ng-model="item.AccountNumber" ng-maxlength="model.validation.maxAccountLength" /></td>
<td>name="origin" ng-model="item.OriginCountry" ng-options="country.Id as country.Name for country in model.OriginCountries"></select></td>
<td><select name="destination" ng-model="item.DestinationCountry" ng-options="country.Id as country.Name for country in model.DestinationCountries"></select></td>
<td><input name="zone" type="text" ng-model="item.Zone" ng-maxlength="4" /></td>
<td><button type="button" ng-click="updateItem(item)" class="btn btn-warning" ><i class="fa fa-refresh"></i></button></td>
<td><button type="button" ng-click="removeItem(item)" class="btn btn-danger"><i class="fa fa-trash-o"></i></button>
</form>
</td>
</tr>
Now you can use the FormController state like form.$submitted or form.zone.$touched
(https://docs.angularjs.org/guide/forms)
Related
I have been trying to add a filter to my code to filter for each input that is on the top of my page, however, the filter is actually filtering for every property.
For example: If I search for a user in the user input field, the filter will actually filter the phone, role and status. I want to filter only the user if it is the user field or role if the text input is in role field.
I'm also using the same fields to add a user, so if the inputs are filled in and you click add, the data is added to the db which works but I'm having issues with the filter. I have searched and tried multiple things, however, it does not seem to work. If someone can point me to the right direction, I would appreciate it.
<tr>
<td><input class="form-control input-sm" ng-model="user.name" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.phone" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.role" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.status" style="height:22px"></td>
<td><button class="btn btn-primary btn-xs" ng-click="adduser(); showAlert($event)">Add</button></td>
<td><button class="btn btn-info btn-xs" ng-click="update()">Update</button></td>
<td><button class="btn btn-info btn-xs" ng-click="deselect()">Clear</button></td>
</tr>
<tr ng-repeat="user in userdb | filter:user.name | filter:user.phone | filter:user.role | filter:user.status">
<td>{{user.name}}</td>
<td>{{user.phone}}</td>
<td>{{user.role}}</td>
<td>{{user.status}}</td>
<td><button class="btn btn-warning btn-xs" ng-click="edit(user._id)">Edit</button></td>
<td><button class="btn btn-danger btn-xs" ng-click="remove(user._id)" disabled>Remove</button></td>
</tr>
You can try the following:
<table>
<tr>
<td><input class="form-control input-sm" ng-model="user.name" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.phone" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.role" style="height:22px"></td>
<td><input class="form-control input-sm" ng-model="user.status" style="height:22px"></td>
<td><button class="btn btn-primary btn-xs" ng-click="adduser(); showAlert($event)">Add</button></td>
<td><button class="btn btn-info btn-xs" ng-click="update()">Update</button></td>
<td><button class="btn btn-info btn-xs" ng-click="deselect()">Clear</button></td>
</tr>
<tr ng-repeat="user in userdb | filter:{name: user.name, phone: user.phone, role: user.role, status: user.status}">
<td>{{user.name}}</td>
<td>{{user.phone}}</td>
<td>{{user.role}}</td>
<td>{{user.status}}</td>
<td><button class="btn btn-warning btn-xs" ng-click="edit(user._id)">Edit</button></td>
<td><button class="btn btn-danger btn-xs" ng-click="remove(user._id)" disabled>Remove</button></td>
</tr>
</table>
i have data like this:
[{
"id": 1,
"organizationName": "psda",
"organizationNameEN": "psda",
},
{
"id": 1,
"organizationName": "psda",
"organizationNameEN": "psda",
}]
and i want tvalues, this data to my table field values , here is my code:
<tbody ng-repeat="item in arr" >
<tr>
<td><input style="width:25px; height:25px;" type="checkbox" ng-model="chekselct"
cam-variable-name="isItemSelected"
cam-variable-type="Boolean" /></td>
<td><input style="width:140px;" type="text" id="id" value= "{{item.id}}" readonly /></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" value="{{item.organizationName}}" readonly/></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" value="{{item.organizationName}}" readonly/></td>
<td><button type="button" class="btn btn-primary" style="height:25px">details</button></td>
</tr>
</tbody>
AND IT TROWS EXCEPTION Cannot read property 'value' of undefined,
WHAT SHOULD I CHANGE TO MAKE THIS CODE WORK?
Instead of value attribute on input try ng-model
<tbody ng-repeat="item in arr" >
<tr>
<td><input style="width:25px; height:25px;" type="checkbox" ng-model="chekselct"
cam-variable-name="isItemSelected"
cam-variable-type="Boolean" /></td>
<td><input style="width:140px;" type="text" id="id" ng-model="item.id" readonly /></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" ng-model="item.organizationName" readonly/></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" ng-model="item.organizationNameEN" readonly/></td>
<td><button type="button" class="btn btn-primary" style="height:25px">details</button></td>
</tr>
</tbody>
I would have a question concerning variables in scope and visibility.
Currently I have two controller variables:
vm.selectedUser
vm.selectedUserRole
The problem is, that I generate the tables in a ng-repeat loop and all inputs and selects in the different tables share this two mentioned variables above.
My question now would be how can I use this two parameters above in my method:
vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent, selectedUser, selectedUserRole)
Is there any chance to do this because the input, select elements and the span-button element (add user) have different scopes (this is my guess - I don't know exactly)
Thanks a lot for help!
<div ng-repeat="institutionUserConnectionsOfInstitution in vm.institutionUserConnectionsOfInstitutions">
<div ng-repeat="institutionUserConnectionContent in institutionUserConnectionsOfInstitution.institutionUserConnectionContents">
<div ng-show="addUser" class="row">
<table>
<tr>
<td class="adduserinput">
<input
type="text"
class="form-control"
placeholder="Benutzer durchsuchen"
ng-model="vm.selectedUser"
typeahead="user as vm.userLabelFormatter(user) for user in vm.getUsersByTerm($viewValue) | limitTo:5"
typeahead-min-length="3"
typeahead-wait-ms="100"
typeahead-editable="false" />
</td>
<td class="adduserroles">
<select class="form-control" ng-model="vm.selectedUserRole" ng-options="role as role for role in vm.roles">
</select>
</td>
<td>
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent)">add user</button>
</span>
</td>
</tr>
</table>
</div>
</div>
Do it like this -
<div ng-repeat="institutionUserConnectionsOfInstitution in vm.institutionUserConnectionsOfInstitutions">
<div ng-repeat="institutionUserConnectionContent in institutionUserConnectionsOfInstitution.institutionUserConnectionContents">
<div ng-show="addUser" class="row">
<table>
<tr>
<td class="adduserinput">
<input
type="text"
class="form-control"
placeholder="Benutzer durchsuchen"
ng-model="institutionUserConnectionContent.selectedUser"
typeahead="user as vm.userLabelFormatter(user) for user in vm.getUsersByTerm($viewValue) | limitTo:5"
typeahead-min-length="3"
typeahead-wait-ms="100"
typeahead-editable="false" />
</td>
<td class="adduserroles">
<select class="form-control" ng-model="institutionUserConnectionContent.selectedUserRole" ng-options="role as role for role in vm.roles">
</select>
</td>
<td>
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent, institutionUserConnectionContent.selectedUser, institutionUserConnectionContent.selectedUserRole)">add user</button>
</span>
</td>
</tr>
</table>
</div>
</div>
Explanation -
I just changed the vm to institutionUserConnectionContent.
reason - since you'll have multiple rows in the table (ng-repeat), if you use vm, you would end up with overwriting the same selectedUser and selectedUser of one row with other.
Hope this helps.
I am trying to get datepickers to display in a table using an ng-repeat. I have a begin date and end date. When I try to display both datepickers they display one over the other. Below is my code and a screenshot of what is happening.
<table datatable="ng" dt-options="dtOptions" dt-columns="dtColumns" class="table table-bordered">
<tbody>
<tr ng-repeat="waiver in model.waivers" >
<td class="input-group">
<input class="form-control" type="text" datepicker-popup="MM/dd/yyyy" ng-model="waiver.StartDate" is-open="waiver.isOpen" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event, waiver)"><i class="fa fa-calendar"></i></button>
</span>
</td>
<td class="input-group">
<input class="form-control" type="text" datepicker-popup="MM/dd/yyyy" ng-model="waiver.EndDate" is-open="waiver.isOpen" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event, waiver)"><i class="fa fa-calendar"></i></button>
</span>
</td>
<td><input type="text" ng-model="waiver.FuelCap" /></td>
<td><button type="button" ng-click="updateWaiver(waiver)" class="btn btn-warning"><i class="fa fa-refresh"></i></button></td>
<td><button type="button" ng-click="removeWaiver(waiver)" class="btn btn-danger"><i class="fa fa-trash-o"></i></button></td>
</tr>
</tbody>
</table>
Screenshot
Here is a quick plunkr example.
I know they are both opening when the open button is clicked but if you could help explain why they appear in the same column of the table.
It has to do with how bootstrap is styling the input-group. You need to not place that class on the td. Try moving it down a level like so:
<td>
<div class="input-group">
<input class="form-control" type="text" datepicker-popup="MM/dd/yyyy" ng-model="waiver.StartDate" is-open="waiver.isOpen" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event, waiver)">open</button>
</span>
</div>
</td>
<td>
<div class="input-group">
<input class="form-control" type="text" datepicker-popup="MM/dd/yyyy" ng-model="waiver.EndDate" is-open="waiver.isOpen" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event, waiver)">open</button>
</span>
</div>
</td>
I have a view where I want to iterate a list in the model to render the view, the current code is something like
<form method="Post">
<table class="table">
#Each
<tr>
<td>
<input type="hidden" name="Id[]" value="#Current.Id" />#Current.Id
</td>
<td>
<input type="text" name="Name[]" value="#Current.Name"/>
</td>
<td>
<input type="text" name="Code[]" value="#Current.Code"/>
</td>
<td>
<button type="submit">Submit</button>
</td>
</tr>
#EndEach
</table>
</form>
What I actually wish to do is
<form method="Post">
<table class="table">
#Each
<tr>
<td>
<input type="hidden" name="Id[#CurrentIndex]" value="#Current.Id" />#Current.Id
</td>
<td>
<input type="text" name="Name[#CurrentIndex]" value="#Current.Name"/>
</td>
<td>
<input type="text" name="Code[#CurrentIndex]" value="#Current.Code"/>
</td>
<td>
<button type="submit">Submit</button>
</td>
</tr>
#EndEach
</table>
</form>
where #CurrentIndex will insert the list index.
List index can then be used to bind the property to a list during POST with something like
Post["/"] = _ => {
var list = this.Bind<List<Model>>();
...... do something with list .........
}
SSVE is "dumb", there's no way to execute any arbitrary code. The only way to do this would be to put the index into your model, you can do it with LINQ with something like (not compiled, just typed from memory):
var indexedModel = model.Select((m,i) => new { Index = i, Model = m });
Then in your view do something like:
<form method="Post">
<table class="table">
#Each
<tr>
<td>
<input type="hidden" name="Id[#Current.Index]" value="#Current.Model.Id" />#Current.Id
</td>
<td>
<input type="text" name="Name[#Current.Index]" value="#Current.Model.Name"/>
</td>
<td>
<input type="text" name="Code[#Current.Index]" value="#Current.Model.Code"/>
</td>
<td>
<button type="submit">Submit</button>
</td>
</tr>
#EndEach
</table>
</form>