Trying to Dynamically Bind my "ng-true-value" in Angularjs - c#

I am loading some values from a database and what I'm trying to do here is have a checkbox, load the description and then have 2 text boxes, the first is editable, and the second is readonly.
Both text boxes start with the values loaded from the database, then when the checkbox is checked, the value from the editable text box appears in the readonly text box, when it is unchecked, the readonly checkbox value is 0.
<div ng-if="condition.ConditionDesc == 'Other'">
<div class="col-sm-1 unpad" ><input type="checkbox" id=OtherCheckbox" ng-disabled="condition.Score_Potential.$invalid && condition.Score_Potential.$invalid" ng-model="condition.ConditionExists" ng-true-value="{{condition.Score_Potential}}" ng-false-value="0"/></div>
<div class="col-sm-2 unpad">{{ condition.ConditionDesc }} </div>
<div class="col-sm-5 unpad"><textarea id="OtherText" cols="30" placeholder="Please Specify." rows="1"></textarea></div>
<div class="col-sm-2"><input type="text" id="" name="" ng-model="condition.Score_Potential" class="form-control" format="number" required /></div>
<div class="col-sm-2"><input type="text" id="" name="" ng-model="condition.ConditionExists" class="form-control" readonly="readonly" format="number" required /></div>
</div>
Whenever I type a number in the editable textbox and then check my checkbox, it only puts the original value of the editable textbox into the readonly textbox. Any ideas of how to fix this?

You can solve this with some basic pre-processing and post-processing of model data:
Remove ng-true-value and ng-false-value, replace the model with a temporary model, and add a controller:
<input type="checkbox" id=OtherCheckbox"
ng-disabled="condition.Score_Potential.$invalid && condition.Score_Potential.$invalid"
ng-model="condition.conditionChecked"
ng-controller="CheckboxController" />
Controller that sets a temporary model value that is not affected by Score_Potential changes:
var cond = $scope.condition
yourApp.controller('CheckboxController', ['$scope', function($scope) {
$scope.$watch('condition.ConditionExists', function(conditionExistsValue) {
cond.conditionChecked = (conditionExistsValue === cond.Score_Potential);
}
}]);
When saving: conditionally set the value of ConditionExists to Score_Potential based on our temporary model value:
var cond = $scope.condition
cond.ConditionExists = cond.conditionChecked ? cond.Score_Potential : 0;

Related

List hidden value passes wrong value to controller

I have a list In my view. For each row, I view button and I am passing Id value as hidden. But when I click any button it is passing wrong hidden value to the controller. Always it passes the first-row hidden value to the controller.
View:
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</div>
</div>
}
Controller:
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string viewId)
{
return RedirectToAction("ViewDetails");
}
To get all values you need to change the input value type in your controller to array of strings.
I hope that this solution can help you
[HttpPost]
[MultipleButton(Name = "action", Argument = "view")]
public ActionResult ViewDetail(string[] viewId)
{
return RedirectToAction("ViewDetails");
}
if you want to get the exact value you need to duplicate the form within your foreach
in this case you should write somthing like this :
#foreach (var list in Model)
{
<div>
<div > #( ((int)1) + #Model.IndexOf(list)).</div>
<div >#list.details</div>
<div class="col-md-2 row-index">
<form ... > // complete your form attributes
<button class="btn btn-link" type="submit" name="action:view" id="view">View</button>
<input type="hidden" name="viewId" id="viewId" value="list.WId" />
</form>
</div>
</div>
}
Note : You should delete the global form
You should have one form for each row. then you submit that row.
Otherwise as you state it passes first value.
You are setting each value to the same element ID (which is invalid anyway) and name. When you submit your form (which would be more helpful to fully answer your question) it is finding the first element that matches that criteria and submitting it.
There are multiple ways to resolve this such as the already mentioned form per entry but the other preference would be to modify you button to a div and add a click handler to pass the specific value to a js function which would then submit to the controller. Its a preference choice regarding how tightly coupled you want your front end. But the main problem is your element naming convention.

asp.net core mvc model binding with jquery repeater

