.NET Core Razor Pages Data Binding with partial views on form submission - asp.net-core

I've got a an object with an Address object as a property which is used several places in my application. I made a partial view which looks like
#model Address
<div>
<div class="form-group">
<label asp-for="#Model.AddressLine1"></label>
<input asp-for="#Model.AddressLine1" />
</div>
....
I use the form like
<form method="post">
<div class="form-group">
<input asp-for="#Model.Request.Business.Owners[0].FirstName" />
<input asp-for="#Model.Request.Business.Owners[0].LastName" />
</div>
<input type="submit"/>
</form>
the data renders fine on the entire form, including the partial Address view. when I submit the form, everyone I reference the Address partial I get back as null when I submit the form, while the other data is data bound correctly. Is it possible to bind data to a partial view and have it submit with a form post correctly?

Likely, you're not providing context to the partial, so that it can generate the names properly. As-is, the partial is going to want to generate names like AddressLine1, when what you actually need for proper binding is Request.Business.Owners[0].Address.AddressLine1. I'm assuming you're doing something like:
<partial name="_Address" model="Request.Business.Owners[0].Address" />
Instead, you need to use the for attribute:
<partial name="_Address" for="Request.Business.Owners[0].Address" />

Related

Scaffolded Identity Razor Pages Forms don't submit unless there is a route parameter

