I have a showSuccess page that requires some get variables, and on that page is a form. When the form submits to executeCreate() and there is an error, it calls the function setTemplate('show') and returns back to showSuccess. However, the get variables are missing.
How do I keep the url the same?
You can get your GET variables from the sfWebRequest object - something like the following should work):
public function executeCreate(sfWebRequest $request)
{
$getVars = $request->getGetParameters();
$qryString = http_build_query($getVars);
// ...some form creation and binding
if (!$form->isValid())
{
$this->redirect("module/show?" . $qryString);
}
}
You probably also need these in your form in the template. Use the relevant parts of the above code in your show action, set them to the view as you would any other variable and use them in the form action parameter:
<form method="post" action="<?php echo url_for("module/create?" . $qryString); ?>">
</form>
Related
I want to pass in two Ids to my method. The method is called DeleteAttendee and is on my SessionController in the Training area.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DeleteAttendee(int sessId, int attId)
I have created a link to get there that takes you to https://localhost:<port>/Training/Session/DeleteAttendee?sessId=1&attId=3.
<a asp-action="DeleteAttendee" asp-route-attId="#item.Attendee.Id" asp-route-sessId="#Model.Id">Delete</a>
Using the default routing, this page can't be found. What do I need to change or set up to route to this method?
Edit: Apparently the problem is that the link is performing a GET, but I need it to POST. How do I change it?
I think you can accomplish what I want to do with a button control. It will actually work better for me now if I can pass in the model and a specific id. I tried the button below. It looks correct in the markup, but the id keeps getting replaced with the sessionId when the button is clicked.
<button formaction="/Training/Session/DeleteAttendee/#item.Id" formmethod="post">Edit</button>
Can you use a ActionLink instead?
#Html.ActionLink("Delete", "DeleteAttendee", "Session", new { sessId = Model.Id, attId = item.Attendee.Id })
I ended up using a submit button that calls javascript and added the value to the viewmodel to get this done.
On the page:
<input type="hidden" asp-for="SelectedAttendeeId" />
<input type="button" onclick="DeleteAttendee(#item.Id)" value="E" />
In javascript:
function DeleteAttendee(attendeeId) {
var selectedAtt = $('#SelectedAttendeeId');
selectedAtt.val(attendeeId);
var model = $('#frmSession').serialize();
$.post('/Training/Session/DeleteAttendee', model, function (data) {
// success logic here
});
}
I'm trying to assign value to the hidden field in java script using the
JavaScript variable and trying to pass it back to the controller. The value every time I go in the post method for my model property DBErrorID is 0.
Razor View:
<body>
#Html.HiddenFor(model => model.DBErrorID, new { id = "DBErrorId" })
<input type="submit" value="Update" class="btn btn-success" onclick="GetValue()" />
</body>
JavaScript:
<script language="javascript" type="text/javascript">
function GetValue() {
$("#DBErrorId").val(totalValues);
// alert(totalValues);
}
<script>
Controller:
[HttpPost]
public ActionResult ErrorStatusView(Models.ErrorStatusModel obj)
{
Models.ErrorStatusModel objreg = new Models.ErrorStatusModel();
objreg.DBErrorID = obj.DBErrorID;
}
Your current server side code is creating an unnecessary new object of ErrorStatusModel as the first line, which will create a new object(objreg variable) with default values(unless you are setting it in a constructor), for an int type property it will be 0. If you are inspecting the values of objreg, that is the reason you see 0 as the property value.
You do not need to create this additional object. The model binder framework will create one for you and map the posted values, when you use ErrorStatusModel your method parameter type. That means your obj property is properly populated by the form data (assuming the DBErrorID property is settable)
[HttpPost]
public ActionResult ErrorStatusView(Models.ErrorStatusModel obj)
{
// obj is populated with form values.
// use obj
// return something.
}
Also, your client side code is trying to set the value of hidden input inside the GetValue method which is called on the onclick event of the submit button. If you are using a normal form submit and your button is inside a form tag, when user clicks on the submit button it will immediately submit the form (with the current value of that input)
If that is the case, you should prevent the default behavior (submitting the form) when the button is clicked, set the value as needded and fire the form submit via JavaScript.
There are multiple ways to do it. Here is one approach- the unobtrusive JavaScript approach- which assumes you have jQuery loaded to your page. Give an Id to the button, which we can use to wireup the click event.
<input type="button" value="Update" class="btn btn-success"
id="btn-save" />
Now in JavaScript, listen to the click event on this button, prevent the normal behavior(submitting the form), update the hidden input value and trigger the form submit.
$(function () {
$('#btn-save').click(function (e) {
e.preventDefault();
$("#DBErrorId").val(34);
$(this).closest("form").submit();
});
})
Also you should not create a new object in server
So, here is a weird behaviour I have noticed today.
I have a controller which inherits from SurfaceController.
I have a [Post] Action method which returns back to the same partial view and that's fine. The reason is due to paging/filtering that happens on that page.
Now, on the view itself, if I use a button submit, I see everything being submitted just fine.
However, if I use a hyperlink with an onclick event to set hidden field values and then do a form.submit(), initially the model has values which are null but then it re-executes the submit with the all of the values put in place again!
That doesn't make sense. What is the difference with a button submit and a javascript function doing a form.submit() ?
There really isn't much code:
// Controller
[HttpPost]
public PartialViewResult FilterResultsForTransaction(MyModel model)
{
.....
}
// View
<script language="javascript">
function ApplySort(fieldname, sortDir)
{
$('#Filter_FieldName').val(fieldname);
$('#Filter_SortDir').val(sortDir);
//var form = $('#form');
//form.submit();
}
</script>
<snip>
<input type="submit" onclick="javascript:ApplySort('OrderDate'........)" value="ASC" />
ASC
Now, if I don't use the submit button but just the hyperlink and comment in the form.submit() in the JS function - it does the post but the model values are null/default and then it recalls itself with the values populated again.
thoughts?!
When you click on the submit button, the page will submit its data BEFORE the script in ApplySort() is complete. So you will have to stop the submitting, then set your hidden field values, and then submit the form. Like this:
<input type="submit" data-field="bla" data-sort="ASC" value="Sort ASC" />
<script>
$("input").on("click", ApplySort)
function ApplySort(e)
{
e.preventDefault(); //stop postback
var btn = $(this);
var form = $('#form');
$('#Filter_FieldName').val(btn.attr("data-field"));
$('#Filter_SortDir').val(btn.attr("data-sort"));
console.log("submit")
form.submit();
}
</script>
Its generally bad to have script code in a onclick, so I bind the click event in my js code with jQuery.
Test it out here: http://jsfiddle.net/03gj1r02/2/
I have a simple Email Composer class where I get all Application Emails content from.
In this example, it sends the products to the email.
Now, I want to print them as well, and I'm trying to re-use the same method to grab the full html from the Email Composer and output it to a View.
the controller action
public ActionResult PrintRules()
{
var products = rep.ListAllProductsByCompanyId(currentCompany.company_id);
string body = mail.GetProductRules(products);
ViewBag.email = HttpUtility.HtmlEncode(body);
return View();
}
the view is:
#{
Layout = null;
string email = HttpUtility.HtmlDecode(ViewBag.email);
}
#Html.Raw(email)
<script>
window.print();
</script>
If I pass the body as a Model I do get errors on the parser, so I'm using the ViewBag instead.
as outputs:
#Html.Raw(email) will output nothing at all
#Html.Raw(email.Length) will output 17463
#email will output the code but the browser outputs it, does not parse it (image below)
What am I missing? I know it must be a really simple thing, but I'm totally blank...
browser output from using #email
Try this
#(new HtmlString(mystring))
or
#MvcHtmlString.Create(ViewBag.Stuff)
i'm trying to join two independent forms (login and register) in the
same page.
My idea is (just looking at the signin form):
Create an action that shows both forms (partials):
public function executeLoginAndRegister(sfWebRequest $request){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
Each partial calls to its action:
form action="php?> echo url_for('#sf_guard_signin') ?>" method="post">
In the actions i write this code
public function executeSignin($request)
{
//...
$this->form = new $MyFormclass();
if ($this->form->isValid())
{
//...
}else{
// save the form to show the error messages.
$this->getUser()->setAttribute('form_signin', $this->form);
return $this->forward('sfGuardAuth', 'loginAndRegister');
}
}
It works, but, for example, if i execute LoginAndRegister and submit
incorrectly the signin form and I go to another page and then return to
LoginAndRegister, i will find the submiting error messages...
If i execute LoginAndRegister and submit incorrectly the signin form and
open another browser tab, i will find the submiting error messages in
the signin form of the second tab...
Any idea? any better approach?
I would just use sfDoctrineApplyPlugin if i were you :)
I have it, just writing in the if "request->isMethod('post')":
public function executeLoginAndRegister(sfWebRequest $request){
if($request->isMethod('post')){
$this->form_signin = $this->getUser()->getAttribute('form_signin');
}
}
Anyway if my approach has any big error or is not safety i would
thank anyone who tell me.
Javi