Make input fields readonly with values based on another input field - c#

I have 3 input fields in the create user form. Based on the selection of status, I want to make the next 2 fields read-only with specific values.
So If the user selects "Full-Time" for Status, the next 2 fields should become read-only with values 5 and 7.6 respectively. For any other selection, it should remain as a normal input field for the user to enter values.
How can I achieve this? Would highly appreciate any help

You can use listener events and jquery's method attr to handle the state of the other two text boxes. Here is an example.
function changeVal(e) {
console.log(e.target.value)
if (e.target.value == "Full Time") {
$("#workingday").val(5)
$("#workinghour").val(7.6)
$("#workingday").attr("readonly", true)
$("#workinghour").attr("readonly", true)
} else {
$("#workingday").val("")
$("#workinghour").val("")
$("#workingday").attr("readonly", false)
$("#workinghour").attr("readonly", false)
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<table>
<tr>
<td>status</td>
<td>Working Day in weeks</td>
<td>Working Hours Per Day</td>
</tr>
<tr>
<td>
<select onchange="changeVal(event)">
<option value="">--select--</option>
<option value="Full Time">Full Time</option>
<option value="other">other value</option>
</select>
</td>
<td>
<input type="text" id="workingday" name="workingday" value="0" />
</td>
<td>
<input type="text" id="workinghour" name="workinghour" value="0" />
</td>
</tr>
</table>

add runat attribute to Status
runat="server"
then take the value of Status and compare it to set the parameters of the other fields
String statustxt = Status.Value;
if(Equals(statustxt, targettxt) {
workingdays.Text = "5";
workingdays.ReadOnly = true;
workinghours.Text = "7.6";
workinghours.ReadOnly = true; }
You can also set Editable = false

Related

asp-for binding and route-value issues inside loop

I am building a little website where users can manage personal gear, which has a name and mass among other properties. I want to display all of this gear in a table, using input boxes bound to each item so the user can change values if desired, then hit an edit button and update the gear database. I can get my foreach loop to bind all of the right values, but when it routes to the handler, it always sets the EditGearName and EditGearMass value to whatever value is in the first row.
<table>
#foreach (var g in Model.Gears) {
<tr class="list-table-main">
<td><input class="form-control" asp-for="EditGearName" value="#g.GearName" /></td>
<td><input class="form-control" asp-for="EditGearMass" value="#g.Mass" type="number" min="0" /></td>
<td style="width:12.5%"><button type="submit" asp-page-handler="EditGear" asp-route-groupid="#gg.ID">Save</button></td>
</tr>
}
</table>
Here is an example of my handler method called on the button press. The GearBL.EditGear method is code behind that handles saving it to database. I know this works (so long as the right values are passed in)
public IActionResult OnPostEditGroup(int groupid)
{
try
{
base.OnGetParent();
if (string.IsNullOrEmpty(EditGearName))
throw new ValidationException("Gear name must not be empty");
if (EditGearMass < 0)
throw new ValidationException("Gear mass cannot be less than 0");
GearBL.EditGear(groupid, User, EditGearName, EditGearMass, false);
Response.Redirect("GearList");
}
catch (Core.Domain.ValidationException ve)
{
ModelState.AddModelError("Error", ve.Message);
}
return Page();
}
I am new to asp.net/razor so any help would be appreciated. I'm not sure I even have the best way to implement something like either.
it always sets the EditGearName and EditGearMass value to whatever value is in the first row.
You should add the form tag in the foreach loop to enable one submit for one row.
<table>
<form>
#foreach (var g in Model.Gears) {
<tr class="list-table-main">
<td><input class="form-control" asp-for="EditGearName" value="#g.GearName" /></td>
<td><input class="form-control" asp-for="EditGearMass" value="#g.Mass" type="number" min="0" /></td>
<td style="width:12.5%"><button type="submit" asp-page-handler="EditGear" asp-route-groupid="#gg.ID">Save</button></td>
</tr>
}
</form>
</table>

dropdown lists in the second row in a for loop of razor view do not dynamically populate [duplicate]

I am trying to update two cascading drop down inside a table there are many answers on SO for drop downs, but I was unable to find help on cascading updates inside a Table with dynamically added rows.
Given the many rows they all have varying Id's filter #Id does'nt work. So, How do I identify which rows Dropdown triggered the change & cascade the update another Dropdown/cell in the next col of the same row?
There are 2 DropDownList (select box) inside a table row cell. To simplify this, the first is Country -> Second is state. So a user is expected to select the country and then the state.
My pseudo algorithm:
find which one was fired, and which row (unsure if its needed, should I wire in place)
then fire an ajax call... to get the values based on country
update the second drop down with value in the same table row.
Case 1 Change country and then change state.
Case 2 Just change State, but first get the Country value in the first dropdown of the same row.
I know how to get the change and value in a regular page, but how do I get those changes and update the adjacent dropdown.
$(document).on('change', 'select', function(){
var data = $(this).val();
alert(data);
});
Edit, Stephen request to show HTML
<tr>
<td>
//DropDown 1 (Imagine Country)
<span class="projectcodeid">
<select class="form-control" id="Records_1__TCode_Project_ID" name="Records[1].TCode.Project.ID"><option value=""></option>
<option value="1">Plumbing</option>
<option value="2">Modeling</option>
</select></span>
</td>
<td>
//DropDown 2 (Imagine State)
<input type="hidden" name="Records.Index" value="1">
<input class="timecodeid" name="Records[1].TCode.ID" type="hidden" value="5">
<span class="timecode timecodeDdlId"> <select class="form-control timecodeDdlId" id="Records_1__TCode_ID" name="Records[1].TCode.ID"><option value=""></option>
</select></span>
</td>
<td>
<input name="Records[1].DataRecords[0].ID" type="hidden" value="">
<input class="hours" name="Records[1].DataRecords[0].Work" type="text" value="">
</td>
<td>
<input class="bs-checkbox" name="Records[1].DeleteRow" type="checkbox" value="true"><input name="Records[1].DeleteRow" type="hidden" value="false">
</td>
</tr>
Sample image for clarification
Assuming that you can't identify dropdwns by class or anything.
Assuming that every time you change the value in a dropdown you want to update the other dropdown on the same row.
Assuming that you have only two dropdowns per row:
$('table').on('change', 'select', function() {
var $current_dropdown = $(this),
$other_dropdown = $(this).closest('tr').find('select').not(this);
/// perform any task you need with current and other dropdown
});
You need to give both your <select> elements class names and use relative selectors to select the associated element in the same row.
Assuming your html is
<table id="table"> // give this an id attribute
<tbody>
<tr>
<td><select class="country" ....> ..... </select></td>
<td><select class="state" ....> ..... </select></td>
</tr>
</tbody>
</table>
Then your script will be
$('#table').on('change', '.country', function() {
var selectedValue = $(this).val();
var row = $(this).closest('tr'); // get the row
var stateSelect = row.find('.state'); // get the other select in the same row
// make you ajax call passing the selectedValue to your controller
// in the success callback, update the options of stateSelect
$.ajax({
url: ...
data { id: selectedValue },
....
success: function(data) {
stateSelect.empty();
$.each(data, function(item, index) {
stateSelect.append($('<option></option>').val(iem.ID).text(item.Name));
}
}
});
}
Refer also better way to load 2 dropdown in mvc for details of the code for populating cascading dropdownlists (consider caching the options as per the 2nd code example to avoid repeated ajax calls)

Angular JS, multiple insert error

I want to fetch data from SQL and display in HTML table using ng-repeat option then I need to edit some values in the table cell. My problem is that I only get initial values in the controller and the changes are not reflected in the controller. Here is my code:
app.controller('CRUD_EntryController', function ($scope, CRUD_InternalEntryService) {
GetStudentMarkDetails();
function GetStudentMarkDetails() {
var PromiseGetMarks = CRUD_InternalEntryService.GetMarkDetails();
PromiseGetMarks.then(function (res) {
$scope.MarkList = res.data;
})
}
$scope.mark = {};
$scope.save = function (MarkList) {
var index = 0;
$scope.MarkList.forEach(function (mark) {
console.log('rows #' + (index++) + ': ' + JSON.stringify(mark));
alert(mark.M1);
}
}
View:
<table class=" table table-condensed" id="myresul">
<tr>
<th>Slno</th>
<th>Name</th>
<th>RegNo</th>
<th>ClassNo</th>
<th>M1</th>
<th>M2</th>
<th>M3</th>
</tr>
<tbody data-ng-repeat="mark in MarkList" >
<tr>
<td class="col-md-1" >#{{$index+1}}</td>
<td class="col-md-2" ng-model="mark.Fname">{{mark.Fname}}</td>
<td class="col-md-2">{{mark.RegNo}}</td>
<td class="col-md-1">{{mark.ClassNo}}</td>
<td class="col-md-1"><input type="number" value="{{mark.M1}}" ng-model="M1" class="form-control" /></td>
<td class="col-md-1"><input type="number" value="{{mark.M2}}" ng-model="M2" class="form-control" /></td>
<td class="col-md-1"><input type="number" value="{{mark.M3}}" ng-model="M3" class="form-control" /></td>
</tr>
<button data-ng-click="save(MarkList)" class="btn btn-success">Save</button>
</tbody>
</table>
Don't think you need to define this: $scope.mark = {}; since mark is set in the scope of your ng-repeat. Remove it because this is somewhat confusing and might cause errors in the future.
Remove the value="{{mark.M1}}" and bind your model to ng-model="{{mark.M1}}". Asuming that you wand to bind to M1, M2 and M3 in your inputs.
Also see the angular docs for ngModel for more details and update your code accordingly.
By the way you don't have to pass MarkList as an argument for Save(..), you can do this:
<button data-ng-click="save()" class="btn btn-success">Save</button>, change the Save method signature to Save() and use $scope.MarkList instead of the argument MarkList.
Or change your method to only save the specific mark instead of the entire list every time.

Check html field hidden or not using C# backend code

I have the following code in which I am showing and hiding html controls based on Dropdown list selected value. Show and Hide is working fine but I want to Check in backend i.e C# that the which <tr> is visible and which one is hidden.
Here is my aspx page code
<script type="text/javascript">
$(document).ready(function () {
$("#AttachemntType").change(function () {
if ($(this).val() == "F") {
$("#tr_CompileFile").show();
$("#tr_SourceFile").show();
}
else if ($(this).val() == "R") {
$("#tr_CompileFile").hide();
$("#tr_SourceFile").show();
}
else {
$("#tr_SourceFile").hide();
$("#tr_CompileFile").hide();
}
});
});
</script>
<tr bgcolor="white">
<td style="height: 20px">
Attachment Type
</td>
<td>
<select id="AttachemntType" name="AttachemntType" style="width: 344px">
<option value="0">Select</option>
<option value="F">Form</option>
<option value="R">Report</option>
</select>
</td>
</tr>
<tr bgcolor="white" id="tr_SourceFile" style="display:none;" runat="server">
<td style="height: 20px">
Source File
</td>
<td>
<input class="body_text" type="file" id="src_File" name="src_File" runat="server"
style="width: 420px" />
</td>
</tr>
<tr bgcolor="white" id="tr_CompileFile" style="display:none;" runat="server">
<td style="height: 20px">
Compiled File
</td>
<td style="height: 16px; width: 625px;">
<input class="body_text" type="file" id="comp_File" runat="server" style="width: 420px" />
</td>
</tr>
This is the code which I am trying in Backend but its returning always true for all fields
if (tr_CompileFile.Visible == true && tr_SourceFile.Visible == true)
{
//This Condition is always true
}
else if (tr_SourceFile.Visible == true && tr_CompileFile.Visible == false)
{
//something
}
else
{
//something else
}
You cannot actually check this in backend. .show() and .hide() are jQuery methods which only operates on client side.
One workaround could be to use a MVVM pattern with knockout.js (Don’t try angular for that, you’ll be lost in docs)
Another option is to actually put your select box and the hidden/visible parts into UpdatePanel. So when you change the selector, the server side is called and you can assign / remove “visible” field.
More : https://msdn.microsoft.com/en-us/library/bb399001.aspx
In last resort, you can put a hidden field, which will be populated on submit with “hidden,shown,etc” values for you inputs.
Personally, I’ll vote for the first, but second is the easiest one to implement
Yes, Jurion was right. just adding more explanation: you can try
tr_CompileFile.Style["HTML Style key here"]
for example you can try
tr_CompileFile.Style["display"]
but it will return to you the value of the particular style defined in your aspx files, not the actual style displayed and changed in client side.
If you defined
<asp:Button ID="btnTest" runat="server" style="display:none" />
when you check it,
btnTest.Style["display"]
will return "none"

How to Get All HtmlInputText Controls Within a Table Row?

I'm trying to create a web page to create small playlists. Once data has been entered into the fields, it needs to be saved to an XML file. Currently the table looks like this:
<%-- song list table --%>
<table runat="server" id="table" class="table">
<%-- info row --%>
<thead>
<tr>
<td>Song Title</td>
<td>Song Artist</td>
<td>Song Album</td>
<td><%-- column for delete button --%></td>
</tr>
</thead>
<%-- input rows --%>
<tbody>
<tr>
<td><input runat="server" placeholder="Title" type="text" /></td>
<td><input runat="server" placeholder="Artist" type="text" /></td>
<td><input runat="server" placeholder="Album" type="text" /></td>
<td>
<a href="#">
<img src="Images/Delete.png" onmouseover="this.src='Images/Delete-Hover.png'" onmouseout="this.src='Images/Delete.png'" alt="Delete" />
</a>
</td>
</tr>
</tbody>
</table>
New rows will be added dynamically with jQuery. When the user clicks save, I need to write the table data into their specific XML file. Currently my backend code looks like this:
//for each row
foreach (HtmlTableRow row in table.Rows)
{
//create row info
textWriter.WriteStartElement("Row");
//for each cell
foreach (HtmlTableCell element in row.Cells)
{
//get inputs
//write current input to xml
}
//close row
textWriter.WriteEndElement();
}
My question is where I go from there with my code to be able to get the values of each input and write them to the XML.
You need to give the element's an ID so you can refer to them by. Also, any dynamically added rows will not be able to be accessed this way; that is because they do not exist in the control tree as a server control, but are a pure client control. You would have to access these using Request.Form collection. You'd have to add them dynamically to the control tree if you want them to persist across postbacks too.
If you are using JQuery, it would be more efficient and easier to grab all the values on the client and send the values to a web service or something like that.
My suggestion would be to re-think how you're gathering the data. I assume that you're going to have this information do an HTTP POST to your server using $.ajax() or something similar - and on the server-side, you're wanting to get all of the instances of the Title, Artist and Album fields, grouped by row.
Instead of posting back the table, which is a set of UI elements that display your data, but do not represent it, consider posting back to the server and having the server expect an IEnumerable of Song objects, which would look something like this:
public class Song {
public String Album { get; set; }
public String Artist { get; set; }
public String Title { get; set; }
}
Now, when you bind the form itself, you can bind something like:
<table>
<thead>
<tr>
<td>Song Title</td>
<td>Song Artist</td>
<td>Song Album</td>
<td><%-- column for delete button --%></td>
</tr>
</thead>
<tbody>
<tr>
<td><input placeholder="Title" type="text" name="Songs[0].Title" /></td>
<td><input placeholder="Title" type="text" name="Songs[0].Artist" /></td>
<td><input placeholder="Title" type="text" name="Songs[0].Album" /></td>
</tr>
</tbody>
</table>
The [0] notation indicates that this element is part of an IEnumerable called Songs, and is at index 0. When your jQuery script then goes and adds new rows, you simply increment the indexes. So - a new row would be something like:
<tr>
<td><input placeholder="Title" type="text" name="Songs[1].Title" /></td>
<td><input placeholder="Title" type="text" name="Songs[1].Artist" /></td>
<td><input placeholder="Title" type="text" name="Songs[1].Album" /></td>
</tr>
The only trick to this is to ensure that you never have gaps in your indexes. I.E. - if you have 5 rows, and you delete the third, you need to re-index rows 4 and 5 (by decrementing the [#] values).
Note: All of the above assumes you are using server-side binding.
If you are already using jQuery, you might also find it simpler to simply parse your table's input elements with jQuery and post things as an object that you have direct control over. This prevents you from having to do any indexing at all. An example would be something like:
$('#submit-button').on('click', function (ev) {
var songs = [];
$('#table > tbody > tr').each(function (index, element) {
var $tr = $(element);
var album = $tr.find('input[placeholder=Album]').val();
var artist = $tr.find('input[placeholder=Artist]').val();
var title = $tr.find('input[placeholder=title]').val();
songs.push({ Album: album, Artist: artist, Title: title });
});
$.ajax({
url: '/my/post/url',
type: 'POST',
data: songs
});
});
On the server-side, you will now receive an HTTP POST to /my/post/url which has a payload containing the song data in the table - without having to worry about funky data-binding syntax or indexing.
Hope this helps.

Categories