Horizontal drop-down menu Umbraco - javascript

I'm using Umbraco and I want my drop-down menu to display horizontal like this:
Right now my drop down menu is like this:
The problem is that I don't know how to do this in Umbraco
Here is my code:
MainNavigation code:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{ var home = CurrentPage.Site(); }
#if (home.Children.Any())
{
#* Get the first page in the children *#
var naviLevel = home.Children.First().Level;
#* Add in level for a CSS hook *#
<ul class="level-#naviLevel">
#* For each child page under the home node *#
#foreach (var childPage in home.Children)
{
if (childPage.Children.Any())
{
<li class="has-child #(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
#if (childPage.DocumentTypeAlias == "Huvudmeny")
{
<span>#childPage.Name</span>
#childPages(childPage.Children)
}
else
{
#childPage.Name
}
</li>
}
else
{
<li class="#(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
#childPage.Name
</li>
}
}
</ul>
}
#helper childPages(dynamic pages)
{
#* Ensure that we have a collection of pages *#
if (pages.Any())
{
#* Get the first page in pages and get the level *#
var naviLevel = pages.First().Level;
#* Add in level for a CSS hook *#
<ul class="sublevel level-#(naviLevel)">
#foreach (var page in pages)
{
<li>
#page.Name
#* if the current page has any children *#
#if (page.Children.Any())
{
#* Call our helper to display the children *#
#childPages(page.Children)
}
</li>
}
</ul>
}
}
The above code is included in my master page through this code:
<nav>
#{ Html.RenderPartial("MainNavigation"); }
</nav>
js
// Navigation
$('#toggle').click(function(){
$('.has-child').removeClass('selected');
$('nav').toggleClass('open');
$('.cross').toggleClass('open');
});
$('.has-child').click(function(){
if ( window.innerWidth < 768 ) {
if ( $( this ).hasClass('selected')){
$('.has-child').removeClass('selected');
} else {
$('.has-child').removeClass('selected');
$(this).toggleClass('selected');
}
}
});
Can anyone give me advice on how to make the drop down menu horizontal?

So described in the comment. The problem can be fixed with CSS as shown in the fiddle
This is what I would call a fix. But the way I would think is the proper way, would be to create a CSS class instead of override the bootstrap CSS.
When overriding the bootstap class, you also create a problem. if you would like to use two navbar's and the one needs the horizontal dropdown menu while the other needs the default CSS. The CSS override would effect both. But if you create a class you could use it on only the one element.
Hope this makes sense. Hard to spell check it from the mobile.

Related

How to display a custom loading bar and control it with custom directive in vuejs?

I want to display a loading bar inside a div tag and control its display with my custom directive in vuejs.
for example, this is my tag and I want to hide all of the content inside it and only show loading bar inside it.
template :
<div>
<div class="data-container" v-loading-spin="loading">
<!-- my content and other tags here -->
</div>
</div>
loading bar tag:
<div class="loading-spinner">
<!-- my loading bar -->
</div>
JS :
Vue.directive('loading-spin', {
bind: function (el, binding, vnode) {
if (binding.value == true) {
// how to display loading and hide other content
} else {
// how to display content and delete loading bar
}
}
});
how can I do that?
thanks.
I think it would be easier to use Vue Class binding to achieve that: https://v2.vuejs.org/v2/guide/class-and-style.html
<div v-bind:class="getClass">
</div>
computed: {
getClass() {
return this.loading ? 'loading-spinner' : 'data-container'
}

How to pass data for partial view using Jquery

I have next code:
#foreach (var offer in Model.Packages)
{
#Html.Partial("Search/PackageOffer", new Primera.Site.WebUI.Models.ViewModels.Search.PackageOfferViewModel
{
Package = offer,
DisplayPricePerPerson = Model.DisplayPricePerPerson,
RoomsCount = Model.RoomsCount
})
}
I need to implement infinite scroll using js. How can I call render partial view on js and pass parameters on it?
As a very basic demo, you want to have a Partial View that is returning some sort of html to you. In my case this is just the next 10 numbers based on the the number submitted:
public IActionResult _InfiniteNumbers(int lastId)
{
var Ids = Enumerable.Range(lastId, 10);
return PartialView(Ids);
}
In a real world scenario this would be the next n entities of whatever - blogs, orderitems, comments.
The view for this is fairly straight forward as well:
#model IEnumerable<int>
#foreach (var number in Model)
{
<li data-number="#number">#number</li>
}
it just renders every number as a list item.
My main view then looks like this:
<h1>InfiniteNumbers</h1>
<ul id="partial-view-container">
</ul>
<input id="btnLoadMore" type="button" name="loadMore" value="Load More numbers" />
#section scripts {
<script>
$(document).ready(() => {
$("#btnLoadMore").click(() => { //the trigger
var ul = $("#partial-view-container"); //our container for all partial views
let lastId = 0; //the lastId displayed
let lastLi = $("#partial-view-container li:last-child"); //find the last number
if (lastLi.length !== 0) {
lastId = lastLi.attr("data-number"); //if we found something set the value
//lastId = +lastLi.data("number");
}
$.get(`/Home/_InfiniteNumbers?lastId=${lastId}`) //call our action method
.then((res) => {
ul.append(res); //append the html to the container
});
});
});
</script>
}
We have a <ul></ul> element that serves as our container for infinite loading. Since I am lazy, I am using a button as the trigger. In a more complex scenario, this would be an event waiting for the scrollbar to reach the bottom of the page or something similar. I'll leave this up to you.
We then query the list for its last <li> item and get its data-number attribute.
After this, we query our action method and get the next 10 items based on that number and finally just inject them into our view.

How to add active class to tab's dynamically created navigation using Vue.js?

