Destroying and re-rendering DataTable using html table populated by VueJS - javascript

I am getting data from a database using Ajax and I display them in an HTML table using VueJS. I let the user perform some actions on the data (Add a new row, edit, delete). It works just fine.
My problem is that I'd like to put a DataTable to allow the user to perform researches and to sort the rows in the table. I'm simply doing : $('my-table').DataTable(); on the HTML table already displayed by Vue. It works until I want to make a change in my data. They're changed in the Vue instance but not rendered in the DataTable.
For now I tried to use the destroy() method on my DataTable then to remake and instance and I have a strange result, here's my code when I want to update my DataTable:
$('my-table').DataTable().destroy();
// Here I'm getting the data and put it in the Vue instance
// Once it's done I simply re-mount the DataTable :
$('my-table').DataTable();
And it doesn't update, it double a line already existing or display the line I inserted until I change the current page.
What's even more weird is that if I do :
$('my-table').DataTable().destroy();
// Here I'm getting the data and put it in the Vue instance
So now it's a simple HTML table on my page, correctly updated with Vue, I type in the console :
$('my-table').DataTable()
And it works just fine. I don't understand because it's exactly the same as above except that i'm typing it from the console right ?
I hope that it's clear enough. Thanks already!

Vue might be competing for DOM elements here with DataTable.
If you use $('my-table').DataTable() it references the table by the DOM position.
When working with Vue, it's better to use $ref to reference an element.
Vue does some magic in the background that allows only object that changed to re-render. So it seems like when you're destroying and creating a new object, Vue doesn't have a way to know that it changed, and doesn't re-render it.
there's a few ways you might for you.
use a key for the DataTable element. When there's a change update the key, which will redraw the element
you can try this.$forceUpdate(); at the end of the function
you can also try this.$nextTick().then(()=>$('my-table').DataTable())

Related

Is there a way to set a vuetify data table page before the table is loaded?

I'm currently struggling with setting the page of a data table externally before the table data is loaded. In my application the data table page either comes from the URL or the local storage. In theory as soon as the component is created I know on which page of the table the user should end up on.
But setting the page immediately will be of no use because after the data of the table is loaded the table page is set back to 1 again. But since I usually use a computed property for keeping the table data I simply wait for changes on this and update the table page afterwards. Unfortunately this doesn't work if there is a lot of data or the data structure is more complicated the rendering takes a bit longer so my update is coming in too early.
I couldn't find any hints in the docs that this is not supported and created a github issue since it seems like a bug to me, at least judging by some contradictory data in the dev tools.
I also tried to recreate the scenario in a codepen, obviously in this case one could just wait until "loadData" is done but as I said for my application the slight delay between getting the data and it showing up in the table seems to be the issue but leads to the same result in the end.
I tried the same with the options property but couldn't see any notable difference:
:options.sync="myOptions"
Do you guys have any recommendations on how to handle this? Either any way of keeping the page after the data changes or any reliable way to update the page after the table is populated and rendered? I feel like I tried most events of the table but had no luck yet.
Thanks in advance! :)
This really seems to be a bug in vuetify. When the items are updated the page gets reset to 1 but only inside the component. The page prop never reflects that change.
A workaround would be to trigger a change of the page variable on our side. So in your example I put the following at the end of the loadData method.
const p = this.page
this.page = 1
this.$nextTick(() => {
this.page = p
})
This puts the page prop back in sync with the component and it seems like the correct page is loaded immediately, at least inside the codepen.

Ag-Grid Master- Details Data Update Problem

I am using ag-grid Master-Details Options for binding data to the grid. But in this case, I am unable to change the detail row data until I am not opening its parent/master node. For that reason, I have to open it and close it explicitly using setExpanded(). But using this approach, it is consuming so much CPU memory and power so it is not a good approach. I have tried many things but unable to update with optimization.I am updating with SetValue(key, value) method. Is anyone know any alternative approach ??
Note: I am using setExpanded() because i am unable to get child row node object until its parent is not expanded. Is anyone know how to get child/details row node object with using setExpand() ??

Vue deleting DOM node in created live-cycle hook to initialize a component

I'm currently trying to understand why this example is not working as expected. So what I'm trying to achieve is to initialize my ContentView with the server side rendered HTML present in the DOM. Therefore I intend to check if init__main-content exists to then initialize the component with the innerHTML. Afterwards I simply tried to delete the initial node but this is not working and I end up with the content shown twice.
There must be some vue "magic" I'm not aware of, can please someone explain this behavior?
I guess there is problem in your code as you are using created hook insted you can use mounted hook.
so after mounting vue does finish all its magic to dom and now your changes can be persisted in to the dom.
if you use created then vue may be using that inner html as template and rewrite it it to dom thinking that previous html is not matching with current html when instance is created. as you already removing that element. so it will try to make it correct and add previous html again to maintain virtual-dom and real-dom changes.
if you use mounted hook your application is working fine try it.

Unmount Vue inistance or remount in a new location

I am working on a project where a new feature is to be added. The feature uses a Vue instance that was created to live on one page. It grabs: window.location.href and creates meta data with some other info that can be shared to other users.
This now needs to have same share feature to live on a page that is dynamically created. I have several rows of information, each row (can be one row, can be 100 rows) has one dropdown that is populated with the info from the box that is clicked on. Within the dropdown, I need to have this share feature. I am able to get the first row to populate with the Vue instance with a shareWidget.$mount('some selector[with a data attribute="active"')
function. This works great no matter which row I click first.
The problem is that, as soon as I click on another row ($('some selector') is removed and a new $('some selector[with a data attribute="active"')) is added within the dropdown that is now part of the active row.
I cannot get the new selector to be populated with the Vue instance called sharingWidget. I have tried to destroy and mount again, but I get [Vue warn]: $mount() should be called only once. which is expected. Is there a way to make the Vue instance move to a new location or unmount then mount it again?
I do not believe that this can actually be done. Once a Vue instance is mounted, it cannot be mounted again. The Vue instance, as opposed to a component can only live in one place. My work around was that instead of each row having a drop down, only one ever exists. When I tile is clicked on, it gets the active row and appends the drop down to the bottom of it. So, as I said, unmounting and remounting do not seem to be a thing.

How do you force Ember to rerender a component?

I have an Ember component that uses jQuery to add a canvas chart. When I change routes, I get a new model, but Ember's automatic rerendering does not work in this case. In fact, I don't know how to make the component code which adds the chart re-run at all. How can I do this?
Would it work better if it was a view?
Without looking at code, I'm going to guess based on your statement of the model changing.
Component Currently
uiSetup: function(){
// do magic here...
}.on('didInsertElement')
Component with observes
Assuming the model in the component is named model, this would fire every time the model changed as well as when the element was initially inserted into the page. You could also break it into two separate functions if you need it to act differently on model change vs element inserted first time.
uiSetup: function(){
// do magic here...
}.on('didInsertElement').observes('model')

Categories

Resources