Bind value to dynamic dropdown, from localStorage - AngularJs - angularjs

I have this project, with VB for backend and AngularJS for the frontend. 1 of the issues i am tasked to fix is a dropdown that doesn't keep it's values after i change page and then go back to said page.
In more detail:
i have a list coming from the backend - VB, with all the data i need.
i have a view that has a 4 dropdowns to apply filters to the page .
i apply a filter or a combination of filters to see only the desired applications.
i click on an application and therefore i am redirected to the page of said application.
i do all i have to do there and so i click the browser back button to go to the list of all the applications.
the filters are lost and i need to still have them active.
List item
<select id="issue1"
ng-model="RecordStatus"
ng-change="RecordStatusSelection(RecordStatus.ID_RecordStatus)"
ng-options="RecordStatus.RecordStatusDesc for RecordStatus in MyDiversionESDList
| unique:'RecordStatusDesc'
| orderBy:'+RecordStatusDesc'">
<option id="issue1" value="">-- Όλες --</option>
</select>
what i have done so far:
i bind the value of each dropdown (each filter to be exact) in localStorage
the localStorage values change along with the dropdowns
What i need is to have the values of localStorage apply to said dropdown, so that each filter can still be applied when i go back to this page.
More code to help you, help me:
1. js code, inside the controller - where i get the filter and save it in localStorage
$scope.RecordStatusSelection = function (recordStatus) {
$scope.filterScope.ID_RecordStatus = recordStatus;
localStorage.setItem('sessionIdRecordStatus', recordStatus);
return $scope.applyMasterFilter()
}
2. js code, where i apply the filters
$scope.applyMasterFilter = function (temp) {
$scope.temp = localStorage.getItem('sessionIdRecordStatus');
$scope.filteredDiversionESD = $filter("filter")($scope.MyDiversionESDList, $scope.filterScope)
$scope.filteredDiversionESD = $filter("filter")($scope.filteredDiversionESD,
$scope.searchKeywordsText)
return $scope.onFilterChange()
}

In case anyone else has the same issue:
I used sessionsStorage. Session instead of Local because i want it to be at the default values each time the website starts.
$scope.RecordStatusSelection = function (recordStatus) {
sessionStorage.setItem('sessionIdRecordStatus', recordStatus);
$scope.filterScope.ID_RecordStatus = sessionStorage.sessionIdRecordStatus;
return $scope.applyMasterFilter()
}
$scope.applyMasterFilter = function (temp) {
$scope.filterScope.ID_RecordStatus = sessionStorage.sessionIdRecordStatus;
$scope.filteredDiversionESD = $filter("filter")($scope.MyDiversionESDList, $scope.filterScope)
$scope.filteredDiversionESD = $filter("filter")($scope.filteredDiversionESD,
$scope.searchKeywordsText)
return $scope.onFilterChange()
}
It works well, but not too well. The value/option is applied but not shown, i get an empty box instead.
I will edit this answer if i find the full solution.

Related

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");

In ReactJS, how to set one select dropdown based on another, both ajax?

