Watcher on an object is better or on its attributes? - angularjs

Am creating a dynamic filter on tables just like phpMyAdmin.
Here I have created an array and used ng-repeat to have filter on multiple columns.
Initially array is empty and am pushing an object on clicking on plus button.
Now Based on user's column preference, I want to show appropriate input field like if user selects 'created_by', input field should be converted to datetime type. For this I am using a different directive where input field would be converted according to column and filter.
Thats why I want to watch column and filter of each row, which is attribute of object of that array.
var filterArr = [];
var filterObj = {
selectField: self.dictionary,
filterField: [],
column:{},
filter:{},
inputField: null,
}
//On Plus button click
filterArr.push(angular.copy(filterObj));
So each row has object structure of filterObj and out of which I want to watch column and filter.
Watcher on object of particular element is appropriate or I should use two seperate watcher on column and filter attribute?

Related

How to filter the JSON data using AngularJS?

I have three dropdown boxes. I need to filter the data and need to be displayed in the table based on my checkbox selection(either with single checkbox or two checkboxes or three checkboxes).
I have done the following, but if we observe it clearly, I am not able to filter the data properly using AngularJS.
Like:
a. It should work for individual checkbox selection: means if I select any single checkbox either from Name or Description or Field4, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
b. It should work for multiple(two) checkbox selection: means if I select any multiple checkboxes like either one from Name and one from Description or one from Description and one from Field4 or one from Field4 and one from Name, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
c. It should work for multiple(three) checkbox selection: means if I select the three checkboxes like one from Name and one from Description and one from Field4, then respective matched filtered data should be displayed in the table, otherwise it shouldn't be displayed any data(i.e if it doesn't match our checkbox selection means it won't display any data)
It is working fine for the first time checkbox selection only, means: after loading the above code/app, if we check either any one of the above selections(like whether single checkbox selection or two checkbox selection or three checkbox selection) then it's working fine, later it is not working(means if we uncheck the above any criteria and then if we select any checkbox again then it's not working, for that again we need to refresh the app/code then only it's working).
Example: if I select one from Name, then respective matched data will be displayed. Then again if I uncheck the same and check the some other checkbox like from Description then it's not working. Similarly for all the above criteria. You can observe it clearly.
Please let me know that what I have done wrong here and let me know how to filter it properly. Created Fiddle. Thanks in advance !
The problem is the convoluted filtering logic. Anytime you find yourself nesting lots of if statements, think about reorganizing the branching logic. By breaking it into smaller components, you can make it easier to manage, and if you can avoid using if altogether, then you only have to test one path, instead of several.
Every time a user checks a box, we need to make sure that we only display items that match however many boxes are checked. So we need to know 1) how many boxes are checked, n, and 2) how many items can be found with n matching fields.
We can take advantage of the fact that Boolean variables can be cast to integers (0 = false, true = 1) and use that to count the number of checked boxes, as well as the number of matches found.
We can also put the field names into an array, so that we don't have a lot of repetition in our functions.
Fiddle example here.
var fields = ["name", "description", "field4"];
//for each field, count how many fields the item matches
function getMatches(item, matchesNeeded) {
var foundMatches = 0;
fields.forEach(field => {
foundMatches += item[field] === $scope.pagedItems[field]
});
//make sure found at least one match and found desired minimum
return foundMatches && foundMatches >= matchesNeeded;
}
//count how many boxes are checked
//this will tell us how many different fields we are matching on
function numChecked() {
var count = 0;
fields.forEach(field => {
//this will auto convert falsy to 0.
//truthy values will be 1
count += Boolean($scope.pagedItems[field]);
});
return count;
}
$scope.filterItems = function(item) {
return getMatches(item, numChecked());
};
As #Larry pointed it was more based on logic. I have modified Apress book 'Pro AngularJS' Source Code from GIT for this.
Basic logic will in filter function as below -
$scope.categoryFilterFn = function (product) {
var canHave = false;//dont load by default
var atLeastOneTrue = false;//Check if previously checked any condition
angular.forEach(filterValues, function(selectedValue, key) {
var selectVals = Object.values(selectedValue);
if(selectVals.indexOf(product[key]) !== -1) {//if values exits in product.
canHave = !atLeastOneTrue ? true : canHave;
}else{
canHave = false;
}
atLeastOneTrue = true;
});
return canHave;
}
For working Fiddle.

how to add a empty string as default in the drop down where dropdown is a directive

In my AngularJS project, I am having a dropdown field as a directive and the values are coming from the backend.The user can also leave the field without selecting the dropdown(optional field) but the problem is, there is no empty field from the backend. So I need to add an empty field into the dropdown as default.
Since there is no option in the directive got struck in this issue.Googled a lot but didnt get any solutions yet.Kindly provide some suggestion.
Note:Client machine,cant post the code.
If there is no value set for the ng-model that the dropdown is bound to, Angular will provide a blank option by default that can be left in place (ignored) by the user and will result in your final value being whatever you set that ng-model to in the first place. If you need an actual empty string for the value, initialize it to that.
If you need to enable the user to select an empty value once they have already selected a value, you will need to add an empty value to the object that the dropdown is bound to. Add the empty value like this:
myPromise.then(function(data){
$scope.ddInfo = data;
$scope.ddInfo.unshift({id:'0000',text:'Not Applicable'});
});

