How to mark checkboxs generated by loop without ID? - javascript

Im going to do my best to describe my issue, its hard to put into words.
On my page, I have a textbox and a button. I type a users name in the textbox and click the button to bring back all the users information.
Below this, I have a table being generated by a foreach loop of every role in my database that the user could possibly be in, with a 2 checkboxs next to it. The roles and textbox display even before the button is clicked.
When the users information comes back, whichever roles the user is in, I need to check those boxes.
It seems easy enough, I am just having a hard time trying to figure out how I am going to target each specific checkbox, because they are being created in a loop, not allowing me to give them specific ID's.
<table border="1" id="ApplicationRoles">
<thead>
<tr>
<th style="text-align:center" width="300">Role</th>
<th style="text-align:center" width="300">Category 1</th>
<th style="text-align:center" width="300">Category 2</th>
</tr>
</thead>
<tbody>
#foreach (var role in Model.appRoles)
{
<tr>
<td>
#Html.DisplayFor(modelItem => role.Name)
</td>
<td>
<input type="checkbox" />
</td>
<td>
<input type="checkbox" />
</tr>
}
</tbody>
</table>
Using javascript, I can check to see what roles the user is in, but how can I target a specific checkbox to check it(saying the user is in this role), without being able to give each one an ID?

Easiest way would be to assign for an idea that would make it easier to select via jquery. Since you're using razor. Would look something like this.
foreach (var role in Model.appRoles)
{
<input type="checkbox" id="chk_#(role.Name)" />
}
Then when you are trying to get the checkbox you would use a selector like this.
$('#chk_' + roleName).prop('checked',true);
If you NEEDED to get the checkboxes using strictly jQuery. You could do something like this...
http://jsfiddle.net/8q9cco37/
var user = {'role':'ADMIN2'};
var $roleMatch = $('td').filter(function(){
return $(this).text().toLowerCase() == user.role.toLowerCase();
});
var chk1 = $roleMatch.next('td').find('input');
var chk2 = $roleMatch.next('td').next('td').find('input');
chk1.prop('checked',true);
chk2.prop('checked',true);

I'm not familiar with asp.net, so I may screw up the syntax, but the idea is the same.
Here I'm using role.Name as the ID of the check box, you can use anything convenient to reference to in JS code.
Role
Category 1
Category 2
#foreach (var role in Model.appRoles)
{
<tr>
<td>
#Html.DisplayFor(modelItem => role.Name)
</td>
<td>
<input type="checkbox" id="<%= role.Name %>1" />
</td>
<td>
<input type="checkbox" id="<%= role.Name %>2"/>
</tr>
}
</tbody>
</table>

I would create a variable and attach it as part of the id to distinguish them all. I assume the two inputs are a group per list? So, I would differentiate them within the numbering convention (like 'y' and 'n' if you get what I'm saying):
#{
var i = 0;
foreach (var role in Model.appRoles)
{
i += 1;
<tr>
<td>
#Html.DisplayFor(modelItem => role.Name)
</td>
<td>
<input type="checkbox" ID="checkbox_Y#i" />
</td>
<td>
<input type="checkbox" ID="checkbox_N#i" />
</td>
</tr>
}

If you are looking to do the actual binding, it would be done like so.
#for(int i = 0; i < Model.appRoles.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => Model.appRoles[i].Name)
</td>
<td>
#Html.CheckBoxFor(x=> Model.appRoles[i].IsEnabled, new { id = Model.appRoles[i].MyId })
</td>
</tr>
}
Then, it would just be a matter of assigning specific IDs if it's something you are interested in.
However, if you wrap that up to an action, it will generate proper names that can be bound back to a model (with a List property) while submitting your form without touching anything.

Related

disable radio buttons of a particular column in a table

