how could i change these code to MVC3 Razor,it script code.
these code i get form http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html
it's MVC2 Template and i want change it to Razor.
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script runat="server">
private object ModelValue {
get {
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model) {
return String.Format(
System.Globalization.CultureInfo.CurrentCulture,
"{0:0.00}", ViewData.ModelMetadata.Model
);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
}
</script>
<%= Html.TextBox("", ModelValue, new { #class = "text-box single-line" }) %>
i changed to Razor as bellow but it can't work:
#{
private object FormattedValue
{
get
{
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
{
return String.Format(System.Globalization.CultureInfo.CurrentCulture,"{0:0.00}",ViewData.ModelMetadata.Model);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
}
}
#Html.Encode(FormattedValue)
Create your own function:
http://weblogs.asp.net/hajan/archive/2011/02/05/functions-inside-page-using-razor-view-engine-asp-net-mvc.aspx
just call the function passing it the value in, and return it however you want to format it.
#functions{
public MvcString FormatValue(object valuetoFormat)
{
...logic here ...
return ....
}
}
Calling it is roughly:
#Html.TextBox("", FormatValue(ModelValue), new { #class = "text-box single-line" })
I don't think you can specify adhoc properties in Razor. You can, however, create variables.
#{
object FormattedValue;
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
{
FormattedValue = String.Format(System.Globalization.CultureInfo.CurrentCulture,"{0:0.00}",ViewData.ModelMetadata.Model);
}else{
FormattedValue = ViewData.TemplateInfo.FormattedModelValue;
}
}
Hope this works for you?
If you use the #{ } tag, the code is inserted inside the method used to generate the output.
You should use #functions { } to define elements you want on class (=page) level.
This would make your code look like:
Read SLaks blog for more information.
#functions {
private object FormattedValue
{
get
{
if (ViewData.TemplateInfo.FormattedModelValue == ViewData.ModelMetadata.Model)
{
return String.Format(System.Globalization.CultureInfo.CurrentCulture,"{0:0.00}",ViewData.ModelMetadata.Model);
}
return ViewData.TemplateInfo.FormattedModelValue;
}
}
}
#Html.Encode(FormattedValue)
Related
I'm trying to find an example to create a ButtonGroup using a viewmodel.
How can I do that?
#(Html.Kendo().ButtonGroup().Name("PredictionType").Items(t =>
{
t.Add().Text("Monthly");
t.Add().Text("Weekly");
t.Add().Text("Yearly");
}))
ButtonGroup does not have a DataSource configuration item like Grid or DropDownList. Use a Razor code block in the HtmlHelper to loop over a list of items that are added. This example has the controller creating the list of items.
View - Views\Example1\Index.cshtml
#model Example.ViewModels.MySettings
#{
ViewBag.Title = "Index";
}
<div>
Prediction Type
#(Html.Kendo().ButtonGroup()
.Name("PredictionType")
.Items(t =>
{
foreach (var item in Model.PredictionTypeItems)
{
t.Add().Text(item);
}
})
)
</div>
<div>
Exponent Level
#(Html.Kendo().ButtonGroup()
.Name("ExponentLevel")
.Items(t =>
{
foreach (var item in Model.ExponentLevelItems)
{
t.Add().Text(item.ToString());
}
})
)
</div>
Model - ViewModels\MySetting.cs
using System.Collections.Generic;
namespace Example.ViewModels
{
public class MySettings
{
public IList<string> PredictionTypeItems { get; set; }
public IList<int> ExponentLevelItems { get; set; }
}
}
Controller - Controllers\Example1Controller.cs
using System.Collections.Generic;
using System.Web.Mvc;
using Example.ViewModels;
namespace Example.Controllers
{
public class Example1Controller : Controller
{
public ActionResult Index()
{
var model = new MySettings {
PredictionTypeItems = new List<string> { "Monthly", "Weekly", "Yearly" },
ExponentLevelItems = new List<int> { -2, -1, 0, 1, 2 }
};
return View(model);
}
}
}
A more robust scenario would have the items come out of a data base table.
Kendo drop down is empty for some reason and I am not sure, below is all my code
#(Html.Kendo().DropDownList()
.Name("parties")
.HtmlAttributes(new { style = "width: 250px" })
.DataTextField("Name")
.DataValueField("PartyId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetParties", "Concept");
});
})
)
Controller Call
public JsonResult GetParties([DataSourceRequest] DataSourceRequest request)
{
var parties = MiscAdapter.GetParties().Select(x => new PartyModel
{
Name = x.PartyName,
PartyId = x.PartyId
});
return Json(parties.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
Model
public class PartyModel
{
public int PartyId { get; set; }
public string Name { get; set; }
}
Data returned according to the F12 tools
{"Data":[{"PartyId":1,"Name":"New Democratic Party"},{"PartyId":2,"Name":"Saskatchewan Party"},{"PartyId":3,"Name":"Liberal"},{"PartyId":4,"Name":"Green"},{"PartyId":5,"Name":"Independant"}],"Total":5,"AggregateResults":null,"Errors":null}
The dropdown does not show anything in there even though i cant see anything with the code or returned data.
Please try with the below code snippet. The method you have used its used for grid data binding.
public JsonResult GetParties()
{
List<PartyModel> models = new List<PartyModel>();
models.Add(new PartyModel() { Name = "Name1", PartyId = 1 });
models.Add(new PartyModel() { Name = "Name2", PartyId = 2 });
return Json(models, JsonRequestBehavior.AllowGet);
}
Let me know if any concern.
I have a view that is loaded with a blank viewmodel initially. I want to populate that already rendered view with a json object (obtained view ajax post) that was based off the viewmodel for that view.
Is there a way of automatically doing this?
Is there a way of doing it in reverse? (fields to matching viewmodel json object)
The only way I am aware of taking data return from an ajax call and putting it in a field is manually
$('#TextField1').val(result.TextField1);
etc..
to send it back to the controller you can do
data: $('form').serialize(),
this will take all of the fields in that form and send them back to the controller
Ok it looks like this will suit my needs.
I need to follow a convention of naming containers the same name as their respective properties as well as putting a class on them to indicate that they contain subfields.
function MapJsonObjectToForm(obj, $container) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var $field = $container.find('#' + key);
if ($field.is('div')) {
MapJsonObjectToForm(obj[key], $field);
} else {
if (obj[key] == null) {
if ($field.hasClass('select2-offscreen')) {
$field.select2('val', '');
$field.select2().trigger('change');
} else {
$field.val("");
}
} else {
if ($field.hasClass('select2-offscreen')) {
$field.select2('val', obj[key]);
$field.select2().trigger('change');
} else {
$field.val(obj[key]);
}
}
}
}
}
}
function MapFormToJsonObject(containerid) {
var obj = {};
$('.dataitem').each(function () {
var exclude = "s2id";
if ($(this).attr("ID").substring(0, exclude.length) !== exclude) {
var parents = $(this).parents(".has-sub-fields");
if (parents.length > 0) {
obj = FindParents(obj, parents.get(), $(this).attr("ID"), $(this).val());
} else {
obj[$(this).attr("ID")] = $(this).val();
}
}
});
return obj;
}
function FindParents(obj, arr, id, value) {
if (arr.length == 0) {
obj[id] = value;
return obj;
}
var parentID = $(arr[arr.length - 1]).attr("ID");
arr.pop();
if (obj[parentID] == null) {
obj[parentID] = {};
}
obj[parentID] = FindParents(obj[parentID], arr, id, value);
return obj;
}
When form is showing initially then I show question and their answer. I show multiple radio button for answer. So user can select only one answer. The problem occurs when I submit my form and action method calls. I saw when form post then answer model is getting null. So guide me how to write code as a result answer model should not be null when form will post.
Here is full code. Please go through the code and if requires changes as a result answer model will not be null when form will be posted to action method.
my ViewModels code
namespace ViewModels
{
public class Question
{
public int ID { set; get; }
public string QuestionText { set; get; }
public List<Answer> Answers { set; get; }
[Required]
public string SelectedAnswer { set; get; }
public Question()
{
Answers = new List<Answer>();
}
}
public class Answer
{
public int ID { set; get; }
public string AnswerText { set; get; }
}
public class Evaluation
{
public List<Question> Questions { set; get; }
public Evaluation()
{
Questions = new List<Question>();
}
}
}
controller code
public ActionResult Index()
{
var evalVM = new Evaluation();
//the below is hardcoded for DEMO. you may get the data from some
//other place and set the questions and answers
var q1 = new Question { ID = 1, QuestionText = "What is your favourite language" };
q1.Answers.Add(new Answer { ID = 12, AnswerText = "PHP" });
q1.Answers.Add(new Answer { ID = 13, AnswerText = "ASP.NET" });
q1.Answers.Add(new Answer { ID = 14, AnswerText = "Java" });
evalVM.Questions.Add(q1);
var q2 = new Question { ID = 2, QuestionText = "What is your favourite DB" };
q2.Answers.Add(new Answer { ID = 16, AnswerText = "SQL Server" });
q2.Answers.Add(new Answer { ID = 17, AnswerText = "MySQL" });
q2.Answers.Add(new Answer { ID = 18, AnswerText = "Oracle" });
evalVM.Questions.Add(q2);
return View(evalVM);
}
[HttpPost]
public ActionResult Index(Evaluation model)
{
if (ModelState.IsValid)
{
foreach (var q in model.Questions)
{
if(q.Answers==null)
{
// Answers is null
}
var qId = q.ID;
var selectedAnswer = q.SelectedAnswer;
// Save the data
}
return RedirectToAction("ThankYou"); //PRG Pattern
}
//reload questions
return View(model);
}
index.cshtml code
#model ViewModels.Evaluation
<h2>Quiz 24</h2>
#using (Html.BeginForm())
{
#Html.EditorFor(x=>x.Questions)
<input type="submit" />
}
and view code which is stored in EditorTemplates folder
#model ViewModels.Question
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.QuestionText </h3>
#foreach (var a in Model.Answers)
{
<p>
#Html.RadioButtonFor(b=>b.SelectedAnswer,a.ID) #a.AnswerText
</p>
}
</div>
the problem is here
[HttpPost]
public ActionResult Index(Evaluation model)
{
if (ModelState.IsValid)
{
foreach (var q in model.Questions)
{
if(q.Answers==null)
{
// Answers is null
}
var qId = q.ID;
var selectedAnswer = q.SelectedAnswer;
// Save the data
}
return RedirectToAction("ThankYou"); //PRG Pattern
}
//reload questions
return View(model);
}
q.Answers==null is getting null when i post the form. i like to know the trick that how to write code in such a way when form will be post to action then Answers should be null.
many guy told me that i need to rebuild the model manually because Answers will be always null. is there any no mechanism in MVC to persist all the data and properly De-serialize it to model when form will be posted.
AnswerText Normally I would recommend using another nested Editor Template for the Answer model, but in this case it will cause issues to properly construct the radio-button group and aftwerwards retrieve the value of SelectedAnswer. As a simple solution I would adapt the Editor Template for Question model in the following way:
<div>
#Html.HiddenFor(x=>x.ID)
<h3> #Model.QuestionText </h3>
<div>
#for (int i = 0; i < Model.Answers.Count; i++)
{
<p>
#Html.RadioButtonFor(model => model.SelectedAnswer, Model.Answers[i].AnswerText #Model.Answers[i].AnswerText
#Html.HiddenFor(model => model.Answers[i].ID)
#Html.HiddenFor(model => model.Answers[i].AnswerText)
</p>
}
</div>
</div>
This will create the following HTML (skipped not-relevant attributes):
<input type="radio" name="Questions[0].SelectedAnswer" ...>
<input type="hidden" name="Questions[0].Answers[0].ID" ...>
<input type="hidden" name="Questions[0].Answers[0].AnswerText" ...>
Output will allow MVC to properly reconstruct the Answer collection.
Update
In your original code you were looking for the Answer.AnswerText, so I've updated the code to include it instead of the Answer.ID.
Hope this helps.
I wish to store an action link in the model.
Something like
public MvcHtmlString ActionLink_New
{
get { return Html.ActionLink("new", "Edit", "News", new { Area = "Admin" }, null); }
}
It appears the model needs a webviewpage context.
Failing that, I thought I would store just the route values.
public RouteValueDictionary[] RouteValue_New
{
get { return new RouteValueDictionary[] { Area = "Admin" }; }
}
//View
#Html.ActionLink("new", "Edit", "News", Model.RouteValue_New, null)
The Area in the property is red. Is either or both scenario achievable. What do i need to add to get this to work, thanks.
try this
public object RouteValue_New
{
get {
return new { Area = "Admin" };
}
}