How to add a menu generated from a doc type list in Umbraco? - umbraco7

I'm new to umbraco and i want to be able to click in a content field, add content, then select specialty nav item. This navigation would be queried from a custom doc type.
I have the doc type list setup and i have a generic custom grid editor setup, however im not sure how to get the grid editor render portion to actually query the doc type and output it.

I did this by using a macro and a partial template like so:
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{
var selection = CurrentPage.Site().FirstChild("benefitNav").Children("benefitNavItem").Where("Visible");
}
<div id="benefitmenu">
<table class="blink">
#foreach (var item in selection)
{
var img = Umbraco.Media(item.GetPropertyValue("benefitIcon")).Url;
foreach (var link in #item.linkToPage)
{
<tr>
<td class="bicon"><img alt="#link.caption" src="#img" /></td>
<td class="btext">#link.caption</td>
</tr>
}
}
</table></div>

Related

Kendo UI Mobile forcing empty cell to not display in template

Is it possible to force an empty cell to not display in a template?
Currently my template is:
template = kendo.template("#if (title != null){#<span class=\"box favorable\">50</span><div class=\"title\">${ title }</div>#}else{}#");
However, if the else statement is called, it just displays an empty cell. I want the cell to not be displayed, instead of being an empty cell.
You need to include the table in the template to have a total control over it. For example, in your case, you need an approach like this:
template = kendo.template("
<table>
# for (var i=0; i<rows.length;i++) { #
#if (title != null){#
<tr><td>
<span class=\"box favorable\">50</span><div class=\"title\">#= title #</div>
</td></tr>
#}#
# } #
</table>
");

How to add an HTML5 data-something attribute in Razor

I am trying to generate a table like this
#foreach (var item in #Model.Where(o => o.Status == "Submitted")){
<tr class="row" data_orderid="#item.Id">
<td class="description">
#item.Customer
</td>
<td class="description">
#item.OrderDescription
</td>
...etc...etc
so that I can handle the click event of each tr, and display some info based on the data-orderid attribute value of the tr that was clicked.
In Visual Studio I get a validation message saying "data_orderid is not a valid attribute of tr" and when it renders the HTML tr has no attributes, Not event the class.
How should I be adding attributes like this?
The format of HTML 5 data attribute is like this
data-AttributeName=AttributeValue
Example :
data-name="John Resig"
Change underscore to a hiphen and it will be rendered correctly.
<tr class="row" data-orderid="#item.Id">
First of all it is more likely that you should be using "data-xxx" (rather than "data_xxx") attributes.
Secondly, It is unlikely (if not imposible) for visual studio to omit class and your "data_orderid" attributes.
Make sure that for loop gets any elements from your condition #Model.Where(o => o.Status == "Submitted"
Additionally, as a note, Razor is smart enough to interpret 'html attributes' passed to elements, like here:
#Html.TextBoxFor(m => m.Name, new { #data_orderid = item.id, #class="input-xxlarge" }))

How to open cshtml file in new tab from controller's method?

I'm working on a Nopcommerce, and need to generate Invoice (custom made not as what they already provide, because it just doesn't solve our purpose). We need to generate Invoice
in new tab(using another cshtml file) using Controller's method also I'm passing model data on view.
<tr>
<td class="adminTitle">
#Html.NopLabelFor(model => model.ProbableDeliveryDate):
</td>
<td class="adminData">
#Html.EditorFor(model=>model.ProbableDeliveryDate)
</td>
</tr>
<tr>
<td>
#if(Model.CanGenrateInvoice)
{
<input type="submit" name="generateinvoice" value="#T("Admin.Orders.Fields.generateinvoice")" id="generateinvoice" class="adminButton" />
}
</td>
</tr>
I've to post data to get value of probableDeliveryDate to controller method and after that want to open view in new tab.
How can i do this?
If you are getting to the action from the first page via an Html.ActionLink you can do this:
Html.ActionLink("Open Invoice", "ActionName","ControllerName", new { id = Model.InvoiceID }, new { target = "_blank" });
Specifying target = "_blank" will open in the new tab
Update
Since you are posting the model to the controller (I was hoping RedirectToAction could help open a new window/tab but that doesn't look to be the case)
My spidy sense is tingling on the flow you have tho... This is just me but I would do something a little different.. such as
Post the model to the controller
Save the data that generates the invoice
Return the InvoiceID to the action
Add the InvoiceID to the model
Send the model back to the view
Inform the user that
the invoice was generated and show a link - like above - that allows the user to open the invoice OR
this provides the perfect clean solution to show model errors if there were any
Your view could have a piece of razor code that did that:
#{
if(Model.InvoiceID != null && Model.InvoiceID !=0) {
#Html.ActionLink("Open Invoice", "ActionName","ControllerName", new { id = Model.InvoiceID }, new { target = "_blank" });
}
}

Can't set SelectedItem in DropDownList in my MVC3 view

I know that I can set the SelectedItem in my controller, but I can't figure out how to set it in my view. I'm working on a sort of flashcard (study guide) application and I have imported about 400 test questions. Now I want to write a page for the instructor to be able to select a "Category" for each question. I'd like them to be able to update the category for all the questions on one page. My model has a question entity that contains a foreign key field to the category entity (the field is called QuestionCategory). So, my view is based on the Question entity, but I'm sending over the list of Categories (there are 14) in the ViewBag (so I don't have to send a full SelectList over with each of the 400 questions. As my view is iterating thru the items in my View, I just want to add a SelectList that contains the 14 categories in my ViewBag and then set the SelectedItem based on the value of item.QuestionCategory. I can't make it work.
Here's my controller action:
public ActionResult Index()
{
var context = new HBModel.HBEntities();
var query = from q in context.tblQuestions.Include("tblCategory") select q;
var questions = query.ToList();
ViewBag.Categories = new SelectList(context.tblCategories, "CategoryID", "CategoryName");
return View(questions);
}
Here's some of the things I've tried in the view (with associated error messages in the comments)
#model IEnumerable<HBModel.tblQuestion>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Question
</th>
<th>
Answer
</th>
<th>
AnswerSource
</th>
<th>
Category
</th>
<th>
Action
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#item.Question
</td>
<td>
#item.Answer
</td>
<td>
#item.AnswerSource
</td>
<td>
#item.tblCategory.CategoryName
#*This one works, but cannot initialize the selected item to be current database value*#
#Html.DropDownList("Categories")
#*compile error - CS0200: Property or indexer 'System.Web.Mvc.SelectList.SelectedValue' cannot be assigned to -- it is read only*#
#*#Html.DropDownListFor(m => item.QuestionCategory, (ViewBag.Categories as SelectList).SelectedValue = item.QuestionCategory)*#
#*error {"DataBinding: 'System.Web.Mvc.SelectListItem' does not contain a property with the name 'CategoryId'."}*#
#Html.DropDownListFor(m => item.QuestionCategory, new SelectList(ViewBag.Categories, "CategoryId", "CategoryName"))
#*error - {"DataBinding: 'System.Char' does not contain a property with the name 'CategoryId'."}*#
#Html.DropDownListFor(m => item.QuestionCategory, new SelectList("Categories", "CategoryId", "CategoryName"))
)
</td>
<td style="width: 100px">
#Html.ActionLink("Edit", "Edit", new { id = item.QuestionID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.QuestionID })
</td>
</tr>
}
</table>
Of course, if I can get this to work, I'll need to try and add an action to go back to the controller and update all the records, but I'll just be happy to resolve my current issue.
I would really appreciate any help on this - Thanks!
You need to explicitly create the options in the select tag, using #Html.DropDownList, as follows (taken from a working app):
#Html.DropDownListFor(model => model.IdAccountFrom, ((IEnumerable<FlatAdmin.Domain.Entities.Account>)ViewBag.AllAccounts).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.AccountName),
Value = option.AccountId.ToString(),
Selected = (Model != null) && (option.AccountId == Model.IdAccountFrom)
}), "Choose...")
#Html.ValidationMessageFor(model => model.IdAccountFrom)
You obviously need to change to the properties on your #Model.
NOTE:
This code was auto-generated by the MvcScaffolding NuGet package when I scaffolded a controller.
This package requires you to use Entity Framework Code First POCO classes for your entities. These are easy to generate from an existing database using the Entity Framework Power Tools CTP.
With MVC, you need to spend some time researching the tooling that is out there to help you generate the stuff that you need. Using these tools is a great way to get started and to see how to do things. You can then tweak the output to your heart's content.