I have a table of radio buttons as shown in the below picture and if the user checks one radio button then that selected radio button column should be disabled and the user can check only one radio button in a row and for this, I have given the same name to the radio buttons of each row so that user can select only one radio button for a row. now the problem is that I am unable to disable the radio button of the checked column. I have used checked and selected interchangeably. any help is very much appreciated. thank you.
table of radio buttons
<table>
<tr>
<th *ngFor="let heading of columnHeadings[selectedScenario]">
{{heading}}
</th>
</tr>
<tr *ngFor="let i of [0,1,2,3];">
<td *ngFor="let loop of columnHeadings[selectedScenario]">
<input type="radio" name="{{i}}"> Correct
<input type="radio" name="{{i}}"> Partial
</td>
</tr>
</table>
You have to track from which row you are selecting a radio button and then disable it.
HTML:
<table border="1px">
<tr>
<th *ngFor="let heading of columnHeadings[selectedScenario]">
{{heading}}
</th>
</tr>
<tr *ngFor="let i of iterables;">
<td *ngFor="let loop of columnHeadings[selectedScenario]">
<input [disabled]="disabledRows[i]" type="radio" name="{{i}}" (change)="disableRow(i)"> Correct
<input [disabled]="disabledRows[i]" type="radio" name="{{i}}" (change)="disableRow(i)"> Partial
</td>
</tr>
</table>
TypeScript:
selectedScenario: string = "scenario";
iterables = [0,1,2,3];
disabledRows = this.iterables.map(m => false);
columnHeadings = {
scenario: [
"Most Effective Response",
"Second Most Effective Response",
"Trird Most Effective Response",
"Least Effective Response"
]
};
disableRow(index: number) {
this.disabledRows[index] = true;
}
Working solution at Stackblitz.
I suppose that you don't want disable the columns, only need that an option is not selected in the same column, else early you get into a situation when you can not select any value
For this, give values to the radiobuttons and use an array to store the values
values=[]; //declare an empty arrays
<tr *ngFor="let i of [0,1,2,3]">
<td *ngFor="let loop of columnHeadings[selectedScenario];let j=index">
<input type="radio" name="{{i}}" [ngModel]="values[i]"
(ngModelChange)="change($event,i)" [value]="j" > Correct
<input type="radio" name="{{i}}" [ngModel]="values[i]"
(ngModelChange)="change($event,i)" [value]="10+j" > Partial
</td>
</tr>
See that values get the column selected (0,1,2,3) if you select correct and 10 + the column selected if you choose partial (10,11,12,13) (e.g. a value of 12 indicate that you choose the "Trird Most Effective Response partial" and a value of 1 indicate you choose "Second Most Effective Response correct")
The function "change", give value to this.values[index] and loop over "values" making null a value if is in the same column
change(value,index)
{
this.values[index]=value
this.values.forEach((x,i)=>{
if (i!=index && x%10==value%10)
this.values[i]=null
})
}
The stackblitz
Try to add checked disabled to your radios like this:
<input type="radio" checked disabled name="{{i}}">

Replace ID for all tag after cloning node by javascript

