How to hide specific rows in Handsontable.
I have buttons in DOM, each of them should hide specific rows.
For example: click button with class `alarm' should shide all rows which second column has value 'alarm'.
For now i do ugly thing. Every button click i loop overy my tableData and delete datas with 'alarm' then just load data and render table. But i can't do that becouse i have some dynamic datas so after render their disapear.
eveGrid.loadData(tableData);
eveGrid.render();
Dynamically hiding rows is quite a complex task which is not documented in the Handosntable documentation. However, there is plenty of functionality available to implement it ourselves. As a matter of fact, I had to do this just last week so I can share with you a potential approach. It's really quite simple and similar to your solution, which is not ugly by the way!
What you want to do is keep two copies of your data. The first we can call data, and the second activeData. Initially, they both equal each other. Now this part is tricky and not easy to grasp but what you have to make sure is that these two arrays are DIFFERENT OBJECTS, but have the SAME REFERENCED ELEMENTS. What this means is that the arrays themselves are not clones, so an equality test would fail. However, their elements are clones. Your activeData elements are just references to the elements on data.
Once we have this set up, it's simple to implement the hiding of rows. Your click should look through data and set a new activeData based on the matching rows you want to display. Then just update handsontable with something like:
hotInstance.updateSettings({data: activeData});
And that's it! Note that that updating method will automatically trigger a render().
Let me know how it goes, I'm curious to see if other people can use this approach.
Related
In my app I import a JSON file and then display it in a table. The table has 3 columns.
Two issues with this:
The table also has sorting and CRUD operations, so using the array index for the row key is not best practice.
Similar with above, I am trying to implement the functionality to edit a row, and doing so by index is finicky because they may have shifted from sorting or CRUD.
I came up with some potential solutions, but they all seem weak:
Uniquely identify a row by a combination of its visible columns. This has problems because while it's extremely unlikely there will be duplicate rows for this data set, I suppose it's possible.
Uniquely identify a row by fields that are relatively guaranteed to be unique. For example, each row has a creation date, and since all rows are generated manually in the program, I believe this could function as an ID for uniquely identifying rows? It kinda feels like identifying a row by a date is bad for some reason though.. Not sure.
Uniquely identify a row by a combination of all its fields (visible and hidden). May be slow or needlessly complex?
Upon row creation, assign an ID to the row that isn't shown to the user and is persisted in the saved file. Would also probably need to have a global counter variable saved (because if a row is deleted we wouldn't want to re-use that ID and we need to know where we left off from).
Assign a GUID to each row? Wouldn't need to store an index counter but more space would be required (although the files are relatively small so I'm not sure how much this matters).
Are there any other or better ways that I'm missing? How is this normally handled?
I'd go with 4 or 5, but with a minor change:
You can keep the JSON as is. Upon importing the JSON, you map each item and assign them an ID or GUID - I'd use ID for simplicity, but it's up to you. Within the execution of your program, this field will be used to the CRUD operations and/or sorting.
When your program is done, map again your data, and save back in the same format you've received (removing the new prop you've added).
I've created a database-driven hierarchy table with 3 hierarchy levels. It works almost exactly how I want it to, but the javascript code that drives its functionality is UGLY. I would like to re-write some of it, but I don't quite know how. I imagine I'll have to use recursive functions, but there are some strange business rules that may make it more difficult than I imagined. Can you make any suggestions to simplify my current code (in particular, the ActivateRow() function)? See fiddle.
Note that there is some funky use of hidden fields due to ASP.NET Web Forms postbacks and losing input values, but there are some useful data-attributes written into the HTML such as data-region-id, data-subregion-id, data-market-id, and data-hierarchy-id. the main requirements are below:
There are two tables - the first is linked to the second, so all actions on the first table should be carried out on the second table as well (though the second table is slightly different).
Three levels of hierarchy. The highest level (Region), a middle level (Sub Region), and a final level (Market)
Row activation enables all controls in a given row. If the activated row is a Sub Region row, it deactivates its parent Region row controls and its sales values sum up to the Region level. This does not apply to activating a Market row.
Similarly, row deactivation should disable and clear all controls within that row. If the row is a parent row, it should clear all children rows and disable their controls as well.
Deactivating all children of a parent row should deactivate the parent row and clear all parent row controls.
Surely, there's a better alternative. Am I reinventing the wheel? Is there anything out there that I could use to improve my spaghetti code? I realize this isn't the best question for Q&A format - is there somewhere else I should ask my question?
It is not entirely clear what you are doing but from what I gather you have some kind of table you are filtering.
Also, you are using ASP.NET webforms.... so sorry for you.
I would not use any kind of form binding controls offered by ASP WebForms, because it is now obsolete, incorrect and very painful.
Instead, create an AJAX enabled page [WebMethod] that returns all the data or filtered with a parameter, what ever, in JSON (Because JSON is easier to read and debug, and much faster than XML)
Go and find the jQuery plugin DataTables. Everykind of functionality is built in and extentable, it works great, super efficient client side, with varios filtering and searching capabilities.
You either create a new model on the Server side and remap the data server side, or dump your existing model and remap it on the client, either way, you just plug JSON data into datatables.
Saving back to webforms is slightly more tricky (compared to MVC/Razor) because you have to take the String and deserialise it to your model, its a few extra lines but I do this all the time and you can carry on with your business logic.
Surprised this question hasn't been asked before, at least I haven't been able to find it.
I have multiple lists or elements that are all connected together using jQuery UI sortable. Its all working as the docs say it should, however I would like to make the lists force sort. For example, when each list is loaded in, the items are ordered by date. When you move an item from list 1 into list two, you can place that item anywhere in the list, regardless of its date. Similarly you can move items within the same list so they are out of date order.
Is there a way to make it calculate the date ordering and render the items in the correct order once an item has been moved?
Once an item is moved from one list to another it performs an ajax request to save that item to that list, a possible solution would be for that request to return that list in a sorted order and then re-render that list, however that doesnt seem like a particularly clean approach as you already have all the data.
Any easier/better ways of doing this? If its also possible to prevent reordering within the same list that would be ideal.
thanks.
JQuery Sortable does not handle the behavior you are trying to achieve. You have to do it your self. I think the receive eventHandler is a good starting point. you can use ui.item.prev() and ui.item.next() to retrieve the previous and the next elements then check if the insertion point matches your requirements and insert the element to that position or turn the element back to it's old list/position ( $(ui.sender).sortable("cancel"); )
I'm writing a web application that displays a large number of rows of data (~2000 at present), each of which has a drop-down "select" element with ~100 options. Any of those options can be selected by default. I'm generating all the actual DOM elements client-side. My problem: rendering this beast takes ~4 seconds on my relatively recent machine, which is really suboptimal. I know the problem is specifically with all the select elements, because replacing them with a bit of static text or a single-option list causes render time to be nigh imperceptible.
The vanilla code, minus failed experiments (see below) is here.
Avoiding the suggestions of "paginate your data" and "don't have so many options in a select", what is the most efficient way I can write my append / render code, assuming I do have a legitimate reason to display that much data and have that many options? For my purposes, Firefox is the only platform I care about.
Things I have tried:
Using an async loop to append rows to the table (slower than a regular loop, and oddly didn't render the intermediate results)
Building up a string that represents the body of the table and inserting it into the DOM in a single call (almost identical performance)
Instead of inserting the entire options list, inserting a single-option "select" element, and then populating the entire list when the "select" element gains focus (presumably because someone is trying to change it). This was actually pretty high-performing for the initial render, but then populating the element with the full list caused some weird behavior, losing focus and never actually being able to "open" the select element.
Right now my default assumption is that the third option is the way to go, and I need to figure out how to do some bookkeeping about what has already been populated. But my suspicion is that there is a plainly better / faster / more idiomatic way to do this. Is there?
Yes, I would "lazily" generate and/or populate the dropdowns.
That is, only create and populate the dropdowns when the user clicks on them, as probably almost all of the dropdowns in the 2000 rows will never be used right?
Perhaps a select element might not be the best UI here too, but instead some kind of HTML menu like so: https://jqueryui.com/menu/ that is created, populated and displayed only when the user clicks on some kind of button to display it.
Maybe this information is out there and my Google-fu is failing me, however I can't seem to find the answer. How can I get the number of rows being currently displayed in a jqGrid?
Every question and answer I've found on this topic tells you how to get either the total number of rows (displayed or not) or the number of rows loaded by an external service. Instead, I'm trying to get how many rows are being displayed in the current page of the jqGrid. One of my jqGrid attributes is rowList:[10,20,30], but I'm not sure how to access which one is selected myself.
All I want is how many rows are being currently dislpayed on each page of the jqGrid. The closest thing I've found so far has been this Q&A, but this displayed how many <tr>s there are and wasn't really what I needed.
$('.ui-pg-selbox').val()
Tested on the latest jqGrid (4.4.1)
Of course, if you have more than jqGrid per page, you can use an wrapper to ensure that it is the one you're looking for.
$('#myjqGridWrapper .ui-pg-selbox').val()
Not sure whether it's the best way, but it gets the job done.
The space means a descendant selector, that is it looks for elements containing the class ui-pg-selbox which are descendant of an wrapper #myjqGridWrapper. That would require having a div or some other wrapper around your table.
UPDATE: Also, if you have the table ID or a reference, you can use a more sturdy way of querying its jqGrid instance's .ui-pg-selbox:
$('#jqgridTableId').closest('.ui-jqgrid').find('.ui-pg-selbox').val()
The following will return you the number of displayed rows on a grid's page:
$('#myjqGridWrapper').getGridParam('reccount');
You shouldn't rely on the view for information. You should pull this information out of the JQGrid model. You can do so by calling the getGridParam method like so:
var rowNum = jqGrid.getGridParam('rowNum');
See here for more information: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options