Orchard CMS: Modifying a menu item alternate and iterating over the items - asp.net

Let's say I created a menu titled "Main Menu" from the admin panel and I need to customize the default markup, e.g. let's say I want to modify/replace the <ul>, <li> as well as the surrounding <article> and <nav> tags.
I assume that I have to come up with something like this in my Parts.MenuWidget.cshtml alternate template.
<ul class="a b c">
for each item in menuItems:
display("<li>" + item + "</li>")
end
</ul>
How do I do that in Orchard?

That's quite simple.
You could first create an alternate for you MenuWidget like so:
Parts.MenuWidget-MyZoneName.cshtml
<nav>
<div class="logo">
#Html.Partial("_Logo")
</div>
<ul>
#*Display all the stuff added in the admin*#
#DisplayChildren(Model.Menu)
#*Add additional stuff. Of course you could also add it as MenuItem to the Menu-Model*#
#if ( Request.IsAuthenticated )
{
if ( Authorizer.Authorize(StandardPermissions.AccessAdminPanel) )
{
<li>
<a href="/Admin">
Admin
</a>
</li>
}
<li>
<a href="~/Example1">
Extra1
</a>
</li>
}
else
{
<li>
<a href="~/Example2">
Extra2
</a>
</li>
}
</ul>
</nav>
And then go on and do something similar for your MenuItems. For example:
MenuItemLink.cshtml
#Model.Text
Another thing that's worth mentioning is that you can either only provide an alternate for a specific shape like the MenuItemLink above or just provide an alternate for the base MenuItem shape which will then be used for every MenuItem type that exists.
(Maybe those are not the best examples, but I guess they'll do the job ;) )
Update:
In order to remove/modify the tags you can create an alternate for MenuItem.cshtml and look at this part:
if (HasText(renderedMenuItemLink))
{
var tag = Tag(Model, "li");
#tag.StartElement
#renderedMenuItemLink
if (items.Any())
{
<ul>
#DisplayChildren(Model)
</ul>
}
#tag.EndElement
}

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.

Is there a way to have multiple router-links inside a li and that li gets the active class in vue2?

Is there a way to have multiple router-links inside a li and that li gets the active class in vue2?
I was thinking in something like this: https://jsfiddle.net/tejitak/o44z47ag/5/
<div id="app">
<ul>
<li>
<ul v-link-active>
<li>
<a v-link="{ path: '/foo' }">Go to Foo</a>
</li>
<li>
<a v-link="{ path: '/bar' }">Go to Bar</a>
</li>
</ul>
</li>
<li>
<a v-link="{ path: '/baz' }">Go to Baz</a>
</li>
</ul>
<router-view></router-view>
</div>
It's supposed to be used in a menu which as submenus.
The migration docs only references a single link so I don't know if this is possible: https://v2.vuejs.org/v2/guide/migration-vue-router.html#v-link-active-replaced
You can use router-link like this to do that:
<ul>
<router-link tag="li" to="/foo">
<span>
<strong>
<a>/foo</a>
</strong>
</span>
</router-link>
</ul>
Here's the documentation for vue-router: http://router.vuejs.org/en/
Here's the documentation for router-link: http://router.vuejs.org/en/api/router-link.html
Here's a demo for nested router-links: https://jsfiddle.net/wx17jh2y/
<ul>
<router-link tag="li" to="/foo">
<span><a>Foo</a></span>
<ul>
<router-link tag="li" to="/bar">
<span><a>bar</a></span>
</router-link>
</ul>
</router-link>
</ul>
If you want to group multiple links underneath one element that should be considered active (e.g. using Bootstrap dropdowns), you can just make the parent element a router-link as well and prevent any interaction by setting the event attribute to an empty list. Example:
<router-link tag="li" to="/function" :event="[]">
<ul>
<router-link tag="li" to="/function/a"><a>Function A</a></router-link>
<router-link tag="li" to="/function/b"><a>Function B</a></router-link>
</ul>
</router-link>
See also the documentation on the event property on router-link.
I would not use router-link and instead bind to the href attribute on the anchor tags. If the links in the menu are static, then you may not even need to bind to the href attribute - just specify href="/foo" (at least that's how it worked in angular1). If the href needs to be generated, like if you're looping through menu items, then create the hrefs in a vue instance function and call it like :href="createHref(menuItem)" for example.
To assign the active class, I would assign the class if the href matches the current route (see https://v2.vuejs.org/v2/guide/class-and-style.html). The current route is in this.$route. Just make sure route is passed into the root app instance: https://router.vuejs.org/en/api/component-injections.html

Indentation of li items in ng-repeat

I am using ng-repeat to show list items with some text. And I want every single item to be indented 10-20px to the right from the previous one. I don't have much experience with css.
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}">
{{todo.toDoText}}
</li>
Here is a jsFiddle with my code.
Thanks in advance!
you may use ng-style to solve your problem:
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}"
ng-style="{'margin-left': 10*$index+'px'}">
{{todo.toDoText}}
</li>
$index is a varibale that will be set by ng-repeat. You may use this to calculate your style.
Change your template with following::
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}" style="text-indent: {{$index * 10}}px">
{{todo.toDoText}}
</li>
</ul>
</div>

Unable to Navigate using LinkText in Selenium C#

I got the following C# code from Selenium IDE:
driver.FindElement(By.LinkText("Sub Link 1")).Click();
But as it wasn't working, I modified the code below to wait. It is still not working.
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement element = wait.Until(ExpectedConditions.ElementExists(By.LinkText("Main Link 1")));
if (element != null)
{
var innerElement = wait.Until(ExpectedConditions.ElementExists(By.PartialLinkText(
"Sub Link 1")));
}
What might be the possible issue?
My HTML:
<html>
Show navigation
Hide navigation
<div id="navlogo"><a title="HOME" href="url">
<span style="position:absolute;width:100%;height:100%;top:0;left: 0;">
</span></a></div>
<ul class="clearfix">
<li>MXLMain1
<ul>
<li>ML1
</li>
<li>ML2
</li>
</ul>
</li>
<li>MXLMain2
<ul>
<li>MK2
</li>
</ul>
</li>
<li>Main Link 1
<ul>
<li>Sub Link 1
</li>
<li>Sub Link 2
</li>
</ul>
</li>
..........................
</html>
How about using xpath?
driver.FindElement(By.XPath("//a[.='Sub Link 1")).Click();
It looks like the link that you are trying to use is from a navigation bar. You will need to use Seleniums Actions class to activate the menu dropdown.
Then use Actions class to move to element and click on it.
public void MouseHover(By locator)
{
element = driver.FindElement(locator);
Actions action = new Actions(driver);
action.MoveToElement(element).Perform();
}
To click same steps.
action.MoveToElement(element).Perform();
action.Click().Perform();
Move to initial element
Move to the second element and use click method

Resources