How to filter the JSON data using AngularJS? - 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.

Related

How to get know if a checkbox has been selected in a dynamic UI in codenameone

I have a container with dynamic UI components including checkboxes. How can I know the selection status of a particular component?
Using isSelected() doesn't work as it is always false because it seems to pick the last checkbox in the list which returns false since it is unselected.
bool_isMemberSelected = cb_member.isSelected(); //returns false.
I am able to get the checkbox at a particular index in the parent component but once I have it there is no isSelected option on it. So I use a dirty way by tokenizing the string representing the component to get to the selected status. There must be a better way.
System.out.println("Checkbox Data "+cnt_tablerow[Integer.parseInt(lbl_memberno.getName())].getComponentAt(0)); //Checkbox Data: CheckBox[x=0 y=0 width=63 height=152 name=524, text = , gap = 2, selected = true]
String str_chkbox = StringUtil.tokenize(StringUtil.tokenize(cnt_tablerow[Integer.parseInt(lbl_memberno.getName())].getComponentAt(0), ']').get(0), '[').get(1);
String str_status = StringUtil.tokenize(StringUtil.tokenize(str_chkbox, ',').get(3), '=').get(1).trim();
if(str_status == "true"){}
You could generate and set a name for each component when generating your dynamic UI. With a name you can use the ComponentSelector API or a simple for to get the Checkbox you want and then use the isSelected method.
If you want to keep your actual selection logic with the index, you can simply check the instance of your component and cast it to a CheckBox, that would also do the trick.

Select all rows in django tables2 with pagination

How can I select all records of a django_tables2 table using a CheckBoxColumn when the table is split into several pages?
I have used this select all rows in django_tables2 code to select all records from one page and this How to get information from Django_tables2 row? to do something with them.
But how can I select all records across pagination limits?
And also keep the status of a checkbox when I go back and forth on the pages?
I would suggest to add a 'check all' checkbox to your template. Apart from visually checking all rows of the current page (using JavaScript), it being checked should signal the logic in your view that the user intends to check all rows.
Keeping the status of those checkboxes is another story. It can lead to bookkeeping in some very big lists. You could keep them in request.session if they need to be kept for a user in a particular browser session, if they need to be persisted to the database, you can create a model to keep track of the selection of a certain record for a certain user.
Ok, now I came up with this JavaScript/jQuery solution. It addresses two aspects. First, to store and display the selected checkboxes when the sort order of the table is changed, the table is filtered or when you naviagte to another page and return the table again. Secondly to check and store all checkboxes on a table page when the "Select All" button on in the table head is clicked. Here I'm stuck with selecting all rows in a table, not only the ones that are displayed on one table page (with pagination on). The selected checkboxes are stored in the session storage of the browser. There is certainly room for improvement in the functions, I don't like the iteration over all rows of the table a lot, but I couldn't find a better solution yet.
Still I think it would be nice to have this kind of funtionality available in django-tables2. Maybe in some coming version?
The checkbox column is called "selvars" in my tables.py
class dataset_varsTable(tables.Table):
selvars=tables.CheckBoxColumn(accessor='pk',attrs = { "th__input": {"onclick": "toggle(this)"}}, orderable=False)
... (other table columns)
It's the integer primary key of my model
class vars(models.Model):
idvar=models.IntegerField('Var.ID', primary_key=True)
...
And the JavaScript and jQuery functions in the HTML template with the table
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
var storage_name="checkedvars"; // name of session storage
// function to store/remove checked varids in session storage
function update_checkedvars(varid, check_status){
var current_checked=[];
if (sessionStorage.getItem(storage_name)){
current_checked=sessionStorage.getItem(storage_name).split(",");
}
if (isNaN(parseInt(varid))==false && check_status==true){
current_checked.push(varid);
// store checked varid in session storage without duplicates
sessionStorage.setItem(storage_name, Array.from(new Set(current_checked)));
} else if (isNaN(parseInt(varid))==false && check_status==false){
// remove unchecked varid from session storage
sessionStorage.setItem(storage_name, current_checked.filter(e => e !== varid));
}
}
// toggle button
function toggle(source) {
checkboxes = document.getElementsByName('selvars');
for(var i in checkboxes){
checkboxes[i].checked = source.checked;
update_checkedvars(checkboxes[i].value, checkboxes[i].checked);
}
}
$(document).ready( function() {
// display checkboxes according to selected varids in session storage
var current_checked=[];
if (sessionStorage.getItem(storage_name)){
current_checked=sessionStorage.getItem(storage_name).split(",");
checkboxes = document.getElementsByName('selvars');
for(var i in checkboxes){
if(current_checked.includes(checkboxes[i].value)){
checkboxes[i].checked=true;
}
}
}
// save/remove checked/unchecked varid in session storage
$(".selvars").click( function(event) {
var varid=event.target.value
var check_status=event.target.checked
update_checkedvars(varid, check_status);
});
});
</script>