I am using jquery repeater in my form to dynamically add only a part of input group to form. I did try but couldn't get inputs bind to model, I went blind.
Here my model.
public class SuggestionCreateEditViewModel
{
public Guid[] DetectionId { get; set; }
public SuggestionCreateEditRepeatedModel[] Repeated { get; set; }
}
public class SuggestionCreateEditRepeatedModel
{
public Guid To { get; set; }
public string Description { get; set; }
public DateTime Deadline { get; set; }
}
Form, I removed a lot of parts of form for brevity
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-9 col-md-9 col-sm-12 input-group date">
<input name = "Repeated.Deadline" type="text" readonly class="form-control toValidate dtDueDate" />
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name = "Repeated.Description" class="form-control toValidate txtSuggestion" type="text" >
</textarea>
</div>
after adding a new repeated section to form and before posting it to server, if I form.serailizeArray() it returns collection like as follows (what jquery form repeater dynamically shape names I believe)
{name: "DetectionId", value: "afca1b82-0455-432e-c780-08d6ac38b012"}
{name: "[0][Repeated.To][]", value: "b1176b82-1c25-4d13-9283-df2b16735266"}
{name: "[0][Repeated.Deadline]", value: "04/04/2019"}
{name: "[0][Repeated.Description]", value: "<p>test 1</p>"}
{name: "[1][Repeated.To]", value: "188806d8-202a-4787-98a6-8dc060624d93"}
{name: "[1][Repeated.Deadline]", value: "05/04/2019"}
{name: "[1][Repeated.Description]", value: "<p>test 2</p>"}
and my controller
[HttpPost]
public IActionResult CreateSuggestion(SuggestionCreateEditViewModel model, IFormFile[] documents)
{...
controller couldn't get Repeated binded, only DetectionId is binded. How should I shape my model to get the data?
Here is a working demo for with jquery.repeater.js, pay attention to this line <div data-repeater-list="Repeated"> which will format the field like name="Repeated[0][Description]"
#model TestCore.Models.SuggestionCreateEditViewModel
#{
ViewData["Title"] = "Contact";
}
<form class="repeater" asp-action="CreateSuggestion" method="post">
<!--
The value given to the data-repeater-list attribute will be used as the
base of rewritten name attributes. In this example, the first
data-repeater-item's name attribute would become group-a[0][text-input],
and the second data-repeater-item would become group-a[1][text-input]
-->
<div data-repeater-list="Repeated">
<div data-repeater-item>
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name="Description" class="form-control toValidate txtSuggestion" type="text">
</textarea>
</div>
</div>
</div>
<input data-repeater-create type="button" value="Add" />
<input type="submit" value="Submit"/>
</form>
#section Scripts{
<!-- Import repeater js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js"></script>
<script>
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// start with an empty list of repeaters. Set your first (and only)
// "data-repeater-item" with style="display:none;" and pass the
// following configuration flag
initEmpty: true,
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if (confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
// (Optional)
// Removes the delete button from the first list item,
// defaults to false.
isFirstItemUndeletable: true
})
});
</script>
}
By the looks of things, the controller cannot bind the repeater properties back to your view model because the naming of the posted content does not match the naming in your view model (as Topher mentioned).
The DetectionId is named correctly though because the name of the property matches and its not an array.
To resolve an array we need to make sure we include the property name in the form as well as an index so that mvc model binding knows where to bind the result to.
With that, can you try changing the format of the name to:
Repeated[0].To
That should match up with your controller and correctly bind.
For more info on binding, please see this.

How do i get radio button checked in C# MVC without a Model? [duplicate]

This question already has answers here:
How can I bind a radio button with model data in ASP.Net MVC?
(2 answers)
Closed 6 years ago.
I have this radio button code in my MVC Razor View form and other form data.
<div class="row">
<input type="radio" id="Apply-Self" name="selector">
<label for="Apply-Self">Apply for Myself</label>
<div class="check"></div>
<input type="radio" id="Apply-Others" name="selector">
<label for="Apply-Others">Apply for Others</label>
<div class="check"><div class="inside"></div></div>
</div>
This radio button is not a datatype in my model because I'm using this as a front end option. When I click on submit my controller has all the data I want but want to use the radio button to do a condition check before I submit.
How can I get the radio button id to the controller so that I can do this?
[HttpPost]
public ActionResult ApplyAC(ACModel Model)
{
if (Apply-Self is check)
{
var AddAC = Ac.Add(Model);//add data1 in model
}
else
{
var AddAC = Ac.Add(Model);//add a different data
}
}
OK, I found a solution. Simply add a catch by its selector name in the controller and values to the radio buttons.
<div class="row">
<label for="Apply-Self"><input type="radio" id="Apply-Self" name="applyself" value="True" #(ApplySelf ? "checked='checked'" : "")>Apply for Myself</label>
<div class="check"></div>
<label for="Apply-Others"><input type="radio" id="Apply-Others" name="applyself" value="False" #(ApplySelf ? "":"checked='checked'") />Apply for Others</label>
<div class="check"><div class="inside"></div></div>
</div>
Controller
[HttpPost]
public ActionResult ApplyAC(ACModel Model, bool selector)
{
if (Selector)
{
var AddAC = Ac.Add(Model);//add data1 in model
}
else
{
var AddAC = Ac.Add(Model);//add a different data
}
}
You can bind it to a simple string value, on the server side. First add value attributes:
<div class="row">
<input type="radio" id="Apply-Self" name="selector" value="self">
<label for="Apply-Self">Apply for Myself</label>
<div class="check"></div>
<input type="radio" id="Apply-Others" name="selector" value="others">
<label for="Apply-Others">Apply for Others</label>
<div class="check"><div class="inside"></div></div>
</div>
On the server side you can bind the selected value to a string parameter:
[HttpPost]
public ActionResult ApplyAC(ACModel Model, string selector)
{
if (selector == "self" )
{
// ...
}
else if( selector == "others" )
{
// ...
}
}
The ideal solution would be to bind the value to an enum on the server side, but the string is easier.

