The client should be able to send everything with a button, so I can do the following:
Send everything as form fields named like invoiceId_detail_text where invoiceId would be the id of the invoice, detail the part, and text the kind of field.
Example:
<form id="invoices" name="invoice">
#foreach(var Invoce in Model.Invoices) {
<div>
<input type="number" id="#String.Format("{0}_amount", Invoice.InvoiceId)"/>
</div>
/*More Input Fields for the Invoice*/
<div>
<button type="submit"></button>
</div>
}
</form>
Or I can put every invoice separated in its own form, and send them by ajax, every form success I send the next one and so on.
Example:
#foreach(var Invoice in Model.Invoices) {
string formName = String.Format("{0}_form", Invoce.InvoceId);
<form id="#formName" class="invoiceForm" id="#formName" action="#Url.Action("EditIndividualInvoice","InvoicingEdit")">
<input type="hidden" name="InvoiceId" value="#Invoice.InvoiceId"/>
<div>
<input type="number"/>
</div>
/*More Input Fields for the Invoice*/
</form>
}
<button type="button" onclick="SendAllForms();">Send</button>
I did some research between some of my co-workers and many of them told me to just go with a post with all the invoices at the same time and then access every field by item id because I don't have knowledge of how many invoices are going to be sent, but i can get all of them by class on JQuery so it shouldn't be a problem.
I also read this article from a UX point of view and it keeps me thinking about it.
By doing it with AJAX the cliend could be able to see a loading bar and it would be great, but if he closes the page the request would be incomplete and it could be complicated.
Which option could be better and why and what are the security implications of using one over another?
I think the solution depends principally of the behavior that you wish.
By doing it with AJAX the cliend could be able to see a loading bar and it would be great, but if he closes the page the request would be incomplete and it could be complicated.
In the 2 solutions, if the user closes the page after clicking the button, this will not cancel the save. Once the request sent, it cannot be cancelled. So you shouldn't have "security" problems whatever the choosen solution.
The only thing you need to be careful, is to disable all AJAX buttons during an AJAX request, to avoid the user sending several request in the same time (that can provoke saving inconsistency data).
The classic solution is generally most simple to implement.
The AJAX solution can be most complicated to implement (more code), but provides a friendliest behavior.
Related
I am currently working on a form. In the form, if there is not an item needed you can click the add button and it takes you to a new form where you can add the item. Instead of my view going to another page, I want it to pop up above the form so that the user can just quickly add the item and not have to travel pages.
Here is a snipit from my Create.cshtml
<div class="form-group">
<label asp-for="INT_CertificationsID" class="col-md-2 control-label"></label>
<div class="col-md-3">
<select asp-for="INT_CertificationsID" class ="form-control" asp-items="ViewBag.INT_CertificationsID"></select>
</div>
<a class="btn btn-default" asp-area="" asp-controller="INT_Certifications" asp-action="Create">Add Certification</></a>
</div>
When the add certification attribute is clicked I would like a box to pop up to the Create.cshtml for the certification. So that they may quickly add it to the list and continue to fill out the form.
I have looked up several examples to do this but most of them are either too old, too long, or don't work in .netcore due to nuget package errors with JqueryUI.
You need to make a controller method that returns the page you want in the popup as a PartialView.
I think you mean modal and not "popup"... you need to use a modal mechanism to create a modal window and get (or post) your partial via AJAX and use the result to display in the modal window.
I like bootbox which is a wrapper for bootstraps modal functionality.
I would load partial view in a hidden div together with the pages that needs them and dynamically display them with JavaScript when needed. Don't use forms to send http request, instead use AJAX.
Using pop-ups can work against you because browsers comes by default with pop-up blockers. Might work on your devbox but it could have a completely different behaviour somewhere else.
Using forms to send request requires the page to be reloaded which does not provide a good user experience.
Fix your solution, don't use nugget for client side script. Use bower instead. Here's a link https://learn.microsoft.com/en-us/aspnet/core/client-side/
I have a requirement for multiple tasks to be populated dynamically in response to a user 'add task' button. I don't know how many tasks will be created by the user and would prefer not to set a maximum number with hidden fields as this would be inefficient with regards to database storage space.
Tasks can be thought of as child elements to notes and are stored in separate tables. I've managed to display multiple tasks on the view but I'm less confident with front-end development and am unsure of how I can add an input field without calling a post-back, thus entering 'mid-stream save' territory..
<html>
<div class="container">
<!-- #using(Html.BeginForm()) { -->
<div>
<label asp-for="Note">Note</label>
<input id="Note" />
<span asp-validation-for="Note"></span>
<label asp-for="Task">Task</label>
<input id="Task" />
<span asp-validation-for="Task"></span>
</div>
<div>
<button type="button">Add Task</button>
<input type="submit" value="Save" />
</div>
<!-- } -->
</div>
</html>
I have also made a small jQuery function that can create task inputs upon the 'add task' button, but with little success in connecting it to the controller/model.
I've had AJAX with JSON recommended to address this requirement but I'm unsure of how this can be implemented in a form and how this can then be read by the controller and ultimately the model?
I'm open to design alternatives, should it better suit my solution.
Ok, I'll try to explain here the approach I usually use to this type of problems, after quite a while developing different applications it finished as one of my favorites.
First of all, If I'm understanding you well, you have a view where a form is build, as a part of a client interaction you need to inject elements that depends on the main entity of your form (usually as a one to many relationship). I will call those "subforms" during this answer.
You need to:
A) Manage client interaction with the elements added/modified/replaced
B) Send the final data to your server's controller so data can be persisted into database.
My approach to this type of situations is try to manage all the client interactions in the client, sending final data only on the end, after user pushes "Save" button.
Obviously... this is not valid for EVERY situation, as sometimes specific requirements could make this solution not recommended.
For the client part:
I build the core of the form on a normal way, through a standard view, usually I place specific containers to inject there the information of the "dynamic" data.
On the "Add task" button I add a listener that creates the HTML for one element of the subform and appends it to the container. Usually this code includes a delete button to eliminate it from the DOM as a whole. I also have a listener to manage those interactions.
Ok... so you now have a form where some buttons can add and remove small parts of code that represents individual elements of your subform.
Include in your client code a data structure (I usually use a JSON object) that represents a list of elements of the subform.
When your user hits the "Save" button, capture the event and, before sending data back to server make this two things:
Loop through your subform structure reading the info that it contains at this moment and store it in your client data structure (the JSON object I refer before). Now you have a JSON object with all your subform information.
Stringify it and store it in a hidden text component which is sent within the form. All of your "subform" fields could be outside of the form, as they doesn't need to be sent, the info travels back to the server in a "class instance" as a JSON structure.
In the server:
When your controller receives your form data, there will be a field which stores a string representing the whole info your user sent through the "subform".
Now you just need to get this info and manage it in the way you like. You can, for example, design a class to load this type of info and send it to the database through your usual persistence engine.
Keep in mind that in this package you are storing not only the elements added, you also have the elements that have been changed since the last edit, so you will probably have to look for them in the database and modify them.
This is quite a wall of text, and probably it's less clear to understand the idea than it's on my mind, so feel free to ask if you don't understand something or there is anything that is not clear enough.
I am writing a recipe manager for my wife in C#/.NET MVC 5. I'm getting to the page for creating a recipe, and I'm a little stumped. A recipe consists of a Name and a list of ingredients.
When I create a view, I have my form:
#using(Html.BeginForm()){
//Form elements
#Html.DisplayNameFor(x => Model.Name)
//button for adding a new ingredient to the recipe
<input type="submit" text="Submit New Recipe!" />
}
When the button for adding an ingredient is clicked, it should render a block of html inside the form just above the button itself, that way the user can add any number of ingredients and then submit the recipe back when the form is posted back to the controller.
For this functionality, should I make the button call a controller that sends back a partial view or something? I'm not sure how to accomplish this outside of JavaScript, but I'm wanting to use a .NET MVC solution if I can.
I try to minimize my reliance on javascript whenever I can, however I agree with #br4d that knockout is your best option here. If you want to avoid it at all cost, it will be more complex, slower and not as user friendly but here is how I would do it.
Enclose the form in a div. Have a place holder div inside the form to hold your ingredients list. Make the "Add new ingredient" call into a controller that will return a partial view with the required fields. In the target attribute indicate the place holder div as the update target and append the response to the html of the place holder div by specifying InsertionMode.InsertAfter.
<div id="parentDiv">
#Html.BeginForm........
#Ajax.ActionLink("Add New Ingredient","ActionName","ControllerName",routeValues,
new AjaxOptions
{
UpdateTargetId = "ChildDiv",
InsertionMode = InsertionMode.InsertAfter
}
<div id=ChildDiv>
</div>
</div>
This code is by no means comprehensive or production ready (I prefer to have a way of handling failed ajax calls and you might want to block off interactions until the call comes back just to mention two of the enhancements). Once again KnockOut would be the preferred way to do this.
I am rendering out a ViewUserControl (.ascx file) in a view:
<% Html.RenderPartial("Comments", Model.Comments); %>
This ViewUserControl shows associated comments on an entry. I would like this control to render out a form as well, so users of my application can contribute.
How would you add a form to a ViewUserControl and handle it's postback?
Just add the form in there the same as you would on any page. In MVC, the form does not postback as such - it simply submits itself and its content (input controls) via HTTP Post to a URL.
Simply create an action in your controller (and hence a URL) which the form will post and do whatever activity is required there...
There is no postaback, like in standard asp.net, there can be only form tag that posts data to some url (controller/action).
Inside your partial user control, write:
<form action="controller/actionname" method="post">
<input type="text" name="inputText" />
<input type="submit" value="Post data to server" />
</form>
In MVC, only input type="submit" triggers form submit. In standard ASP.NET webforms, you can have many Linkbuttons, Buttons, ... but under cover, they all triggers this simple click on input type="submit" through javascript event. One form can post data to only one URL (controller/action), but that can be changed with javascript (as we can see in html source of 'old' asp.net webforms).
then, in controller you can handle post data:
[AcceptVerb(HttpVerb.Post)] // optionally
public ActionResult ActionName(string inputText) ...
Like others have answered already, you simply render a form and handle it's submit with an ActionResult.
For example, if your form (which could be rendered anywhere in your site) was submitting to http://www.yoururl.com/home/save, you would create an ActionResult method named save on the home controller to handle the submit (likely post/get method).
I have a single product, a file that is dynamically created and I need a paypal to return a customer after payment is done to the address of the file.
Simple Buy Now button is elegant but if I put
<input type="hidden" name="return" value="http://www.mysite.com/x727x7e.dat">
into a button's code, simple browser's Page - View Source can reveal the file address before the payment.
Here is a sample of button code:
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="return" value="http://www.mysite.com/x727x7e.dat">
<input type="hidden" name="cancel_return" value="http://www.mysite.com/nothanx.html">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="1111111111">
<input type="image" src="https://www.paypal.com/en_AU/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src="https://www.paypal.com/en_AU/i/scr/pixel.gif" width="1" height="1"></form>
I assume the right way would be to use PayPal api and to generate the file after the transaction has been sucessfull but since I am noob to paypal and was wondering can this be solved in an elegant way?
Can I make a (asp.net c#) button that makes post method with this parameters to paypal, so that return url in not visible to the customer?
Yes, create a hidden input named return and insert your return address. You can also set a hidden input named cancel_return and insert a cancel-return address that is used if the user tries to cancel the transaction. Finally you may add one named notify_url that will receive a POST asynchronously after the purchase. The return address will also receive a POST but only if the user clicks to return.
EDIT:
I just noticed you want to hide the address. One, as I mentioned the payment information is posted to that address, which includes a validation code you can ask paypal if the payment is valid. So this means it's not vital to keep the address secret (besides, after one payment a user could see where he went to anyway).
Two, you may register an SSL key with paypal and then encrypt your fields with it. Please see their documentation on how to do this.
The worst that a user can do is complete an erroneous payment through paypal -- they'd still be charged money but would have to, with a straight face, claim that your website said it (whatever you are selling) was only $0.01 USD instead of $10.00 USD.
That may or may not be a concern depending on what you are selling.