Why does export table export just the first page, not all data in the table?
$("#button1").shieldButton({
events: {
click: function (e) {
$('#grid').tableExport({ type: 'excel', escape: 'false', tableName: "shieldui-grid" });
}
}
});
The exporter will export only the currently loaded data.
One possible option would be to disable paging, export and get all the data. At present, the exporting functionality will export the rendered element(s) in the page.
Related
I have e language table in my db where it has all the words/sentences of my website in different language. I don't want to call API for every single word/sentence in the website. What is the best approach in svelte kit to get all the data from that table before my website initializes and then store them in such way that all my pages and component can access them? Also that data need to be updated if the user changes the language of the website.
You could define a server load function at the top level layout and pass on that data to a store which can be provided as a context to every page using the layout.
E.g.
// +layout.server.ts
import type { LayoutServerLoad } from './$types';
const fakeData = {
title: 'SvelteKit',
description: 'A new way to build web applications',
};
export const load: LayoutServerLoad = async ({ fetch }) => {
// Fetch localization data here
return {
localization: fakeData,
};
};
<!-- +layout.svelte -->
<script lang="ts">
import { setContext } from 'svelte';
export let data: { localization: any };
setContext('localization', writable(data.localization));
</script>
Usage in a page:
<script lang="ts">
import { getContext } from 'svelte';
import type { Writable } from 'svelte/store';
const localization = getContext<Writable<any>>('localization');
</script>
{$localization.title}
The key for the context and getting/setting the context could be extracted to constants/extra functions. If the language has to be updated on the fly, you just have to fetch the new data and set the store content.
I'm trying to retrieve the url parameter without using query strings, for example, http://localhost:3000/test/1, this is what I have so far:
Dir structure
test
- [pageNumber].jsx
index.jsx
import React from 'react';
import { useRouter } from 'next/router';
const Index = () => {
const router = useRouter();
return (
<>
<h1>Page number: {router.query.pageNumber}</h1>
</>
);
};
export default Index;
It works, but if I omit the pageNumber param, all I got is a 404 page, an issue we don't have on using query strings.
Now, the question: is it possible to sort this without creating an additional index.jsx page and duplicating code to handle the empty parameter scenario?
I see I may as well answer this as I got notified of MikeMajaras comment.
There are several ways of doing this, say you have a route that gets posts from a user and shows 10 posts per pages so there is pagination.
You could use an optional catch all route by creating pages/posts/[[...slug]].js and get the route parameters in the following way:
const [user=DEFAULT_USER,page=DEFAULT_PAGE] = context?.query?.slug || [];
"Disadvantage" is that pages/posts/user/1/nonexisting doesn't return a 404.
You could create pages/posts/index.js that implements all code and pages/posts/[user]/index.js and pages/posts/[user]/[page]/index.js that just export from pages/posts/index.js
export { default, getServerSideProps } from '../index';
You get the query parameters with:
const {user=DEFAULT_USER,page=DEFAULT_PAGE} = context.query;
You could also just only create pages/posts/[user]/[page]/index.js and implement all code in that one and config a redirect
module.exports = {
async redirects() {
return [
{
source: '/posts',
destination: `/posts/DEFAULT_USER`,
permanent: true,
},
{
source: '/posts/:user',
destination: `/posts/:user/DEFAULT_PAGE`,
permanent: true,
},
];
},
};
How can I get the current domain name from a request on server side?
My Nuxt based website is reachable from different domains. I would like to get the domain name from where the user has accessed the website. How can I do this?
I tried to write a middleware for that purpose but it always displays localhost:3000
export default function({ store, req }) {
if (process.server) store.commit('hostname', req.headers.host)
}
Any idea how to fix this issue?
If you are using Vuex, you can use the nuxtServerInit action to access the request headers.
In my example, I am storing the domain in Vuex so it can be accessed anywhere in the application because this middleware fires before all other ones.
store/index.js
export const state = () => ({
domain: '',
});
export const mutations = {
setDomain(state, domain) {
state.domain = domain;
},
};
export const actions = {
nuxtServerInit(store, context) {
store.commit('setDomain', context.req.headers.host);
},
};
export const getters = {
domain: (state) => state.domain,
};
middleware/domain.js
export default function ({ route, store, redirect }) {
console.log('hey look at that', store.getters['domain']);
}
nuxt.config.js
export default {
...
router: {
middleware: 'domain'
},
}
I'm able to get the domain name declaring the function on the server by this way:
export default function (req, res, next) {
console.log(req.headers.host)
}
If you need to commit the data to the store, saving data in the environment and recover it on the client side could be a solution.
I have a react-redux app with 3 reducers: clientPrivileges, userFilter and userData acting on my store.
A table component is used to present the data for each user and a drop down component is used to filter this table for specific users. When the drop down is selected for a specific user I need to call the backend to retrieve the data. This is the action associated with this:
selectUser(userId, dispatch) {
api.getUserData(userId, accessTypeId, (data) => {
dispatch(userActions.update(data));
});
return{
type: selectUser,
userId
}
}
However you can see that I have an argument called accessTypeId which needs to be sent to the backend as well as the userId. This value has been set in the store using the clientPrivileges reducer on login to the app.
I can't see any other way other than setting accessTypeId as a prop for the drop-down component in its mapStateToProps. And then in the component itself:
this.props.users.map(u => {
function onClick()
{
selectEndUserGroup(u.id, this.props.accessTypeId);
}
return <div id={"filter_group_"+u.id} key={u.id} onClick={onClick}>{name}</div>
But now I've destroyed my generic drop-down component with an accessTypeId property. How should I be doing this?
If I'm understanding correctly, you want your action to have access to a value stored in the Redux state, yes?
Redux-Thunk handles this nicely. The code would look something like this;
selectUser(userId) {
return function(dispatch, getState){
var accessTypeId = getState().[PATH TO REDUX STATE ELEMENT]
api.getUserData(userId, accessTypeId, (data) => {
dispatch(userActions.update(data));
});
dispatch({
type: selectUser,
userId
})
}
}
Note: I am using Reflux as my Flux library, so the samples will use its syntax. The question applies to Flux in general, however.
In my sample Flux application I have a productStore.js file that holds the state of the products in the system and listens to various product management actions, e.g REMOVE_PRODUCT, ADD_PRODUCT.
Here is a sample data in the store:
{
products: [
{
productName: "A"
},
{
productName: "B"
}
]
}
Now I would like to add a REFRESH_PRODUCTS action to a component.
The invocation looks like that:
component.jsx
onRefresh(e) {
actions.refreshProducts();
}
Since refreshing the products is an async operation, I would like to show the spinner while it goes on and show an error if it fails. The obvious, Flux way, would be to add the loading state and the resulting error, if such happens, to the store, like so:
productStore.js
onRefreshProducts() {
logger.info("Logging in:", email);
this.storeData.inProgress = true;
this.storeData.error = null;
this.trigger(this.data);
api.getProducts()
.then((response) => {
this.storeData.products = response.data.products;
})
.catch((response) => {
this.storeData.error = error;
})
.then(() => {
this.storeData.inProgress = false;
this.trigger(this.data);
});
}
And now the store of the data becomes dirty with various flags:
{
inProgress: false,
error: null,
products: [
{
productName: "A"
},
{
productName: "B"
}
]
}
This kind of state would be perfectly fine for me if multiple components would need to see the progress of products loading, or refresh failing, but in case, no other components needs that kind of information. So it feels I am putting private data to global state without a good reason.
I would like to be able to do something like that:
component.jsx - BAD CODE
onRefresh(e) {
this.setState({error: false, inProgress: true});
actions.refreshProducts()
.catch(function(err) {
this.setState({error: err});
})
.then(function() {
this.setState({inProgress: false});
});
}
Then I could keep the code of store clean. However, I have no obvious way to do that - Actions, by design, create a separation that don't allow to return data from actions.
What's the proper way to do it? How can I do private spinners/errors/etc while keeping the related data out of global state?
Here is one solution I thought of while writing this question:
Create a new action on the store that allows to update the product data by argument, e.g: refreshProductFromData
Call the API directly from the component
Manipulate the spinners/error handling in the component
Pass the data retrieved from API to the store via the new action
Like so:
component.jsx
onRefresh(e) {
this.setState({error: false, inProgress: true});
api.getProducts()
.then(function(data) {
actions.refreshProductFromData(response.data.products);
});
.catch(function(err) {
this.setState({error: err});
})
.then(function() {
this.setState({inProgress: false});
});
}
Not sure if it is the right/best solution or not however.
I found your post because I had the same question. I think I'm going to structure mine like this, keeping everything decoupled and communicating via actions. I like to keep the component and store ignorant with regards to the API.
The Product Actions know how to interact with the API to complete the requested action.
The Product Store listens to the Completed action to update its internal state.
The LoadingActions manage the spinner state and are asked to show/hide the spinner when API calls are initiated.
I have a Spinner component that listens to LoadingActions and updates its state to show/hide the spinner.
Component:
actions.refresh();
(Product) Actions:
onRefresh: function () {
LoadingActions.showSpinner();
api.loadProducts().then(this.completed, this.failed).finally(LoadingActions.hideSpinner);
}
Loading Actions:
onShowSpinner: function () { ... }
onHideSpinner: function () { ... }
Store:
onRefreshCompleted: function (data) {
this.products = data;
this.trigger();
}