How to Bind a specific field to json instead of model? - c#

I am using Asp.net MVC5. The scenario is like I have a view which is bound to a model.
Now there is a textbox in the view which I don't want to be bound to model field but to a specific json. The view is getting automatically bound to that field because of the declaration.
Is there any way we can stop a specific field from binding to view or to override this ?
#Html.TextBoxFor(m => m.country, new { #class = "form-control input-lg"})
While populating this textbox I dont want values from model , I want from specific json which is available in javascript code , but when it posts back I want textbox to post to country field.

You can set the value of contuntry using javascript. As below
$(document).ready(function () {
var JsonObj = GetJson();
$("#country").val(JsonObj.country)
});

Try using #Html.TextBox("country", new { #class = "form-control input-lg"}). And populate the value of your input through JavaScript on client side from JSON object.

Related

How to update properties from object using input fields with onchange methods to write the data?

I'm trying to make a "Edit" section to edit objects and update them in the database:
First of all I obtain the current object and load input fields depending on PropertyType(string = textfield, int = number picker, etc):
Object:
Place input fields:
<EditForm #ref="EditForm" Model="ObjectType" novalidate>
<DataAnnotationsValidator />
#foreach (var property in EditObject.GetType().GetProperties())
{
#if (property.PropertyType.Name.Equals("String"))
{
<SfTextBox Placeholder="#property.Name"
Type="InputType.Text"
#onchange="#((Microsoft.AspNetCore.Components.ChangeEventArgs __e) => property.SetValue(EditObject, __e.Value))"
Value="#property.GetValue(EditObject, null)"
CssClass="create-model-item">
</SfTextBox>
}
else if (property.PropertyType.Name.Contains("Int"))
{
<SfNumericTextBox TValue="int?" Placeholder="Choose a Number Value="#property.GetValue(EditObject, null)" CssClass="create-model-item">
<NumericTextBoxEvents TValue="int?"
ValueChange="#((Syncfusion.Blazor.Inputs.ChangeEventArgs<int?> __e) => property.SetValue(EditObject, __e.Value))">
</NumericTextBoxEvents>
</SfNumericTextBox>
}
}
<SfButton OnClick="SendForm" IsPrimary="true" CssClass="mb-3">Create</SfButton>
</EditForm>
Now I want to change the data of the properties in "EditObject" to the new values that the user has filled in, this is done by the "OnChange" method:
#onchange="#((Microsoft.AspNetCore.Components.ChangeEventArgs __e) => property.SetValue(EditObject, __e.Value))"
However this is giving me this error:
Does anyone know what is going wrong?
Thanks in advance!:)
You don't have to specify the type of the event.
Your #onchange code needs to change to #onchange="#((__e) => { property.SetValue(EditObject, __e.Value); })"
That should stop the error.
There is a two-way binding support for Textbox component. Therefore, no additional method is needed to update new values to Model property. If you used two-way binding it will be updated by default. So, kindly try with #bind-Value attribute.
Also have a look at the below UG link.
UG link: https://blazor.syncfusion.com/documentation/textbox/data-binding/#two-way-data-binding

request.Form[control id] getting null after submit button click

My html controls in my view are bound to my view Model properties
like so:
#Html.ListBoxFor(
m => m.SelectedServiceLine,
Model.ServiceList,
new { id = "Service", multiple = "multiple", style = "width: 150px;" })
I am fetching the selected value using request.Form[Service] and passing it as a parameter to my procedure when clicking submit but when I change my values and submit I am not able to retrieve value in request.Form[Service] as I am getting null here.
Note: during rebind after clicking the submit button the value in SelectedServiceLine is taken from request.Form[Service].
The key used in post is the name of the control, not the id.
To get the value of this control:
#Html.ListBoxFor(m => m.SelectedServiceLine, Model.ServiceList, new { id = "Service", multiple = "multiple", style = "width: 150px;" })
you should use
Request.Form["SelectedServiceLine"]

C# ASP.net MVC4 How to get Main View Control Values from a Partial View ActionResult

