Umbraco get node custom property value - umbraco7

I am trying to get the value of a custom property (isFeatured). I am working against the current page.
#inherits Umbraco.Web.Macros.PartialViewMacroPage
<div id="featuredpartnerwrapper">
#{
var page = Umbraco.TypedContent(1092);
}
#foreach (var child in page.Children)
{
#child.Name<br />
#child.GetPropertyValue("isFeatured")
}
</div>
the isFeatured property never is rendered

This code works - but you have to spell the property alias correctly -
#inherits Umbraco.Web.Macros.PartialViewMacroPage
<div id="featuredpartnerwrapper">
#{
var page = Umbraco.Content(1092);
}
#foreach (var child in page.Children) {
#child.Name<br />
#child.isFeatured
}

Related

Partial view in NET 6

i am lost with NET6.
I created this partial view _MenuNav.cshtml :
#model IEnumerable<CateringMilano.Models.Menu>
#foreach (var item in Model)
{
<div>
<a alt="#item.MenuTitle)">#item.MenuName</a>
<b>#item.MenuTitle</b>
</div>
}
and the cod in my controller is :
// GET: /Menus/_MenuNav/
public ActionResult _MenuNav(string menuPosition)
{
// Get my db
var model = _context.Menu.Include(m => m.ChildMenuSub) as IQueryable<Menu>;
model = model.Where(p => p.MenuPosition == menuPosition);
// Send your collection of Mreations to the View
return PartialView(model);
}
and in the last project with net 4 i use to write the following code in the principal view in order to call my partial view :
#Html.Action("_MenuNav", "Menus", new { menuPosition = "Menu" })
but it looks like it does not work anymore this with NET6
Do you know how to rewrite my code in order to get the same result?
you must be mixing view components with partial views. Partial view were always used like this
<div id="partialName">
<partial name="_PartialName" />
</div>
with model
<partial name="_PartialName" model="Model.MyInfo" />
or for async
<div id="partialName">
#await Html.PartialAsync("_PartialName")
</div>
and the most popular way to update parital view is using ajax
And you can check my answer about viewcomponents here
https://stackoverflow.com/a/69698058/11392290

ASP .NET MVC Ajax insert view instead instead replace data only first time

I'm new to AJAX, and I have a very simple example, but has a problem; first call the data is duplicated at the View and in subsequent calls work correctly. What am I doing wrong?
The ~/Views/Shared/_Layout.cshtml file had all scripts necesary:
<script src="~/Scripts/jquery-3.1.0.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
First time, the initial view:
Second time, first time button click inserts a number instead of replace number:
Third time, second time button click works fine but in the second line number... an so on:
This is my code:
Model
namespace MQWebSt.Models
{
public class AjaxTest
{
public int Number { get; set; }
}
}
Controller:
using System.Web;
using System.Web.Mvc;
using MQWebSt.Models;
namespace MQWebSt.Controllers
{
public class AjaxTestController : Controller
{
// GET: AjaxTest
public ActionResult Vista()
{
AjaxTest at = new AjaxTest { Number = 1 };
return View(at);
}
[HttpPost]
public ActionResult Vista( AjaxTest model)
{
Random rnd = new Random();
model.Number = rnd.Next(1, 100);
return PartialView("AjaxTestPartial", model);
}
}
}
View Vista.chtml:
#model MQWebSt.Models.AjaxTest
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Ajax.BeginForm("Vista", new AjaxOptions { UpdateTargetId = "divEmp", InsertionMode = InsertionMode.Replace }))
{
<button class="btn btn-primary btn-md glyphicon glyphicon-menu-right" name="Contestar" type="submit" value="+1"></button>
<div class="panel panel-footer">
<table id="divEmp">
#Model.Number.ToString()
</table>
</div>
}
AjaxTestPartial.chtml:
#model MQWebSt.Models.AjaxTest
#Model.Number.ToString()
The issue is you're using InsertionMode = InsertionMode.Replace, it's going to replace the data in the UpdateTargetId. You could use InsertionMode.InsertBefore instead and it would build the values out in the parent of #divEmp. However, if you need the values to be placed in #divEmp, you'll need to write a JavaScript handler for the OnSuccess option of your Ajax form, that way you can dictate if you're doing insert vs. pre-pend vs. replace.
The issue is, your HTML markup code in your razor view is not valid. With the code you have, razor will generate the below markup (Check the view source)
<div class="panel panel-footer">
1
<table id="divEmp"></table>
</div>
You can see that 1 is not inside the table. It is outside. So when your ajax form submit happens, it will update the tables content with the new value. that is the reason you are still seeing the initial number.
The solution is to change the table to a div/span
<div id="divEmp"> #Model.Number.ToString() </div>
Or if you absolutely need to have a table for any reason, have the value inside a td and use "divEmp" as the id attribute value of that.
<table >
<tr>
<td id="divEmp">1</td>
</tr>
</table>