This happens on all the Scaffolded Identity Razor Pages that do not include a route parameter in the Form definition, but let's take the ForgotPassword one as an example:
Here is the form as defined on the scaffolded page:
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
When I click the submit button, nothing happens. The browser dev tools confirm nothing happens. The page does not submit to the server. (and yes, I have entered a valid email address; if I don't, then the jquery validation correctly displays the appropriate error messages.)
But I've found that if I change the form definition to include a route parameter, as follows:
<form asp-route-unusedArg="SomeValue" method="post">
then the submit button works fine, and the form is submitted to the server. (Even though the OnPostAsync method defined by the server code does not expect a parameter at all; it is defined as public async Task<IActionResult> OnPostAsync()). The way I figured this out was to compare the form definition with that of the Login form, which was working fine, and had a route parameter for returnUrl.
What is going on here? Why is the form not submitting unless I add a route parameter?

Checkbox Click Form Submit in Razor Pages AspNetCore 2.2

I am trying to (non-Ajax) get a checkbox to resubmit form in Razor Pages and reload the page / and catch the result in my OnPost method.
I have in my index.cshtml
#page "{id:int?}"
#model IndexModel
<div class="text-center">
<form action="post" name="form1">
<strong>Filter:</strong> Hide Single Runs <input onclick="document.form1.submit()" asp-for="#Model.HideSingle" />
<hr />
And in my PageModel
public class IndexModel : PageModel
{
public bool HideSingle { get; set; } = true;
public async Task OnPost(int? id, bool hideSingle)
{
for say a starting page URL:
http://localhost:5000/TestRuns/1
The form submits on the checkbox click, but it ends up with a Url:
http://localhost:5000/TestRuns/post?HideSingle=false
Which obviously fails to resolve as I am expecting a route of http://localhost:5000/TestRuns/1.
For Asp.net Core form, the default method is Get which means for your current code, it send request with Get instead of post. You could specify the method with post like
<div class="text-center">
<form method="post" name="form1">
<strong>Filter:</strong> Hide Single Runs <input onclick="document.form1.submit()" asp-for="#Model.HideSingle" />
<hr />
</form>
</div>
For another way, you could explictly set the handler like
<div class="text-center">
<form asp-page-handler="post" name="form2">
<strong>Filter:</strong> Hide Single Runs <input onclick="document.form2.submit()" asp-for="#Model.HideSingle" />
<hr />
</form>
</div>
<input onclick="document.form1.submit()" />
is using JavaScript to submit the form. Do you want the page to post back, since you're not using Ajax (from your question)?
You want the call from your page to end up being http://localhost:5000/TestRuns/post?id=1&HideSingle=false. Is id required for your post to work (it's unclear with OnPost(int? id..)?
I order to get both values, you'll need to have hidden form values or multiple <input asp-for="Email" class="form-control" />. You need 1 for hideSingle and on for the id.

Razor Pages ASP.NET unobtrusive ajax Post partial update

I'm trying to update only part of my page from a partial View.
It works perfectly fine if i use this
Click heeeeeeeere
But this is a simple get and i'd like to actually post some data and do something with it. I wrote a form, set its method to post like this.
<form method="post" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed" data-ajax-update="#panel" >
<div class="row">
id : #Html.TextBoxFor(x => x.customer.ID)
</div>
<div class="row">
Name : #Html.TextBoxFor(x => x.customer.Name)
</div>
<div class="row">
<input type="submit" value="send data" />
</div>
</form>
BUT this updates my entire page so my entire page is just the little partial view thats supposed to be updated.
a first observation, it seems you are missing the data-ajax-url from the second form .
Saying that, then in your Razor view you should include on the top of the page
#page "{handler?}"
This will allow you to pass additional information to your handler, then in your form you can simply include something like
<input type="hidden" name="id" value="send value"/>
where value is the value you want to pass and name is how the handler will identify what property to bind this to, then in your .cshtml.cs page your handler should look something like this
public IActionResult OnPostPartial(string id) {...//do something here id == "send value"}
hope this helps

Binding View-Models with collection properties

My view model has a sole property, currentProject, which itself has a child property that is an array of strings. When I bind everything to the view, all the data populates correctly including the array of strings. When I edit the data, the array of strings is not updated.
Is there something specific I have to do here to make this a two-way binding? I tried the the two-way command but it made no difference.
My View Model looks like this:
export class Edit {
currentProject;
...
}
CurrentProject gets set to an instance of the project class:
export class Project {
id = '';
name = '';
modifiedDate = '';
createdBy = '';
students = [];
}
My edit view looks like this:
<template>
<section>
<h1>Edit ${currentProject.name}</h1>
<form role="form" submit.delegate="save()">
<label for="name">Project Name</label>
<input type="text" maxlenth="100" id="name" value.bind="currentProject.name" />
<h2>Students</h2>
<div repeat.for="student of currentProject.students">
<label for="name${index}">Student ${$index + 1}</label>
<input type="text" maxlenth="100" id="name${$index}" value.bind="student" />
</div>
<button class="btn">Add Student</button>
<button type="submit" class="btn btn-primary">Update project</button>
</form>
</section>
</template>
Any help would be greatly appreciated. I suspect I am missing some minor detail.
Thanks,
Andrew
Looks like the issue here is due to strings (primitive type) immutability, there is no reference between string you are editing in input field and the one in the array, it's just two different copies.
That being said, there are two approaches you can take to make it work properly. The best one is to have array of object for students, maybe like this:
[{name: 'Tomas Mann'}, {name: 'Alex Bloom'}]
then repeat.for part would look like:
<div repeat.for="student of currentProject.students">
<label for="name${index}">Student ${$index + 1}</label>
<input type="text" maxlenth="100" id="name${$index}" value.bind="student.name" />
</div>
This data structure is also more flexible. For example, you can add additional student information like age, score, etc. You could even have students array to be an array of Student objects students: Student[], etc.
If you still want to use array of simple strings then you could do this:
<div repeat.for="student of currentProject.students">
<label for="name${index}">Student ${$index + 1}</label>
<input type="text" maxlenth="100" id="name${$index}" value.bind="$parent.currentProject.students[$index]" />
</div>

Prestashop smarty make a form for user and save the input fields to the database?

In Prestashop I am doing a module. In that module I have view file(smarty template). In smarty I am doing form so that user can submit the form from frontend. Now when user makes fill the form and clicks on submit then the form should save all the vales to thae database. So for that in smarty I made a form like this
<div id="content" class="form-wrapper" >
<div class="form-content">
<input type="text" id="name" name="name" placeholder="Name" /> <br />
<input type="text" id="email" name="email" placeholder="email"/> <br />
<input type="text" id="phone" name="phone" placeholder="Phone Number"/> <br />
<input type="submit" name="submit-query" id="submit-enquiry" value="submit" />
</div>
</div>
and in the file where the values will be submitted I have made my code like this
<?php
include '../../../config/settings.inc.php';
include '../../../config/defines.inc.php';
include '../../../config/config.inc.php';
include(dirname(__FILE__).'/../../../../init.php');
if(Tools::getValue('submit-query')) {
$this->_html .=$this->displayConfirmation($this->l('Settings updated successfully'));
}
else {
$this->_html .= $this->displayError($this->l('You Have Some Errors'));
}
?>
Now when doing click on my submit button It is showing error like this
Fatal error: Using $this when not in object context in file.php on line 11
Now can someone kindly tell me what is the issue here and how can I make a form in smarty for frontend users so that they can submit the form and the value will be stored to the database. Any help and suggestions will be really appreciable. Thanks
First I would recommend to do the processing inside of your module, e.g. in init() function, you can get your module link using $this->context->link->getModuleLink('myModuleName'); and add it to the form action attribute, all variables can be assigned using $this->context->smarty->assign().
Storing values in database is quite a wide question. You have to provide some more details about it.
Check some tutorials from Prestashop e.g. Creating a Prestashop Module. You will find most of your answers there.