FormCollection not posting a input value - c#

I'm trying to get two input values from a view and pass them to controller using FormCollection.
These values change is based in a double click in a table row as you can see in jquery code below.
When i tried the first time only with id_artigo it worked! Then, when i tried do the same with descricao, it return the same view because descricao isn't geting the value.
id_artigo is an integer and descricao is a string.
What am i doing wrong ?
public ActionResult Create(NebluViewModel necessidadeModel, FormCollection collection)
necessidadeModel.NecessidadesModel.id_artigo = int.Parse(collection["label"]);
necessidadeModel.NecessidadesModel.descricao = collection["labelD"];
<div class="form-group">
<span class="id-label"></span>
<input type="hidden" id="label" name="label" value="" />
</div>
<div class="form-group">
<span class="id-labelD"></span>
<input type="hidden" id="labelD" name="labelD" value="" />
</div>
<script>
$(document).ready(function () {
var table = $('#example').DataTable();
$('#example tbody').on('dblclick', 'tr', function () {
let $tr = $(this);
if ($tr.hasClass('selected')) {
$tr.removeClass('selected');
} else {
table.$('tr.selected').removeClass('selected');
$tr.addClass('selected');
$('#classModal').modal('hide');
let targetValue = $tr.find('td:first').text();
let targetDesc = $tr.find('td:nth-child(3)').text();
$('.id-label').text(targetValue);
$('#label').val(targetValue);
$('.id-labelD').text(targetDesc);
$('#labelD').val(targetDesc);
}
});
});
</script>
Update
After check using DevTools, my input values are getting the right values. Only "label" is being passed to controller. I can't understand why "labelD" isn't.

Related

How to post dynamic created elements to database MVC c#

