How to get mixed text and HTML-codes from surfacecontroller to partial view?
Instead of running business logic directly in partial view (what is not recommended in more advanced calculations), I want to loop through a database table and generate different calculations in a list mixed with text, numbers and HTML tags in a surfacecontroller. This I wish to send to partial view overall. An example what the partial view should get can be like this:
<h4> Most visits in 2017: </ h4>
<p> 3 visits: John Doe </ p>
<p> 2 visits: Jane Doe </ p>
<p> 1 visit: john smith </ p>
How does the method look like mainly in a surface controller, and how is it recommended to retrieve the html tags in partial view?
I would return a ViewModel to the partial, and then use that to render the HTML.
View Model:
public class VisitViewModel
{
public string Period { get; set; }
public Dictionary<string, int> Visits { get; set; }
}
Controller:
public ActionResult GetVisits()
{
var visitView = new VisitViewModel();
/// actual code to do something....
visitView.Period = "2017";
visitView.Visits = new Dictionary<string, int>();
visitView.Visits.Add("John Doe", 3);
visitView.Visits.Add("Jane Doe", 2);
visitView.Visits.Add("john smith", 1);
return PartialView("partial/path", visitView);
}
and then in your partial view you can enumerate the items
@inherits UmbracoViewPage<YourNamespace.Models.VisitViewModel>
<h4>Most visits in @Model.Period</h4>
@foreach(var visit in Model.Visits)
{
<p>@visit.Value Visits: @visit.Key</p>
}
this way the logic remains in your controller but the HTML output is all in the Razor so it's easier to change.
you could tidy up the Dictionary a bit, so it was another object and then it might be @visit.Count Visits: @visit.Name but other than that. I think this keeps it fairly neat.
Thank you very much for the solution. Dictionary is probably what I needed. Now it's only up to me to figure out the logic for the rest of the calculations.
Dictionary works as it should when I add more lines manually, but obviously, I have to get the number of lines from a foreach loop, and I have not figured out yet. Is this where you use ToDictionary?
you should be able to use a dictonary directly in a foreach,
e.g
var myDictionary = new Dictionary<string, int>();
// ... add items
foreach(var item in myDictionary)
{
// item is a now KeyValuePair
// item.Key - will be a string
// item.Value - will be an int
}
This is from the repository where the data in HikingDestinations above are selected:
public static IList<HikingDestinationViewModel> GetAll()
{
UmbracoDatabase db = Umbraco.Core.ApplicationContext.Current.DatabaseContext.Database;
return db.Fetch<HikingDestinationViewModel>("SELECT * FROM HikingDestinations ORDER BY StartDate");
}
and this from the foreach loop in the surfacecontroller:
HikingDestinationViewModel model = new HikingDestinationViewModel();
model.Visits = new Dictionary<string, int>();
int points = 0;
foreach (HikingDestinationViewModel hikingDestination in allHikingDestinations)
{
//Some untested calculations here
//model.Visits.Add("John Doe", 1) <<= not working when looping more than 1 time
}
//model.Visits.Add("John Doe", 1) <<= working, but manual assignment can't be used
And my model HikingDestinationViewModel is where public Dictionary<string, int> Visits { get; set; } also is defined, so I still working to find out how to connect this.
It fails even with one of this model.Visits.Add("John Doe", 1); inside the foreach loop if looping more than 1 times, but it work outside of the loop - even if adding model.Visits.Add("John Doe", 1) more than 1 time.
Dictionary Keys have to be unique so it's possible it fails if the string is the same more than once?
if that's possible then you either need to check
if (!Model.Visits.ContainsKey(name)) {
Model.Visits.Add(name, points);
}
or use a List and a model so you can have multiple values.
Model.Visits = new List<VisitInfo>();
Model.Visits.Add(new VisitInfo { Name = name, Point = points });
// info for the list
public class VisitInfo {
public string Name {get;set;}
public string Points {get;set;}
}
Yes that is correct. I just figure out that an error message came when the key was not unique, so I've used the dictonary in the wrong way. (the number of visits can't be unique).
Well, then there will be a longer break here, but before I go: What's the Model.Visits in your example? Which of my models is this thought taken from (see the example below)? model.Visits = new List<VisitInfo>(); gives me an error (cant convert... etc, and I use small m in model).
Yes, it look like that makes sense. I give feedback when I've finally returned to the office to test the modification of HikingDestinationViewModel. Thanks.
Yes, this works excellent. Now that the VisitInfo class can receive all kinds of numbers, not just unique, printing works as intended. Then only the actual calculations remain. Thank you for your help.
Thanks, this looks promising and I will test it. The next thing I need to figure out now, is how I return the result from the Dictionary defind in model, from the inside of the loop, and out to the view (still error in view).
// Find all registered hiking destinations from all members, from the dbTable HikingDestinations:
IEnumerable<HikingDestinationViewModel> allHikingDestinations = HikingDestinations.GetAll();
// where hikingDestination.HikingCode (pr. hiking destination, given from admin)
// match members typed code, add some point (pr. hiking destination, given from admin)
// and set the members name and points to Dictionary<string, int> Visits (model HikingDestinationViewModel)
HikingDestinationViewModel model = new HikingDestinationViewModel();
model.Visits = new Dictionary<string, int>();
int points = 0;
foreach (HikingDestinationViewModel hikingDestination in allHikingDestinations)
{
points = hikingDestination.HikingCode.ToLower() == hdcode.ToLower() ? points + point : points;
model.Visits.Add(Members.GetById(hikingDestination.nodeId).Name, points );
}
return PartialView("HikingDestinationMenu", model);
How to get mixed text and HTML-codes from surfacecontroller to partial view?
Instead of running business logic directly in partial view (what is not recommended in more advanced calculations), I want to loop through a database table and generate different calculations in a list mixed with text, numbers and HTML tags in a surfacecontroller. This I wish to send to partial view overall. An example what the partial view should get can be like this:
How does the method look like mainly in a surface controller, and how is it recommended to retrieve the html tags in partial view?
Hi Tom,
I would return a ViewModel to the partial, and then use that to render the HTML.
View Model:
Controller:
and then in your partial view you can enumerate the items
this way the logic remains in your controller but the HTML output is all in the Razor so it's easier to change.
you could tidy up the Dictionary a bit, so it was another object and then it might be
@visit.Count Visits: @visit.Name
but other than that. I think this keeps it fairly neat.Thank you very much for the solution. Dictionary is probably what I needed. Now it's only up to me to figure out the logic for the rest of the calculations.
Dictionary works as it should when I add more lines manually, but obviously, I have to get the number of lines from a foreach loop, and I have not figured out yet. Is this where you use ToDictionary?
Hi
you should be able to use a dictonary directly in a foreach,
e.g
What is meant by
// ... add items
here?The foreach loop is the lookup from a database table that is still growing
sorry that was just an example of the loop.
if you are passing the dictionary back from the Controller (like the post below) then it should look like this in the razor:
because your dictionary is Model.Visits ?
I get all my hiking destination data from this database table:
This is from the repository where the data in HikingDestinations above are selected:
and this from the foreach loop in the surfacecontroller:
And my model HikingDestinationViewModel is where
public Dictionary<string, int> Visits { get; set; }
also is defined, so I still working to find out how to connect this.It fails even with one of this
model.Visits.Add("John Doe", 1);
inside the foreach loop if looping more than 1 times, but it work outside of the loop - even if addingmodel.Visits.Add("John Doe", 1)
more than 1 time.Hi
Dictionary Keys have to be unique so it's possible it fails if the string is the same more than once?
if that's possible then you either need to check
or use a List and a model so you can have multiple values.
Yes that is correct. I just figure out that an error message came when the key was not unique, so I've used the dictonary in the wrong way. (the number of visits can't be unique).
Well, then there will be a longer break here, but before I go: What's the
Model.Visits
in your example? Which of my models is this thought taken from (see the example below)?model.Visits = new List<VisitInfo>();
gives me an error (cant convert... etc, and I use small m in model).Thanks in advance for any response that may come.
Hi yeah
i think the
Model.Visits
would be fromHikingDestinationViewModel
so if you can you would need to change the definition of the
HikingDestinationViewModel
Visits property in the classFrom something like
To
Yes, it look like that makes sense. I give feedback when I've finally returned to the office to test the modification of HikingDestinationViewModel. Thanks.
Yes, this works excellent. Now that the VisitInfo class can receive all kinds of numbers, not just unique, printing works as intended. Then only the actual calculations remain. Thank you for your help.
Thanks, this looks promising and I will test it. The next thing I need to figure out now, is how I return the result from the Dictionary defind in model, from the inside of the loop, and out to the view (still error in view).
is working on a reply...