I have a main view with a textbox and dropdown list:
#using (Ajax.BeginForm("GetResults", "SomeController", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "PartialDiv" }))
<select name ="dropdown1" onchange="$(this.form).submit();" >
<option></option>
#foreach (var recordrow in ...)
{
<option value="#recordrow.Value" >#recordrow.Text</option>
}
</select>
<select name ="dropdown2" >
<option></option>
#foreach (var recordrow in ...)
{
<option value="#recordrow.Value" >#recordrow.Text</option>
}
</select>
#Html.TextBox("textbox1", null, new { size = 10 })
<div id="PartialDiv" class="GroupBoxForeground" >
#Html.Partial("PartialView")
</div>
The main view automatically renders a partial view once certain controls on the main view have been filled with values. Inside the Partial View, there is a submit button which calls an ActionResult.
Part of the Partial View:
#using (Ajax.BeginForm("Function1", "SomeController", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "someDiv" }))
...
<input type="submit" name="btn_submit" value="Process" style="width:80px" />
My ActionResult looks like this:
[HttpPost]
public ActionResult Function1(FormCollection formdata, MasterModel MstModel)
{
...
}
I am able to successfully bind the values in my Partial View to MasterModel. However, I am unable to get the values of the controls in the Main View while calling the ActionResult. I cannot find the key in the FormCollection and have tried the same method I used in the partial view for model binding.
Both Views are strongly-typed with the MasterModel.
Since the values in the Main View can be changed after the Partial View is rendered, I need to get the values once more when the submit button is clicked in the partial view. Is there a way to access those control values in the Main View inside ActionResult of the Partial View?
Edit:
To explain the situation more clearly as suggested in the comments, My main view is basically a search screen with a textbox and one of the dropdown lists which will be used by the partial view for processing later.
My partial view (in a separate form) shows the results of the search along with a submit button inside to process certain tasks based on the results. However, this processing also requires the 2nd dropdown list's value and the textbox's value in the main view. Those 2 controls in the main view can be changed even after the partial view is loaded. Therefore, I am hoping to find some way to get those values in the main view when the submit button is pressed.
so you mean, you have two separate forms. On posting second form, you also want to post values of the controls, that are in first form. For that purpose, you can take help of jquery, as values outside the form are not posted on submit.
You can create hidden fields in your second form (partial view form), as:
#Html.Hidden("dropdown1value", "", new { #id = "ddl1val" })
#Html.Hidden("dropdown2value", "", new { #id = "ddl2val" })
and then on change event of your dropdown1, you can do like:
//assuming 'dropdown1' is the `id` of your dropdown1
$("#dropdown1").change(function () {
$("#ddl1val").val($("#dropdown1").val());
});
same way for the second dropdown.
Hope you have got the idea.

Generating a list of RadioButtons with the same name in a for-loop in an ASP.NET MVC3 view