I'm attempting to add an active class to an element for tabs navigation using vue.js. The problem is, besides being new to Vue, the navigation items are dynamically created in a for loop as follows:
<c:forEach items="${tabnav.tabs}" var="tab" varStatus="loop">
<c:if test="${loop.count le tabnav.totalTabs}">
<li v-bind:class="{active : isActive}" v-on:click="tabSelected = ${loop.count}; isActive = !isActive">${tab.heading}</li>
</c:if>
</c:forEach>
the JS looks like this:
Vue.component('tabnav', {
data: function() {
return {
tabSelected: 1,
isActive: false
};
}
});
The problem is that this is toggling the class on ALL the items in the navigation rather than the one that was clicked.
Do I need to create a method for handling this?
Don't use isActive. Check to see if the tabSelected is equal to the current tab in the loop.
v-bind:class="{active : tabSelected === ${loop.count}}"

MVC DropDownListFor gets disabled after the first selection and post request

We have an old ASPNET MVC application designed using Kendo(v4.0.30319). In the view I am using DropDownListFor to populate a list of items. The way the webpage works is after selecting an item from dropdown, there will be an ajax call to load data into grid.
My problem is when the page gets loaded for first time, dropdown is populated and I am able to select the item and load the grid. But, once it's loaded the dropdown is inactive/disabled and I am not able to select any other item.
Here is the snap of webpage
Here is the code block from my view:
<div class="col-sm-9 col-md-8 col-lg-9">
#Html.DropDownListFor(model => model.company_id, new System.Web.Mvc.SelectList(Model.CompanyList, "company_id", "company_name"), new { #class = "form-control", #id = "ddlCompany" })
</div>
The script block is:
$(document).ready(function () {
$('#ddlCompany').change(function () {
$("#CompanyConnectorPropertyGrid").data("kendoGrid").dataSource.read({ "companyConnectorID": 0 });
$('#dvGrid').hide();
$('#dvMessage').html('');
if ($('#ddlCompany').val()) {
BindConnectorDropdown();
}
else {
$('#dvGrid').hide();
}
});
$('#ddlConnector').change(function () {
$('#dvMessage').html('');
if ($('#ddlConnector').val() && $('#ddlConnector').val() > 0) {
$("#CompanyConnectorPropertyGrid").data("kendoGrid").dataSource.read({ "companyConnectorID": $('#ddlConnector').val() });
$('#dvGrid').show();
}
else {
$('#dvGrid').hide();
}
});
var connectorID = getParameterByName('cid');
if (connectorID) {
$("#ddlConnector").val(connectorID);
$('#ddlConnector').trigger('change');
}
});
There is nowhere it's mentioned to disable the dropdown.
I want the dropdown to be active so that I can select a diffrent item , bind it and get data. Any help to solve the problem would be appreciated. Thanks in advance.

load a cshtml file (razor) in the iframe

I have in my Layout page (Menu + Iframe)
and i want to load a cshtml files (view pages) in the iframe after the click in the menu.
the goal is not to load the entire Layout page
I tried this way:
<ul id="qm0" class="qmmc">
<li><a class="qmparent" >FILES</a>
<ul class="rgauche">
<li>#Html.ActionLink("USERS","getUsers")</li>
<li><a id="disconnect">Deconnexion</a></li>
</ul>
</li>
</ul>
but it loads the entire layout page
I had this idea from another ASP.NET project that uses javascript to load a .aspx page in the iframe after the click on the menu
<ul id="qm0" class="qmmc">
<li><a class="qmparent" >FILES</a>
<ul class="rgauche">
<li><a id="getuser">USERS</a></li>
<li><a id="disconnect">Deconnexion</a></li>
</ul>
</li>
</ul>
$(function () {
$('#getuser').click(function () {
document.getElementById('myIframe').src = "users.aspx";
return false;
});
});
Any ideas ?
You have to point the "src" attribute of the iframe to a controller action that returns the view.
For ex.
Action that returns the partial view without layout
public PartialViewResult IframeAction()
{
return PartialView();
}
Javascript
$('#getuser').click(function ()
{
document.getElementById('myIframe').src
= "/IframeController/IframeAction";
return false;
});
Load the view thru an action method. In this view, set the Layout value to null so that it wont use the layour defined in viewstart.cshtml
#{
Layout=null;
}
<p>some partial view content</p>
EDIT :
Not quite sure what you want to achieve. But If you want to update the Iframe content inside the Layout you can do like this
Assuming your Layout.cshtml is like this
<head>
//Load jQuery library
</head>
<body>
#Html.ActionLink("List", "GetUsers", "Users", null, new { #class = "iframable" })
<iframe id="ifrm" style="width:500px; height:200px; border:1px solid black;">
</iframe>
#RenderBody()
<script type="text/javascript">
$(function () {
$(".iframable").click(function (e) {
e.preventDefault();
var item = $(this);
$("#ifrm").attr('src', item.attr("href"));
});
});
</script>
Now have the GetUsers action method in your Users controller
public ActionResult GetUsers()
{
return View();
}
and make sure in the GetUsers.cshtml view, the layout is set to null
#{
Layout=null;
}
<p>some partial view content</p>
you need a different layout for the page you are loading within the iframe.
Then, within this page, you can do
#{
Layout = "YourLayout.cshtml";
}
By default all your cshtml views are using the layout provided in the _ViewStart.cshtml
EDIT
You can use the following concept:
<iframe name="my_frame"></iframe>
#Html.ActionLink("Users", "GetUsers", null, new { target = "my_frame" })
You give your iframe a name, and then use the name as the target for your action link. Thats the simplest solution. if you prefer, you can also use jquery click handler, as provided in one of the other answers.

Categories