Get selected value from bootstrap country picker

I'm using the bootstrap country picker in my web form. I want to get the selected value from country picker.
Here's my country picker code:
<div id="country" class="form-group bfh-selectbox bfh-countries" data-country="US" data-flags="true">
<input type="hidden" value="">
<a class="bfh-selectbox-toggle" role="button" data-toggle="bfh-selectbox" href="#">
<span class="bfh-selectbox-option input-medium" data-option=""></span>
<b class="caret"></b>
</a>
<div class="bfh-selectbox-options">
<div role="listbox">
<ul role="option"></ul>
</div>
</div>
</div>
And I try to get the selected value with this code (I'm using the post method to pass values):
Country.Text = Convert.ToString(Request.Form["country"]);
I use another page (Country picker in Login.aspx, Data retrieving from another page Test.aspx) to retrieve the data.
But this is not giving me any result - what should I do?
It may be a bit long winded but you could use jQuery to get the selected value and then pass that to an asp control...
//Get selected value
var selected = $( "#country option:selected" ).text();
//Then pass to control
var controlCountry = $("#<%=controlId.ClientID%>");
controlCountry.val = selected;
Hope it helps or puts you on the right path.

MVC 5 Razor view not binding bool to input

I have a razor view (Framework 4.5, MVC 5) and an html input type=checkbox with the value equal to a model boolean value but instead of true or false it binds "value".
This is my code:
for (int index = 0; index < Model.Item1.Locations.Length; index++)
{
WSTupleOfInt32StringStringBoolean location = Model.Item1.Locations[index];
<div class="editor-field">
<input id="#string.Format("presentation.ServiceInfoes[{1}].Locations[{0}].Key", index, Model.Item2)" type="checkbox" value="#location.ThirdValue" name="#string.Format("presentation.ServiceInfoes[{1}].Locations[{0}].ThirdValue", index, Model.Item2)" />
</div>
<div class="editor-label">
<label for="#string.Format("presentation.ServiceInfoes[{1}].Locations[{0}].Key", index, Model.Item2)">#location.FirstValue</label>
#if (!string.IsNullOrEmpty(location.SecondValue))
{
<img alt="#location.SecondValue" src="#string.Format("//maps.google.com/maps/api/staticmap?center={0}&markers=color:blue|{0}&zoom=15&size=64x64&sensor=false", location.SecondValue)" />
}
</div><br />
}
The location.ThirdValue is the boolean property, debuging the property it's fine.. but in the HTML i get value="value" and not value="false".
What's happening?
See this Answer
Basically you want to use HTML.CheckBoxFor(model => model.booleanProperty)
Do this
<input id="#string.Format("presentation.ServiceInfoes[{1}].Locations[{0}].Key", index, Model.Item2)" type="checkbox" #(location.ThirdValue ? "checked" : "") name="#string.Format("presentation.ServiceInfoes[{1}].Locations[{0}].ThirdValue", index, Model.Item2)" />
The value is not setting checkbox to be checked or not, value has different function. For example if you set value to 'test' and check the checkbox, when you submit the form, you will see that instead of true value of submitted variable will be 'test';
you can do pretty cool stuff with it. For example you have 3 checkboxes on your form. all of them have the same name, but different values. when you submit the form, the result you get will be comma-separated string with values of checked checkboxes;

Categories