Dynamic loading a list from a model MVC 4 - c#

so I'm still pretty new in ASP.net MVC design. I am facing a small problem, which might have already been answered, but don't seem to find an answer that will fit my purpose. Here is what's happening:
Say I have a model with 2 links: Category & Item, and it's a 1 to many relation. What I want to do is generate a list containing Category.Title (which I have completed, using the code following) and clicking on the each list item will generate a list of all Item.Title values of that category. The base idea of the html is:
<div id="cat"><!--float = left-->
<ul>
<li>List<li>
</ul>
</div>
<div id="item"> <!--float = right -->
<ul>
<li>List<li>
</ul>
</div>
Here is how everything is linked up so far:
public ActionResult Equipment()
{
ViewBag.Cat= getCat(1); // Will return a list of categories of ID 1
return View();
}
As for the view:
#{ List<X.Models.Category> catX = ViewBag.Cat; }
BODY:
<div id="pl_categories">
<ul id="pl_ec_ul">
#foreach (X.Models.Category item in catX)
{
<li id="pl_ec_li">
<div id="pl_ec_liItem">
#item.catTitle
</div>
</li>
}
</ul>
</div>
<div id="pl_values">
<ul id="pl_ev_ul">
<li id="pl_ev_li">
<div id="pl_ev_liItem">
???
</div>
</li>
</ul>
I have seen a bunch of examples, but they all involve dropdowns or what not. Here are a quick checklist of what I am trying to accomplish:
On page laod, default selected category will be the first in the list. If list is null, a simple "No Categories" is shown. Edit: if the category is empty, it will show No Items in Category.
On clicking an item in the category it will show the items of that category under pl_values.
I have tried to make this is small as possible but there are a lot more factors I need to consider. However, if I can solve this, I am certain to figure out the rest. If something however is not clear, please let me know and I can try and clarify it. Any help will be appreciated. Thank you.

For your item 1, you could try something like this (assuming your OK using jQuery):
$(document).ready(function() {
var count = $("#pl_ec_ul li").length;
if(count <= 0) {
$("#pl_categories").html("<p>No Categories</p>");
}
});

Related

C# MVC System.StackOverflowException

