Control Layout Rendering from Child Pages - asp.net

I have a layout page and, for the moment, one page that uses that layout. I would like to have a portion of the page that can be shown or hidden at the child pages discretion. If it is hidden, then other style changes, like the width of the main content div, need to be adjusted. Below is my non-working attempt at this:
Layout page
#{
Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.ShowTree = true;
}
<div class="row">
#if(ViewBag.ShowTree){
<div class="col-md-2">
#Html.Action("ItemTree")
</div>
}
<div class="#(ViewBag.ShowTree ? "col-md-10" : "col-md-12")">
#RenderBody()
</div>
</div>
Child Page
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_NestedLayout.cshtml";
ViewBag.ShowTree = false;
}
In this instance the value for ShowTree is set to true, the layout page renders, and then the child sets it to false and the content renders. This makes perfect sense based on the page life cycle for MVC. But of course is not how I want it to work.
I know I could set this value in the controller, and not set it in the layout/web page at all, but I'd like to have this be purely a design thing if I can and keep it out of the controller.
My preference would be for it to not call the action at all, and not just hide the data with JavaScript.

I like your approach, but if that doesn't work, the only other mechanism I can think where the child view can control the layout would be using #section. Not ideal, but should work.
Layout page:
<div class="row">
#RenderSection("ItemTreeSection", required: false)
<div class="#(ViewBag.ShowTree ? "col-md-10" : "col-md-12")">
#RenderBody()
</div>
</div>
Child view:
#section ItemTreeSection {
<div class="col-md-2">
#Html.Action("ItemTree")
</div>
}

Related

How do I pass data up from the child page to the page calling #Body?

So I have a MainLayout with a title bar, and I want to have a parameter that allows the page to set the title bar to whatever it wants. So mainlayout calls the page through #Body, I'm confused how I would pass data up through body to the mainlayout to update the title bar.
Any help would be greatly appreciated!
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<h3 bind="#TitleValue">#(TitleValue)</h3>
<a class="ml-md-auto">#ADService.LoggedUser().DisplayName (#*#(ADService.LoggedUser().IsMemberOf())*#Admin)</a>
</div>
<CascadingValue Value="#TitleValue" Name="TitleValue">
<div class="content px-4">
#Body
</div>
</CascadingValue>
</div>
<Footer />
#functions {
string TitleValue = "Inventory";
}
So what I want to do is pass the TitleValue down, have the page update it depending what is happening and have the title bar update with the new value.
If this isn't the way to do it, or I'm missing something, any help would be great :)
I guess the following, which is not mine, can help you:
Create a class which holds your data. Register it as singleton
service. Inject it into layout and into page. You should probably add
a notification mechanism to inform all your components that something
was changed in your data class.
You can look here...
Source and more...

How to display subsites of a page within grid columns of the grid layout on GetGridHtml() using Umbraco

I come across a issue on umbraco, suggest me how I can bind the subsites of a page within a grid layout of what I set as DataType. kindly do reply how to do it.
note:
I don't want to use strongly-typed model to implement grid layout.
#CurrentPage.GetGridHtml(Umbraco.AssignedContentItem,"postTiles",
"bootstrap3")
#CurrentPage.GetGridHtml(#Umbraco.RenderMacro("ArticlesList"),"postTiles","bootstrap3")
//ArticlesList
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{ var selection = CurrentPage.Children.Where("Visible").OrderBy("CreateDate desc"); }
<section class="container">
<div class="row">
#foreach (var item in selection)
{
<div class="col-md-3">
<img src="#Umbraco.Media(item.ArticleFeaturedImage).Url" style="width: 200px; height: 120px;" />
<h3>
#item.Name
</h3>
<p>
— posted under #item.ArticleCategory
· #String.Format("{0:dddd, MMMM d, yyyy}", #item.CreateDate)
· by #item.WriterName.ToString().ToLower()
</p>
<p>#Umbraco.Truncate(#item.ArticleDescription,100)</p>
</div>
}
</div>
</section>
If you want to have a custom rendering of some content in the Grid, you need to either:
Use a Macro and have content editors pick the Macro in the Grid
Create a custom property editor and specific the rendering partial in the package.manifest
Use a grid editor tool such as LeBlender or DocType Grid Editor to create a custom editor and assign a custom partial for rendering
I'm not sure exactly if that's what you're looking for, but I think these may get you on the right track.

Partial view for container

Say, I'm using often the following HTML in ASP.NET MVC application:
<div class="a">
<div class="b">
(varying content)
</div>
</div>
I'd like to put the repeating div part to a separate file and reuse it (notice, that the content may, and will change). How can I do that?
Keep it in a partialView, eg: _CommonDiv
call Partial view from your view
#Html.Partial("_CommonDiv", null, new ViewDataDictionary {{ "yourvaringcontentKey", yourcontent}})
get content in partialView
string yourcontent= (string)this.ViewData["yourvaringcontentKey"];
And use the same where you want.
In your web application add App_Code\Helpers.cshtml
Paste the code below inside Helpers.cshtml
Helper code:
#helper DivHelper(string text)
{
<div class="a">
<div class="b">
#text
</div>
</div>
}
Now you can call this helper in any of your views using #Helpers.DivHelper("Some text...") and because the logic is inside App_Code no using statements are required!

