This is within Sitefinity if that matters, and I am really new at ASP.NET and C#.
I have an image-based navigation element at the bottom of a page that links to different articles using the same template. There are 5 articles, and I would like the link to the active page/article to be hidden so there is a grid of 4 image links.
Here's a screenshot:
https://i.imgur.com/PG2Sfpo.png
Here is the code behind it:
#{
string navTitle = string.Empty;
string url = string.Empty;
if (Model.CurrentSiteMapNode != null && Model.CurrentSiteMapNode.ParentNode != null)
{
if (Model.CurrentSiteMapNode.Title == "Home")
{
navTitle = Model.CurrentSiteMapNode.ParentNode.Title;
}
else
{
navTitle = Model.CurrentSiteMapNode.Title;
}
url = Model.CurrentSiteMapNode.ParentNode.Url;
}
}
<div class="foundation-stories-container">
#foreach (var node in Model.Nodes)
{
#RenderRootLevelNode(node);
}
</div>
#*Here is specified the rendering for the root level*#
#helper RenderRootLevelNode(NodeViewModel node)
{
string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";
<a href="#node.Url" target="#node.LinkTarget">
<div class="foundation-story-block">
<div class="hovereffect">
<img src="[OUR WEBSITE URL]/stories/#thisImage" class="img-fluid">
<div class="overlay">
<h2>#node.Title</h2>
</div>
</div>
</div>
</a>
}
So we're already getting the page URL and image file name
string[] thisPage = (node.Url).Split('/');
string thisImage = thisPage[4] + ".jpg";
Is this as easy as doing the following?
if (thisImage = thisPage)
{
foundation-story-block.AddClassToHtmlControl("hide")
}
Seems easy enough, but I don't know where to start.
I'm better at Javascript, so I do have a JS solution in place for this already, but I'd really like to find a cleaner way to do it.
<script type="text/javascript">
$(document).ready(function() {
var active = window.location.pathname.split("/").pop()
var name = active;
name = name.replace(/-/g, ' ');
jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
return function( elem ) {
return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >=
0;
};
});
$("h2:Contains('" + name + "')").closest(".foundation-story-block").addClass("hide");
});
</script>
This exists on the main template page.
Gets the last part of the URL
Sets that as a variable called "name"
Changes the dash to a space if there is one (most of the pages are associated with names so it's like /first-last)
Then it goes and looks at the which is where the title of the page lives, and if it equals the "name" variable, the ".hide" class is added to the block.
Thanks for any help anyone can provide.
You could bind a click event to your elements with the foundation-story-block class. The reason I use .on instead of .click is because when using UpdatePanels the click event won't fire after an UpdatePanel has it's update event triggered - you might encounter a similar problem with your dynamic binding so I used .on to avoid this.
$(".foundation-story-block").on("click", function() {
// Remove the "hide" class from any elements that have it applied
$.each($(".foundation-story-block.hide"), function(index, value) {
// Remove the class using the "this" context from the anonymous function
$(this).removeClass("hide");
});
// Add the "hide" class to the element that was clicked
$(this).addClass("hide");
});
I haven't run this though an IDE so it might not be 100% correct but it will put you on the correct path.
It is possible, yes. Here is how:
...
#{
var hiddenClass = thisImage == thisPage ? "hide" : string.Empty;
}
<div class="foundation-story-block #hiddenClass">
<div class="hovereffect">
<img src="[OUR WEBSITE URL]/stories/#thisImage" class="img-fluid">
<div class="overlay">
<h2>#node.Title</h2>
</div>
</div>
</div>
I haven't worked so much with jquery, ajax and json before, but I want to learn how to use it using dojo and dijit. There are many tutorials, but few c# with sql database examples.
I've created a json output with dijit menubar data from my database which looks like this:
[{"MenuItemId":1,"MenuName":"Root","Tooltip":"Root","IsParent":true,"ParentId":0,"IsVisible":false,"SortIndex":null},
{"MenuItemId":3,"MenuName":"Blogg","Tooltip":"Min Blogg","IsParent":false,"ParentId":1,"IsVisible":true,"SortIndex":1000},
{"MenuItemId":4,"MenuName":"Administrasjon","Tooltip":"Viser Administrasjon","IsParent":true,"ParentId":1,"IsVisible":true,"SortIndex":10000},
{"MenuItemId":5,"MenuName":"DropMenu","Tooltip":"Drop menu","IsParent":true,"ParentId":1,"IsVisible":true,"SortIndex":9000},
{"MenuItemId":6,"MenuName":"Menuitem1","Tooltip":"Menuitem1","IsParent":false,"ParentId":5,"IsVisible":true,"SortIndex":9001},
{"MenuItemId":9,"MenuName":"Menuitem2","Tooltip":"Menuitem2","IsParent":false,"ParentId":5,"IsVisible":true,"SortIndex":9002}]
I want to bind these data to dijit menubar, but I haven't figured out how to doo it yet.
Here is the code I've made so far. I've been trying back and forth, but I haven't managed to get data out from the json data I try to get.
Here is a sample in where I try to get data out of my json data output. The sample is trying to write data in console view, but I want to populate a dijit manybar:
<script>
require([
"dijit/MenuBar",
"dijit/PopupMenuBarItem",
"dijit/Menu",
"dijit/MenuItem",
"dijit/DropDownMenu",
"dojo/dom",
"dojo/request",
"dojo/json",
"dojo/_base/array",
"dojo/domReady!"
], function(MenuBar, PopupMenuBarItem, Menu, MenuItem, DropDownMenu, dom, request, JSON, arrayUtil) {
console.log('hello world');
// Results will be displayed in resultDiv
var resultDiv = dom.byId("resultDiv");
// Request the JSON data from the server
request.get("/api/Menu", {
// Parse data from JSON to a JavaScript object
handleAs: "json"
}).then(function(data) {
// Display the data sent from the server
var html = "";
var pMenuBar = new MenuBar({});
var pSubMenu = new DropDownMenu({});
console.log('data : ' + data.toString());
arrayUtil.forEach(data.items, function(item, i) {
console.log(item[0].value);
//console.log('item :' + item.name + '\r\n');
//console.log('value : ' + item.value + '\r\n');
});
//html += "<dt>" + item.name +
// "</dt><dd>" + item.value +
// " (" + (typeof item.value) + ")</dd>";
//});
//resultDiv.innerHTML = html;
//pMenuBar.placeAt("wrapper");
//pMenuBar.startup();
},
function(error) {
// Display the error returned
resultDiv.innerHTML = error;
});
});
</script>
What I need is a an example in how to iterate json data to populate dijit menubar.
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'sidebar', gutters:true, liveSplitters:true" id="borderContainer">
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="splitter:true, region:'leading'" style="width: 300px;">
<div id="markup" style="width: 300px; height: 300px"></div>
</div>
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="splitter:true, region:'center'">
<div id="wrapper"></div>
<div id="resultDiv"></div>
</div>
</div>
</body>
I could really use some help on this one. Thanks for all the advice I can get.
Thank you! :)
Kind regards,
Jon Haakon
I think I would make a recursive function that burrows down into the JSON structure you receive from the server, and builds menu items along the way.
Annoyingly, there is a small difference between items in the menu bar itself, and items in submenus belonging to the menu bar. The menu bar wants dijit/PopupMenuBarItem and dijit/MenuBarItem objects, while the popup menus themselves want dijit/PopupMenuItem and dijit/MenuItem, correspondingly.
Here's an example:
function recursiveMakeMenuItem(data, id, inMenuBar) {
// Get the item itself and its children (if any)
var item = arrayUtil.filter(data, function(i){return i.MenuItemId==id;})[0],
subs = arrayUtil.filter(data, function(i){return i.ParentId==id;}),
widget = null, menu = null;
if(subs.length) {
// This item has children, so we need to make both an item that
// triggers the a submenu (differentiating between items in the
// menu bar and items in menus) and the submenu itself.
widget = inMenuBar ? new PopupMenuBarItem() : new PopupMenuItem();
menu = new Menu();
widget.set("popup", menu);
// We then recursively dig deeper to generate the sub menus.
arrayUtil.forEach(subs, function(item) {
menu.addChild(recursiveMakeMenuItem(data, item.MenuItemId));
});
}
else {
// No children, but again we need to differentiate between items
// in the menu bar and items in menus.
widget = inMenuBar ? new MenuBarItem() : new MenuItem();
}
widget.set("label", item ? item.MenuName : "ERROR id "+id);
return widget;
}
In your code, you would call this when you receive data from the server. For example, if you wanted the single item with ParentId 0 to be the top level menu bar item, you could do:
request.post("/echo/json/", {
handleAs: "json"
}).then(function(data) {
var pMenuBar = new MenuBar({region: "top"});
pMenuBar.addChild( recursiveMakeMenuItem(data.items, 1, true) );
dijitRegistry.byId("borderContainer").addChild(pMenuBar);
pMenuBar.startup();
});
Or, if everything with ParentId 1 should be top level items:
request.post("/echo/json/", {
handleAs: "json"
}).then(function(data) {
var pMenuBar = new MenuBar({region: "top"});
arrayUtil.forEach(data.items, function(i) {
if(i.ParentId !== 1) return;
pMenuBar.addChild(recursiveMakeMenuItem(data.items, i.MenuItemId, true));
});
dijitRegistry.byId("borderContainer").addChild(pMenuBar);
pMenuBar.startup();
});
Here's an example fiddle: http://fiddle.jshell.net/2Gpkd/1/
I am tryong to do the following in a Row_Command event of a gridview. But the the pop up box never comes up, I have tried it in so many different ways.. but yet no luck. Please if someone can see the issue i would really appreciate a pointer.
protected void Gridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName == "Merchant")
{
if (ItemsAvailable)
{
StringBuilder sb = new StringBuilder();
MyClass class = new MyClass();
TList<LineItems> otherItems = MyClass.GetItems(id);
bool IsNotAvailable = false;
foreach (LineItems item in otherItems)
{
Merchandise skuMerchandise = skuMerchandise.GetMerchandise(otherItems.mid);
if (skuMerchandise != null)
{
if (skuMerchandise.AvailableItems <= 0)
{
sb.Append(OtherItems.Name);
sb.Append(Environment.NewLine);
IsNotAvailable = true;
}
}
}
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"function Redirect() {location.href = 'homePage.aspx';}
if(confirm('The items : "+sb.ToString()+" will arrive in 1 month.
Do you wish to continue?') == true){Redirect();};", true);
}
}
}
Everytime i click the button, it just passes like nothing.. never prompts eveb though IsNotAvailable is true when I add a breakpoint.
You can go for a simpler way,
Define the javascript function in the design/separate script file so that it accepts the name of item. eg. myFunction(itemName)
And in your CS file, simply add a call to that function,
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
"myFunction('" + itemName + "')
}
}
It will make things simpler and you would be able to confirm if this is a Javascript issue or a problem in how you are writing it through CS file.
Update:
Your first goal should be to make sure that your JS function is working for you, so before anything, add the following code in an empty html file and run it,
<script type='text/javascript'>
ItemNotInStock('item');
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
If you redirect correctly then do what's mentioned below.
Define the following javascript in your design file(tested it locally, working for me in chrome,)
<script type='text/javascript'>
function ItemNotInStock(itemName)
{
var message = "The following items are no longer in stock :" + itemName + ".
Would you like to continue?";
if (confirm(message) == true)
{ location.href = "homePage.aspx"; }
}
In your C# code, add following line
if (IsNotAvailable)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "key",
string.Format("ItemNotInStock('{0}');", itemName);
}
}
Make sure your JavaScript code is executed by using breakpoints available in the developer tools of the browser of your choice, like Chrome Developer Tools: Breakpoints
BTW: Why do you create an instance of Merchandise if you instantly discard it with the next line?
I'm creating javascript Variable using c#.net inside code behind page and putting that variable on page using Page.ClientScript.RegisterClientScriptBlock(). So that variable is available on page and I can read(get) that variable value on client side using jquery.
I'm doing following:
C# :
category_columnNames += "var vertical_" + catItem.VerticalID + "_columnNames=['Tools','PersonID','Topic','Category','Cost','Company']";
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "LoadColumnNames", category_columnNames, true);
By doing this let's say :var vertical_1_columnNames=['Tools','PersonID','Topic','Category','Cost','Company']; is on page. Now I want to first check if that variable(vertical_1_columnNames) exists on page or not. If yes then I need to get value of it (['Tools','PersonID','Topic','Category','Cost','Company']) on client side.I'm doing following on client side:
Client Side :
function ViewCartDirectLeadsGridInit(gridID) {
alert(gridID);//vertical_1_CategoryGrid
var vertical = gridID.toString().split('_')[1];
var columnNames = "vertical_" + vertical + "_columnNames";
alert(columnNames); // vertical_1_columnNames
alert(typeof(columnNames));// string
alert(eval(columnNames)); // ['Tools','PersonID','Topic','Category','Cost','Company']
if (!window.columnNames) // This is not working.I want to check for existence of var vertical_1_columnNames
{
alert("success");
return false;
}
else{
// do something;
}
}
Any suggestion?
Thanks,
A
window.columnNames will search for a variable named "columnNames" not "vertical_" + vertical + "_columnNames". Use window[columnNames].
I use C#.net.
I wrote JavaScript for hide and show expand and collapse div accordingly. It work well in IE but not on Firefox, not even call the JavaScript function and gives me error as Error: ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse is not defined.
My JavaScript is as follows
function displayDiv(divCompact, divExpand) {
//alert('1');
var str = "ctl00_cpContents_";
var divstyle = new String();
// alert("ibtnShowHide" + ibtnShowHide);
divstyle = divCompact.style.display;
if (divstyle.toLowerCase() == "block" || divstyle == "") {
divCompact.style.display = "none";
divExpand.style.display = "block";
// ibtnShowHide.ImageUrl = "images/expand_img.GIF";
}
else {
// ibtnShowHide.ImageUrl = "images/restore_img.GIF";
divCompact.style.display = "block";
divExpand.style.display = "none";
}
return false;
}
ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse is an element id generated by ASP.NET. It's a profiledetailscollapse control inside dlSearchList.
JavaScript variable "ctl00_cpContents_dlSearchList_ctl08_profiledetailscollapse" is not
defined. Firefox does not automatically create, for each element with an id, a
variable in the global scope named after that id and containing a reference
to the element.
You might want to consider using jQuery to make sure that your DOM manipulation is cross-browser compatible.