In my DB I have tables System(id, name) and AssignedSystems(id, system_id). I display every system from the second table like this (I can't copy my code, so I have to rewrite it, I will use pseudo PHP+HTML):
while () { // if there are many systems assigned, I will display them all in separate selects
<select><option value="'.$systemAssigned.'">'.$systemAssigned.'</option>
while () {
// display every system from table System except for the one listed above
}
</select><img src="drop.gif" onclick="deleteSystem()">
}
<img src="plus.gif" onclick="addSelect()">
JavaScript (to be specfic - AJAX) functions deleteSystem() and addSelect() do (in order) delete a row from AssignedSystems and add new select, so a new system can be selected from table System.
Now when I want to add few, let's say 3 new selects, I have to click plus.gif three times - and the page reloads three times with a new select added. Now I would like to have my previous selections remembered. So when I click plus.gif one time and select a system, then click plus.gif again and again I would like to have my first selection remembered.
I thought about using sessions variables like:
<select>
$_SESSION["selectValue"] = SELECTED_VALUE_WHEN_PLUS.GIF_IS_CLICKED;
<option>...</option>
</select>
or passing the currently selected value to javascript, but I don't really know how, because I don't have any specific number of blank selects, so I don't know how to retrieve it back.
Related
I have a table with variable number of records (could be up to hundreds) where its body is build with one ng-repeat.
Within each record, there are two input fields of type select where their contents is also built using ng-repear and the number of options for each is about 100.
This is working right now, except that it takes a lot of time for the page to be built (several seconds; I guess due to the large number of html records that AngularJS is adding to the DOM).
Here is an example of one of the selects:
<select class="form-control" ng-model="One_Source.Measuring_Method_Code">
<option ng-selected="{{One_Method.Value == One_Source.Measuring_Method_Code}}"
ng-repeat="One_Method in All_Collections.Parameters_Test_Methods"
value="{{One_Method.Value}}"
title="{{One_Method.Test_Method_Name}} | {{One_Method.Method_Internal_Name}}">
{{One_Method.Value}}
</option>
</select>
Two questions:
Is there a simple way to speed up the page building process?
As shown in the example, each option in the list has a title clause displaying a detailed description of the option's meaning. How can I add a title to the select showing the description of the current value?
For the first question I was thinking about building the list of options for each select element only upon clicking on it, but I'm not sure if that would be the best way to do it.
Try using one time bindings so that Angular doesn't watch the value by prefixing it with ::. It can also be more efficient to use track by in your ng-repeat if each row has a unique value, like an ID.
<option
ng-selected="{{One_Method.Value == One_Source.Measuring_Method_Code}}"
ng-repeat="One_Method in All_Collections.Parameters_Test_Methods track by One_Method.id"
value="{{::One_Method.Value}}"
title="{{::One_Method.Test_Method_Name}} | {{::One_Method.Method_Internal_Name}}"
>
{{::One_Method.Value}}
</option>
If you still can't gain the performance you're expecting from #doublesharps's answer, you will have to implement one of the following:
You could build a custom list that has a 'load more' button which would destroy say the first '50' options and load the next 50.
A better option would be to turn this into an autocomplete, where the user searches for values.
Virtual repeat - Something angular material does really well, it constantly draw's and re-draws new elements based on the scroll position inside the element.
Other resources:
http://blog.scalyr.com/2013/10/angularjs-1200ms-to-35ms/
https://github.com/stackfull/angular-virtual-scroll
http://klajd.github.io/angular-virtual-repeat/#/Home
I found a PARTIAL SOLUTION that still needs to be polished but is quite promising.
During creation of the page, I do not make use of ng-repeat for the options but instead deploy a single option with the value received for the field from the database (if any, otherwise the select element is left blank).
When the user clicks on the select element a $scope function is invoked that checks the number of options within the select element and, if less or equal to 1, the inner HTML of this select element is re-generated and deployed.
Though clicking on all these select in the page will take (accumulative) a comparable time as when built upon load, this time is distributed over several events (the user clicking on all the select elements) and hence it is not perceived by the user.
Now, by polishing I mean that there is a strange behavior. In order to see the generated list of options, I need to click on the select twice. Will keep investigating this and post the solution (hoping I find one).
Am working on a data table, that is based on this api http://www.datatables.net/examples/api/multi_filter_select.html
I have done some modification, but the main idea is the same.
At the moment i want to make it possible for the user to click on a row which makes it selected and changes color. If the user clicks on another row the old one gets unselected and color get changed back. But as you can see in the API example you can minimize the visual result by searching or change the amount of entries that should be visible.
The code for selecting and deselecting is below:
unction select(t) {
imei=t;
//console.log("IMEI");
//console.log(imei);
if(selected!=""){
console.log("Selected"+selected);
document.getElementById(selected).style.backgroundColor=savedColor;
}
selected= t;
savedColor=document.getElementById(selected).style.backgroundColor;
document.getElementById(selected).style.backgroundColor='#F7F000';
}
The problem is that when a user selects a row and then make a search which make the selected item invisible and then selects a new row. Then when i want to retrieve the old row by document.getElementById(selected) so i can change the color to the old one, it return null.
It's only when the element is not visible. If the previous is visible when selecting a new one, it works-
I have requirements to disable save and cancel buttons in my page on page load. I should enable save and cancel buttons if user changes something in the page. To achieve this, I am using
http://plugins.jquery.com/are-you-sure/
This plugin is working fine but there is need for customization in many scenarios, one like below
I have a page like Item groups which consists of three panels.
LeftPanel : List of item groups in the system
CenterPanel : List of items assigned to a selected item group
RightPanel : List of items to assign to an item group
Now Assume I have a datatable
<p:dataTable var="itms" value="#{myBean.listOfItems}" rows="10"
paginator="true"
paginatorTemplate="{CurrentPageReport}
{FirstPageLink}
{PreviousPageLink}
{PageLinks}
{NextPageLink}
{LastPageLink}
{RowsPerPageDropdown}"
rowsPerPageTemplate="10,50,100">
</p:dataTable>
To assign items to the item group I would select items in the right panel and click on assign button which would add to the listOfItems to show in the center panel
listOfItems.addAll(selectedItems);
I am calling rescan method defined in the plugin on assign button oncomplete to detect the changes and track new records added because I want to consider addition or removal of fields also a change.
Now on page load if an item group is selected and it has 13 items assigned then I could see the first page with 10 records. If any items added then they will be added in the list at back end list. Since I'm in first page and page is having complete rows plugin is unable to find any changes in form.
How to find a change in this scenario.
Since you say you want to consider any addition or removal of fields also a change to make sure that your users save the changes, one way to do it could be like this:
You can have a hidden input:
<h:inputHidden id="hiddenInput" />
And in your assign button oncomplete you mentioned you can add:
oncomplete="$('#hiddenInput').val('dirty').change();"
This would add the 'dirty' string (for example) to the hidden input and call change() to tell the plugin that something changed, and the plugin would mark the form as dirty (changed).
And in the oncomplete of your saving button, all you have to do is clear that value and reinitialize the plugin to start again:
oncomplete="$('#hiddenInput').val('');$('#formId').trigger('reinitialize.areYouSure');"
Also it would be good to add some checking or to do that at the end of the action (link).
NOTE: If you add and delete the same 'item', technically there aren't changes, but you want to keep the form as changed right? This solution will work for that. Correct me if I'm wrong and you want to manage this particular case. You would have to add some logic in which you compare old and new values and clear or dirty the hidden input accordingly.
Presently i have a Angular Js Grid which is pagination Enabled say 5 records per page for example and total number of records is 2000, so there are going to be 400 pages in All.
when pagination in ng-grid is handled the gridOption data is specified per page which means for 1st page the gridOption will be 1-5 rows for 2nd 6-10 rows and so on........
Here i have implemented a selection functionality through checkboxes thus whenever a row is selected[checkBox becomes selected] and it's stored in selectedItems array and i show selected items in another grid like this.....
Now when i move on to second page[pagination] and select further rows like this ...
The real trouble lies here when i again go back to the previous page i.e page 1 the checkboxes will not be checked because in pagination we load data runtime thus the pages shows following result...
Hope you must have understood my problem....
what i need here is a callback before/after data is loaded so that i can select the checkboxes as i have the number of selection preserved
OR any other workaround for my problem will be much helpful too.
Thanks!.
Can you store the checked value on the data model where you are storing the row values? Then you come back and its just checked by Angular bindings?
I am not sure of your setup, but I do this in a similar situation.
I have been working on this for a couple days now.
While I am still unable to preserve selection across pagination, I am able to clear selections while simultaneously "deselecting" the select all checkbox.
The allSelected variable is not exposed in the gridScope but you are able to grab it and address it using the following code.
// Use this to deselect all options.
$scope.gridOptions.$gridScope.toggleSelectAll(null, false);
// use this to find the allSelected variable which is tied to the
// (the ng-model related to the select all checkbox in the header row)
var header = angular.element(".ngSelectionHeader").scope();
// use this to turn off the checkbox.
header.allSelected = false;
I'll follow up again if I manage to get the "reselecting" to work as documented, but for now I might remain content with this.
Honestly been looking everywhere..
The traditional 3-dropdown list dynamically populated from database:
1st table gives airport departure
2nd table gives airports choices
from 1st choice
3rd table show routes between 1 and 2.
That works perfectly!!
When passenger chooses a route from the 3rd drop list I want to check if the value from 3rd dropdownlist is represented in a 4th table called "donations"
Some routes are marked for donation possibility where passengers can donate their unused baggagecapacity to charity
My last hurdle is:
when 3rd list is selected --> check for donationpossibilities--> if possible then show a hidden div on submit
...
I've tried and read so much and gotten a lot more clever and I think I have the query to check the values in order, but I'm lost...
Not sure what programming language you are using to load the dropdowns from your database, but one option that you could try is that when you are adding the html option elements to the 3rd dropdown list you could add a data attribute to each, for example:
<option value="route 1" data-can-donate="true">...</option>
Then if you are using jquery you could bind the change event to the 3rd dropdown and do something like this:
$('#ddlRoutes').change(function() {
var canDonate = $('#ddlRoutes > option:selected').data('can-donate');
if (canDonate) {
$('#myDiv').show();
}
};
Obviously this is untested but it may work for what you are trying to do.