Index of current item in mvc display template

I have an mvc page with a displaytemplate.
How do I get the index of the current item being rendered in the displaytemplate.
it produces correct bindable results in the name attributes.
<input name="xxx[0].FirstName"/>
<input name="xxx[1].FirstName"/>
I want that index value in the display template. Is it in the ViewContext somewhere?
#* page.cshtml #
#model ...# property Contacts is IEnumerable *#
<table id="contacts" class="editable">
<thead>
<tr><th>Name</th><th>Surname</th><th>Contact Details</th></tr>
</thead>
<tbody>
#Html.DisplayFor(x => x.Contacts)
</tbody>
in the display template we have
#* contact.cshtml *#
#model ...#* This is the T of the IEnumerable<T> *#
<tr>
#* I NEED THE INDEX OF THE CURRENT ITERATION HERE *#
<td>#Html.DisplayFor(x => x.FirstName)</td>
</tr>
I am afraid there is no easy way to get the index. It's buried inside the internal System.Web.Mvc.Html.DefaultDisplayTemplates.CollectionTemplate method and not exposed. What you could use is the field prefix:
#ViewData.TemplateInfo.HtmlFieldPrefix
Another possibility is replace #Html.DisplayFor(x => x.Contacts) with:
#for (int i = 0; i < Model.Contacts.Length; i++)
{
#Html.DisplayFor(x => x.Contacts[i], new { Index = i })
}
and then inside the template #ViewBag.Index should give you the current index but I must admit it's kinda ugly.
Depending on why you need the index, there may be an easier way.
I was doing something similar and wanted the index just so I could easily number the list of items such as:
First items in List
Second item in List
etc.
The maybe obvious solution was to render my display template as a List Item within an Order List, and let the browser handle the display of the index. I was originally doing this in a table and needed the index to display in the table, but using a ordered list makes it much easier.
So my parent view had the following:
<ol>
#Html.DisplayFor(m => m.Items)
</ol>
And my template wrote on the items in an list item using divs - note you could use floating divs, or better yet display: inline-style to get a table like effect
<li>
<div class="class1">#Html.DisplayFor(m => m.ItemType)</div>
...
</li>
And the css:
.class1 {
display: inline-block;
width: 150px;
}
Extending #DarinDimitrov's answer, I wanted to submit a complete solution:
Extention:
namespace ApplicationName.Helpers
{
public static class RazorHtmlHelpers
{
public static Int32 GetTemplateIndex(this TemplateInfo template)
{
var index = 0;
var match = Regex.Match(template.HtmlFieldPrefix, #"\d");
Int32.TryParse(match.Value, out index);
return index;
}
}
}
Parent View Markup:
#Html.DisplayFor(model => model.Items)
Template Markup:
#using ApplicationName.Helpers
#model ApplicationName.Models.ModelName
<span>Item #ViewData.TemplateInfo.GetTemplateIndex()</span>

Resources