How to make an xeditable select input mandatory (required) in AngularJS - angularjs

I have an AngularJS project that uses Angular Bootstrap and I use the Angular-xeditable library for some edit-in-place fields in a table.
One of the inputs I have is a "select" input, i.e. a drop-down list that allows a user to select one option. (editable-select in xeditable).
I am trying to make this input mandatory when saving the form, but I cannot find a way to do this. Similar to all the x-editable controls I would expect that I can simply add an e- prefix to the standard angular directive to apply that directive to the xeditable control, that is, I should be able to add e-ng-required="true" to my control to make it mandatory. Yet this does not work. I do not get any errors when I add this, but it doesn't "do" anything. I can still save my form without selecting an item.
The following is a code sample of what I'm trying to do:
<form editable-form name="tableform" onaftersave="saveSubmissions()" oncancel="cancel()">
<table>
<!--Define table headings and columns...-->
<!--Define an ng-repeat to display each row-->
<tr ng-repeat="currentRow in dataRows">
<!--Add some columns for the row-->
<!--Add the select/drop-down column pertaining to this question-->
<td>
<span editable-select="currentRow.vendorID" e-ng-options="x.vendorId as x.name for x in vendors" e-form="tableform" e-ng-required="true">
{{showVendor(currentRow)}}
</span>
</td>
<!--Add some more columns for each row-->
</tr>
</table>
</form>
Even though I've set e-ng-required="true" on the element, it does nothing. How can I make the selection of an item mandatory using xeditable? I have searched for examples but couldn't find anything helpful.

Unfortunately required doesn't work with form validators as stated in the following links
Required field validation is not working
Validation field form using tag "form" with angular-xeditable
You have to manually check and set the validity of input onbeforesave and set validity of input element.
html
<span editable-select="currentRow.vendorID" e-ng-options="x.vendorId as x.name for x in vendors" e-form="tableform" e-name="vendor" onbeforesave="checkValidity()">
{{showVendor(currentRow)}}
</span>
js
$scope.checkValidity = function(){
if(valid){
$scope.tableform.$setValidity("vendor", true);
}
else{
$scope.tableform.$setValidity("vendor", false);
}
}

Related

Angular dynamic model naming?

i'm learning angular, so please be gentle ;)
I have a table that is populated with some data. And i would like to add filtering (not angular filter, but data filter) on each column.
The idea for me is to add a text box at the top of each column in the header. Then use those textbox values to create the Filters array in my service when it called the api to get the data.
I currently have:
<tr>
<th ng-repeat="column in report.Columns" ng-show="column.IsVisible">
<span class="sort" ng-click="updateSortOrder($index)" ng-class="{'sort-asc': predicate == $index && !reverse, 'sort-desc':predicate == $index && reverse}">{{ column.DisplayName }}</span>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-filter fa-fw"></i></span>
<input class="form-control" type="text" placeholder="Search" ng-model="">
</div>
</th>
</tr>
what i'm stuck on, is how to assign the text boxes to the ng-model, naming them dynamically based on the column that they stand in.
I thought about using ng-model="column.ColumnName" - but wont that bind the text boxes to the report.Columns.ColumnName ? i dont want to edit that, i want to create a new var on the scope for each one.
Something like $scope.Filters.-ColumnName-.
And then i would like to loop through each ColumnName on $scope.Filters and use it's value in my filters array on my service call.
I hope this is making sense. If I'm heading down the wrong route to achieve this, please feel free to point me in the right direction, as i said, i've just started learning Angular.
Thanks in advance
This is not angular related specifically it is more of a javascript issue.
For variable property names you use [] object notation
<input ng-model="filters[column]"
In controller :
$scope.filters ={}
If properties aren't already created in the scope object, ng-model will create them automatically when there is any user input

How to extend angular-xeditable editable row with file upload field

I am trying to extend (my real example is very similar) angular-xeditable - Editable row - example described here:
http://vitalets.github.io/angular-xeditable/#editable-row
or its jsFiddle link here:
http://jsfiddle.net/NfPcH/93/
so that I have one additional column for uploading file for every row/item. It is fine if it can be just input element of type file, but I am opened for other solutions. Usually, my column looks like this:
<td>
<span editable-text="template.description" e-name="description" e-form="rowform" e-required>
{{ template.description || 'empty' }}
</span>
</td>
But, now I want to add my custom column, and I tried input element with or without all metioned attributes here:
<td>
<input id="file"
accept="application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
ng-show="rowform.$visible"
class="btn btn-default"
name="file"
type="file"
e-name="file"
e-form="rowform"
value="{{ user.file || 'empty' }}" />
</td>
In any case, I cannot get - file - value in my angular controller after trying to save row, when this code is executed:
$scope.saveUser = function (data, id) {
//$scope.user not updated yet
angular.extend(data, { id: id });
angular.extend(data, { file: file });
return $http.post('/saveUser', data);
};
My - data - object is here with all other properties like - description - but not with - file - property!
Of course, I extended form onbeforesave event with:
...
form editable-form name="rowform" onbeforesave="saveTemplate($data, user.id, user.file)"
...
Any suggestion?
Thanks,
Vedran
I'm stuck with this.
When I thought that everything is fine because I got file object in my angular model by using solution with creation of custom directive mentioned here:
ng-model for <input type="file"/>
... then new issue started to bother me.
I can't get this file object mapped during binding process to HttpPostedFileBase parameter of MVC controller.
I tried everything, like excluding property and adding separate parameter to my MVC controller, or creating custom MVC model binder but examples I saw used ModelBinderResult class which I couldn't find under MVC 5 classes in any namespace.
This File object is here for sure, but I couldn't make it work. I know that object is not empty or null because if I specify type of controller's input parameter => object, then it is not null.
Please, any help will be more than welcome!
Vedran