I need to change all ID after cloning node below by javascript or jquery.
<table id="1">
<tr>
<td id="RM_1"><button type="button" onclick="duplicateFunction(1)"></td>
<td id="CL_1"><input id="[1][999]"/></td>
</tr>
</table>
when I clone node with ID = "1" I need to change 1 to 2 as in all ID tags below.
<table id="2">
<tr>
<td id="RM_2"><button type="button" onclick="duplicateFunction(2)"></td>
<td id="CL_2"><input id="[2][999]"/></td>
</tr>
</table>
Remark : The table id is unique id. I use simple number to explain the code.
update
When user click duplicate button. The duplicateFunction will be called.
now , I can change table id but I can't change inside.
function duplicateFunction(table_id){
var myTable = document.getElementById(table_id);
myClone = myTable.cloneNode(true);
var newTableID = Date.now();
myClone.id = newTableID;
document.getElementById("AddingSpace").appendChild(myClone);
}
because every tags have another features to do when user click.
that's the best way on this time.
Thank you in advance
This is an attempt along the lines suggested by Rory McCrossan. Instead of the individual ids of your elements inside the table I used shortened class names. The tables do not have actual ids but dataset attributes with id properties. This way it will not cause serious problems if ids should become double ...
My function calculates a newid on the basis of the number of already existing tables in the #addingspace div. This is not production ready either but probably less problematic than your original approach.
const $trg=$('#addingspace');
$(document).on('click','.RM button',function(){
let newid=$trg.find('table').length+2;
$trg.append(
$(this).closest('table').clone().data('id',newid) // set data-id
.find('.CL span').text(newid).end() // set span and return cloned element
)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table data-id="1">
<tr>
<td class="RM"><button type="button">duplicate</button></td>
<td class="CL"><input /> id: <span>1</span></td>
</tr>
</table>
<div id="addingspace"></div>

Accessing an individual column in a row which is selected by default with a radio button on page load

With the code below, I am trying to access a particular column "quantity" from a row in a table. What is happening is one of the rows is selected by default when page loads while the rest of the rows can be selected when user chooses. I created a click event handler to handle manual selection.
When accessing the column with a class name, it returns nothing. I need to assign this value to an input box in the same form. I would attach the image of the row
Table Markup:
<tr valign="top" class="row6">
<td>
{if $tpl_order_details[lineitems].quantity > 1}
{if $radio_flag == "false"}
<input type="radio" name="line_item" class="radio_class" id="line_item" value="{$tpl_order_details[lineitems].mSku}" checked onclick="handleClick(this);"/>
{assign var=radio_flag value='true'}
{else}
<input type="radio" name="line_item" class="radio_class" id="line_item" value="{$tpl_order_details[lineitems].mSku}" onclick="handleClick(this);" />
{/if}
{/if}
</td>
<td>
{$tpl_order_details[lineitems].sku}
</td>
<td>
</td>
<td>{$tpl_order_details[lineitems].item_description}</td>
<td class="quantity_class" >{$tpl_order_details[lineitems].quantity}</td>
<td>{$tpl_order_details[lineitems].item_status}</td>
Markup with the Input field outside the loop:
<table>
<tr>
<td><label for="new_quantity">Enter New Quantity</label></td>
<td><input type="number" id="split_quantity" name="split_quantity"
min="1" max="6"></td>
<td><button type="submit" value="Save"
name="submit_action">Submit</button></td>
<td><button type="submit" value="Cancel"
name="submit_action">Cancel</button></td>
</tr>
</table>
JavaScript:
// This is to handle the radio button selected by default on page load.
$( document ).ready(function() {
var firstRadioValue = 0;
firstRadioValue = $("input[name='line_item']:checked").val();
$('input[name="split_quantity"]').attr('max', firstRadioValue);
var quantity = $(".radio_class").parent().find(".quantity_class").val();
alert(quantity);
});
// This is to handle the radio button that user actually chooses.
var currentRadioValue = 0;
function handleClick(line_item) {
alert('New value: ' + line_item.value);
currentRadioValue = line_item.value;
$('input[name="split_quantity"]').attr('max', currentRadioValue);
}
You're not going far enough up the tree to find the class. You have:
var quantity = $(".radio_class").parent().find(".quantity_class").val();
which gets you to the parent <td> The element you're looking for is a sibling of this:
<td class="quantity_class" >...
What you want to do is go one element higher (the table row), then find the class you're looking for from there, so use closest(). Note that .quantity_class doesn't have a value so you have to get the text in the table cell:
var quantity = $(".radio_class").closest('tr').find(".quantity_class").text();
In addition, I do not see any markup with the max attribute or any markup with the name of split_quantity.
EDIT - based on a conversation with the user it was found that there needed to be a number of changes. First, the table holding split_quantity needed to be identified so it could be targeted in the grander markup:
<table id="split_quantity_id">
<tr>
<td><label for="new_quantity">Enter New Quantity</label></td>
<td><input type="number" id="split_quantity" name="split_quantity" min="1" max="6"></td>
<td><button type="submit" value="Save" name="submit_action">Submit</button></td>
<td><button type="submit" value="Cancel" name="submit_action">Cancel</button></td>
</tr>
</table>
Then we got rid of the onclick="handleClick(this) inline JavaScript in favor of letting jQuery handle the click event. Finally we refactored the functions:
$(function() {
var firstRadioValue = 0;
firstRadioValue = $("input[name='line_item']:checked").closest('tr').find('.quantity_class').text();
$('input[name="split_quantity"]').attr('max', firstRadioValue);
var quantity = $(".radio_class").closest('tr').find(".quantity_class").text();
console.log(quantity);
$('table').delegate('.line_item', 'click', function(){
currentRadioValue = $(this).closest('tr').find('.quantity_class').text();
console.log(currentRadioValue);
$('#split_quantity_id').find('[name="split_quantity"]').attr('max', currentRadioValue);
});
});
NOTE: It was also discovered that the OP is using Smarty 2 which is an older version of Smarty using an older version of jQuery, so .delegate() is used instead of on().

apply calculations to column in php

Hi I fetching some data from database and constructing the table.
foreach($data_array->LINEDETAILS as $data){
if(empty($data->CREDITEDAMOUNT)){
$data->CREDITEDAMOUNT=0;
}
$linetotal='';
$linetotal = $data->LINEAMOUNT + $data->TAXAMOUNT;
$column='<td>
<input onclick="sum_value(\''.trim($data->LINEAMOUNT).'-'.$data->TAXAMOUNT.'\',this.checked)" type="checkbox" name="checkdata'.$i.'" id="checkdata'.$i.'" value="'.$data->CUSTOMERTRXLINEID.'"style="position: inherit;" checked />
</td>
<td>'.$data->DESCRIPTION.'</td>
<td>'.$data->ORIGINALLINEAMOUNT.'</td>
<td>'.$data->CREDITEDAMOUNT.'</td><td>'.$data->LINEAMOUNT.'<input type="text" value="'.$data->LINEAMOUNT.'" hidden="true"></td>
<td>'.$data->TAXAMOUNT.'</td><td>'.$linetotal.'</td>
<td>
<select>
<option>--</option>
<option>%</option>
<option>Area</option>
<option>Period In Months</option>
</select>
</td>
<td><input type="text"></td>
<td><input type="text"></td>';
$row .= '<tr>'.$column.'</tr>';
$grandtotal = $grandtotal + $data->LINEAMOUNT + $data->TAXAMOUNT;
$i++;
}
This code returns one to many lines of data.
Each like has a dropdown of 3 value based upon which calculations will be done. If I select as % and Credit value as 80%, the approved line amount should be calculated onblur 80% of Eligible line amount.
I tried to set id's for each elements and do the math using JavaScript it won't calculate and give the result. it gives an error since ID of an element should be unique and since the elements are looped the ID also gets looped. Please help.
Give a try for : "onChange" of the dropdown value and then fetch the % value and calculate in your javascript code and display on the filed that is required, and mark the field as read-only if you want it "not" to be changed.
You can dynamically add id for each element as in the loop.. abd after that fetch all the records till the max value or iteration (say i)
You can add a class on each input field. For eg.
jQuery('.credit_val').change(function(){
var eligible = parseFloat(jQuery(this).parents('tr').find('.eligible_line').text());
var credit = parseFloat(jQuery(this).val());
jQuery(this).parents('tr').find('.approve_amount').val(eligible*credit/100);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<div class="eligible_line">1000</div>
</td>
<td>
<input class = "credit_val">
</td>
<td>
<input class = "approve_amount">
</td>
</tr>
<tr>
<td>
<div class="eligible_line">2000</div>
</td>
<td>
<input class = "credit_val">
</td>
<td>
<input class = "approve_amount">
</td>
</tr>
</table>

how to combine ng-if , ng-click and ng-show and use them together

Pre-info
I try to sperate Admin and customer in a different stage or view.
so that, admin can modify the table before releasing it to customers.
Questions
In the table -> td there is button to control the staging, release(show) or revert (hide)?
so basically what I wanna do is that every table checked can be shown on the both in admin and customer. if it's unchecked, the data only show to admin.
Currently, the code is disabled whole table-body instead of 1 row.
is there any way to check or uncheck only 1 row?
thanks for the advice.
$scope.showDiv = isAdmin();
$scope.toggleShowDiv = function () {
$scope.showDiv = !isAdmin()&isAdmin();
console.log('fired');
};
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<thead>
<tr>
<th style="width: 80px">foo1</th>
<th style="width: 80px">foo2</th>
<th style="width: 200px">foo3</th>
<th>foo4</th>
<th>foo5</th>
<th>foo6</th>
</tr>
</thead>
<tbody class="auction-group" ng-repeat="a in foos" ng-if="showDiv">
<tr>
<td>abcd1</td>
<td>abcd1</td>
<td>abcd1</td>
<td>abcd3</td>
<td>abcd4</td>
<td>abcd5</td>
//is admin - show only to admin
<td ng-if="::isAdmin()">
<input type="checkbox" ng-click="toggleShowDiv()" />
</td>
</tr>
</tbody>
Take your first ng-if outside ng-repeat
<div ng-if="showDiv">
<tbody class="auction-group" ng-repeat="a in foos">
</div>
second ng-if should be like this,
<td ng-if="isAdmin()">
<input type="checkbox" ng-click="toggleShowDiv()" />
</td>

Categories