Angular select multiple not setting selected items

Scenario is quite simple. I have edit view which comprises of select element with multiple selection. Select element looks as follows
<select class="selectpicker" multiple
ng-model="UserBeingEdited.UberTypes"
ng-options="uberType.Id as uberType.Name for uberType in UberTypes"></select>
</div>
If I press edit for specific user then showEditModal function is called and edit pop up shows up. User has his own UberTypes objects selected so I pick theirs Ids and assign to UserBeingEdited.UberTypes.
$scope.UserBeingEdited = { UberTypes: []};
$scope.showEditModal = function (user) {
for (var i = 0; i < user.UberTypes.length; i++) {
$scope.UserBeingEdited.UberTypes.push(user.UberTypes[i].Id);
}
$("#editUserModal").modal("show");
};
Unfortunately they are not selected, no matter what. Suprisingly, if I set values to property UserBeingEdited by the time of declaring then it works, items are selected.
$scope.UserBeingEdited = { UberTypes: [1,2]}; //this works
It seems like angular does not refresh selected items within UI.
EDIT:
I have two items: Uber1 and Uber2. Both items are selected but view does not reflect it. If I open drop down menu and select Uber2 it shows Uber1 selected, apparently Uber2 was selected and another click was treated as unselection. The same happens when I click Uber1 first, Uber2 shows as selected.
As above picture depicts, Uber2 is highlighted since I have just clicked it but it shows Uber1 as selected. Both were selected in User's UberTypes but view just simply does not mark them as selected.
http://jsfiddle.net/upusq8ah/7/
I use bootstrap-select.js for select element and presumably this library causes such an error since without including it, it works fine.
Solution
After a while of struggle, I accidentally ran into below workaround. You need to call refresh on selectPicker and this has to be delayed otherwise it will bring no effect.
setTimeout(function () {
$('.selectpicker').selectpicker('refresh');
}, 100);
$("#editUserModal").modal("show");

Angular JS for Mutually Exclusive Selections

I have two selection tag, each with the same options. The behavior that I am aiming for is to have whatever the selected option of one not be selectable on the options of the other one. Given that I am using an array of objects for the source of the options: [{name:'one'}, {name:'two'}, {name:'three'}]
1. Default.
selection 1
- one
- two
- three
selection 2
- one
- two
- three
2. Selection 1 gets selected.
selection 1
- one
- two
-(three)
selection 2
- one
- two
3. Selection 2 gets selected.
selection 1
- two
-(three)
selection 2
-(one)
- two
FIDDLE
You can do this by using a custom filter function to filter out already selected options.
<select ng-model="picks.select1">
<option ng-repeat="option in options | filter:optionFilter(picks.select1)" ng-value="option.name">
This function takes the model of the select as the parameter to be able to show it as still selectable.
$scope.optionFilter = function(selectedOptionModel){
return function(option){
//actual filtering function starts here, angular passes all items in the array
// to this function and filters out the ones you returned false
if(option.name === selectedOptionModel) return true; // if it's already the selected option it should still be an option in the dropdown
else{
for(var key in $scope.picks){
//otherwise we check to see if they are picked in
//another select dropdown and immediately return false because
// that option is elected should be filtered out.
if(option.name===$scope.picks[key]) return false;
}
//if we successfully got out of the loop it means it's not selected so return true
return true;
}
}
}

SWT/JFace: disabled checkbox in a table column

It is quiet easy to create a Table with a checkbox column, e.g., using the SWT.CHECK flag. But how to make checkboxes in certain table rows not editable while those in other rows remain editable?
I don't know a simple way of doing that.
But I see two possible solutions: There is a JFace Snippet doing a rather extreme hack to emulate natively looking checkboxes in tables with images here.
And then you could put own checkboxes into a plain Table, like this. That way you can control the state of every checkbox on your own.
I'd go with the 2nd solution.
try this:
table.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if( event.detail == SWT.CHECK ) {
event.detail = SWT.NONE;
event.type = SWT.None;
event.doIt = false;
((TableItem)event.item).setChecked(false);
}
}
});
I had faced a similar problem and i was able to solve it in the table using SWT.check.
In the widgetSelected Event of the table you can try the following code:
TableItem[] item = table.getItems();
for(int j=0; j<item.length;j++)
{
TableItem tblItem = item[j];
if (tblItem.getChecked())
{
table.setSelection(j);
if(codition for the checkbox to be non-Editable written here)
{
item[table.getSelectionIndex()].setChecked(false);
}
}
}
In the above code after the table has been filled and when the user tries to check any item in the table the above code should be called. When the checkbox is clicked if the condition meets for the checkBox to be non-editable the checkbox is not selected otherwise it is selected.In this way in a table certain rows can be editable while others will be non-editable according to the required conditon.

Resources