NextJS - Serverside Data to Component (partially loading) - next.js

I'm sending 'SSR data' to my react component ()
The problem is;
Generallayout returns
<header className={`topbar-shadow`}>
<div className="header-top">
<div className="promo-message">
Some text over there
</div>
</div>
<div className={`header-bottom`}>
<div className="container">
<ul className="main-menu">
{headerData.map((item, index) => (
<li class="items">Item 1</li>
....blablabla
headerData is 'SSR data' that I passed throught component like <GeneralLayout headerData={headerData} />
When I load my website,
website returns firstly <li class="items">Item 1</li> before render <header>. So that, CSS is broken because It's not wrapped by header.
Whats wrong with it?
Why my whole header renders at the same time? What should I do for render this inside the header whole time?

Related

Pagination Wordpress in Custom Plugin ( Javascript )

Hi I hope someone can help with this. I'm building a wordpress plugin. I just have basic knowledge of php and i managed to build the whole plugin except pagination. I have tried so many code using javascript but none is working for me. Here is the image. I want to divide the items with pagination
Thank you in advance!
A good approach will be to think about the pages like tabs. Then the page link will behave like buttons that show/hide based on the page link clicked.
Here's an example using jQuery
// Add an event listener for when the page link is clicked
$('.page-link').on('click', function(){
// Save the page number that was clicked
var pageNum = $(this).data('page-id')
// Hide any open 'pages'
$('.page-content').hide();
// Find and show the selected page
$('[data-page=' + pageNum + ']'').show();
});
For this to work, you'd need a HTML structure a bit like this
<!-- The Page Link -->
<div>
<ul>
<li class="page-link" data-page-id="1">Page 1</li>
<li class="page-link" data-page-id="2">Page 2</li>
<li class="page-link" data-page-id="3">Page 3</li>
</ul>
<!-- The Page Content -->
<div class="page-content" data-page="1" style="display: none;">
Page 1 content
</div>
<div class="page-content" data-page="2" style="display: none;">
Page 2 content
</div>
<div class="page-content" data-page="3" style="display: none;">
Page 3 content
</div>
</div>
Here is a super basic jsfiddle

UIkit - how to get order with the sortable component?

I implemented the UIkit sortable component and added a stop event. But I can't figure out how to calculate the new order if an item has been dragged. So far the only thing I can think of is giving each item an id then calculating based upon that id, but it doesn't seem like the proper way to do so
There is a quite simple way of achieving this. The element stores originalEvent where you can find also explicitOriginalTarget - our moved element. As it is wrapped in li inside ul, I went up to its parentNode (li), so I am at the level of elements I need, then converted it to jQuery object (you don't have to, I did it just because it was quick), then you can get its index. All of these values can be accessed by console.log(e);
Only problem with this solution is performance, it works, but when you move elements too often, it can show 0 instead of correct index value
EDIT: I realized you're probably asking about the whole set of items and their order, not only the index of currently moved item, so I added also console logging for this as well
Example below:
var indexes = new Array();
$(document).on('moved', '.uk-sortable', function(e) {
var currentLi = e.originalEvent.explicitOriginalTarget.parentNode;
indexes = [];
$(this).find('li').each(function() {
indexes.push($(this).data("index"));
});
alert("New position: " + $(currentLi).index());
console.log(indexes);
});
$('.uk-sortable').find('li').each(function(i) {
$(this).data("index", i);
indexes.push(i);
});
console.log(indexes);
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/js/uikit-icons.min.js"></script>
<ul class="uk-grid-small uk-child-width-1-4 uk-text-center" uk-sortable="handle: .uk-card" uk-grid>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 1</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 2</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 3</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 4</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 5</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 6</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 7</div>
</li>
<li>
<div class="uk-card uk-card-default uk-card-body">Item 8</div>
</li>
</ul>
I came across this searching for something else and happen to know the answer you're looking for. You don't need jQuery or anything else for this, just UIkit.
<ul id="sortable-element" uk-sortable>
<li class="uk-sortable-item" data-id="1">Content</li>
<li class="uk-sortable-item" data-id="2">Content</li>
<li class="uk-sortable-item" data-id="3">Content</li>
<li class="uk-sortable-item" data-id="4">Content</li>
<li class="uk-sortable-item" data-id="5">Content</li>
</ul>
let sortable = UIkit.sortable("#sortable-element");
UIkit.util.on(sortable.$el, "added moved", function(e, sortable) {
sortable.items.forEach(function(item, index) {
console.log({ item, index});
// Grab data attributes if you need to.
// UIkit.util.data(item, "id");
});
});
The second parameter of the callback references the sortable component and contains the array of item elements. Loop through this array and use the index (0 based) to get the new order of items. It's important to use the .uk-sortable-item or define a different class with the cls-item option for the sortable component to return the items.
You also don't need to define sortable like I have, you can just use the UIkit.util.on with CSS selectors, e.g. UIkit.util.on("#sortable-element", "added moved removed start stop", function(e, sortable) { console.log(e.type); });
UIkit.util is more or less undocumented, but it's extremely well built. Check the repo to see available functions. They are binded to UIkit.util in the dist/uikit.js file. https://github.com/uikit/uikit/tree/develop/src/js/util
The easiest way I have found is to get the list of all the elements and perform a mapping operation that returns an array of unique & identifiable attributes (e.g. the IDs of the sortable elements.
The moved event has a detail property that's an array containing the UIKitComponent and the target element; you can get the items from the UIKitComponent.
const new_order = event.detail[0].items.map(el => el.id);
//["id-1", "id-2", "id-3"];
You can then get the indices after the fact, at least the messy DOM side of things is sorted.

Bootstrap Tab Inside ASP.Net Razor Loop

I have simple bootstrap(3) tabs inside a div (class="example").
I have the div saved in a Partial view.
I am using foreach loop in my Razor view, passing the object to the Partial view and outputting it for each iteration.
How can I simply navigate each div's own tabs without affecting other tabs inside the loop?
View:-
#foreach (var pbrModel in Model)
{
#Html.Partial("~/_TestViewPartial.cshtml", pbrModel)
}
Partial View:-
#model PbrViewModel
<div class="example">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home">...</div>
<div class="tab-pane" id="profile">...</div>
<div class="tab-pane" id="messages">...</div>
<div class="tab-pane" id="settings">...</div>
</div>
</div>
You can use a for loop to iterate over the items in your main view's Model, and then use the i iterator to make each tab's id unique by appending it in the partial view.
You can pass the i value as a "model" to the partial view when you iterate.
Like so:
#for (var i = 0; i < Model.Count; i++)
{
#Html.Partial("~/_TestViewPartial.cshtml", i)
}
Then in the partial view, you can use the "model" passed to it from your for loop - in this case as an int type, so it can print the value into the ids accordingly.
Like so:
#model int
<div class="example">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="home#Model">...</div>
<div class="tab-pane" id="profile#Model">...</div>
<div class="tab-pane" id="messages#Model">...</div>
<div class="tab-pane" id="settings#Model">...</div>
</div>
</div>
Much like my previous (before this edit) answer, passing the i variable to each iteration ensures the ids are unique.
Unfortunately, with this way you will not be able to access any properties of the main view's Model, as you are only passing the int to the Partial view, and nothing else (I explain more below).
A couple of notes to think about:
Your path to the partial doesn't need to be "relatively absolute". In that, I mean you can just use "_TestViewPartial.cshtml" as the first argument (omitting the "~/")
If you do wish to access properties of your main view's pbrModels inside the partial, you will need to pass these to the partial (as per your OP, with PbrViewModel as the #model type) and I would suggest adding a unique indexer property to that type, if possible - so you can then print this in the id/href of the elements within your partial view, like in my example; just use #model.MyUniqueIDProperty or whatever friendly name you have for it
THINK - Do you really need a separate partial view for this? If you're reusing the code elsewhere, then yes. If it's solely for the purpose of the page, then no; I would defer to having the code in the main view's code - you would then still be able to access the main Model of the page, if you need to get properties from the PbrViewModels using the indexer you're at (Model[i])
Any questions, just ask.
Hope this helps! :)

CKEditor (.net) disappears on postback where HttpResponse hijacked to deliver download stream

I have a page with 2 tabs on it (using bootstrap's .tab-nav). In one tab, inside an update panel, I have a CKEditor 4.x instance. In the other tab, I have a button that pushes a CSV file via HttpResponse (initiates a download). This download button triggers a full postback since partial postbacks can't push streams for download.
The problem is that after I initiate the download, when I switch back to the tab with the CKEditor instance, it's vanished.
Any ideas how to fix? I suspect it is directly related to the fact that I'm hacking the HttpResponse from the server to deliver the download, but why would the CKE instance disappear?
Here's how I fixed it: Every time someone opens the tab with the ckeditor on it, I use cke's js API to restore it.
HTML
<ul class="nav nav-tabs" role="tablist">
<li class="active">Tab 1</li>
<li>Tab 2</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
...
</div>
<div class="tab-pane" id="tab2">
<textarea class="ckeditor" id="ckeditor1" />
...
</div>
</div>
JS
// Every time someone opens the ckeditor-containing tab, replace the CKEditor if it is missing
$("a[href='#tab2']").on("shown.bs.tab", function (e) {
if (CKEDITOR.instances.ckeditor1 == null) {
// Decode the textarea content
var t = $("#ckeditor1");
t.val(CKEDITOR.tools.htmlDecode(t.val()));
// Show the ckeditor instance
CKEDITOR.replace("ckeditor1", { toolbar: 'CustomToolBar' });
}
});
Just using CKEDITOR.replace didn't work because the content is encoded when stored into cache. I had to upgrade cke from 4.0.2 so that I could decode the content using CKEDITOR.tools.htmlDecode when restoring the instance.

Personalized Accordion (like a list of Master-Details)

I need to create an Accordion Ajax control that in the first Pane has a list of records
(for example Users).
When the web users clic on one of them, the other Panes have to be populated with details of this user.
For example, if I clic in the first record, Pane2 will be populated with LifeDetails, Pane3 with HomeDetails, Pane4 with JobDetails and so on.
Anyone has idea of how realize this?
Thanks a lot.
Luigi
I would try to solve this using http://docs.jquery.com/UI/Accordion and http://pjax.heroku.com/ ...
Something along the lines of
<div id="accordion">
<h3>pane1</h3>
<div>
<ul id="persons">
<li>Person 1</li>
<li>Person 2</li>
<li>Person 3</li>
</ul>
</div>
<h3>Life Details</h3>
<div>
Some content here
</div>
<h3>Home Details</h3>
<div>
Some content here
</div>
<h3>Job Details </h3>
<div>
Some content here
</div>
</div>
For the markup. Then your JavaScript should be something like
<script src="jquery.min.js"></script>
<script src="jquery.cookie.js"></script>
<script src="jquery-ui.min.js"></script>
<script src="jquery.pjax.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#accordion").accordion();
$('.persons').pjax('#accordion');
});
</script>
And in your aspx you check for the HTTP_X_PJAX header (see xhr.setRequestHeader('X-PJAX', 'true')), and if it's present, you render just the <div id="accordion"> for the selected item (without the Masterpage, just the div), if it's not present you render the whole page (with Masterpage).

Resources