I'm working on an ASP.NET MVC3 project, and I have a problem with RadioButtons name generated by a for loop in a PartialView.
First, here is my code, I'll explain the exact problem just after :
Model FileUploadModel
public class FileUploadModel
{
public HttpPostedFileBase File { get; set; }
public bool IsMainFile { get; set; }
}
Model MyModel
public class MyModel
{
// Some properties
public List<FileUploadModel> Files { get; set; }
}
How the PartialView _UploadFiles is called
#Html.Partial("_UploadFiles", Model) // Model is a MyModel model
PartialView _UploadFiles - HERE IS THE PROBLEM
#model MyModel
#{
var nbFiles = (Model.Files != null ? Model.Files.Count : 0);
const int NB_DEFAULT_UPLOAD_FIELDS = 3;
}
#for (int i = 0; i < NB_DEFAULT_UPLOAD_FIELDS; i++)
{
#Html.TextBoxFor(m => m.Files[nbFiles].File, new { type = "file", name = "Files", id = "Files" })
#Html.RadioButtonFor(m => m.Files[nbFiles].IsMainFile, "Main ?", new { id = "rb" + i + "_File_IsMain" })
}
So this is the last snippet the problem. I'd like to create 3 upload fields with an associated RadioButton indicating if the file is the "main file". However, with the above snippet, the displayed view is OK, but when I validate my form, my posted model only have the first picture uploaded (and the corresponding boolean IsMainFile , the others are just ignored). That means the List Files contains only the first TextBox and first RadioButton data
So I tried with #Html.RadioButtonFor(m => m.Files[i].IsMainFile, but the RadioButtons have a different name so user can check all RadioButtons, which is NOT the desired behavior. MVC doesn't authorize me to override the name of the RadioButtons, so I can't give them my own name.
How can I generate these fields is order to only ONE Radiobutton can be checked AND my MyModel.Files property contains all chosen files ?
Thank you
I think your best bet here is to use editor templates.
First, you create a view named FileUploadModel, and place it a folder named EditorTemplates which should exist under your controller's Views folder. Note that the name of the view must match the name of your view model's class.
Its contents would look something like:
#model FileUploadModel
#Html.TextBoxFor(m => m.File, new { type = "file" })
#Html.RadioButtonFor(m => m.IsMainFile, true)
Then, back in your "_UploadFiles" view, your markup for the input field and radio button would change to:
#model MyModel
using (Html.BeginForm(...
#Html.EditorFor(m => m.Files)
...
Note that this will automatically iterate through and apply that editor template for each FileUploadModel object, and automatically name them as required. This of course assumes that the Files property in your model is populated.
Your action that accepts the post should accept type MyModel as its sole parameter, and everything should bind up automatically at post.
There are ways to avoid editor templates and build and name those fields programmatically, but this is really the preferred way, and much cleaner.
More specific to your issue... (In other words, I forgot that the code above won't group radio buttons.)
For the grouping of radio buttons to work, you should set the attribute name as follows:
#Html.RadioButtonFor(m => m.IsMainFile, true, new { Name = "IsMainFile" })
Case matters here. Note that Name must be capitalized for this to work. I'm not sure why this is the case.
The problem is that once you change that attribute, this field will no longer automatically bind in the post. This is unfortunate but understandably is as designed since, if you look at the request, I believe you will see that only the selected radio button value has been posted.
So, you could change the value of the radio button to something recognizable since just that one instance of IsMainFile will show up in the request, if I'm correct.
Perhaps you can use this specific knowledge to tweak your existing code.

Devexpress 12.1 MVC GridView Inside Tab Strip Issues

I'm an intern that has never done any web development just so you know where I'm coming from. I'm currently trying to learn asp.NET MVC 3 using devexpress 12.1 tools. I started with a template that had a devexpress gridview in the content area that is linked up to the Northwind db. It works by itself, but when I create a devexpress tab strip and place the gridview inside the second tab I get the column headings, but no data is displayed. When I click on a column heading to sort the data shows up. I'm wanting the gridview to load after I click the tab and not when the page loads. Maybe my callbacks are the problem. My tab strip is using an ajax callback and the gridview is as well for the paging. I have added the model to the TabControlPartial page and passed in the model in the controller for the TabControlPartial action. I've tried looking at the demos at mvc.devexpress.com, but there is nothing that puts the two together. I don't 100% understand passing the model into the view I guess. I know this is simple, but I don't know what to do. Thanks for your help.
Controller (this may be my issue):
public ActionResult LookUp()
{
return View(NorthwindDataProvider.GetCustomers());
}
public ActionResult _TabControlPartial()
{
return PartialView("_TabControlPartial", NorthwindDataProvider.GetCustomers());
}
public ActionResult _GridViewPartial()
{
return PartialView("_GridViewPartial", NorthwindDataProvider.GetCustomers());
}
LookUp View (Index):
#model System.Collections.IEnumerable
#Html.Partial("_TabControlPartial", Model)
Tab Partial:
#model System.Collections.IEnumerable
#Html.DevExpress().PageControl(
settings =>
{
settings.Name = "TabControl";
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.Height = System.Web.UI.WebControls.Unit.Percentage(100);
settings.CallbackRouteValues = new { Controller = "Customers", Action =
"_TabControlPartial" };
settings.TabPages.Add(
tabOne =>
{
tabOne.Name = "TabOne";
tabOne.Text = "Start";
tabOne.SetContent(() =>
{
ViewContext.Writer.Write("Start");
});
});
settings.TabPages.Add(
tabTwo =>
{
tabTwo.Name = "TabTwo";
tabTwo.Text = "Customer List";
tabTwo.SetContent(() =>
{
Html.RenderPartial("_GridViewPartial", Model);
});
});
}).GetHtml()
GridView Partial:
#Html.DevExpress().GridView(
settings =>
{
settings.Name = "GridView";
settings.CallbackRouteValues = new { Controller = "Customers", Action =
"_GridViewPartial" };
settings.Width = System.Web.UI.WebControls.Unit.Percentage(100);
settings.Height = System.Web.UI.WebControls.Unit.Percentage(100);
settings.SettingsPager.Visible = true;
settings.SettingsPager.PageSize = 15;
settings.ControlStyle.Paddings.Padding = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.Border.BorderWidth = System.Web.UI.WebControls.Unit.Pixel(0);
settings.ControlStyle.BorderBottom.BorderWidth =
System.Web.UI.WebControls.Unit.Pixel(1);
//Configure grid's columns in accordance with data model fields
settings.Columns.Add("ContactName");
settings.Columns.Add("Address");
settings.Columns.Add("City");
settings.Columns.Add("PostalCode");
settings.Columns.Add("Phone");
}).Bind(Model).GetHtml()
You're missing the data in the GridView when the tab is opened. When you open the page, the data for the GridView needs to be loaded in the Model that is returned. right now you load the page (in LookUp), but you aren't pushing the data for the grid. whenever any callback occurs, only at that point is the data getting pulled from the database and returned to the screen (notice you only return data in the Callback methods _TabControlPartial and _GridViewPartial). When you sort a column, or filter, etc, then the callback is fired and the data is returned from the server.
The code you have looks correct, but somewhere in the process the Model is losing it's value. the best option is to put a breakpoint in the tab control, the Grid Binding, and the controller and make sure the data you expect is in place when it's bound.
You could "cheat" by putting in a callback when the tab is activated such as:
#Html.DevExpress().PageControl(
settings =>
{
settings.Name = "TabControl";
settings.ClientSideEvents.Init = "TabControl_Init";
...
}).GetHtml()
and in JavaScript have:
function TabControl_Init(s, e) {
GridView.PerformCallback();
}
this way, after the tabs are initialized, the GridView will run a callback, and grab the data correctly. But it would be better to figure out why the data isn't being sent down in the first place by stepping through the code.

Categories