Good day, i have dynamically created form elements with jquery that looks like this:
<label for="fname" class="fname_label col-sm-2 control-label">First Name</label>
<div class="col-sm-4">
<input type="text" class="fname_input form-control" id="fname" placeholder="First Name" name="firstnames">
</div>
<label for="uemail" class="uemail_label col-sm-2 control-label">Email</label>
<div class="col-sm-4">
<input type="text" class="uemail_input form-control" id="uemail" placeholder="Email" name="emailaddresses">
A user can create multiple elements like this with same name and ids. I mean if a user should click on add more, the same elements are created with the same name and id with jquery. A user can create multiple elements say 10 or more. My question is how can i post or insert the values of the dynamically create elements to the database. i am using c# in MVC. Thank You.
Had a bit of time and put this together. I created a JavaScript namespace to hold my functions, data etc; kept the jQuery part separate for the event (submit and add rows) management. You could easily add capability to delete new entry groups (row) as well, just need ONE to stay as I used .clone() to get that new row.
Sample markup using some bootstrap stuff (not required for the functional part). Note I used jQuery for the ajax stuff, you would not have to but it made the sample a bit smaller perhaps.
<div class="container">
<form id="myform">
<div class="inputs-holder">
<fieldset class="entry-group">
<legend class="col-form-legend col-xm-2">
one input
</legend>
<div class="form-group row">
<label class="col-xs-2 col-form-label col-form-label-sm">Name</label>
<div class="col-xs-7">
<input required="true" class="form-control form-control-xs name-field" type="text" />
</div>
</div>
<div class="form-group row">
<label class="col-xs-2 col-form-label col-form-label-sm">Email</label>
<div class="col-xs-7">
<input required="true" class="form-control form-control-xs email-field" type="email" placeholder="enter email" value="testme#example.com" />
</div>
</div>
</fieldset>
</div>
<div class="form-group row">
<div class="offset-xs-2 col-xs-5">
<button id="submitme" type="submit" class="btn btn-primary btn-xs">Submit Me</button>
</div>
<div class="offset-xs-2 col-xs-5">
<button id="addnewgroup" type="button" class="btn btn-xs">Add new group</button>
</div>
</div>
</form>
</div>
<div id="results">
Entries
</div>
Some script to process and push data via ajax to server:
/* Latest compiled and minified JavaScript included as External Resource */
var myApp = myApp || {};
myApp.arrayObj = {
// some stuff clipped out not used here...
// use to lookup duplicates
lookup: function(myArray, searchTerm, property, firstOnly) {
var found = [];
var i = myArray.length;
while (i--) {
if (myArray[i][property] === searchTerm) {
found.push(myArray[i]);
if (firstOnly) break; //if only the first
}
}
return found;
},
// could be used to validate duplicates for example
lookupAll: function(myArray, property, searchTerm) {
return this.lookup(myArray, searchTerm, property, false);
}
};
myApp.data = {
entries: [],
saveUrl: "/Home/SaveEmails" this COULD be from server/MVC
};
myApp.func = {
addEmailRow: function(myArray, item, allowdups, uniquekey) {
// matches the POCO object class names
var entry = {
"name": item.name,
"email": item.email
};
if (allowdups || (!allowdups && !myApp.arrayObj.lookup(myArray, entry[uniquekey], uniquekey, true).length)) {
myArray.push(entry);
} else if (allowdups && myApp.arrayObj.lookup(myArray, entry[uniquekey], uniquekey, true).length) {
myApp.data.entries[uniquekey] = item[uniquekey];
} else if (allowdups && !myApp.arrayObj.lookup(myArray, entry[uniquekey], uniquekey, true).length) {
myArray.push(entry);
}
},
// just something to show what is entered/being submitted
showEntries: function(list) {
$.each(list, function(index, value) {
$('#results').append("<div>" + value.name + " " + value.email + "</div>");
});
},
// the important part
saveEntries: function(list) {
var entries = JSON.stringify({
'Entries': list
});
$.ajax({
contentType: 'application/json;',
dataType: 'json',
type: 'POST',
url: myApp.data.saveUrl,
data: entries
}).done(function() {
$('#results').html('"SaveEmails()" successfully called.');
})
.fail(function(response) {
$('#results').html(response);
});
}
};
$(document).ready(function() {
// add new "group" row
$('#addnewgroup').on('click', function() {
var holder = $('.inputs-holder');
// clone that first row
var newRow = holder.find('.entry-group').eq(0).clone();
// clear any values entered and append it
newRow.find('input').val("");
newRow.appendTo(holder);
});
// a bit verbose for clarity here
$('#myform').on('submit', function(e) {
e.preventDefault();
e.stopPropagation();
// clear entries
myApp.data.entries = [];
var allowdups = false,
uniquekey = "name";
var holder = $('.inputs-holder');
// get entries
holder.find('.entry-group').each(function() {
var email = $(this).find('.email-field').val();
var name = $(this).find('.name-field').val();
var item = {
"email": email,
"name": name
};
myApp.func.addEmailRow(myApp.data.entries, item, allowdups, uniquekey);
});
$('#results').html("<div>Results:</div>");
myApp.func.showEntries(myApp.data.entries);
myApp.func.saveEntries(myApp.data.entries);
// supress default submit form
return false;
});
});
Now the server side:
/* MVC for this: */
// POCO object: - reference this whereever you put it.
public class EmailEntry
{
public String name { get; set; }
public String email { get; set; }
}
// controller/ method: used IEnumerable instead of List as simpler
public class HomeController : Controller
{
[HttpPost]
public void SaveEmails(IEnumerable<EmailEntry> entries)
{
// do stuff with email entries here...validate/save for example
}
}
ALL this is untested and my contain small errors but I believe it to be pretty bug free.

How to use unobtrusive validation to make an input field required field if another input field is empty?