I am getting this error, I believe that it is because I have one two many Html.RenderAction(); on my home page. On top of a few #Html.Partial() My site is fine if I remove the last one I put in. Which is bringing up a list of Operating hours from a table. I have 2 on the footer one to show recent posts and the hours. The Footer is on a Partial page. In total there are Login Partial, Cart Summary -- RenderAction, and Footer Partial on the main Layout page plus of course RenderBody(). The Index page has 2 partials on it so far and was planning on using more. All of these have models to tables attached to them from tables. I get the error on the login Partial and sometimes on the blog posts. If I comment out the one I just made it works fine. And navigating to the page itself works with no errors. At first I had it as a partial page in the shared folder and it just doesn't show up. I have done all of these,
public ActionResult _Hours()
{
var hrs = db.OperatingHours.OrderBy(x => x.SortOrder).ToList();
return PartialView(hrs);
}
public ActionResult Hours()
{
var hrs = db.OperatingHours.OrderBy(x => x.SortOrder).ToList();
return View(hrs);
}
Is there a work around for this?
The issue was as David mentioned above in the comments, I had an infinite loop in my view code. Below is how it originally was written.
<ul class="list-border">
#foreach (var item in Model)
{
<li class="clearfix">
#if (item.SelOpen == true)
{
<span>#if (item.ShowSelect == true)
{<text>Select</text>} #item.Day : </span>
<div class="value pull-right flip"> #item.OpenTime #if (item.ShowBreak == true)
{<text>-</text> #item.BreakTime} - #item.CloseTime </div>
}
#if (item.SelClosed == true)
{
<span> #item.Day : </span>
<div class="value pull-right flip"> Closed </div>
}
</li>
}
</ul>
Below is the code that it was changed to for it to work.
<ul class="list-border">
#foreach (var item in Model)
{
<li class="clearfix">
#if (item.SelOpen == true)
{
<span>#if (item.ShowSelect == true)
{<text>Select</text>} #item.Day : </span>
<div class="value pull-right flip"> #item.OpenTime #if (item.ShowBreak == true)
{<text>-</text> #item.BreakTime} - #item.CloseTime </div>
}
else
{
<span> #item.Day : </span>
<div class="value pull-right flip"> Closed </div>
}
</li>
}
</ul>
I normally code the above way with `if(){ }else{}. And I guess I have done it the other way as well, but not in a foreach loop.. Lesson learned.

Hide <li> element if a scope value is null

I want to hide certain items in my list depending on whether a scope value is null.
This is my controller:
angular.module("umbraco").controller("my.custom.grideditorcontroller", function ($scope) {
$scope.control.heading;
$scope.control.punkt1 = null;
$scope.control.punkt2 = null;
$scope.control.punkt3 = null;
$scope.control.punkt4 = null;
$scope.control.punkt5 = null;
});
I have 5 li elements as well, that I want to show/hide depending on whether each of these scope properties has
This is one of my li elements:
<li ng-hide="control.punkt5 == null">#Model.punkt5</li>
This doesn't work, as the element is still being shown.
My properties use 2-way binding with my input elements:
<input type="text" ng-model="control.punkt1" placeholder="Indtast første punkt...">
But the input and the li elements are located in 2 separate HTML documents, since I am creating a grid editor for Umbraco.
This is my folder structure: https://i.imgur.com/ZbejcOl.png
Where the infobox.cshtml file contains the li elements, and the infobox.html file contains the input elements.
I tried using razoe code in my ng-hide/show condition, but that didn't return any boolean values. What is the correct way to approach this without using razor?
My render view (infobox.cshtml) receives a dynamic model of type JObject, but I can't use any of its methods in my ng-hide condition as it is c#. I've tried everything as mentioned in my previous post.
Edit:
<div ng-controller="my.custom.grideditorcontroller">
<div class="list-group">
<div class="list-group-item">
<h4 class="list-group-item-heading">#Model.heading</h4>
<ul class="ul-with-bullets">
<li ng-show="IsProperty(#Model,'punkt1')">#Model.punkt1</li>
<li ng-show="#Model.GetType().GetProperty("punkt2") != null">#Model.punkt2</li>
<li ng-show="#Model.GetType().GetProperty("punkt3") != null">#Model.punkt3</li>
<li ng-show="#Model.GetType().GetProperty("punkt4") != null">#Model.punkt4</li>
<li ng-hide="control.punkt5">#Model.punkt5</li>
</ul>
</div>
</div>
</div>
use this code
$scope.control={
punkt1:null,
punkt2:null,
punkt3:null,
punkt4:null,
punkt5:null
};
and now in your view you can check your control properties

Select an ID if it's a number?

Is there a way to select a list item from an aspx file from a .cs file to make the <li> visible. The ID for the <li> are numbers.
The reason why they are numbers is because this page is a custom view editor for the website, it is updating a database and then loads the correct view for the user. I need to hide some items for certain users on this page.
Snippet from aspx page:
<div id="connectedSortableLists">
<ul id="unselected" class="connectedSortable">
<li class="ui-state-highlight" id="0">Log #</li>
<li class="ui-state-highlight" id="19">Log date</li>
</ul>
</div
I've tried adding in runat="server" to various places however had no luck.
Is there a way to select like for a grid-view like : grdv_dummy.Columns[29].Visible = false; ?
I want to select the li by an ID to set the visibility to false to do it server side based on user. When the new custom view is saved, database will be updated with the id number. When I try with id="item" the desired page tries to load I get the error Input string was not in a correct format; due to the database having an entry of 'item'.
I feel as though i'm overlooking something although more likely completely wrong.
Thank you for your time
You will definitely need runat=server on your li elements (or ul element). Then you need to add letters to your ids - you can't have just numbers as an id. So something like "item". Then in you .cs file use something like:
private HtmlElement FindListItem(int id)
{
HtmlElement listItem = this.FindControl("item" + id.ToString()) as HtmlElement;
if (listItem != null && listItem.TagName == "li")
{
return listItem;
}
return null;
}
Basically FindControl() is what you need. Then you can use it like:
var item = FindListItem(19);
if (item != null)
{
item.Visible = false;
}
Oh an depending on how you've setup your code, you'll use it either in Page_Load or onPreRender...
you cannot directly access it in server side.However, you can call javascript function from server side which can enable\disable it.
At server side
string jsFunc = "DisableHtmlLi(" + iterator + ")";
ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "DisableHtmlLi", jsFunc, true);
At Client side
<script type="text/javascript" language="javascript">
function DisableHtmlLi(index) {
var element = document.getElementById(index);
element.visible= false;
}
</script>
Managed to find a way round the problem. I know that li shouldn't be put in other li , but it worked for me.
ASPX Altered
<div id="connectedSortableLists">
<ul id="unselected" class="connectedSortable">
<li class="ui-state-highlight" id="0">Log # </li>
<li class="ui-state-highlight" id="19">Log date</li>
<li runat="server" id="full" visible="false">
<li class="ui-state-highlight" id="32">Days Country</li>
<li class="ui-state-highlight" id="33">Days total</li>
</li>
</ul>
</div
.CS Page
full.Visible = true;

Extract text from a div

I am trying to make a DropDownList using divs and jquery (so that I can style it as I want)...and its working but the problem is I cant get the selected value from the list..
After selection of the option I am copying the selected value into the a div.. and I want to extract this using c# (in .aspx.cs page)... I've tried to do it using string builder and innerHtml(after adding runat="server" to the div).. but it doesn't work ...code is as follows
.aspx Page:
<div class="ddl">
<div id="lowertriangle" class="lowertriangle"></div>
<div id="uppertriangle" class="uppertriangle"></div>
<div id="label" class="labeldiv_dd" runat="server"></div>//***This is the div from which I want to extract value***
<div id="options" class="optionsidv_dd">
<ul id="options_ul">
<li id="0">Select One Option</li>
<li id="1">Option 1</li>
<li id="2">Option 2</li>
<li id="3">Option 3</li>
<li id="4">Option 4</li>
<li id="5">Option 5</li>
</ul>
</div>
</div>
aspx.cs page
Method 1 that I tried:
string sel_text = label.InnerHtml;
display_sel_value.Text = sel_text.ToString();
2nd method:
var sb = new StringBuilder();
label.RenderControl(new HtmlTextWriter(new StringWriter(sb)));
string s = sb.ToString();
Kindly point out my mistakes and help me in this regard(in extracting innerHTML of the div that is).
Thanks
No, putting content in a div won't work.
Your example isn't complete enough to see all that happens, but let's assume that you're in a standard <form>, you're setting the div's inner HTML to a value with Javascript and then you're submitting in the standard way.
Then one way to do what you want is to use a hidden input and setting its value attribute instead of its contents.
<input id="label" class="labeldiv_dd" runat="server" type="hidden">
In the codebehind, the C# can retrieve the value from this control after submitting with the .Value property.
Ok guys thx for your replies..I found a way around the problem...I used HiddenField control to store the selected value using jQuery like so
$("#options_ul li").click(function () {
var text = this.innerHTML;
***$('#<%= selectedvalue.ClientID %>').val(text);***
$("#options_ul li").css("background-color", "#c2c2c2");
$(this).css("background-color", "white");
//var prev = this.id;
//document.getElementById("label").innerHTML = text;
toggleHeight();
});
and then accessed it server side using
selectedvalue.value;
PS: "selectedvalue" is id of the hiddenfield control

How to incrementally reveal div tags

I have collection of div tags in the form tag, like this:
<form ...>
<div id="div1"> ... </div>
<div id="div2"> ... </div>
...
...
</form>
I want to display only div1 in the visible area than when user presses next, the next div tag i.e. div2 is displayed, and so on.
How can I achieve this?
I don't have much knowledge about different approaches available to do this, but I have some knowledge of Javascript, so any idea will be appreciated.
P.S. please provide sample code if possible, also I want client-side scripting.
Here's some javascript and html demonstration that may help. Increment a current integer. You could deincrement with -- for back as well. There are many ways to do this. This is just one I thought of.
<img src="mynextbutton.jpg" onclick="showNext()" />
<form ...>
<div id="Div0" style="display:inherit;"> ... </div>
<div id="Div1" style="display:none;"> ... </div>
<div id="Div2" style="display:none;"> ... </div>
...
...
</form>
//---------------------------------------------------
var currentDiv = 0;
function showNext()
{
document.getElementById("Div"+currentDiv).style.display = "none";
currentDiv ++;
document.getElementById("Div"+currentDiv).style.display = "ihherit";
}
If you put all of the element IDs into an array, and then use that to get the next item you can remove the dependence on the ID numbering determining the order that they rotate in, and also prevent them from needing to follow such a rigid format.
//add all element IDs to this array
var elements = ["firstElementID","div2","someConentsID","lastElementID"];
var currentIndex = 0;
//ensure that the first item is visible at the start.
function next()
{
//hide current item.
document.getElementById(elements[currentIndex]).Style = "display:none";
//move up the current index by one, wrapping so as to stay within array bounds.
currentIndex = (currentIndex + 1) % elements.length;
//show the new current item.
document.getElementById(elements[currentIndex]).Style = "display:inline";
}
You can adjust the show/hide code to use JQuery, or whatever other mechanism you want.

Categories