I've run into an issue using jqGrid 5.2.1.
I'd like to retrieve a property from a row of data when a user clicks on a cell. The property is in the original data set, but it isn't displayed in the grid. Also, I'm using the scroll feature, so the row ID's are coming back like "jqg20".
I've tried using getRowData, but that only returns the data that is displayed in that row. getLocalRow will not accept the row ID with "jqg" in it. Is there another way that I can access the same row in the local data that the user clicked in the grid to pull out a property? The property 'attr' is what I want to pull out in the example:
var testData = [
{col1:10, col2:20, col3:30, col4:'TEST', col5:50, col6:60, col7:70, col8:80, col9:90, col10:100, attr: {property: "this is column 1"}}
]
Here is the jsfiddle that I've created to show the problem:
https://jsfiddle.net/rhv247q7/
Before to answer of the direct problems I need to do some notes.
It is recommend to use the jqGrid version where the problem persist. You tell us for version 5.2.1, but you use 4.6, which we think can come to some uncomfortable situations.
It is always good idea to set id row – this can be done either in the description of the colModel (key : true) or with the appropriate reader in this case localReader. When you set this you will be sure that there will be not a problems getting certain row and some other important commands. It is not good idea to let the grid create the ids.
Now to the problem : to do what you want you should use the getLocalRow, which return the data as it comes to the grid – i.e the original data.
In your case there was a bug when scroll is on and no id is set from the developer (i.e. the grid creates internally the id). The problem is fixed in GitHub and you can test it.
Related
I'm using highcharts / highstock and their documentation.
I need to dynamically add a series (once after the original chart data is loaded) and I need to hide the series to not be shown into the chart (but still to exist).
The reason for this is, I need to apply indicators to a certain time range and for this I'm using the hidden series (which actually works).
I also need to be able to access to the data of the hidden series at any time, but here is where my issue appears. If I try to access to my hidden series like:
console.log(chart.get('hidden-series').data);
then this returns an empty array.
I have the full code in the following jsfiddle and here is a short explanation of what I'm doing there:
With a click on the first two buttons, I'm dynamically adding two series series2 and series3. One of them is added "normally" (it's visible) and the other is added to not be visible on the chart (using the false, false as second and third parameters in the method addSeries - which I'm not sure what actually this means, since this was a legacy code and I can't find the proper documentation for this anywhere).
And then with the last buttons I'm trying to get the data for each of the series. As you can notice from my test example, even that the series3 is added (it's not visible) when trying to get the data, it's an empty array.
If I comment the two false parameters in the line:
}, false, false);
the data will be retrieved as expected, but the series will be displayed (and this is not what I want).
Is there any other way for getting the data from invisible series? Or maybe the proper description for the parameters in the addSeries method can also help in understanding the issue.
EDIT: (add the reason why I need this, based on the comments below)
The reason that I need this feature is: I need to have the VWAP indicator on the chart and to be applied only for the current day (so starting from 00:00 until the current moment), while the chart itself contains data for multiple days.
So what I'm doing is: I'm taking the subset of the data that represents the current day only, hide this subset and use it's data to show the VWAP indicator only for this certain time range.
The initial load of the indicator works as expected. I need to have access to this data, since the chart is updating in real time and I need to be able to dynamical add new points in the general series of data and but also in the hidden subset for the current day as well.
Regarding docs: you use only part of docs, the one describing options, not methods. You can find methods and props in "Classes" tab, for example addSeries: https://api.highcharts.com/class-reference/Highcharts.Chart#addSeries - the params you have set to false are animation and redraw - definitively not what you want to achieve :)
To achieve what you need you should:
add the third series just like the first one (with redraw=false)
hide this series with series.visible and series.showInLegend options set to false (if you have disabled legend, no need to set showInLegend)
Now the question is why you need series.data. The only reason to use Point Class instances is to call methods like point.remove() or point.update(). Since that one series is always hidden, then I think it's not the case.
If you don't need real Points, just some data from it, then you always have access to the dataset you used to create the series, right? Like chart.addSeries({ data: [ ... ]}).
Anyway, you can force generating points this way: https://jsfiddle.net/BlackLabel/nqsemy3z/2/ - note that series.processData() and series.generatePoints() methods are not part of API.
I have an edit popup, when the popup opens and i edit, it is reflecting on the table. I must avoid the reflection, once i click on save button then only the edited part must be displayed on the table. I am able to do this only for one input, i am not getting how to carry out the same way for other 2 inputs.
//Ts
editTutorial(tutorial) {
this.editTutorials.show();
this.edit_tut = tutorial;
}
You are assigning tutorial value which you sent from table into edit_tut varable, which is working as two-way binding.
so, the data in the table is getting changed along with your input.
The solution can be changing the variable reference, you can do something like,
editTutorial(tutorial) {
this.editTutorials.show();
let tut = JSON.parse(JSON.stringify(tutorial))
this.edit_tut = tut;
}
This will change the value reference and will work for you.
You have to have two different properties on your component, referencing to two different object instances. Few things to do:
Step 1: on clicking "edit", make a copy of the table row (all props) and put them inot the modal. Keep the reference to, e.g. table row you're editing, or _id or something.
In your case, add a property to TutorialComponent called currentlyEditing: any. Then, modify your editTutorial method:
editTutorial(tutorial) {
this.editTutorials.show();
this.currentlyEditting = tutorial;
}
Step 2: editing those should not reflect on the table. Go on and edit your thing.
Step 3: upon saving, sync your changes back to the table, or rather, to the original data set that's being displayed in the table. That's why you needed the reference from step 1.
Now, it's not clear to me if your edit_tut component is the one that saves changes. But if it is, I think everything will work as is. If not, you'd have to, after saving and response of "success", go and find the original tutorial in the tutorials array, and replace it with the edited component.
I have a data table in my application built using JSF and primefaces 3.5 which populates the data from database.Since it is a large data set i have implemented live scrolling to fetch rows as and when end of scrolling is reached.In this data table i have incorporated the search functionality for each column of the table as shown in the showcase here.I am developing an application as part of re-platforming of one of MS access application to java web application.The customer has now changed the requirement where instead of the find text box for each column they want the find dialog similar to the one used in MS access as shown in the image below.
The dialog should contain all matching criteria as shown in the image.
Can someone please suggest how to incorporate the above feature by any means.It can be either using JSF or any other front-end technologies.
Thanks in advance.
There are basically two options for this with the primefaces datatable:
You could use a lazy table, providing the required filtering when executing the lazy statements.
You could setup a custom filter that adapts to the constraints selected in the dialog.
The first approach would be preferable for huge amounts of data, because your live-scroll would just load entries that are matching the filter defined on the LazyModel.
The second approach would be faster to implement, but suitable for regular dataset-sizes I'd say.
Lazy Approach
http://www.primefaces.org/showcase/ui/data/datatable/lazy.xhtml
You would need to implement your own LazyDataModel and handle the conditions in the load() Method. The concrete implementation of this completly depends on whether you are using sql-queries, or some sort of Entitymanager to load the data required. The load method just needs to take care to take the filters into account along with the required pageSize determined by your live-scrolling logic.
custom filter
This way would allow you to keep your current "logic" of fetching entities and completly work "on top" of the data.
looking at the example you already linked http://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml (last column) you could solve this using some javascript along with the proper custom filter:
setup the same custom filter for all columns of your table.
hide the primefaes searchfields using some css (you are using them, customer just does not see them)
Whenever the filter conditions on your dialog are changing, set the corresponding filter-input to a value (based on your conventions) and call PF('table').filter() afterwards.
i.e. "Look In":
"Current Field": Update only the respective (hidden) input element. (Set others to null or empty string)
"All Fields": Update the global (hidden) input element.
i.e. "Match":
WholeField: set a regular String : kitchen to the fields of the required "Look In".
StartOfField: use some Wildcard-Identifier behind: kitchen%.
EndOfField: use some Wildcard-Identifier behind: %kitchen.
AnyPartOfField: use Wildcards on both sites: %kitchen%.
ps.: Use some Asci-Character no body would search like ❤ :P
After calling PF('table').filter(), your custom filter will be invoked, which could look roughly like this:
public boolean filterColumn(Object value, Object filter, Locale locale) {
String filterText = (filter == null) ? null : filter.toString().trim();
//no filter?
if(filterText == null||filterText.equals("")) {
return true;
}
//cell empty?
if(value == null) {
return false;
}
String valueText = (String)value; //assuming only strings
//"contains"
if (filterText.startsWith("%") && filterText.endsWith("%")){
return valueText.contains(filterText);
}
//"endsWith" - Yes wildcard at the BEGINNING is a endsWith!
if (filterText.startsWith("%")){
return valueText.endsWith(filterText);
}
//"startsWith"
if (filterText.endsWith("%")){
return valueText.startsWith(filterText);
}
//no wildcards? "exact match"!
return valueText.equals(filterText);
}
Aww, just saw you are on 3.5 - I think the custom Filter is available in 5.0+ only. But maybe it gives you a hint, or you can update PF.
I have issue with sort in my jqGrid.
This is my jqGrid.
All columns sort normal. But only title column sort some strange. How i can resolve this issue?
Get data from sharepoint online 2013
It's not good to place HTML fragments like var taskTitle = '<a href="'... in the grid. Instead of that one should use custom formatter for the "taskTitle" column. The difference is very easy to explain. The current code interpret 'taskTitle' as string during sorting. So the URL from src attribute is more important as the text of <a> which see the user.
By usage of custom formatter you provides formatter and unformat callbacks which will be called by jqGrid to display the data in the cell and to get the data from the cell. So You can choose which data you use for sorting . If the custom formatters still not solve your problem you can define sorttype as function. It's helpful to replace the cell data to another data which should be used for sorting only.
I have an ajax function which call a servlet to get list of products from various webservices, the number of products can go up to 100,000. I need to show this list in a html table.
I am trying to provide users an interface to filter this list based on several criteria. Currently I am using a simple jQuery plugin to achieve this, but I found it to hog memory and time.
The Javascript that I use basically uses regex to search and filter rows matching the filtering criteria.
I was thinking of an alternate solution wherein I filter the JSON array returned by my servlet and bind the html table to it. Is there a way to achieve this, if there is, then is it more efficient than the regex approach.
Going through up to 100,000 items and checking if they meet your criteria is going to take a while, especially if the criteria might be complex (must be CONDO with 2 OR 3 bedrooms NOT in zip code 12345 and FIREPLACE but not JACUZZI).
Perhaps your servlet could cache the data for the 100,000 items and it could do the filtering, based on criteria posted by the user's browser. It could return, say, "items 1-50 of 12,456 selected from 100,000" and let the user page forward to the next 50 or so, and even select how many items to get back (25, 50, all).
If they select "all" before narrowing down the number very far, then a halfway observant user will expect it to take a while to load.
In other words, don't even TRY to manage the 100,000 items in the browser, let the server do it.
User enters filter and hits
search.
Ajax call to database, database has indexes on appropriate
columns and the database does the filtering.
Database returns result
Show result in table. (Probably want it to be paged to
only show 100-1000 rows at a time
because 100,000 rows in a table can
really slow down your browser.
Edit: Since you don't have a database, the best you're going to be able to do is run the regex over the JSON dataset and add results that match to the table. You'll want to save the JSON dataset in a variable in case they change the search. (I'm assuming that right now you're adding everything to the table and then using the jquery table plugin to filter it)
I'm assuming that by filtering you mean only displaying a subset of the data; and not sorting.
As you are populating the data into the table add classes to each row for everything in that row you want to filter by. e.g.:
<tr class="filter1 filter2 filter3">....
<tr class="filter1 filter3">....
<tr class="filter2">....
<tr class="filter3">....
Then when you want to apply a filter you can do something like:
$('TR:not(.filter1)').hide();
I agree with Berry that 100000 rows in the browser is bit of a stretch, but if there's anything that comes close to handling something of that magnitude then it's jOrder. http://github.com/danstocker/jorder
Create a jOrder table based on your JSON, and add the most necessary indexes. I mean the ones that you must at all cost filter by.
E.g. you have a "Name" field with people's names.
var table = jOrder(json)
.index('name', ['Name'], { sorted: true, ordered: true });
Then, for instance, this is how you select the records where the Name field starts with "John":
var filtered = table.where([{ Name: 'John' }], { mode: jOrder.startof, renumber: true });
Later, if you need paging in your table, just feed the table builder a filtered.slice(...).
If you're getting back xml, you could just use jQuery selection
$('.class', context) where context is your xml response.
From this selection, you could just write the xml to the page and use CSS to style it. That's where I'd start at first, at least. I'm doing something similar in one of my applications, but my dataset is smaller.
I don't know what you mean by "bind"? You can parse JSON and then use for loop (or $.each()) to populate ether straight HTML or by using grid plugin's insert/add