How can I set selected model with list?

In my controller I set the items in the ViewBag:
List<ShopItemModel> items = new List<ShopItemModel>();
/* populate my items */
ViewBag.Items = items;
So on the cshtml i run thru the list, but how do I connect it so on postback sets the argument of the Post method in the controller?
The CSHTML:
#model Models.ShopItemModel
<h2>Webshop</h2>
#foreach( var item in ViewBag.Items)
{
using (Html.BeginForm())
{
<p>#item.Name</p> <!-- List the item name, but not bounded? -->
#Html.LabelFor(model => model.Name, new { Name = item.Name }) <!-- outputs just "Name", not the items name -->
<input type="submit" value="Buy" />
}
}
The post version of the method in the controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(ShopItemModel m)
{
return View();
}
But how do I fix this binding? So I fetch the selected item from the list?
In your view:
using (Html.BeginForm())
{
for (int i = 0; i < Model.Count; i++)
{
#Html.LabelFor(model => model[i].Name)
}
}
This will produce html controls like this:
<input name="ShopItemModel[3].Name" ...
If you're using this in a form, in your controller, iterate over the POSTed model data:
foreach (var item in model)
{
... do something to each item
}
You can use a foreach loop in the view rather than a for loop, example here

MVC 4 Razor using Ajax forms to update a foreach loop

Where to start...I can find similar things on the Internet as to how, but they never seem to work with my specific way of wanting to do something. I have tried with and without partial views with very little success.
Quick rundown: I have a strongly-typed View with an Ajax form. underneath the form, I have a foreach loop that repeats a code block. I need to be able to update the code block from the forms choices (filters).
Here's my View, 'FindATeacher.cshtml', as it currently stands (after trying many different ideas):
#model Teachers.Models.OmniModel
#{
ViewBag.Title = "FindATeacher";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Find a Teacher</h2>
#using (Ajax.BeginForm("FilterTeachers", "Home", new AjaxOptions { HttpMethod = "Post", OnSuccess = "onSuccess" }))
{
<div id="ContentFilter">
<div class="filterLabels">
<p>Search by Name</p>
<p>Filter By Instrument</p>
<p>Filter By City</p>
</div>
<div class="filterObjects">
<p>
<input type="text" id="nameTXT" />
<button type="submit" id="findButton">find</button>
</p>
<p>#Html.DropDownList("InstrumentID", (SelectList)Model.Instruments, "-- Select an Instrument --", new { id = "instrumentDD" })</p>
<p>#Html.DropDownList("CityID", (SelectList)Model.Cities, "-- Select a City --", new { id = "cityDD" })</p>
</div>
</div>
}
<hr />
#foreach (var r in Model.Teachers)
{
<div id="ContentResults">
<div id="avatar">
<img src="i" />
</div>
<div id="demographics">
<h6>#r.Teacher</h6>
<strong>#r.StudioName</strong>
<p>#r.URL</p>
<p>#r.StreetAddress</p>
<p>#r.City, #r.AddressStateID #r.Zip</p>
<p>#r.Phone</p>
<p>#r.EmailAddress</p>
</div>
<div id="studioDetails">
<p><strong>Instrument(s) Taught</strong></p>
<p>
#{
var instrumentString = r.Instruments.Aggregate("", (a, b) => a + b.Instrument + ", ");
if (instrumentString.Length != 0)
{
instrumentString = instrumentString.Remove(instrumentString.LastIndexOf(","));
}
}
#instrumentString
</p>
<br />
#if (r.Information != "" && r.Information != null)
{
<p><strong>Information</strong></p>
<p>#r.Information</p>
}
</div>
</div>
}
Now here's my Controller. I get the results back correctly in the Controller, just not updating the code block:
public ActionResult FindATeacher()
{
Model.Instruments = new SelectList(TeacherService.GetInstrumentList(0),"InstrumentID","Instrument");
Model.Cities = new SelectList(TeacherService.GetCityList(),"CityID","City");
Model.Teachers = TeacherService.GetTeacherList("", 0);
return View(Model);
}
[HttpPost]
public JsonResult FilterTeachers(String teacherName, String instrumentID, String cityID)
{
Model.Teachers = TeacherService.GetTeacherList("John", 0, 0);
return Json(Model.Teachers);
}
Thanks.
#VishalVaishya presents the right idea, but there's a simpler way, which doesn't involve custom javascript code: AjaxOptions has an UpdateTargetId property that the AJAX toolkit will interpret to mean you want the given target to be updated with the results sent back from the controller.
FindATeacher.cshtml:
#using (Ajax.BeginForm("FilterTeachers", "Home", new AjaxOptions {
HttpMethod = "Post", UpdateTargetId = "TeacherList" }))
{
...
}
<hr />
<div id="TeacherList">
#Partial("TeacherList", Model.Teachers)
</div>
TeacherList.cshtml
#model IEnumerable<Teacher>
#foreach(var teacher in Model)
{
...
}
Controller action:
[HttpPost]
public ActionResult FilterTeachers(String teacherName, String instrumentID, String cityID)
{
Model.Teachers = TeacherService.GetTeacherList(teacherName, instrumentID, cityID);
return PartialView("TeacherList", Model.Teachers);
}
You can try following method:
Separate your foreach loop into another partial view.
And load your partial view on filter / click event and pass filtered parameters to your controller-action.
JS change event code will be something like this:
var teacherName = ''; //get your selected teachername
var instrumentID = ''; //get your selected instrumentid
var cityID = ''; //get your selected city id
var url = '#Url.Action("FilterTeachers", "ControllerName", new { teacherName = "teacher-Name", instrumentID="instrument-ID", cityID="city-ID" })';
url = url.replace("teacher-Name", teacherName).replace("instrument-ID", instrumentID).replace("city-ID", cityID);
$('#result').load(url);

