foreach item only displaying for one row - asp.net-mvc

I have a jquery accordion in mvc view. It works fine for one row but will not display foreach row in the table. can't see why as it is contained within the foreach statement.
#Scripts.Render#if ("~/jquery")
#StylesModel.Render("~/Content/css"Isproject)
<link{ href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="//code.jquery.com/jquery-1.10.2.js"></script>
<script type="text/javascript" src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<script>
$(function () {
$("#accordion").accordion({
<div class="table">
<div>collapsible: true </div>
});<div>
});
</script>
#if (Model.Isproject)
{
<div class="table">
<div>
</div>
<div>
<table class="name" style="border-spacing: 0 8px; border-collapse: separate;">
#foreach (var item in Model.project)
{
#:<tr style="background-color:grey;-moz-border-radius: 15px;border-radius: 15px;">
<td class="position">
#item["post"]
</td>
<td class="image">
<img src="#item["image"]" style="height: 37px; width: 37px"/>
</td>
<td style="width: 50%;padding-left: 10px;text-align: left;">
<div id="accordion">
#item["name"]
<p>Content in dropdown</p>
</div>
</td>
<td style="width: 10%; text-align: center">
#item["rate"]
</td>
#:</tr>
}
</table>
</div>
</div>
}​
So in brief I need the jquery working for each entry/row and not just the first entry/row.

so when you do this $("#accordion").accordion, it will pick the first element with the id accordion and inject accordion properties and markup to it, rest will be ignored.
And, in your foreach loop, you are assigning same id to each of the div inside that particular td i.e. <div id="accordion">, which is wrong.
try assigning a unique id or instead of id use class i.e. <div class="myaccordion"> and in your jQuery code above do this, $(".myaccordion").accordion
and also the correct syntax to initialize the accordion will be:
$( ".accordion" ).accordion({
collapsible: true
});
and not what you have right now(I will consider that as typo). Also correct way of doing multiple sections inside your accordion is this:
<div id="accordion">
<h3>Section 1</h3>
<div>
<p> this is section 1</p>
</div>
<h3>Section 2</h3>
<div>
<p>this is section 2</p>
</div>
<h3>Section 3</h3>
<div>
<p>this is section 3</p>
</div>
</div>
so basically, you need to reconstruct your foreach loop, keeping the main accordion div outside and repeating the sections only

Related

asp.Net Core ViewComponent doesn't show CSS

I'm trying to get to grips with ViewComponents but having trouble trying to get the ViewComponent to reload on a button click. Whats the correct way to handle this?
Initially on the page loading it looks OK like this
In my controller I have
public IActionResult ReloadViewComponent(int characterRegionId, int materialTypeId)
{
return ViewComponent("MarketOrderComponent", new { characterRegionId, materialTypeId});
}
and in my razor view I'm passing parameters to the ReloadViewComponent method
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
full razor view
<body>
<div class="row" style="margin-top:5px;">
<div class="col-lg-4 col-md-12">
<div class="card" style="margin-bottom:0; ">
<div class="header" style="margin-bottom:55px;">
<h2 class="text-primary">Blueprint Breakdown</h2>
</div>
<div class="body">
<div>
<h5 class="text-center">#Model.BlueprintName</h5>
</div>
<div class="row text-center">
<div class="col-6 border-right pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ImageUrl" alt="#Model.BlueprintName">
</div>
<div class="col-6 pb-4 pt-4" style="padding-top:0px !important; padding-bottom:0px !important;">
<img src="#Model.ProductImageUrl" alt="#Model.BlueprintName">
</div>
</div>
<div class="text-center" style="margin-top:5px;">
<text style="font-size:small;">Material Quantity Based on Manufacturing Efficiency</text>
<br />
<text style="font-size:small;">Price Based on Lowest Region Market Sell Orders</text>
<br />
<text style="font-size:small;">Current Region is <span class="text-green">#Model.CharacterRegionName</span></text>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-custom spacing5">
<thead>
<tr>
<th></th>
<th>Material</th>
<th>Quantity</th>
<th>Price</th>
<th>Market</th>
</tr>
</thead>
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td><button class="btn btn-sm btn-outline-primary" value="#material.MaterialTypeID" onclick="location.href='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'">View</button></td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
</div>
but when clicking the view button to reload the ViewComponent it is rendered like this.
Note by using the ViewComponent() controller method, your client only gets the component part of the view. So instead of changing the browser's current location, you should send an ajax request and dynamically replace the right side content.
Add an id='MarketOrderComponent'attribute so that we can reference this element later:
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>
And change the button click event handler to send an ajax request. For example, in order to reload the market order component, you can change your code as below:
<script>
function reload(url){
return $.ajax({
method:"get",
url:url,
success:function(resp){ $('#MarketOrderComponent').html(resp);},
});
}
</script>
<div class="card" style="margin-bottom:0; ">
...
</div>
<div class="table-responsive">
...
<tbody>
#foreach (var material in Model.RequiredMaterials)
{
<tr class="text-cente" style="font-size:small;">
<td><img src="#(String.Format("{0}{1}{2}", "https://imageserver.eveonline.com/Type/", material.MaterialTypeID, "_32.png"))" /></td>
<td>#material.TypeName</td>
<td>#material.Quantity</td>
<td>#material.MaterialCost</td>
<td>
<button class="btn btn-sm btn-outline-primary"
value="#material.MaterialTypeID"
onclick="var link='#Url.Action("ReloadViewComponent", "BlueprintBreakdown", new { Model.CharacterRegionId, material.MaterialTypeID })'; event.preventDefault(); reload(link)"
>
View
</button>
</td>
</tr>
}
</tbody>
...
</div>
<div id='MarketOrderComponent' class="col-lg-8 col-md-12">
#await Component.InvokeAsync("MarketOrderComponent", new { Model.CharacterRegionId, Model.RequiredMaterials.First().MaterialTypeID })
</div>

Display hidden row in asp.net mvc grid

I have made grid with html table tag .in one of TD tag I have this code
<td>
<a onclick="$('#lightBox').css('display','inline')"></a>
<div style="display: none" id="lightbox">
<%--<%Html.RenderAction("LightBox","PremiumSharingAdmin",new {historyId = premium.SharingPremiumHistoryID}); %>--%>
<img src="Storage/Images/<%=premium.SharingPremiumHistoryID %>.jpg" title="image" width="100" height="100"/>
<div>
<textarea readonly="readonly">
<%= premium.Content %>
</textarea>
</div>
<div>
<input type="text" readonly="readonly" value="<%= premium.SharingTitle %>"/>
</div>
</div>
</td>
These tag provide me some extra info from grid row that By default is hidden.
In other side I have Link tag that if user pressed that display that row.
but problem is that when I pressed it, it just show me the first record detail and when I press the others it show me the first row detail.
where is the problem guys ?
This is my whole ASPX view
<% foreach (var premium in Model)
{%>
<tr>
<td style=" font-weight: bold;width: 130px;">
<span ><%= premium.SharingTitle %></span>
</td>
<td style=" font-weight: bold;width: 130px;">
<span ><%= premium.AddedDate.ConvertToPersianDate(true) %></span>
</td>
<td style="width: 130px;">
<span> <%= premium.IsSubmit %></span>
</td>
<td style="width: 130px;">
<span> <%= premium.ResturantName %></span>
</td>
<td style="width: 130px;">
<span> <%= premium.Content %></span>
</td>
<td style="width: 130px;">
<div class="group">
<a class="delete" href="<%= Url.Action("submit", "PremiumSharingAdmin", new {historyId = premium.SharingPremiumHistoryID}) %>" onclick="return confirm('آیا می‌خواهید این خبر را تایید کنید؟');">تایید</a>
</div>
</td>
<td>
<a onclick="$('#lightBox').css('display','inline')"></a>
<div style="display: none" id="lightBox">
<%--<%Html.RenderAction("LightBox","PremiumSharingAdmin",new {historyId = premium.SharingPremiumHistoryID}); %>--%>
<img src="Storage/Images/<%=premium.SharingPremiumHistoryID %>.jpg" title="image" width="100" height="100"/>
<div>
<textarea readonly="readonly">
<%= premium.Content %>
</textarea>
</div>
<div>
<input type="text" readonly="readonly" value="<%= premium.SharingTitle %>"/>
</div>
</div>
</td>
</tr>
<%} %>
You are generating invalid html by giving multiple <div> elements the same id attribute. $('#lightBox').css('display','inline') will return all elements with id="lightbox" but set the style of only the first.
Instead, use class names and use relative selectors. I also recommend you use Unobtrusive Javascript and css, rather tan polluting your mark up with behavior.
Html
<td>
Show
<div class="lightbox">Some content to display</div>
</td>
CSS
.lightbox {
display: none;
}
Script (at bottom of page)
<script>
$('.toggle').click(function () {
if ($(this).hasClass('hidden')) {
$(this).next('div').show();
$(this).text('Hide');
} else {
$(this).text('Show');
$(this).next('div').hide();
}
$(this).toggleClass('hidden');
});
</script>
</body>
Side note: Using RenderAction to render the contents of the hidden div suggest the contents are large and/or you calling a service/database to get the contents. If that's the case you should be loading the contents on demand using ajax (unless your expecting the users to view the details of all rows)

jquery ui tab select method not working

I have two tabs with a submit button on each tab. When the button is clicked, I need to reload the content of that specific tab to get updated data from the server.
if (validStatus()) {
$.ajax({
//...
success: reloadTab
});
}
function reloadTab() {
var currentTab = $("#tabs").tabs("option", "active");
alert(currentTab);
$('#tabs').tabs('select', currentTab);
alert(currentTab);
}
When the button is clicked, the tab doesn't refresh. I see the first alert but not the second.
HTML is as follows:
Head:
<link rel="stylesheet" href="#this.Url.Content("//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css")" />
<script>
$(function () {
$("#tabs").tabs();
});
</script>
Body:
<div id="tabs">
<ul>
<li>The first tab</li>
<li>the second tab</li>
<li>Success</li>
</ul>
<div id="Success">
testing
</div>
<div id="Tab1">
<fieldset >
<legend>Overview</legend>
<input type="button" id="submit1" value="submit" />
<br />
</fieldset>
<fieldset style="width: 700px;">
<legend>Overview</legend>
<div>
<table >
//updated with ajax
</table>
</div>
</fieldset>
<script>
//reloadTab is in here
</script>
</div>
<div id="Tab2">
<fieldset style="float:left; width:300px;">
<input id="submit2" type="button" value="submit"/>
</fieldset>
<fieldset style="float:left;">
<legend>Overview</legend>
<table>
//updated with ajax
</table>
</fieldset>
<script>.....</script>
</div>
Turns out tabs.('select', ...) is deprecated, using tabs.('option', 'active', index) fixed my issue. Solution found in this comment: https://stackoverflow.com/a/16033969/1463649
Do you see anything in the console of your browser? What browser are you using?
Try this to help you with the debugging.
function reloadTab() {
console.log($('#tabs')); // if this is an empty object, the element doesn't exist when you call this function
console.log($('#tabs').tabs()); // if this doesn't return 'function', you haven't included a library properly, maybe jquery ui, or jquery, or you're using an old version or something
console.log(currentTab); // if this is undefined then something went wrong and no tab is active
var currentTab = $("#tabs").tabs("option", "active");
alert(currentTab);
$('#tabs').tabs('select', currentTab);
alert(currentTab);
}

How to create a Nested Collapsible widget?

How can i create simple nested collapsible widget ?
This is what i've tried :
<div data-role="collapsible" data-theme="b">
<h2>2KB</h2>
<table border="1">
<thead>
<tr>
<td>Description</td>
<td>Week number</td>
<td>Total demand</td>
<td>Average daily on demand</td>
<td>Quantity on hand</td>
<td>Days stock on hand</td>
</thead>
<tbody id="warehouseList" padding="0">
<div data-role="collapsible"></div>
</tbody>
<tfoot></tfoot>
</table>
</div>
Any help will be hihgly appreciated.
<div data-role="page">
<div id="accordion">
<div data-role="collapsible">
<h3 data-role="header"> Some top level contents </h3>
<ul data-role="listview">
<li> contents </li>
</ul>
</div>
<div data-role="collapsible">
<h3 data-role="header"> Some top level contents </h3>
<ul data-role="listview">
<li> contents </li>
</ul>
</div>
</div>
</div>
<script>
$(document).ready(function(){
$('#accordion').accordion({header: 'h3'});
$('#accordion').accordion('activate', 2);
});
</script>

Error while loading Partial View based on the Tab selected on ASP.NET MVC page

I am new to MVC and trying to load a partial view based on the tab selected.
Here are the two tabs (Prodcuts and Doc Types) and
Two partial views (NavMenuProduct.ascx and NavMenuDocType.ascx).
The default page is: Index.aspx
My code is not loading the Partial view.
I would appreciate if someone has any code sample for this.
Here is the Javascript:
<script type="text/javascript">
$(function () {
var $tabs = $("#tabs").tabs({
select: function (e, ui) {
hdnTabSelected.value = ui.index;
alert(hdnTabSelected.value);
}
});
});
</script>
Html Code:
<table class="tableNoBorder" width="100%">
<!--Header Dashboard-->
<tr>
<td colspan="2">
<div id="container">
<h1>DocShare</h1>
<div id="welcome">Welcome, <%=new CacheUser().GetLoginUser().CommanName%></div>
</div>
</td>
</tr>
<!--Tabs Section for Products and DocType-->
<tr>
<td colspan=2>
<DIV id=tabs>
<UL>
<LI><A href="#" >Products</A></LI>
<LI>Doc Type</LI>
</DIV>
</td>
</tr>
<!--Left Menu Navigation and Main Content-->
<tr>
<td valign="top" width="200px">
<div >
<input type="hidden" id = "hdnTabSelected" runat="Server" />
<%-- If TabSelected = 0, load Product Menu, otherwise Load DocType Menu--%>
<%if (hdnTabSelected.Value == "0") %>
<% Html.RenderAction("NavMenuProduct","Home"); %>
<% else %>
<% Html.RenderAction("NavMenuDocType","Home"); %>
</div>
</td>
<td valign="top" width ="100%" >
<div id="content">
<asp:ContentPlaceHolder ID="MainContent" runat="server"></asp:ContentPlaceHolder>
</div>
</td>
</tr>
</table>
What you look to be doing is a standard master page ... I would open up a file new MVC and look at how it does that with the home and about tabs ...
Master :
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%: Html.ActionLink("Home", "Index", "Home")%></li>
<li><%: Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
about
<asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
About Us
</asp:Content>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>About</h2>
<p>
Put content here.
</p>
</asp:Content>
Remove the runat="server" from the above hidden input. The problem is that the rendered html and the javascript are not matching.
This should work the first time the page loads, however the rendered id for the hidden input will look like ctl00$MainContent$hdnTabSelected which does not match hdnTabSelected.value in the javascript.
You could change the javascript to this, but I recommend against it
<script type="text/javascript">
$(function () {
var $tabs = $("#tabs").tabs({
select: function (e, ui) {
<%=hdnTabSelected.ClientID %>.value = ui.index;
alert(<%=hdnTabSelected.ClientID %>.value);
}
});
});
</script>
It isn't obvious what is wrong according to you question, but at the first glance I think you should replace your calls to Html.RenderAction to calls to Html.Action.
The difference between the two is that
Html.RenderAction will render the
result directly to the Response (which
is more efficient if the action
returns a large amount of HTML)
whereas Html.Action returns a string
with the result.
Haaked has a blog-post with more details.

Resources