I have a simple form with three different text boxes to enter the search criteria before a resultset can be returned. Among the three fields I want to make two fields conditionally required if the other one is empty.
In the attached screenshot the search form cannot be submitted without entering either the "Title" or "Performers" fields. It is fine if both fields have values. I wanted to achieve this by making "Title" as a required field when "Performers" is empty. But my code below doesn't work. I have the necessary validation at the server side. I am looking for a client side solution.
HTML Source code:
<form id="searchWorkForm">
<div class="contourField textfield">
<label for="searchWorkTitle" class="fieldLabel">Title</label>
<div class="search-input">
<a id="searchWork" href="#" style="z-index: 2000; margin-top: 0;"><img src="/images/profile-search.png" alt="" style="z-index: 1000;" id="profileSearch" /></a>
<input type="text" name="searchWorkTitle" id="searchWorkTitle" class="text caps" value="" placeholder="Title" data-val="true" data-val-requiredif="title is mandatory" data-val-requiredif-otherpropertyname="searchWorkPerformer">
<span class="field-validation-valid" data-valmsg-for="searchWorkTitle" data-valmsg-replace="true"></span>
</div>
</div>
<div class="contourField textfield">
<label for="searchWorkWriter" class="fieldLabel">Writers</label>
<div class="wideInput">
<input type="text" name="searchWorkWriter" id="searchWorkWriter" class="text caps" value="" placeholder="Writer Name">
<span class="field-validation-valid" data-valmsg-for="searchWorkWriter" data-valmsg-replace="true"></span>
</div>
</div>
<div class="contourField textfield">
<label for="searchWorkPerformer" class="fieldLabel">Performers</label>
<div class="wideInput">
<input type="text" name="searchWorkPerformer" id="searchWorkPerformer" class="text caps" value="" placeholder="Performer Name" data-val="true">
<span class="field-validation-valid" data-valmsg-for="searchWorkPerformer" data-valmsg-replace="true"></span>
</div>
</div>
</form>
Client side validation code:
$(function() {
if ($.validator && $.validator.unobtrusive) {
$.validator.addMethod("requiredif", function (value, element, params) {
return !(value.length === 0 && $(params).val().length === 0);
});
$.validator.unobtrusive.adapters.add("requiredif", ["otherpropertyname"], function (options) {
options.rules["requiredif"] = "#" + options.params.otherpropertyname;
options.messages["requiredif"] = options.message;
});
}
$("#searchWork").click(function() {
if ($("#searchWorkForm").valid()) {
// Make an Ajax Call and get the search result
}
});
}
You first need to move the $.validator.addMethod() and $.validator.unobtrusive.adapters.add() functions outside the $(function() { .. }
But based on the description of what your wanting to validate, then the code in your $.validator.addMethod() method should first check if the 'other property' (searchWorkPerformer) has a value, and if so return true. If it does not, then check if searchWorkTitle has a value. If it has, then return true, otherwise its invalid, so return false.
// scripts for jquery, jquery.validate and jquery.validate.unobtrusive
<script>
$.validator.addMethod("requiredif", function (value, element, params) {
if ($(params).val().length === 0) {
return true;
} elseif (value.length === 0) {
return false;
}
return true;
});
$.validator.unobtrusive.adapters.add("requiredif", ["otherpropertyname"], function (options) {
options.rules["requiredif"] = "#" + options.params.otherpropertyname;
options.messages["requiredif"] = options.message;
});
$(function() {
$("#searchWork").click(function() {
if ($("#searchWorkForm").valid()) {
// Make an Ajax Call and get the search result
}
});
}
</script>
Side note: requiredif does not really describe your validation - perhaps requiredifempty would be more appropriate since you only require a value if the other property is empty.

How to overwrite one model property in ASP.Net core

I have a model with say 10 properties. A, B, C and so on...
Property A is an array.
For each value in array I generate one tag like this:
<div class="col-sm-10 row">
#foreach (var item in Model.A)
{
<div class="col-sm-1 right-buffer">
<i class="" aria-hidden="true">#item.Text</i>
</div>
}
</div>
When user clicks on some link I should redirect it to the same page, but with Some model property changed. For example:
Current url: my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=
with model ?name=Alex&age=20&from=fr&CurrentA=
If user clicks on <a> with text foo it should be redirected on my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=foo
then is clicks on <a> with text bar and it should be now redirected on my/controller/someaction?name=Alex&age=20&from=fr&CurrentA=bar
So entire query string (except one parameter) should be preserved to send current model state to server while I want to set one value and redirect it to the same page but with new value.
Eventually, it should acts like postback with one extra value setted to model
Is it possible or I should use JS and perform everything myself?
Manually i solved it like this:
First, create hidden fields for every property in model:
<form asp-controller="search" asp-action="index" method="get" role="form" id="searchForm" asp-antiforgery="false">
<input asp-for="SessionId" type="hidden" name="sessionId" value="#Model.SessionId" />
<input asp-for="Quantity" type="hidden" name="quantity" value="#Model.Quantity"/>
<input asp-for="SortField" type="hidden" name="sortField" value="#Model.SortField"/>
<input asp-for="IsAscending" type="hidden" name="IsAscending" value="#Model.IsAscending" />
<input asp-for="Offset" type="hidden" name="offset" value="0" />
...
</form>
Then, use JS to replace value in hidden field and then submit form. Values from inputs will be autimatically converter in query string, so everything works fine:
function sortDocuments(sortField) {
var sField = document.getElementById('SortField');
var isDescending = document.getElementById('IsAscending');
if (sField.value === sortField) {
if (isDescending.value.toUpperCase() === 'FALSE') {
isDescending.value = 'TRUE';
} else {
sField.value = 'rank';
isDescending.value = 'FALSE';
}
} else {
sField.value = sortField;
isDescending.value = 'FALSE';
}
document.getElementById('searchForm').submit();
}
Not very elegant, but it does its job.

Delete button sending the value of another form

I have the following code that creates multiple different forms within a for loop to delete the different values in a database:
#foreach (var item in Model.value)
{
<script>var temp = {'value' : '#item.name'}</script>
<form class="formStyle" id="allCurrentNames_#item.name" method="post" action="">
<input type="hidden" id="part_name_#item.name" value="#item.name"/>
<button class="partDelete" onclick="deletePart(temp);return false;">Delete</button>
</form>
}
The following is the deletePart(temp) function:
function deletePart(temp) {
var personName = $("input#part_num_"+temp.value).val();
var dataString = 'partnumber=' + partnumber;
$.ajax({
AJAX STUFF
})
}
Assuming I will have something like the following:
Person Name1 [DELETE]
Person Name2 [DELETE]
Person Name3 [DELETE]
Person Name4 [DELETE]
Person Name5 [DELETE]
Person Name6 [DELETE]
If I click Person Name3 it sends in the value of Person Name6 always no matter which Delete button I click.
Any help is much appreciated!
Thank you for your time!
Remove your javascript from html
#foreach (var item in Model.value)
{
<form class="formStyle" id="allCurrentNames_#item.name" method="post" action="">
<input type="hidden" id="part_name_#item.name" value="#item.name"/>
<button class="partDelete">Delete</button>
</form>
}
And change your javascript code like this
$('.partDelete').click(function(){
var $this = $(this);
var partnumber = $this.parent().find('input').val();
var dataString = 'partnumber=' + partnumber;
//ajax
return false;
});
$('.partDelete').click(function(){
var $this = $(this);
var partnumber = $this.parent().find('input').val();
var dataString = 'partnumber=' + partnumber;
alert(dataString)
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="formStyle" id="allCurrentNames_1" method="post" action="" onsubmit="return false;">
<input type="hidden" class="part_name" value="1"/>
<button class="partDelete">Delete</button>
</form>
<form class="formStyle" id="allCurrentNames_2" method="post" action="" onsubmit="return false;">
<input type="hidden" class="part_name" value="2"/>
<button class="partDelete">Delete</button>
</form>
<form class="formStyle" id="allCurrentNames_2" method="post" action="" onsubmit="return false;">
<input type="hidden" class="part_name" value="2"/>
<button class="partDelete">Delete</button>
</form>
A much simpler action could be setting a unique id to each person's name. You'll just need to replace two lines of code.
When building your forms, replace:
<input type="hidden" id="part_name" value="#item.name"/>
<button class="partDelete" onclick="deletePart();return false;">Delete</button>
with this:
<input type="hidden" id="part_name_#item.name" value="#item.name"/>
<button class="partDelete" onclick="deletePart(#item.name);return false;">Delete</button>
And in the deletePart js, replace:
function deletePart() {
var personName = $("input#part_num").val();
with this:
function deletePart(id) {
var personName = $("input#part_name" + id).val();
Your problem is in your javascript on this line:
var personName = $("input#part_num").val();
Since you are rendering these forms in a loop, you will have multiple input fields with part_num as the id. JQuery is going to give you the first instance found which matches your selector, which is why you are always posting the value of the first person.
You can easily fix this by figuring out which form the event came from and then selecting the correct part_num.
var personName = $('#correct_form_id #part_num').val();
Hope this helps!
EDIT: Adding some sample code
One approach could be to capture your form submit and handle it yourself. For instance:
$( "form" ).submit(function( event ) {
var personName = $(this).find('#part_num').val();
// Do what you want with this information
// prevents the form from posting, if that is desired
event.preventDefault();
});
Now you may have other forms on your page that you don't want to be caught by this handler, so you could add a class to the forms you are generating in your loop to verify that you are only capturing the correct events. Then your definition would look like:
$('form.some_class').submit(function(event)) {
...
});

keeping the data in a form after it has been sent

I have a form that you enter data into and it performs a calculation on it and give an answer. what i want to do is for it to keep the data in the form so that you can quickly repost so that you don't have to change all the data. but I cant keep coming up with the error of it not existing, which I suppose is correct until the form has been posted!
#{
var total = 0m;
var totalMessage = "";
if (IsPost)
{
var age = Request["frmage"].AsInt(0);
var weight = Request["frmweight"].AsDecimal();
var SerCre = Request["frmSerCre"].AsDecimal();
var sexfactor = Request["frmGender"]== "M" ? 1.23m : 1.04m;
total =Convert.ToDecimal ((((140 - age)*weight)* sexfactor )/SerCre ) ;
totalMessage = total.ToString("0.00") + "(ml/min) ";
}
}
<div class="memberRegistration">
<form method="post">
<p>
<label class="formLabel">Age:</label> in years
<input class="formTextField" type="text" name="frmAge" size="3" value="#age"/>
</p>
<p>
<label class="formLabel">Weight:</label> in Kg (1st = 6.35kg)
<input class="formTextField" type="text" name="frmWeight" value="#weight"/>
</p>
<p>
<label class="formLabel">Serum Creatinine:</label> in μmol/L
<input class="formTextField" type="text" name="frmSerCre" value="#SerCre"/>
</p>
<p>
<label class="fieldLabel">Gender:</label>
<select name="frmGender" id="select" value="#sexfactor">
<option value="M">Male</option>
<option value="F">Female</option>
</select>
</p>
<p><input type="submit" value="Calculate" /></p>
</form>
<p>Calculated creatinine clearance <b>#totalMessage</b></p>
</div>
Try this
var age = 0;
if (IsPost)
{
age = Request["frmage"].AsInt(0);
}
<input class="formTextField" type="text" name="frmAge" size="3" value="#age"/>
But normally it would be better to use a model to hold your values, then in your controller you pass those values back again to your form
Enable the ViewState of the page and controls and also use aspx control, not HTML.
I don't thing that i realy understand the Question because the default thing is that the web page keeps it's view state so the data will still be the same after the post back but here's the solution :
you can simply use ASP Controls because it keep it's view state
or you can give each control of them it's value in the C# , you can assign to each control it's value back
Hope I Helped
Since you are using ASP.NET MVC Razor, what you can do is, do not submit the form using <input type="submit" value="Calculate" /> , instead change it to a simple button like
<input type="button" value="Calculate" onclick="javascript:Submitform();" />
and submit the form using Jquery POST.e.g. like below
function SubmitForm(){
var formData = $("form").serialize() ;
var submitUrl = 'yourURL' ;
$.ajax({
type : 'POST' ,
url : submitUrl ,
data : formData ,
success : function (data ){ alert ("Request successful") ;}
error : function (jqXHR, status , errorthrown) { alert ("error Occured");}
});
}

Categories

Resources