Why mvc Html.HiddenFor does not render my field? - asp.net-mvc-2

I'm trying to do this simple thing
<%= Html.HiddenFor(model => model.Id)%>
the model is
[HiddenInput(DisplayValue=true)]
public int Id { get; set; }
but i always get this rendered
<input type="hidden" value="0" name="UserInfo.Id" id="UserInfo_Id">
i've check and the id is NOT 0.. ?!
need some explanation here...
Edit
The problem seem's to be the post thing mentionned below.
This is working
<input type="hidden" value="<%= Html.AttributeEncode(Model.Id) %>" id="<%= Html.IdFor(model=>model.Id)%>" name="<%= Html.NameFor(model=>model.Id)%>" />
Thanks to Manaf

I'm not sure if this is the case with you but the Html.HiddenFor() "do not output correct values after a post if the value is changed during the post." and this is a not a bug it was designed that way.
Quick Fix :
Don't use the helper, try this instead :
<input type="hidden" value="<%= Html.AttributeEncode(model.Id) %>" id="Id" name="Id" />
Always worked for me :)

To add to Manaf's correct answer--you note correctly that the problem occurs in controller actions that handle posts. I was getting the same problem in a controller action that handles a get when I explicitly pass a model to a view:
[HttpGet]
ActionResult SearchForSomething(SearchForm searchForm)
{
searchForm.MyId = SomeValueFromSession;
return View("SearchForSomething", searchForm);
}
In the view, this line that rendered a hidden input for MyId always rendered "0":
#Html.HiddenFor(m => m.MyId);
Per Darren Oster's suggestion I changed to the following and fixed the problem:
[HttpGet]
ActionResult SearchForSomething(SearchForm searchForm)
{
searchForm.MyId = SomeValueFromSession;
ModelState.Clear();
return View("SearchForSomething", searchForm);
}