Setting DefaultValue of a directive field type

Please look at the following jsbin
You will notice that there are two fields. One is a normal input while the other is a new field type that references exampleDirective. Please note...in my real application, these fields are pulling pulled from JSON and are not manually added to the fields array.
I set the DefaultValue on each record within the fields array. Again, these default values are being pulled from JSON.
The RegularInput field is properly displaying the default within its input field.
The DirectiveInput is not. Please look at the model and you will see that the default value was applied to the field itself and not the input field (or fields if I had multiple) within the directive.
Is there a way to make DefaultValue work in this type of situation? And if not...what would the best way to get the value that I am pulling from JSON to be placed on the directive fields?
just update your incoming json to include the "defaultValue" in the form object that gets passed to your directive. Try this: http://jsbin.com/coyuriyazu/1/edit?html,js,output
I ended up fixing my issue by passing data INTO the directive.
formlyConfig.setType(
{
name: 'dirTest1',
template: '<div directive-test checked="to.IsChecked" amount="to.CoverageAmount"</div>'
});
With this approach, I can specify IsChecked and CoverageAmount in my directive and pass the values that I need when setting up the various inputs within the directive. So, when I push this field type to my fields array, I can easily set my values like so:
var newRow = {
key: TestKey,
type: dirTest1,
templateOptions: {
CoverageAmount: 12345,
IsChecked: true
}
};
vm.fields[i].fieldGroup.push(newRow);

How to access hidden column in angular js

I have a column named id in my datagrid. I have set visible:false for the field since I don't want to display the field in the grid.
But then how can I get the value in id? any hope?
I am adding column as
columns.push({'sTitle':'id','visible': 'false'},{'sTitle':'name','visible': 'false'});
And I am retrieving the value in selected row as
this.$view.on("click",function(event){
selectedRow = event.target.parentElement;
var name = selectedRow.cells[0].innerHTML;
}
Here in click event I can't get the value of id as html is not generated for the field with visible:false. So I am searching for a method to access my id field.
You should use display:none property
-Edit:
In order to specify a custom css to your angular datagrid you should also specify the columns. Something like:
$("#gridContainer").dxDataGrid({
// ...
columns: ['CompanyName', 'ContactName', 'City', 'Country']
});
Here's the page I referenced to
Edit2:
Since you're trying to retrieve the value of the field I would recommend you to take a look to this answer

AngularJs Select ng-model not working with foreign key value

Let's say I have a service that provides a list of objects that I want to load as options in a <select> element.
The service method is myReferenceList.getCachedList().
It returns an array of objects of the following structure:
[
{
ReferenceId: "guid-1234",
ReferenceName: "some string",
SomeRandomRefField: 5
},
// etc...
]
In my controller I have a $scope.dataRow variable defined like so:
$scope.dataRow = {
ReferenceIdFk: "guid-2345",
// etc...
}
I want to load the select option list with data from myReferenceList.getCachedList(), with the displayed text coming from ReferenceName and the non-visible value coming from ReferenceId.
I want to hook this select item up to $scope.dataRow.ReferenceIdFk something like this:
ng-model="dataRow.ReferenceIdFk"
When all is said and done, and the data is loaded into $scope.dataRow.ReferenceIdFk, the select element should hold the selected object's ReferenceId value. When a user selects a different item in the select list, the value in $scope.dataRow.ReferenceIdFk should automagically get changed to the correct value.
How can I get this to work?
Loading the values into the select list is easy. Getting the automagic binding to the underlying data value in $scope.dataRow.ReferenceIdFk just doesn't seem to work.
Obviously, I can hand-jam in some procedural code to make this binding work, but I'm trying to understand how to declaratively make it work using angular features. Is it possible?
ng-options provides a micro-syntax to declare how to map objects in an array to display value and the selected result:
Angular's documentation provides the full syntax, but for your case the following should work:
<select ng-model="dataRow.ReferenceIdFk"
ng-options="i.ReferenceId as i.ReferenceName for i in myReferenceList.getCachedList()">
</select>
In a nutshell, the microsyntax is:
"<valueExp> as <displayExp> for <itemAlias> in <arrayExp>"
where:
arrayExp: is the expression that returns an array of values
itemAlias: is the alias for each item in an array; can be whatever you want
displayExp: a string expression that is used for each label; uses the itemAlias
valueEx: an expression whose value is assigned to ngModel-bound variable; uses itemAlias, and can return either a property of the item (itemAlias.prop as) or the item itself (itemAlias as)

Resources