Passing actual object to function on event - javascript

I have a button that when pressed I need to pass the object 'contract' into.
<td class="col-md-1" colspan="1" style="text-align: center; vertical-align: middle;">
<button class="btn btn-primary" data-ng-click="removeContract(ctrl.selectValue, contractIndex)"> < </button>
</td>
<td class="col-md-5" colspan="5">
<label class="control-label">{{item.fields[132].displayName}}</label>
<select size="5" ng-model="ctrl.selectValue">
<option data-ng-repeat="contract in contracts" value="{{contract}}">{{contract.CONT_ORDNO}} - {{contract.SUPP_NAME}}[{{contract.SUPP_NUM}}]</option>
</select>
</td>
The object is being passed but it is a string of the object, not the object itself:
I'm aware I could convert it after, but the way the app was designed it's supposed to be the object.
How do I pass the actual object?

Use this construction:
<select size="5" ng-model="ctrl.selectValue" ng-options="(contract.CONT_ORDNO + ' - ' + contract.SUPP_NAME + '[' + contract.SUPP_NUM + ']') for contract in contracts">
</select>

Related

Select Items not showing after form appends

The Select Items in my code below works if I havent added a new row yet.
The items are fetched from a db using php mysql.
How Can I still make the select options in the children elements work like the parent element cloned. The select button works like its disabled in the children element
I want the children element to also have the room to select items
<script type="text/javascript">
function create_tr(table_id) {
let table_body = document.getElementById(table_id),
first_tr = table_body.firstElementChild
tr_clone = first_tr.cloneNode(true);
table_body.append(tr_clone);
clean_first_tr(table_body.firstElementChild);
}
function clean_first_tr(firstTr) {
let children = firstTr.children;
children = Array.isArray(children) ? children : Object.values(children);
children.forEach(x => {
if (x !== firstTr.lastElementChild) {
x.firstElementChild.value = '';
}
});
}
function remove_tr(This) {
if (This.closest('tbody').childElementCount == 1) {
alert("First Row Can't Be Deleted");
} else {
This.closest('tr').remove();
}
}
</script>
<div class="col-xl-8 col-md-12">
<div class="card">
<div class="card-header">
<h3 class="card-title">Add Device Information</h3>
</div>
<div class="card-body">
<form id="" method="POST" autocomplete="off" novalidate="novalidate">
<table class="table border text-nowrap text-md-nowrap table-striped mb-0">
<thead>
<tr>
<th>Device Model</th>
<th>Serial No</th>
<th>
<button type="button" id="add" class=" btn text-success" onclick="create_tr('table_body')">
<i class="fe fe-plus-circle" id="add" style="font-size:1.6em;"></i>
</button>
</th>
</tr>
</thead>
<tbody class="field_wrapper" id="table_body">
<tr>
<td>
<select class="form-control form-select select2" data-bs-placeholder="Select" name="model[]" required="" id="model"> <?php
$readALL1 = "SELECT * FROM productmodels WHERE deleted = 0";
$displayAll1 = mysqli_query($conn,$readALL1);
while($rowFetchAll1 = mysqli_fetch_array($displayAll1)){
$modelName = $rowFetchAll1['modelName'];
$modelid = $rowFetchAll1['modelID'];
?> <option value="
<?=$modelid?>"> <?=$modelName?> </option> <?php } ?> </select>
</td>
<td>
<input type="" name="" class="form-control" placeholder="Serial No...">
<input type="text" name="addedBy[]" class="form-control" id="addedBy" value="
<?=$_SESSION['user_uniq_id']?>" hidden="">
<input type="text" name="client[]" class="form-control" value="
<?=$clientID?>" id="client" hidden="">
<input type="text" name="deviceID[]" class="form-control" value="
<?=time()?>" id="deviceID" hidden="">
</td>
<td>
<button type="button" id="add" class=" btn text-danger" onclick="remove_tr(this)">
<i class="fe fe-minus-circle" id="add" style="font-size:1.6em;"></i>
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>
As per the comment I made above, you have duplicate IDs so whenever you use document.getElementByID you are going to have issues if attempting to call an element that has it's ID duplicated.
Fo the delete buttons to work you can either assign the event handler explicitly when you make the clone of the entire table row or the preferred method is to use a delegated event handler that intercepts click events to the common parent ( the table is easy ) and then reacts accordingly. The following HTML is a modified version of the above - all IDs have been removed, some replaced with dataset attributes. The select menu simply has a basic statically written few options to illustrate the case.
// No element in the HTML now has an ID so there will be no duplicate IDs. To identify
// DOM elements a more useful set of selectors (querySelector & querySelectorAll) are
// very useful. The `event` can be used to begin DOM traversal to find elements of
// interest rather than rely upon a static ID or crudely constructed dynamic IDs, usually
// involving numbers.
document.querySelector('button[data-name="add"]').addEventListener('click', e => {
// from the event.target, find the parent table row and from that the table-body
let tbody = e.target.closest('table').querySelector('tbody');
// clone the first row from table-body and do some manipulations
let clone=tbody.firstElementChild.cloneNode(true);
clone.querySelector('button[data-name="del"]').hidden=false;
clone.querySelectorAll('input, select').forEach(n=>{
n.value='';
});
// add the new row - no IDS anywhere.
tbody.appendChild(clone);
});
// Delegated Event Listener. This is bound to the table and monitors `click` events
// but processes only those events originating from the specified elements (button & i)
// - newly added elements are not registered in the DOM when the page loads initially
// which is why a delegated listener is used.
document.querySelector('form table#dyntbl').addEventListener('click', e => {
e.stopPropagation();
// only process clicks from either a button with dataset.name='del' or it's child i
if (e.target != e.currentTarget && (e.target.dataset.name == 'del' || e.target.parentNode.dataset.name == 'del')) {
// identify the table-body as before
let tbody = e.target.closest('table').querySelector('tbody');
// remove table row unless it is the 1st one otherwise things break.
if( tbody.childNodes.length > 3 ) tbody.removeChild(e.target.closest('tr') )
}
});
<div class='col-xl-8 col-md-12'>
<div class='card'>
<div class='card-header'>
<h3 class='card-title'>Add Device Information</h3>
</div>
<div class='card-body'>
<form method='POST' autocomplete='off' novalidate='novalidate'>
<table id='dyntbl' class='table border text-nowrap text-md-nowrap table-striped mb-0'>
<thead>
<tr>
<th>Device Model</th>
<th>Serial No</th>
<th>
<button type='button' data-name='add' class=' btn text-success'>
<i class='fe fe-plus-circle' data-id='add' style='font-size:1.6em;'>#Add#</i>
</button>
</th>
</tr>
</thead>
<tbody class='field_wrapper'>
<tr>
<td>
<select class='form-control form-select select2' data-bs-placeholder='Select' name='model[]' required>
<option>A
<option>B
<option>C
</select>
</td>
<td>
<input type='text' name='serial[]' class='form-control' placeholder='Serial No...' />
<input type='text' name='addedBy[]' class='form-control' hidden />
<input type='text' name='client[]' class='form-control' hidden />
<input type='text' name='deviceID[]' class='form-control' hidden />
</td>
<td>
<button type='button' data-name='del' class='btn text-danger' hidden>
<i class='fe fe-minus-circle' style='font-size:1.6em;'>#Delete#</i>
</button>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
</div>

How check condition of checkbox when uncheck/check with id of HTML

I'm using css and javascript to check condition of value of partner Code is null and 01
If user checks checkbox is PARTNER, value of partnerName '01 - Elite' and value of partnerCode is '01' will send when submit
If user unchecks checkbox is PARTNER, value of partnerName is 'NULL' and value of partnerCode is 'NULL' will send when submit
This is my code:
<tr>
<th scope="row">Partner</th>
<td colspan="0" style="margin-top: 4px;">
<input id="parnerNameCheck" name="parnerNameCheck" type="checkbox"/><span>PARTNER</span>
</td>
<td>
<select id="partnerName" name="partnerName" disabled>
<option value="" selected>Choose One</option>
<option>01 - Elite</option>
</select>
</td>
<td>
<input id="partnerCode" name="partnerCode" type="hidden" value="01" />
</td>
</tr>
<script>
$('#parnerNameCheck').click(function() {
console.log('parnerNameCheck checked:' + $("#parnerNameCheck").is(":checked"));
$('#partnerName').prop("disabled", !$(this).prop("checked"));
$('#partnerCode').prop("disabled", !$(this).prop("checked"));
});
</script>
UPDATED:
$('#parnerNameCheck').click(function() {
console.log('parnerNameCheck checked:' + $("#parnerNameCheck").is(":checked"));
$('#partnerName').prop("disabled", !$(this).prop("checked"));
$('#partnerCode').prop("disabled", !$(this).prop("checked"));
$("#partnerCode").val('');
});
But when I uncheck checkbox is PARTNER, value of partnerCode is 01 still sending when submit.
So how to fix the problem? thank a lot
set $("#partnerCode").val('');
$('#parnerNameCheck').click(function() {
console.log('parnerNameCheck checked:' + $("#parnerNameCheck").is(":checked"));
$('#partnerName').prop("disabled", !$(this).prop("checked"));
$('#partnerCode').prop("disabled", !$(this).prop("checked"));
$("#partnerCode").val('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<tr>
<th scope="row">Partner</th>
<td colspan="0" style="margin-top: 4px;">
<input id="parnerNameCheck" name="parnerNameCheck" type="checkbox"/><span>PARTNER</span>
</td>
<td>
<select id="partnerName" name="partnerName" disabled>
<option value="" selected>Choose One</option>
<option>01 - Elite</option>
</select>
</td>
<td>
<input id="partnerCode" name="partnerCode" type="hidden" value="01" />
</td>
</tr>
I believe you are missing the ability to toggle the value of partnerCode. Your updated code would only set the value of parnetCode to null and that's it.
Below is the code that would switch the values for partnerCode:
$('#parnerNameCheck').click(function() {
console.log('parnerNameCheck: ' + $("#partnerCode").val());
$('#partnerName').prop("disabled", !$(this).prop("checked"));
$('#partnerCode').prop("disabled", !$(this).prop("checked"));
// Declare variables
var partnerCode = $("#partnerCode");
var partnerCodeVal = partnerCode.val();
// Apply condition to $("#partnerCode").val()
// that will switch between values
partnerCode.val(partnerCodeVal === "01" ? "" : "01");
});
Working example - https://jsfiddle.net/ma4orbnw/1/

assign variable for multiple textboxes

I have a form that collects information on 15 participants, and based on a Class selected for each participant 3 drop down boxes (Events) are populated. Originally I had a drop down box to select the Class and I have changed to a textbox. However I cannot figure out how to associate the variable with the text box (instead of dropdown) with the Class for each participant. This is the part of function I am having trouble with: var class_id = class_dropdown.value; I have read other similar posts but cannot figure out how they associated text box and name in variable.
This is the form:
<form name="myform" method="post" action="insert_entries.php">
<table style="width: 139%" align="center">
<tr>
<td class="style2" style="width: 166px"><strong>FIRST NAME</strong></td>
<td class="style2" style="width: 161px"><strong>LAST NAME</strong></td>
<td class="style2" style="width: 66px"><strong>GENDER</strong></td>
<td class="style2" style="width: 224px"><strong>DOB</strong></td>
<td class="style2" style="width: 74px"><strong>CLASS</strong></td>
<td class="style2" style="width: 104px"><strong>EVENT 1</strong></td>
<td class="style2" style="width: 104px"><strong>EVENT 2</strong></td>
</tr>
<tr>
<td style="width: 166px">
<input type="text" name="first1" size="35" style="width: 155px" /></td>
<td style="width: 161px">
<input type="text" name="last1" size="35" style="width: 155px" /></td>
<td style="width: 66px">
<select name="gender1" class="dropdownbox" id="series id15"style="height: 23px; width: 70px">
<option></option>
<option>M</option>
<option>F</option>
</select></td>
<td style="width: 224px">
<input type="date" name="dob1" size="35" onchange = "repeat()" style="width: 155px; height: 27px;" /></td>
<td style="width: 74px">
<input type="text" name="class1" size="35" style="width: 155px" /></td>
<td style="width: 104px">
<select name="events1" class="dropdownbox" id="series id"style="height: 23px; width: 104px">
<option></option>
</select> </td>
<td style="width: 72px">
<select name="events1B" class="dropdownbox" id="series id16"style="height: 23px; width: 104px">
<option></option>
</select> </td>
</tr>
</table>
And this is the function:
<script>
// function to get event list for selected class -
function get_event(class_dropdown)
{
// get selected class value -
var class_id = class_dropdown.value;
// get name of selected class dropdown -
var class_dropdown_name = $(class_dropdown).attr('name');
// get no. appended to class dropdown name -
var class_no = class_dropdown_name.replace ( /[^\d.]/g, '' );
// prepare names of 3 event dropdowns -
var event1 = 'events'+class_no;
var event2 = 'events'+class_no+'B';
var event3 = 'events'+class_no+'C';
// empty 3 event dropdowns -
$('select[name="'+event1+'"]').html('');
$('select[name="'+event2+'"]').html('');
$('select[name="'+event3+'"]').html('');
if(class_id != '')
{
$.ajax({
url:"get_event.php",
type:"POST",
dataType:"json",
data:{class_id:class_id},
success:function(data)
{
var event_option = '';
event_option = event_option+'<option value=""></option>';
for(var i=0; i<data.length; i++)
{
event_option = event_option+'<option value="'+ data[i].eventcode +'">'+ data[i].event +'</option>';
}
// append event list to 3 dropdowns next immediate -
$('select[name="'+event1+'"]').html(event_option);
$('select[name="'+event2+'"]').html(event_option);
$('select[name="'+event3+'"]').html(event_option);
}
});
}
}
</script>
If I understand your issue, you want to run the included Javascript and have the class_dropdown variable populated with a reference to your class1 input.
There are multiple ways to do that, one of possible approaches is to inline the event call in a similar way your other input, the dob1 calls the repeat() function in the onchange inlined handler:
<input type="date" name="dob1" size="35" onchange = "repeat()" ...
The similar approach here would be to pick one the change event that occurs when the input value is changed or the blur event that occurs when the focus is taken away from the input. Then, inline the handler call passing this as the reference to actual input:
<input name='class1' onblur="get_event(this)" />
In the example call from above, the get_event is called whenever the focus is taken away from the input and the get_event is called passing the class1 reference to the method.
You can verify this in the following playgound. Just type whatever you want and focus out of the textbox. The message will display the actual value of the input.
function get_event(class_dropdown) {
var text = class_dropdown.value;
alert(text);
}
<input name='class1' onblur="get_event(this)" />

Passing selected object model on button press/event trigger

I have a button that currently passes the selected value to the removeContract().
<td class="col-md-1" colspan="1" style="text-align: center; vertical-align: middle;">
<button class="btn btn-primary" data-ng-click="removeContract(ctrl.selectValue, contractIndex)"> <= </button>
</td>
<td class="col-md-5" colspan="5">
<label class="control-label">{{item.fields[132].displayName}}</label>
<select size="5" ng-model="ctrl.selectValue">
<option data-ng-repeat="contract in contracts">{{contract.CONT_ORDNO}} - {{contract.SUPP_NAME}}[{{contract.SUPP_NUM}}]</option>
</select>
</td>
However, I need to send back the actual current contract model, called 'contract' above. The function's 1st parameter needs to be the currently selected contract. How would I achieve this?
Some suggestions as per the current code :
Instead of passing whole {{contract.CONT_ORDNO}} - {{contract.SUPP_NAME}}[{{contract.SUPP_NUM}}] into the ng-model just pass the contract.CONT_ORDNO to identify the selected data from the dropdown.
<option data-ng-repeat="contract in contracts" value="contract.CONT_ORDNO">{{contract.CONT_ORDNO}} - {{contract.SUPP_NAME}}[{{contract.SUPP_NUM}}]</option>
As we already have contracts array of objects inside the controller.Hence, no need to pass the second parameter inside the removeContract function.
<button class="btn btn-primary" data-ng-click="removeContract(ctrl.selectValue)"> <= </button>
Based on the selected value we can remove the contract object from the contracts array inside removeContract function with the help of Array filter() method.
DEMO
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.contracts = [
{
"CONT_ORDNO": "1",
"SUPP_NAME": "alpha",
"SUPP_NUM": "0001"
},
{
"CONT_ORDNO": "2",
"SUPP_NAME": "beta",
"SUPP_NUM": "0002"
},
{
"CONT_ORDNO": "3",
"SUPP_NAME": "gaama",
"SUPP_NUM": "0003"
},
{
"CONT_ORDNO": "4",
"SUPP_NAME": "xyz",
"SUPP_NUM": "0004"
}
];
$scope.removeContract = function(selectedVal) {
var removedObj = $scope.contracts.filter(function(item) {
return item.CONT_ORDNO != selectedVal;
});
console.log(removedObj);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<td class="col-md-1" colspan="1" style="text-align: center; vertical-align: middle;">
<button class="btn btn-primary" data-ng-click="removeContract(ctrl.selectValue)"> <= </button>
</td>
<td class="col-md-5" colspan="5">
<label class="control-label">{{item.fields[132].displayName}}</label>
<select size="5" ng-model="ctrl.selectValue">
<option data-ng-repeat="contract in contracts" value="{{contract.CONT_ORDNO}}">{{contract.CONT_ORDNO}} - {{contract.SUPP_NAME}}[{{contract.SUPP_NUM}}]</option>
</select>
</td>
</div>

function to disable/enable dynamically generated form fields

I'm no javascript expert and i'm currently trying to create a function for a form that has the same fields repeated depending on a number selected on a previous page.
There could be between 1 and 10 rows of the form fields with each having a radio button selection that will enable/disable each row.
At the moment i've written something but having trouble with concatenating form field names and variable names.
Is anyone able to point me in the right direction please.
Javascript:
var i = 1;
var iChildren = 2; //could be any number - depends what user selected.
function toggle(switchElement) {
for (i = 1; i = iChildren; i++) {
var frmSchoolSelected+i = document.getElementById('<%=c_' & i & '_selected.ClientID%>');
var frmSchoolAge+i = document.getElementById('<%=c_' & i & '_type.ClientID%>');
var frmSchoolType+i = document.getElementById('<%=c_' & i & '_type1.ClientID%>');
var frmSchoolAdditional+i = document.getElementById('<%=c_' & i & '_additional.ClientID%>');
if (switchElement.value == 'Yes') {
frmSchoolSelected+i.disabled = false;
frmSchoolAge+i.disabled = true;
frmSchoolType+i.disabled = true;
frmSchoolAdditional+i.disabled = true;
}
else {
frmSchoolSelected+i.disabled = true;
frmSchoolAge+i.disabled = false;
frmSchoolType+i.disabled = false;
frmSchoolAdditional+i.disabled = false;
}
}
}
Thanks for any help.
J.
EDITED
Example of generated form HTML.
<form method="post" action="schoolingform.aspx" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'Button1')" id="form1">
<table id="Table1" cellspacing="0" cellpadding="0" style="border-width:0px;border-collapse:collapse;">
<tr>
<td><strong>School Selected</strong></td>
<td colspan="4"><span id="c_1_school_selected" onlick="javascript:toggle(this);">
<input id="c_1_school_selected_0" type="radio" name="c_1_school_selected" value="Yes" />
<label for="c_1_school_selected_0">Yes</label>
<input id="c_1_school_selected_1" type="radio" name="c_1_school_selected" value="No" />
<label for="c_1_school_selected_1">No</label>
</span></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Child</th>
<th style="border-right:1px solid #dddddd;">School Name</th>
<th>School Type</th>
<th>School Type</th>
<th>Additional Information</th>
</tr>
<tr valign="top">
<td><strong>Fred Wilkinson</strong></td>
<td style="border-right:1px solid #dddddd;"><input name="c_1_selected" type="text" id="c_1_selected" disabled="disabled" class="aspNetDisabled" style="width:190px;" />
<input type="hidden" name="c_1_id" id="c_1_id" value="22" /></td>
<td><select name="c_1_type" id="c_1_type" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="Primary">Primary</option>
<option value="Secondary">Secondary</option>
<option value="Higher Education">Higher Education</option>
</select></td>
<td><select name="c_1_type1" id="c_1_type1" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="State">State</option>
<option value="Independent">Independent</option>
</select></td>
<td><textarea name="c_1_additional" rows="6" cols="30" id="c_1_additional" disabled="disabled" class="aspNetDisabled" style="width:190px;"></textarea></td>
</tr>
<tr>
<td><strong>School Selected</strong></td>
<td colspan="4"><span id="c_2_school_selected" onlick="javascript:toggle(this);">
<input id="c_2_school_selected_0" type="radio" name="c_2_school_selected" value="Yes" />
<label for="c_2_school_selected_0">Yes</label>
<input id="c_2_school_selected_1" type="radio" name="c_2_school_selected" value="No" />
<label for="c_2_school_selected_1">No</label>
</span></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Child</th>
<th style="border-right:1px solid #dddddd;">School Name</th>
<th>School Type</th>
<th>School Type</th>
<th>Additional Information</th>
</tr>
<tr valign="top">
<td><strong>Sara Wilkinson</strong></td>
<td style="border-right:1px solid #dddddd;"><input name="c_2_selected" type="text" id="c_2_selected" disabled="disabled" class="aspNetDisabled" style="width:190px;" />
<input type="hidden" name="c_2_id" id="c_2_id" value="23" /></td>
<td><select name="c_2_type" id="c_2_type" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="Primary">Primary</option>
<option value="Secondary">Secondary</option>
<option value="Higher Education">Higher Education</option>
</select></td>
<td><select name="c_2_type1" id="c_2_type1" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="State">State</option>
<option value="Independent">Independent</option>
</select></td>
<td><textarea name="c_2_additional" rows="6" cols="30" id="c_2_additional" disabled="disabled" class="aspNetDisabled" style="width:190px;"></textarea></td>
</tr>
<tr>
<td align="right" colspan="5"></td>
</tr>
</table>
<input type="hidden" name="iChild" id="iChild" value="2" />
<input type="submit" name="Button1" value="Next" id="Button1" class="submitBtn" />
You are mixing .NET code and JavaScript code. Because .NET runs first, it will try to process the code as you have written it:
<%=c_' & i & '_selected.ClientID%>
and most likely generate an error message because that is invalid code.
A simpler solution might be to use a class name. Then with jQuery, you could condense all of your code into a single call:
$('.ClassName').toggle();
Illegal javascript syntax. You ARE mixing .net and JS
var frmSchoolSelected+i is not allowed.
Also your loop is assigning i instead of testing i (= versus ==)
try this
function toggle(switchElement) {
var clientId = '<%=c_1_selected.ClientID%>';
var isYes = switchElement.value == 'Yes';
for (var i=1; i==iChildren; i++) {
var frmSchoolSelected = document.getElementById(clientId.replace('_1_selected','_'+i+'_selected'));
var frmSchoolAge = document.getElementById(clientId.replace('_1_selected','_'+i+'_type'));
var frmSchoolType = document.getElementById(clientId.replace('_1_selected','_'+i+'_type1'));
var frmSchoolAdditional = document.getElementById(clientId.replace('_1_selected','_'+i+'_additional'));
frmSchoolSelected.disabled = !isYes;
frmSchoolAge.disabled = isYes;
frmSchoolType.disabled = isYes;
frmSchoolAdditional.disabled = isYes;
}
}
A few notes on your approach.
Be aware of how you're using this as it means different things in different contexts. In your case it would be better to pass in the index of the row you're toggling. Your server side code most likely knows what row it's currently generating so this should be easy to accomplish.
As others pointed out, you are mixing client side and server side. In this case i is a client side variable that you're trying to use in a '<%=c_'... which is a server side context
I'm not quite sure why you're putting a + into what should be a variable name, but using a plus sign as part of a variable name isn't legal in JavaScript
switchElement in this case isn't a CheckboxList as you're expecting it to be, it's just an html span element and as such won't have a meaningful value property. You have to look at the actual input elements inside it and see if the yes element is checked (for example).
If you were to go with a JavaScript solution you would need code along these lines
function toggle(i) {
var schoolSelected = document.getElementById('c_' + i + '_school_selected_0').checked;
// client side names of variables will be predictable so to an extent you can get away with
// hard-coding them. Not the best practice, but it'd work
var frmSchoolSelected = document.getElementById('c_' + i + '_selected');
var frmSchoolAge = document.getElementById('c_' + i + '_type');
var frmSchoolType = document.getElementById('c_' + i + '_type1');
var frmSchoolAdditional = document.getElementById('c_' + i + '_additional');
// JavaScript, like some other languages lets you chain assignments like this
frmSchoolSelected.disabled =
frmSchoolAge.disabled =
frmSchoolType.disabled =
frmSchoolAdditional.disabled = !schoolSelected;
}
If you were to approach this from jQuery side I would suggest making a few changes to your HTML as well. Your output can be thought of as a list of mini-forms so instead of having one large table with different rows corresponding to different parts, create a list (or a table with a single column if you aren't ready to give up on table based layout quite yet).
New HTML
<ul>
<li class="school1">
<!-- school information form goes here -->
...
<span id="c_1_school_selected" class="toggle" onclick='toggle("school1")'>
...
</li>
<li class="school2">
<!-- school information form goes here -->
...
<span id="c_1_school_selected" class="toggle" onclick='toggle("school2")'>
...
</li>
...
</ul>
New code
function toggle(row) {
var allInputs = $("#" + row + " :input")
.not(".toggle input:radio");
var state = $(".toggle :checked").val();
if (state == "Yes") {
allInputs.removeAttr("disabled");
} else {
allInputs.attr("disabled", "disabled");
}
}
There are two nice things about this approach:
You are no longer relying on knowing what the ClientID will be as you're dealing with input elements as input elements
You can now refactor this input form into some sort of a repeating control (like a ListView) so if you decide you'd like to change how each row is formatted, it'll be very easy to do (since it'll all be in one place).
I got there eventually, once I had worked out how to add the onclick attribute to the input tag instead of the span tag I could then concentrate on the javascript function.
Code behind
Adds onclick to input tag.
Dim newRadioYes As New RadioButton
newRadioYes.Text = "Yes"
newRadioYes.ID = "c_" & childID & "_school_selected_0"
newRadioYes.Attributes.Add("onclick", "javascript:toggle(this, " & childID & ");")
newRadioYes.Attributes.Add("value", "Yes")
newRadioYes.GroupName = "c_" & childID & "_school_selected"
Dim newRadioNo As New RadioButton
newRadioNo.Text = "No"
newRadioNo.ID = "c_" & childID & "_school_selected_1"
newRadioNo.Attributes.Add("onclick", "javascript:toggle(this, " & childID & ");")
newRadioNo.Attributes.Add("value", "No")
newRadioNo.GroupName = "c_" & childID & "_school_selected"
Generated HTML form
<form method="post" action="schoolingform.aspx" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'Button1')" id="form1">
<table id="Table1" cellspacing="0" cellpadding="0" style="border-width:0px;border-collapse:collapse;">
<tr>
<td><strong>School Selected</strong></td>
<td colspan="4"><input id="c_1_school_selected_0" type="radio" name="c_1_school_selected" value="Yes" onclick="javascript:toggle(this, 1);" />
<label for="c_1_school_selected_0">Yes</label>
<input id="c_1_school_selected_1" type="radio" name="c_1_school_selected" value="No" onclick="javascript:toggle(this, 1);" />
<label for="c_1_school_selected_1">No</label></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Child</th>
<th style="border-right:1px solid #dddddd;">School Name</th>
<th>School Type</th>
<th>School Type</th>
<th>Additional Information</th>
</tr>
<tr valign="top">
<td><strong>Fred Wilkinson</strong></td>
<td style="border-right:1px solid #dddddd;"><input name="c_1_selected" type="text" id="c_1_selected" disabled="disabled" class="aspNetDisabled" style="width:190px;" />
<input type="hidden" name="c_1_id" id="c_1_id" value="26" /></td>
<td><select name="c_1_type" id="c_1_type" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="Primary">Primary</option>
<option value="Secondary">Secondary</option>
<option value="Higher Education">Higher Education</option>
</select></td>
<td><select name="c_1_type1" id="c_1_type1" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="State">State</option>
<option value="Independent">Independent</option>
</select></td>
<td><textarea name="c_1_additional" rows="6" cols="30" id="c_1_additional" disabled="disabled" class="aspNetDisabled" style="width:190px;"></textarea></td>
</tr>
<tr>
<td><strong>School Selected</strong></td>
<td colspan="4"><input id="c_2_school_selected_0" type="radio" name="c_2_school_selected" value="Yes" onclick="javascript:toggle(this, 2);" />
<label for="c_2_school_selected_0">Yes</label>
<input id="c_2_school_selected_1" type="radio" name="c_2_school_selected" value="No" onclick="javascript:toggle(this, 2);" />
<label for="c_2_school_selected_1">No</label></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Child</th>
<th style="border-right:1px solid #dddddd;">School Name</th>
<th>School Type</th>
<th>School Type</th>
<th>Additional Information</th>
</tr>
<tr valign="top">
<td><strong>Sara Wilkinson</strong></td>
<td style="border-right:1px solid #dddddd;"><input name="c_2_selected" type="text" id="c_2_selected" disabled="disabled" class="aspNetDisabled" style="width:190px;" />
<input type="hidden" name="c_2_id" id="c_2_id" value="27" /></td>
<td><select name="c_2_type" id="c_2_type" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="Primary">Primary</option>
<option value="Secondary">Secondary</option>
<option value="Higher Education">Higher Education</option>
</select></td>
<td><select name="c_2_type1" id="c_2_type1" disabled="disabled" class="aspNetDisabled">
<option selected="selected" value="State">State</option>
<option value="Independent">Independent</option>
</select></td>
<td><textarea name="c_2_additional" rows="6" cols="30" id="c_2_additional" disabled="disabled" class="aspNetDisabled" style="width:190px;"></textarea></td>
</tr>
<tr>
<td align="right" colspan="5"></td>
</tr>
</table>
<input type="hidden" name="iChild" id="iChild" value="2" />
<input type="submit" name="Button1" value="Next" id="Button1" class="submitBtn" />
Javascript function
function toggle(switchElement, childID) {
var frmSelected = document.getElementsByName('c_' + childID + '_school_selected');
var frmSchoolSelected = document.getElementById('c_' + childID + '_selected');
var frmSchoolAge = document.getElementById('c_' + childID + '_type');
var frmSchoolType = document.getElementById('c_' + childID + '_type1');
var frmSchoolAdditional = document.getElementById('c_' + childID + '_additional');
if (switchElement.value == 'Yes') {
frmSchoolSelected.disabled = false;
frmSchoolAge.disabled = true;
frmSchoolType.disabled = true;
frmSchoolAdditional.disabled = true;
}
else {
frmSchoolSelected.disabled = true;
frmSchoolAge.disabled = false;
frmSchoolType.disabled = false;
frmSchoolAdditional.disabled = false;
}
}
Thanks to those who pointed me in the right direction, much appreciated.

Categories