My comment is relegated to the last place (even I couldn't find it), so:
In case you don't want to clear the modelstate, as Darren Oster suggested, removing the problematic key worked for me: ModelState.Remove("HiddenKey")

I ran into this problem as well with #Html.HiddenFor.
#Html.Hidden("Id", Model.Id) also gave value 0, but a foreign key field, e.g., #Html.Hidden("Model_Category_ModelId", Model.Category.ModelId) did work, while it #Html.HiddenFor(m => m.Category.ModelId) did not.
My solution was to redirect to the get action, as described in ASP NET MVC Post Redirect Get Pattern.

Related

Protractor: element is not getting cleared with clear function

I am expecting that the previous value on firstname is removed and then I can write the new value. But it is not removing the name.
Clear() function is not helping here.
var firstname= element(By.model('subject.firstName'));
firstname.clear().then(function() {
firstname.sendKeys('bob');
})
HTML:
<input type="text" ng-model="subject.firstName"
placeholder="First Name" name="firstName" validator="required"
valid-method="submit" message-id="requireFirstName"
ng-maxlength="50" class="ng-pristine ng-pending ng-empty
ng-valid-maxlength ng-touched">
Protractor version: 4.0.11
I generally add click() event before performing clear() or sendKeys(), just to make sure focus is on element. For example:
element(by.model('anyvalue')).click().clear().sendKeys(value);
Make sure you have an element with model anyvalue on your website.
Change
element(By.model...
to
element(by.model...
I believe that you don't have to use then() on clear, even though it returns a promise. So you can check if this will work:
firstname.clear();
firstname.sendKeys('bob');

How to bind multiple snippets to one input field in a form

I'am trying to have auto complete and onBlur functionality attached to the same input field using Liftweb framework.
I have them working independently.
What I'am trying to do is have an auto complete input field and on selecting the value from the suggestion, some business logic is to be performed and another input field needs to be updated.
But only the auto complete feature is working.
This is the form
<form class="lift:CapitalOnBlur">
Country : <input id="countryNameOnBlur" type="text" name="countryNameOnBlur"/><br />
Capital: <input id="capitalNameOnBlur" type="text" name="capital"/>
</form>
This is the snippet
object CapitalOnBlur {
val capitals: Map[String, String] = Map(
"india" -> "New Delhi",
"uganda" -> "Kampala",
"japan" -> "Tokyo")
def render = {
def callback(countryName: String): JsCmd = {
val capital = capitals.getOrElse(countryName.toLowerCase, "Not Found")
SetValById("capitalNameOnBlur", capital)
}
val default = ""
def suggest(value: String, limit: Int) = capitals.filter(_._1.startsWith(value.toLowerCase)).keys.toSeq
def submit(value: String) = Unit
"#countryNameOnBlur" #> AutoComplete(default, suggest, submit) &
"#countryNameOnBlur [onBlur]" #> SHtml.onEvent(callback)
}
}
This is what I actually want to do. I tried this and only onBlur event is triggered.
According to my needs, When I start typing the country name in the first input field, it should show me the suggestions and on selecting the suggestion i.e.; onBlur from that input field, the corresponding capital should be rendered in the next input field.
And also is there a way to trigger an action on selecting a suggestion using the inbuilt Auto complete feature of lift.
I am adding this as a separate answer since the edit is essentially a separate question. The AutoComplete widget from Lift does not modify an existing element on the page, but rather replaces it with the following NodeSeq, as per the source.
<span>
<head>
<link rel="stylesheet" href={"/" + LiftRules.resourceServerPath +"/autocomplete/jquery.autocomplete.css"} type="text/css" />
<script type="text/javascript" src={"/" + LiftRules.resourceServerPath +"/autocomplete/jquery.autocomplete.js"} />
{Script(onLoad)}
</head>
<input type="text" id={id} value={default.openOr("")} />
<input type="hidden" name={hidden} id={hidden} value={defaultNonce.openOr("")} />
</span>
Since that has now replaced the original HTML, the second line where you add an onBlur handler is not applied to anything useful. However, the AutoComplete constructor does take an optional parameter for attributes and you can probably use that to add an onBlur attribute to the input tag.
You can try something like this:
"#countryNameOnBlur" #> AutoComplete(default, suggest, submit,
("onBlur", SHtml.onEvent(callback).cmd.toJsCmd))
The above should pass in a tuple which specifies the attribute name, and the string representation of the Javascript you want executed. This should accomplish what you are looking for as long as the AutoComplete library doesn't also rely on the onBlur event. That case is doable too, but a bit more work.
One other thing to note is that onBlur is fired when the input loses focus, ie: the user moves the cursor to another field. If you want it to fire any time the text changes, regardless of cursor position, you may prefer the onChange event.
If you are looking to bind to different events on the same element, so that you end up with something like: <input onblur="getCapitalName" onchange="autoComplete">, you can try using SHtml.onEvent. Something like this in your snippet should do the trick:
object CapitalOnBlur {
def render =
"* [onblur]" #> SHtml.onEvent(e => CapitalOnBlur.getCapitalName(e)) &
"* [onchange]" #> SHtml.onEvent(e => CapitalOnBlur.autoComplete(e)) &
...
}
And then call the snippet from your input, like this:
<form>
Country : <input id="countryNameOnBlur" data-lift="CapitalOnBlur" type="text" name="countryNameOnBlur"/><br />
</form>
I am not sure what any of the arguments your code takes, so the above is mostly illustrative - but will hopefully get you on your way.

Getting value of a hidden element in Lift

I have a hidden input field in HTML, it contains SomeValue:
<input id="event_id" type="hidden"> SomeValue </input>
I need SomeValue in server-side.
Is there a SHtml method I can use? The following code should get the value on submit, I need the value once the page is loaded.
"event_id" #> SHtml.onSubmit(id = _)
In the template you can just write
<input id="event_id"></input>
And in the snippet you can use the SHtml.hidden method:
SHtml.hidden(() => println("hidden field"))

$_post in Kohana controller

i was wondering if i can get a variable with $_post, in a kohana controller if the controller doesn't 'control' a form.
So, if i insert in a view something like:
<form name="ordering" id="ordering" method="post" action="">
<input type="hidden" id="ordering" value="0">
<select id="ordering" name="ordering">
....
in the controller i put :
$ordering = $_POST['ordering'];
but gives me an error
or
if ($this->request->method == 'POST') {
$ordering = $_POST['ordering'];
}
but in this case it never gets there(at this bunch of code).
so my question is: how can i retrieve in a controller a $_post variable if the controller doesn't handle only a form? thank you!
Kohana 3.0 :
if ($_POST)
{
$ordering = arr::get($_POST, 'ordering');
...
Kohana 3.1 :
if ($ordering = $this->request->post('ordering')) // or just $this->request->post()
{
...
PHP will issue a notice if you attempt to access an undefined array element.
So if the "ordering" form was never submitted, attempting to access $_POST['ordering'] will result in
PHP Notice: Undefined index: ordering in ...
Kohana's Arr class provides a nice helper method to get around this.
If you call
$ordering = Arr::get($_POST, 'ordering', 0);
It will retrieve the ordering value from the post variable. If $_POST['ordering'] is not set, it will return the third parameter instead. You can then try if ($ordering) ...
This is useful for $_POST/$_GET arrays, or any function that accepts arrays – it allows you to concisely specify a fallback behavior rather than having to test with isset.
One of the advantages of Kohana is that the source code tends to be very clean and easy to understand (which is nice because documentation is sparse.) I'd suggest you take a check out the Kohana_Arr class and look at the methods available!
ID's are unique! Use class insted or different IDs.
Your form and the select both have got ordering, change one to something else, like:
<form name="ordering_form" id="ordering_form" method="post" action="">
<input type="hidden" id="ordering_input" value="0">
<select id="ordering" name="ordering">
...
</select>
</form>
and in your Kohana Controller:
if( isset( $_POST['ordering'] ) )
{
$ordering = $_POST['ordering'];
}
this should work, because i cant find any other error

Request.Form as array

Greetings. I have some inputs dynamically added to form.
<input name="input_names[]" />
When form was posted, I can get these names like this:
var names = Request.Form["input_names[]"];
And I've got CSV string. It's not a problem and I can split it by comma. Problem happens when I write down text which includes comma. Then I cannot split this string correctly. Split method will divide single string into two or more and that's a problem.
How can I avoid this problem?
One way would be to call them:
<input type="text" name="inputNames" />
<input type="text" name="inputNames" />
...
And in your controller action:
[HttpPost]
public ActionResult Index(string[] inputNames)
{
return View();
}
This way you don't have to worry about splitting. You controller action will already receive an array.