CSS that operates like a boolean AND for multiple complex selectors?

I'm writing a Stylish user style sheet, and am trying to see if something is possible. I am customizing a page that has a structure like this:
<div class="main">
<div class="someExtraLayers">
<div class="page">
1
</div>
</div>
<div class="someOtherLayers">
<div class="post">
blah blah
</div>
<div class="post">
foo foo
</div>
<div class="post">
bar bar
</div>
</div>
</div>
Where 'someExtraLayers' and 'someOtherLayers' indicate a few levels of divs inside divs. I'm not fully replicating the page's structure here for brevity's sake.
I have this in my user CSS:
div.post:nth-child(1) {
display:block !important;
}
Essentially, I'm making visible the first post element, and this does most of what I want to do. The thing I want to add is that I only want to make that element visible if the content of the page class is 1. If it's not 1, then I don't want to display the first post element.
CSS doesn't seem to offer conditionals, or boolean ANDs, that work this way. But I'm still new-ish to CSS, so I might be missing something. If I have to use a Greasemonkey script instead, I'll do that, but I was hoping there's some CSS trickery that will let me accomplish this.
Stylish cannot do this because Stylish just injects CSS and CSS does not have a selector for text content.
To do what you want, you will have to install Greasemonkey (Firefox) or Tampermonkey (Chrome) and then a userscript can set that visibility.
Assuming that div contains only 1, then something like this complete GM/TM script will do what you want. It uses the awesome power of jQuery selectors.
You can also see a live demo of the code at jsFiddle. :
// ==UserScript==
// #name _Show the first post on page 1
// #include http://YOUR_SERVER.COM/YOUR_PATH/*
// #require http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// #grant GM_addStyle
// ==/UserScript==
var pageHasOne = $("div.main:has(div.page:contains(1))");
pageHasOne.each ( function () {
var jThis = $(this); //-- this is a special var inside an .each()
var pageDiv = jThis.find ("div.page:contains(1)");
if ($.trim (pageDiv.text() ) == "1") {
//--- Show the first post div. !important is not needed here.
jThis.find ("div.post:first").css ("display", "block");
}
} );
Given the logic that jQuery javascript must use, we can see part of the reason why CSS doesn't attempt to provide selectors for this. It's beyond mission scope for CSS, but the kind of thing that javascript was made for.
Also note that this is for a static page. If the page uses AJAX for its content, the logic becomes a bit more involved.
CSS can not access HTML content.
To solve the problem, you will also need to add a class so CSS can "see" it:
HTML:
<div class="main one">
<div class="someExtraLayers">
<div class="page">
1
</div>
</div>
<div class="someOtherLayers">
<div class="post">
blah blah
</div>
<div class="post">
foo foo
</div>
<div class="post">
bar bar
</div>
</div>
</div>
CSS:
.one .post:nth-child(1) {
display:block !important;
}

angular js dom manipulation with directives

I am trying to use angular directives to dynamically replace an html portion of a portlet of a page.
The html portlet has 2 sections embedded. The top part has the heading which is obtained from a different backend service
<div class="headerdiv">
<h3 class='headerclass'> Object Heading </h3>
</div>
The content is loaded in to a different section
<div id="objectDiv" ng-controller="ObjectCtrl">
<div ng-show="object.title" mydirective><b>{{object.title}} </b></div>
<div element-trigger><b>{{object.name}} </b></div>
<div element-trigger><b>{{object.description}} </b></div>
</div>
The controller loads the details successfully
The new directive added is
app.directive('mydirective', function(){
return function(scope, elem, attrs){
//obtain old header
var oldHeader = angular.element( '.headerdiv .headerclass' );
//get the new header
//replace old header with new header
}
});
I need to dynamically change the heading in headerdiv with the object.title value . Note that the new directive is bound to the filed that is listening to the object.title div.
I dont think this is the right use of directive, as the directive should be used to affect the functionality of element on which it is defined in most of the cases.
What you can try to do is in ObjectCtrl define a watch on title property, and then broadcast the message
$scope.$watch('object.title',function(newValue) {
$rootScope.$broadcast('titleChanged',newValue); //You can pass any object too
});
If you header is contained inside a controller catch the event
$scope.$on('titleChanged',function(args) {
//Code to handle the title update
});
The html for header should have binding expression for title
<div class="headerdiv">
<h3 class='headerclass'> {{title}} </h3>
</div>
Note: I am not sure about the structure of the html but this all would not be required if the header and the content inside the ObjectCtrl are using the same\shared model (object).

Resources