I have a dashboard app, that displays certain applications to the user, loaded from the database..
The tiles are draggable (Jquery).. But im struggling to understand how to move a tile, and then keep the state, so that a user can come back the next day, and still have his preferences.
I have tried to follow Telerik demo, but unfortunately, i am a student, i can't afford the license.. Has anybody done something similar, to keep a users preferences?
Here is the Telerik demo, im struggling with what would be in the models.
Local storage for state
using Microsoft.JSInterop;
using System.Text.Json;
using System.Threading.Tasks;
namespace TelerikBlazorDemos.Services
{
public class LocalStorage
{
protected IJSRuntime JSRuntimeInstance { get; set; }
public LocalStorage(IJSRuntime jsRuntime)
{
JSRuntimeInstance = jsRuntime;
}
public ValueTask SetItem(string key, object data)
{
return JSRuntimeInstance.InvokeVoidAsync(
"localStorage.setItem",
new object[] {
key,
JsonSerializer.Serialize(data)
});
}
public async Task<T> GetItem<T>(string key)
{
var data = await JSRuntimeInstance.InvokeAsync<string>("localStorage.getItem", key);
if (!string.IsNullOrEmpty(data))
{
return JsonSerializer.Deserialize<T>(data);
}
return default;
}
public ValueTask RemoveItem(string key)
{
return JSRuntimeInstance.InvokeVoidAsync("localStorage.removeItem", key);
}
}
}
This is the part im struggling with.. @Code{ }
@page "/tilelayout/persist-state"
@inject LocalStorage LocalStorage
@inject IJSRuntime JsInterop
@using TelerikBlazorDemos.Shared.DemoConfigurator
<DemoConfigurator>
<DemoConfiguratorColumn>
<TelerikButton OnClick="@SaveState" Icon="save" Class="mr-xs">Save State</TelerikButton>
<TelerikButton OnClick="@ReloadPage" Icon="reload" Class="mr-xs">Reload the page</TelerikButton>
<TelerikButton OnClick="@LoadState" Icon="download" Class="mr-xs">Load last State</TelerikButton>
<TelerikButton OnClick="@SetExplicitState" Icon="gear" Class="mr-xs">Configure State</TelerikButton>
</DemoConfiguratorColumn>
</DemoConfigurator>
<div class="demo-alert demo-alert-info" role="alert">
<strong>Change the Tile Layout</strong> (resize and reorder some tiles, remember their order) and
<strong>Save</strong> the TileLayout state, then <strong>Reload</strong> the page to see the state persisted.
<strong>Change</strong> the layout some more and <strong>Load</strong> the state to see the last one preserved.
You can manage the TileLayout state with your own code to put it in a specific configuration through the <strong>Configure</strong> button.
This demo will remember your last layout until your clear your browser storage or click the Configure button to put it in its initial state.
</div>
<div style="display: inline-block;">
<TelerikTileLayout @ref="@TileLayoutInstance"
Columns="3"
ColumnWidth="285px"
RowHeight="285px"
Resizable="true"
Reorderable="true">
<TileLayoutItems>
<TileLayoutItem HeaderText="San Francisco">
<Content>
<img class="k-card-image" draggable="false" src="images/cards/sanfran.jpg" />
</Content>
</TileLayoutItem>
<TileLayoutItem HeaderText="South Africa">
<Content>
<img class="k-card-image" draggable="false" src="images/cards/south-africa.jpg" />
</Content>
</TileLayoutItem>
<TileLayoutItem HeaderText="Sofia" RowSpan="2">
<Content>
<img class="k-card-image" draggable="false" src="images/cards/sofia.jpg" />
<div class="text-center">
<div class="k-card-body">
<p>Sofia is the largest city and capital of Bulgaria. Sofia City Province has an area of 1344 km<sup>2</sup> while the surrounding and much bigger Sofia Province is 7,059 km<sup>2</sup>. The city is situated in the western part of the country at the northern foot of the Vitosha mountain, in the Sofia Valley that is surrounded by the Balkan mountains to the north. The valley has an average altitude of 550 metres (1,800 ft). Unlike most European capitals, Sofia does not straddle any large river, but is surrounded by comparatively high mountains on all sides.</p>
<br />
<em>* The data used in this demo is taken from <a href="https://wikipedia.com" target="_blank"><em>wikipedia.com</em></a></em>
</div>
</div>
</Content>
</TileLayoutItem>
<TileLayoutItem HeaderText="Rome" ColSpan="2" RowSpan="2">
<Content>
<img class="k-card-image image-center" draggable="false" src="images/cards/rome.jpg" />
<div class="text-center">
<div class="k-card-body">
<p>
</p>
<p>
<em>* The data used in this demo is taken from <a href="https://wikipedia.com" target="_blank"><em>wikipedia.com</em></a></em>
</p>
</div>
</div>
</Content>
</TileLayoutItem>
<TileLayoutItem HeaderText="Barcelona">
<Content>
<img class="k-card-image" draggable="false" src="images/cards/barcelona.jpg" />
</Content>
</TileLayoutItem>
</TileLayoutItems>
</TelerikTileLayout>
</div>
@code { TelerikTileLayout TileLayoutInstance { get; set; }
TileLayoutState SavedState { get; set; }
string stateStorageKey = "TelerikBlazorTileLayoutStateDemoKey";
async Task SaveState()
{
var state = TileLayoutInstance.GetState();
await LocalStorage.SetItem(stateStorageKey, state);
}
async Task LoadState()
{
TileLayoutState storedState = await LocalStorage.GetItem<TileLayoutState>(stateStorageKey);
if (storedState != null)
{
TileLayoutInstance.SetState(storedState);
}
}
void ReloadPage()
{
JsInterop.InvokeVoidAsync("window.location.reload");
}
async void SetExplicitState()
{
TileLayoutState desiredState = GetDefaultDemoState();
TileLayoutInstance.SetState(desiredState);
await SaveState();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var state = await LocalStorage.GetItem<TileLayoutState>(stateStorageKey);
if (state != null && TileLayoutInstance != null)
{
TileLayoutInstance.SetState(state);
}
}
TileLayoutState GetDefaultDemoState()
{
TileLayoutState defaultDemoState = new TileLayoutState()
{
ItemStates = new List<TileLayoutItemState>()
{
new TileLayoutItemState { Order = 1, ColSpan = 1, RowSpan = 1 },
new TileLayoutItemState { Order = 2, ColSpan = 1, RowSpan = 1 },
new TileLayoutItemState { Order = 3, ColSpan = 1, RowSpan = 2 },
new TileLayoutItemState { Order = 4, ColSpan = 2, RowSpan = 2 },
new TileLayoutItemState { Order = 5, ColSpan = 1, RowSpan = 1 },
}
};
return defaultDemoState;
} }
<style>
.k-card-image {
width: 285px;
height: 189px;
}
.k-card-body {
overflow: auto;
}
.image-center {
display: block;
margin: auto;
}
</style>
For instance TileLayoutInstance.SetState(storedState); I don't know how this is set up behind the bonnet. p.s im using .netCore5 and visual studio 2019. Any help is much appreciated.