Specific to initial page load:
In my ReactJS page I have two dropdowns/select elements. The first is loaded via Ajax, and the second is loaded via Ajax. The values in the second select depend on which value is selected in the first select.
This is straightforward to do in response to the user changing the first select because an onchange event is fired and I can then update the second dropdown.
But I cannot work out how to do the initial page load. During initial page load, a value will be set in the first dropdown, but I can't work out how to get that value so I can load the values for the second dropdown.
Just fire the request in componentDidMount(). This will give you an opportunity to update the second select.
Use state to store the first dropdown value.
render() {
let secondDrop = null;
if (this.state.firstDropValue) {
secondDrop = (
<div id='secondDrop'>...
)
else secondDrop = null;
return (
<div id='firstDrop'>...</div>
{secondDrop}
)
}

How do I keep results filtered with new results added dynamically?

I'm using an infinite scroller package which loads results dynamically. I have a set of filters which display the results I want depending on what filter is selected.
The results will not be returned to the front end in any sort of filtered order. What I want to achieve is get the unfiltered results being returned into filtered state that I may already have selected.
For example one filter is a star rating and lets say that I have 3 and 4 star selected in my filter. How would I get newly loaded results to be returned within that filter.
I suppose I could send the filters back to the backend to specifically request what I'm looking for but I'm looking for an angular solution.
Here's the ng-repeat that iterates over each hotel I want any newly loaded results to be subjected to any filters already selected:
<div ng-repeat="hotel in (filteredHotels = (hotelResults | hotelRatingsFilter:ratings)) | startFrom:(currentPage - 1)*10 | limitTo:10 " class="hotel-results-container">
<ul>
<li>{{hotel.starRating}}</li>
</ul>
</div>
This is the code that communicates with the backend, as far as I can tell (I didn't write it)
.constant('HOTEL_SEARCH_CONSTANTS',{
httpSettings:
{
url:'/hotel/hotelsearch/search',
method:'POST'
}
})
.service('hotelSearchService', ['CachedObservable','$http','HOTEL_SEARCH_CONSTANTS','HOTEL_CONSTANTS','baseSearchSettings','loadingScreen',
function(CachedObservable,$http,HOTEL_SEARCH_CONSTANTS,HOTEL_CONSTANTS,baseSearchSettings,loadingScreen){
CachedObservable.call(this)
var _this = this,
p
this.search = function(searchParameters){
var config = HOTEL_SEARCH_CONSTANTS.httpSettings
var currentSearch = angular.extend(searchParameters,baseSearchSettings)
config.data = {
basicSearch: baseSearchSettings,
hotelSearch: searchParameters
}
_this.update(p=$http(config), angular.extend(angular.copy(searchParameters),baseSearchSettings) )
//Alert subscribers with both the promise and the search parameters
//used
loadingScreen.newSearch.update(p,HOTEL_CONSTANTS.loadingTemplates.loadingMessageTemplate)
//Trigger a loading screen and specify the template to use
}
}])
Thank you
I found this article that says that angular will iterate over the array if there is any change to the data. Looks like its safe to keep adding to the data array and any filters already being used will be applied by angular to the updated data array.
Step 6 says:
"A watch is added on the array, which triggers step 1 again if the array undergoes any change"
ng-repeat in angular

Initializing ngModel with data - AngularJS Bootstrap bs-select

I am maintaining a site that allows users to create a profile of sorts that will allow them to broadcast activities to a feed. I implement ng-grid to keep track of all the profiles that are created, and have created two buttons that allow users to create/edit these profiles. My only problem right now is, when users select a row on the grid and attempt to edit that specific row, the drop-down menu is not auto-populated with the data from ngModel.
This is the part of the form I am having trouble with:
<select ng-model="source.canSendTo" ng-options="value.name for value in sourceCanSendTo" data-style="btn" bs-select></select>
And within the controller, I have sourceCanSendTo defined as:
$scope.sourceCanSendTo = [ {"id":"abc", "name": "ABC"}, {"id":bcd", "name": "BCD"} ... ];
On row selection, I simply set source = the selected item, and console.logs show that all the data is there. The other parts of the form are being populated properly (mainly s), and console.log($scope.source.canSendTo) shows that the original data is there, it's just that select is defaulted to being blank...how would I go about trying to pre-select certain elements on the drop-down select I currently have?
For example, if the profile has 'abc', 'bcd' selected, how can I make it so that when I edit that profile, the drop down box shows 'abc,bcd' instead of just "Nothing Selected"?
Edit: I previously responded to a comment inquiring about bs-select, saying that it simply controlled some CSS elements of the drop down box - seems like this is completely incorrect after a quick google search when everything else led to dead ends. Does anyone have any idea how to properly initialize the model with data so that when I preload my form, the 'can send to' drop down select actually has the selected options selected, as opposed to saying "Nothing Selected"? Thanks in advance for all help!
As you are binding source.canSendTo to the name (value.name) of sourceCanSendTo then you just need to initially have an structure binding the names which had been saved, something like this:
source.canSendTo = ['abc', 'bcd']; //And all the selected values
So you need to construct your source.canSendTo property to this structure.
PS: If you show how you bring your data from the server, I can help you to construct the source.canSendTo property.
$scope.canSendTo must be initialized with a reference to the selected option.
var initialSelection = 0;
$scope.source = { canSendTo : [ {"id":"abc", "name": "ABC"}, {"id":bcd", "name": "BCD"} ... ] };
$scope.canSendTo = $scope.source.canSendTo[initialSelection];
Finally found out what was wrong with my code - seems like the data being stored in the model wasn't the same as what was in ngOptions, played around a bit with ngOptions and managed to get something that works. Working snippet of code:
<select ng-model="sendTo.name" ng-option="value.name as value.name for value in sourceCanSendTo" data-style="btn" multiple bs-select>
(Realized that the variable being used for ngModel was a fairly ambiguous in terms of naming convention, changed it)

web2py - Dropdown menu

I'm trying to have a dropdown menu for the user to select the database table. I have defined few tables in db.py and I want the user the to select a particular table from a dropdown menu and insert entries. Right now I use SQLFORM:
def index():
form=SQLFORM(db.selectedtable) #want to change the table name#
if form.process().accepted:
response.flash = 'form accepted'
elif form.errors:
response.flash = 'form has errors'
else:
response.flash = 'please fill out the form'
return dict(form=form)
I need the user to select 'selectedtable' value from a dropdown list that shows all the available tables in the DB. I do not necessarily want to retrieve the table values from DB. I am OK with defining a list with the available tables and the dropdown menu can pull the table names from that list.
So far I only found IS_IN_DB to automatically create a dropdown and PluginDropdown() but that does not serve my purpose. If soemebody can direct me to the proper way of handling this task I'd be really thankful.
Regards.
Update:
After Anthony's suggession I tried the following with , as I'm not that familiar with JS.
{{extend 'layout.html'}}
{{select='NONE'}}
<form>
<select>
{{for item in TOOLS:}}
<option value="{{select=item}}">{{=item}}</option>{{pass}}
</select>
<input type="submit" value="Go!"/>
</form>
<h2>Input form</h2>
{{=form}}
<h2>{{=select}}</h2>
As you might see this doesn't work properly. What I tried to do is to get the user chose value to 'select' variable. But it doesn't work. It always gets the last element in ITEMS (this list is defined in db.py). My next option would be to be call another controller function, passing the user selected value as an argument. Then it can prepare the form with the passed value and send to a view to display
<h2>Input form</h2>
{{=form}}
But I'm not sure how I can assign the user chosen value to an argument and then call another controller function with that arugument value.
If you have any suggestion how I can modify this to get the user chosen value thats very much appreciated. Thank you.
You could create a <select> element listing all the tables, and then load the form associated with the selected table as a web2py component via Ajax. In the view of the main page (e.g., /views/default/index.html):
<script>
jQuery(function() {
jQuery('#table').change(function() {
web2py_component("{{=URL('default', 'form.load')}}" + "/" +
jQuery(this).val(), target='form')
})
})
</script>
{{=SELECT('Select a table', *db.tables, _id='table')}}
<div id="form"></div>
And in a controller (e.g., default.py):
def form():
if request.args(0) in db.tables:
response.generic_patterns = ['load']
return dict(form=SQLFORM(db[request.args(0)]).process())
else:
raise HTTP(404)
Note, db.tables is a list of all the tables defined on the db connection object -- it is used in the SELECT() helper in the view to generate a <select> list of all the tables. The script in the view registers a jQuery event handler that fires whenever a different table is selected from the dropdown. The handler calls the web2py_component() function (which is in /static/js/web2py.js), which loads the form component via Ajax into the div with id="form". It appends the value of the selected table to the URL.
In the controller, the form() function checks for the db table name in request.args(0). It then sets response.generic_patterns so the "generic.load" view will be allowed (by default, generic views are only enabled for local requests). Alternatively, you could define your own "form.load" view, or even use a different extension (e.g., "form.html").
Because the form is loaded as a web2py Ajax component, the form submission will be trapped and submitted via Ajax as well, so it will not result in a full page reload.

Resources