ng-table with inline editable columns

Im trying to create an ng-table which needs following
each cell should be editable on single click.
Each cell will have a template ( like few cells are text fields and few cells have options dropdown in it ).
3.This grid should always have one empty/new row for user to enter values , as user clicks on empty/new row ( which is always shown by default ) a new row should get added.
More precise, do I have to add a template like this ?
<td data-title="'Agency #'"><input type="text" ng-model="dealer.AgencyKey" /></td>
also for options do I have to add like this
<td data-title="'Account Type 2'"> <select class="form-control" ng-model="contractsHeader.AccountTypePT" required autofocus id="accountType2Options">
<option ng-repeat="accountType2 in accountTypes2" value="{{accountType2.KeyValue}}">{{accountType2.Description}}</option> </select> </td>
NOTE : I have basic knowledge on ng-table ( creating read only table by binding data from service )
Appreciate your thoughts and inputs
You need to move your ng-repeat from the option to the select

Validating form using Angular when name field has dots and brackets

The form to be validated is master detail i.e. it has two portions. master portion contains two fields while detail portion initially has two rows but they can be increased by pressing a button on DOM. The form looks like the following
The problem is that in detail portion I have to create the inputs using ng-repeat like
<div class="form-group">
<table style="margin-left:10%;">
<tr>
<th>Account id</th>
<th>Amount</th>
</tr>
<tr class="edit-row" ng-repeat ="entry in model.Entries">
<td>
<input type="text" ng-model="model.Entries[$index].AccountId" required name="Entries[{{$index}}].AccountId"/>
</td>
<td>
<input type="text" ng-model="model.Entries[$index].Amount" required name="Entries[{{$index}}].Amount"/>
<span class="field-validation-error text-danger" ng-show="transactionForm['Entries['{{$index}}'].Amount'].$invalid && transactionForm['Entries['{{$index}}'].Amount'].$dirty">
Amount is Required
</span>
</td>
</tr>
</table>
</div>
But the ng-show attribute is not working fine for the detail portion. This is because, I have dots (.) and brackets ([) in the name of input fields. How can I perform validation in such scenario. Someone may argue to change the names of the input but I have to use this convention for input names in the detail portion. In current code, I have used bracket notation in ng-show attribute of Amount field as described in This SO question, but to no avail. you can find complete example at plunker
Can you do something like this?
ng-show="model.Entries[$index].Amount === ''"
Rather than trying to check the form value check the actual model value. This will work assuming you are just checking to make sure there is a value other than the empty string. You will have to make the check more specific to what you are looking for. You can also set the type="number" if you only want to allow the user to enter a numeric value.

angularjs multilingual text field with ngmodel

I'm trying to implement a multilingual text input field with a little dropdown button to the left for selecting the language. For instance, when the dropdown menu shows 'de' the text field should be bound to model.multilingualData['de'].someField and so on.
My first approach was to set ngModel to model.multilingualData[selectedLanguage].someField. But when the user selects a different language without filling in the field correctly, no error is set on the form, because the model now points to a different object.
My next idea was to create an entire element directive without ngModel, but then I wouldn't be able to do other validations like ngMaxLength.
I couldn't find anything helpful on the web either. Any idea on how to implement this properly?
EDIT
Here's a little fiddle that illustrates the problem: http://jsfiddle.net/FZ2kg/
Not only that the form appears valid when you switch languages, the previous field value is also deleted, because the model is set to null when the field becomes invalid.
would be nice if you use this awesome external directive for multilanguage!
https://angular-translate.github.io/
I hope it helps
If you need to have form validation for all language variations and you're loading all languages at once in your model, can't you just create an input per language in the form and hide all but the currently selected language?
Here's a fiddle: http://jsfiddle.net/jvl70/w3rstmwd/5/
<form name="myForm">
<div ng-repeat="(lang, value) in model.multilingualData"
ng-show="lang==stuff.currentLanguage">
<ng-form name="innerForm">
<div ng-class="{ 'has-error': innerForm.anything.$invalid }">
<input type="text" name="anything" ng-model="value.someField" ng-maxlength="6"/>
</div>
</ng-form>
</div>
</form>
(At first I tried to use dynamic names for each input but found that the individual field $invalid wasn't available for dynamically named inputs. See this post to get around it: Dynamic validation and name in a form with AngularJS.
As an alternative to ng-form, you could use dynamic names for each input and try one of the custom directives on the link.)
I guess if there were many possible languages, this approach might get slower but it's ok for a few languages.

Resources