Get data from Form in MVC3?

I have this this View for rendering form
#using ExpertApplication.ViewModels
#model IEnumerable<QuestionViewModel>
#{
ViewBag.Title = "GetQuestions";
}
#using(Html.BeginForm("ProcessAnswers", "Home", FormMethod.Post))
{
foreach(QuestionViewModel questionViewModel in Model)
{
Html.RenderPartial("QuestionPartialView", questionViewModel);
}
<input type="submit" value="Send data"/>
}
}
<h2>GetQuestions</h2>
And partial view
#using ExpertApplication.ViewModels
#model QuestionViewModel
<div id="question">
#Model.Text
<br />
<div id="answer">
#foreach(var answer in Model.AnswerViewModels)
{
#(Model.IsMultiSelected
? Html.CheckBoxFor(a => answer.Checked)
: Html.RadioButtonFor(a => answer.Checked, false))
#Html.LabelFor(a => answer.Text)
<br />
}
</div>
</div>
I want get data from From
[HttpPost]
public ActionResult ProcessAnswers(IEnumerable<QuestionViewModel> answerForQuesiton)
{
//answerForQuestion always is null
}
but parameter answerForQuesiton is null. How to fix this problem ?
MVC binds lists by using zero indexed names. Unfortunately, for this reason, while foreach loops will create inputs that contain the correct values, they will not create input names that use the correct names. Therefore, you cannot bind lists using foreach
For example:
for (int i = 0; i< Model.Foo.Count(); i++)
{
for (int j = 0; j < Model.Foo[i].Bar.Count(); j++)
{
#Html.TextBoxFor(m => m.Foo[i].Bar[j].myValue)
}
}
Will create textboxes with names like "Foo[1].Bar[2].myValue" and correctly bind. However,
foreach (var foo in Model.Foo)
{
foreach (var bar in foo.Bar)
{
#Html.TextBoxFor(m => bar.myVal);
}
}
will create text boxes with the exact same values as the prior loop, but all of them will have "name="bar.myVal" so none of them can bind.
So to fix your issue:
1) You could replace your foreach loops with for loops. Note: this requires using IList or List instead of IEnumerable
2) You could use EditorTemplates which automatically apply the correct names for you.
You are using the wrong mechanism. You should be using EditorTemplates rather than partial views. Editor Templates know how to deal with collections and creating properly formatted name attributes so they can be bound on post-back.
http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

Resources