Access Property of a List Item Model from Javascript - javascript

I am using Javascript to edit the property of a row in a List of items and i am following a HTML view like this
ON edit button click i am showing a popup and on Save event of popup i want to set the properties of a selected row .
From html console i can see naming pattern is like name=[1].IsVerified [2].isVerified etc or in general [counter].Property But when i try to access element using JQUery i am not getting the element
#model IList<RoyaltyDb.Models.VerifyLicensorModel>
<table class="table">
<tr>
<th>
Licensor
</th>
<th>
Address
</th>
<th>
Status
</th>
<th>
Verify
</th>
</tr>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].Licensor)
#Html.DisplayFor(m => m[i].Licensor)
</td>
<td>
#Html.TextAreaFor(m => m[i].Address)
</td>
<td>
#Html.LabelFor(m => m[i].IsVerified)
#Html.CheckBoxFor(m => m[i].IsVerified, new { #disabled = "disabled" })
<br />
#Html.HiddenFor(m => m[i].ActionId)
#Html.HiddenFor(m => m[i].ReferenceId)
</td>
<td>
<a onclick="SetProperties('#Model[i].Licensor')" class="btn">Verify</a>
</td>
</tr>
}
</table>
<!-- Modal HTML -->
<div id="VerifyLicensorModal" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Verify Licensor</h4>
<input type="hidden" id="targetPopup" />
</div>
<div class="modal-body" id="VerifyLicensorDetails">
</div>
<div class="modal-footer">
<a class="btn btn-primary" onclick="confirmLicensor()">Confirm</a>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
function SetProperties(name)
{
//Showing a POPUp Here on element VerifyLicensorModal
}
function confirmLicensor()
{
//Set the corresponding IsVerified checkbox to true
//Set values of ActionId and ReferenceId params in the hidden fields
//ActionId ReferenceId
}
So how can i set the value of a property field from javascript

Rather than polluting your markup with behavior, use Unobtrusive Javascript. Give you link a class name and add the value of the Licensor property as a data- attribute and move the 2 hidden inputs into the same table cell for easier selection
<td>
#Html.HiddenFor(m => m[i].ActionId)
#Html.HiddenFor(m => m[i].ReferenceId)
Verify
</td>
var currentCell;
$('.verify').click(function() {
currentCell = $(this).closest('td');
licensor = $(this).data('licensor');
// get your partial view and display the popup
});
Similarly give the confirm button a unique id attribute
$('#confirm').click(function() {
var inputs = currentCell.children('input');
inputs.eq(0).val(....); // set the value of ActionId
inputs.eq(1).val(....); // set the value of ReferenceId
});
Note that you question indicates Set the corresponding IsVerified checkbox to true. Because this is in the previous cell, you could do it using
currentCell.prev('td').find('input[type="checkbox"]').prop(checked, true);
however you have disabled the checkbox using new { #disabled = "disabled" } which means it wont post back, but the associated hidden input generated by CheckBoxFor() will, meaning that irrespective of checking it, you will always post back false
If the checkbox is intended to give a visual representation that verification has been completed, then a better approach would be to include a hidden input bound to IsVerified and an unbound checkbox.
<td>
<input type="checkbox" disabled="disabled" />
</td>
<td>
#Html.HiddenFor(m => m[i].ActionId)
#Html.HiddenFor(m => m[i].ReferenceId)
#Html.HiddenFor(m => m[i].IsVerified)
Verify
</td>
Then you can 'check' the checkbox as noted above and include
inputs.eq(2).val("True"); // set the value of IsVerified
in the script
You may also want to consider deleting the 'Verify' link from the DOM once you close the popup (assuming you don't want to verify it again
currentCell.children('a').remove();

<tbody>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>
<input typye="hidden" class="index" value="#i"/>
#Html.HiddenFor(m => m[i].Licensor)
#Html.DisplayFor(m => m[i].Licensor ,{#id="liecenor-#i"})
</td>
</tr>
}
</tbody>
</table>
<script>
$(".table > tbody> tr").each(function () {
var index=$(this).find('.index').val();
var $id="#licensor-"+index;
alert($($id).val());
}
</script>

Related

Having trouble sorting table with JQuery sort method

I am using PHP and JQuery to build a data table, I am using jQuery's .sort() method to sort the table. However, it is not working as excepted.
For the text fields, nothing is changed (except that the rows are rendered again).
For the numeric fields, the table sorts in a really weird manner.
Clearly the ID does not make sense like this? Here is my JavaScript code:
const rows = tbody.find('tr').sort((a, b) => {
let first, second;
if ($(e.target).attr('data-order') === 'asc') {
second = a;
first = b;
$(e.target).attr('data-order', 'desc');
}
else {
second = b;
first = a;
$(e.target).attr('data-order', 'asc');
}
const firstTd = $(first).children().eq($(e.target).attr('data-index') - 1).text();
const secondTd = $(second).children().eq($(e.target).attr('data-index') - 1).text();
// Take care of numbers
try {
return firstTd - secondTd;
}
catch (e) {
// Value is string
const value = firstTd.localeCompare(secondTd, "en");
return value;
}
}).appendTo(tbody);
Here is the source code for my table (I just added two rows):
<table class="table">
<thead>
<tr>
<th>
<button class="btn btn-light data-table-sort"
data-index="1" data-order="asc">
id <span class="fa fa-sort" aria-hidden="true"></span>
</button>
</th>
<button class="btn btn-light data-table-sort"
data-index="3" data-order="asc">
Text <span class="fa fa-sort" aria-hidden="true"></span>
</button>
</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>72</td>
<td>af7c16d8f1</td>
<td>2021-11-26 06:16:55</td>
<td>
<form method="POST">
<input type="hidden" name="id" value="72">
<input type="submit" name="action" value="Details"
class="btn btn-info">
<input class="btn btn-primary" name="action"
type="submit" value="Edit">
<input data-id="72"
class="btn btn-danger data-table-delete"
name="action" value="Delete" type="submit">
</form>
</td>
</tr>
<tr>
<td>7</td>
<td>bedd6af3ed</td>
<!-- The same form as previous row -->
</td>
</tr>
</tbody>
</table>
I have made sure that tbody contains the correct value. I am also selecting the correct column. The table has to be dynamic and reusable so I can't hardcode everything.
Note: I have already tried appending rows to the table instead of the <tbody> element.
You probably need to detach elements since you reattach it again later:
tbody.find('tr').detach().sort...
This may need readjustments depending on how jQuery arrays are returned but detaching elements is the main idea and other things should be pretty trivial.

Hiding and un-hiding table div based off of data being returned

I have a table that I want to be hidden there is no data to be displayed.
I have a controller action that returns data to display for the table. If data is returned, I want the table to be show, otherwise I want it hidden. I have tried several approaches to this and it seems like my fix is working (for a few seconds) but then once the controller returns the model, the table becomes hidden again. I am doing something wrong. How can I fix this? Below is my code:
HTML:
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "submitForm"}))
{
<div class="row">
<div>
#Html.DropDownList("CasinoID", Model.TerminalReceiptPostData.CasinoIdDDL, "Select Casino", new { id = "cIdSearch", #class = "custom-class-for-dropdown card" })
</div>
<div>
<input id="datepicker" class="datepicker-base card" name="Date" placeholder="MM/DD/YYY" type="text"/>
</div>
<div>
<button type="submit" class="btn btn-sm btn-primary" id="search"> Search Transactions</button>
</div>
</div>
}
<hr />
<div class="row" id="ReceiptsMainDiv">
<div class="col-md-12" style="overflow-y:scroll">
<table class="table table-striped table-hover table-bordered" id="terminalReceipts">
<thead>
<tr>
<th>Terminal ID</th>
<th>Local Transaction Time</th>
<th>Amount</th>
<th>Receipt</th>
<td class="hidden"></td>
</tr>
</thead>
<tbody>
#foreach (var item in Model.TransactionsTests)
{
<tr id="#String.Concat("rowIndex", Model.TransactionsTests.IndexOf(item))">
<td>#item.TerminalID</td>
<td>#item.TransactionTime</td>
<td>#item.Amount</td>
#*<td>#Html.ActionLink("View Receipt", "ViewReceipt", new { id = item.Id }, new { #class = "btn btn-primary btn-sm" }) <br /></td>*#
<td class="transactionID hidden">#item.Id</td>
<td>
#if (item.ReceiptData == null)
{
<button class="btn btn-sm btn-primary viewReceipt" disabled>View Receipt</button>
}
else
{
<button class="btn btn-sm btn-primary viewReceipt" data-rowindex="#String.Concat("rowIndex", Model.TransactionsTests.IndexOf(item))">View Receipt</button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
Controller action:
[HttpPost]
public ActionResult Index(string CasinoID, DateTime Date)
{
//var id = Int32.Parse(Request.Form["CasinoID"].ToString());
var Cid = Request.Form["CasinoID"];
Cid = GetNumbers(Cid);
var id = Int32.Parse(Cid);
var model = TRBL.GetTransactionTestsData(id, Date);
model.TerminalReceiptPostData = TRBL.GetCasinosDDL();
return View(model);
}
and finally my JS function:
window.onload = function () {
$("#ReceiptsMainDiv").toggle();
var rowCount = $("#rowindex").length;
console.log(rowCount);
if (rowCount > 0) {
$("#ReceiptsMainDiv").toggle();
}
};
As you can see, the Form at the top contains the button, and the block below is the table that needs to be toggled.
Let me know if there is anything else you guys would need.
When you have results to show, <tr id="#String.Concat("rowIndex", Model.TransactionsTests.IndexOf(item))"> will not produce ids of "rowIndex" (unlike what you might be expecting). Instead, you will have "rowIndex0", "rowIndex1", etc. Therefore, after rowCount will be zero, and your will not toggle.

How to delete a particular row from table by clicking button Angular 2

I am trying to delete a particular row by clicking button from that row which is in for loop,but its deleting all the rows of that table.
Here is my Html code:
<table id="mytable" class="table table-bordred table-striped">
<tbody id="del">
<tr *ngFor="let cart of modalData">
<td>
<div style="display:inline-flex;">
<div style="margin-left:10px;">
<p class="font_weight" style="font-size:13px;">{{cart.ExamName}}</p>
<p>{{cart.Categoryname}}|{{cart.CompanyName}}</p>
</div>
</div>
</td>
<td>
<div style="margin-top: 32px;">
<p class="font_weight" style="font-size:13px;"></p> <span class="font_weight" style="font-size: 13px;"> {{cart.Amount| currency :'USD':'true'}} </span> </div>
</td>
<td>
<div style="margin-top: 19px;">
<button class="button_transparent" (click)="Delete(cart)"> delete </button>
</div>
</td>
</tr>
<tr> </tr>
</tbody>
</table>
Here is my Component:
public loadData() {
let transaction = new TransactionalInformation();
this.myCartService.GetExamOrderForCart()
.subscribe(response => this.getDataOnSuccess(response),
response => this.getDataOnError(response));
}
getDataOnSuccess(response) {
this.modalData = response.Items;
}
This is my delete method:
public Delete(response) {
this.myCartService.updateExamOrder(response)
.subscribe(response => this.getDataOnSuccessForDelete(response),
response => this.getDataOnErrorForDelete(response));
}
Please help me to do, How to delete only one row from table?
You can add index in *ngFor :
<tr *ngFor="let cart of modalData;let i = index">
Then, pass the index in the method:
<button class="button_transparent" (click)="delete(i)"> delete </button>
And finally:
delete(i){
this.modalData.splice(i,1);
}
you can do this:
<button class="button_transparent" (click)="delete(cart)"> delete </button>
then
delete(item){
this. modalData = this. modalData.filter(item => item.id !== id);
this.modalData.push();}
here you are creating a new list without the element that you want to delete.

Filter kendo dropdownlist to remove options

I want to filter security questions such that if I select questiona from the list of questions, for the next questions, I no longer see questiona in the list of security questions. This is to prevent duplicate selection of security questions.
Here's a jsfiddle with a pure jquery implementation:
http://jsfiddle.net/jbfbxvoo/
I was wondering how I can use the same approach to filter kendo dropdownlists:
E.g. I have three dropdownlists like:
<table style="float: left; width:300px;">
<tr>
<td>
<div class="editor-field">
#(Html.Kendo().DropDownListFor(m => m.Q1Id).HtmlAttributes(
new { style = "width:250px;", #id = "idQuestion1", #class="security"})
.Name("Q1DropDown")
.DataTextField("Text")
.DataValueField("Value")
.BindTo(Controllers.AccountController.SecurityQuestionList())
.Enable(true)
.Events(e=>e.Change("CreateAccount.QuestionChanged")))
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.A1, new { #class = "formTextbox k-textbox", #id = "idAnswer1" })
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-field">
#(Html.Kendo().DropDownListFor(m => m.Q2Id).HtmlAttributes(
new { style = "width:250px;", #id = "idQuestion2", #class="security" })
.Name("Q2DropDown")
.DataTextField("Text")
.DataValueField("Value")
.BindTo(Controllers.AccountController.SecurityQuestionList())
.Enable(true)
.Events(e=>e.Change("CreateAccount.QuestionChanged")))
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.A2, new { #class = "formTextbox k-textbox", #id = "idAnswer2" })
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-field">
#(Html.Kendo().DropDownListFor(m => m.Q3Id).HtmlAttributes(
new { style = "width:250px;", #id = "idQuestion3", #class="security" })
.Name("Q3DropDown")
.DataTextField("Text")
.DataValueField("Value")
.BindTo(Controllers.AccountController.SecurityQuestionList())
.Enable(true)
.Events(e=>e.Change("CreateAccount.QuestionChanged")))
</div>
</td>
</tr>
<tr>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.A3, new { #class = "formTextbox k-textbox", #id = "idAnswer3" })
</div>
</td>
</tr>
</table>
I tried this but doesn't work:
QuestionChanged: function () {
var sec = $('.security');
sec.change(function () {
sec.find('option').show().end().each(function () {
$('option[value="' + $(this).val() + '"]:not(:selected):not([value="0"])', sec).hide();
});
}).change();
}
For this implementation i have an idea, where first you need to have 3 dropdownlist that have one same datasource/observable but three different value to store each dropdownlist value and point to one same change event, example in mvvm
<h4 class="title">DropDownList</h4>
<input class="customdropdownlist" data-role="dropdownlist" data-text-field="text" data-value-field="value" data-bind="source:dataSource, value:dd1, events:{change:onChange}" style="width: 400px;"/>
<h4 class="title">DropDownList</h4>
<input class="customdropdownlist" data-role="dropdownlist" data-text-field="text" data-value-field="value" data-bind="source:dataSource, value:dd2, events:{change:onChange}" style="width: 400px;"/>
<h4 class="title">DropDownList</h4>
<input class="customdropdownlist" data-role="dropdownlist" data-text-field="text" data-value-field="value" data-bind="source:dataSource, value:dd3, events:{change:onChange}" style="width: 400px;"/>
On the view model change event you do your logic, maybe you can write better code than mine right now but the main point is
To loop through all 3 dropdownlist <li></li> , and compare with the
three value dd1,dd2,dd3 hide if match, otherwise show it
And the code :
var dropdowns = $("input.customdropdownlist");
for(j=0;j<dropdowns.length;j++){
var list = $(dropdowns[j]).data("kendoDropDownList").ul.find("li.k-item");
for(i=0;i<list.length;i++){
if(viewModel.dd1 &&list[i].textContent == viewModel.dataSource.get(viewModel.dd1).text){
$(list[i]).hide();
}else if(viewModel.dd2 &&list[i].textContent == viewModel.dataSource.get(viewModel.dd2).text){
$(list[i]).hide();
}else if(viewModel.dd3 &&list[i].textContent == viewModel.dataSource.get(viewModel.dd3).text){
$(list[i]).hide();
}else{
$(list[i]).show();
}
}
}
Working example in kendo dojo, add
updated dojo from modifying your code.
I have done something similar for kendo ComboBox. Do manipulate the below js function and it will work for kendo Drop Down also.
function QuestionChanged(event) {
$("[class^=security]").each(function () {
if (event.sender.element.attr('class') != $(this).attr('class')) {
var comboBox = $('#' + $(this).attr('id')).data('kendoComboBox');
$(comboBox.dataSource.data()).each(function () {
if (event.sender._selectedValue == this.Value) {
var data = this;
comboBox.dataSource.remove(data);
}
});
}
});
}
NOTE: Add security class to each of the drop down as security1 for first drop down, security2 for 2nd drop down and so on.
Hope it helps! Feel free to leave your feedback.

Send dynamic textbox element id to child window when clicking a link

I have a textbox called "Branch Code" which ties a branch to a corporate card transaction. Sometimes there is a need to split a transaction among several branches. I have a table being built dynamically in MVC containing the form that needs filled out. In the branch code table cell, I'm adding a href that will fire off the splitTransaction javascript function that opens a new window allowing a value to be built. This new value needs to be written back to the parent window into the textbox that was right next to the hyperlink that opened the child window. My problem is, how do I send the name of the textbox to the child window? I'm not sure how to get it.
Here is my view:
#model List<intranetMVC.Models.sp_CorpCardEmpGetTrans_Result>
#{
ViewBag.Title = "Index";
}
<h2>Corporate Card Transactions</h2>
#using (#Html.BeginForm("Index", "CorpCardTransactions", FormMethod.Post))
{
<table cellpadding="8">
<tr>
<th class="col-md-2">Transaction Details</th>
<th class="col-md-2">Payee</th>
<th>Amount</th>
<th class="col-md-2">Description</th>
<th class="col-md-1">GL/Account</th>
<th class="col-md-1">Branch Code</th>
<th class="col-md-1">Receipt</th>
</tr>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td valign="top">
#Html.HiddenFor(m => m[i].ID)
#*#Html.DisplayFor(m => m[i].AccountID)
#Html.HiddenFor(m => m[i].AccountID)<br />
<em>#Html.DisplayFor(m => m[i].CardHolderName)</em>
#Html.HiddenFor(m => m[i].CardHolderName)<br />*#
Posted: #Html.DisplayFor(m => m[i].PostDate)
#Html.HiddenFor(m => m[i].PostDate)<br />
TranDate: #Html.DisplayFor(m => m[i].TranDate)
#Html.HiddenFor(m => m[i].TranDate)
</td>
<td valign="top">
#Html.DisplayFor(m => m[i].Payee)
#Html.HiddenFor(m => m[i].Payee)
</td>
<td valign="top">
#Html.DisplayFor(m => m[i].Amount)
#Html.HiddenFor(m => m[i].Amount)
</td>
<td valign="top">#Html.EditorFor(m => m[i].Description)</td>
<td valign="top">#Html.EditorFor(m => m[i].GL_Account)</td>
<td valign="top">
#Html.EditorFor(m => m[i].BranchCode)<br />
Split Transaction
</td>
<td valign="top">#Html.EditorFor(m => m[i].Receipt)</td>
</tr>
}
</table>
<br />
<input type="submit" name="saveBtn" id="saveBtn" value="Save Progress" style="font-size:1.2em;font-weight:bold;width:200px;" /> <input type="submit" name="finishBtn" id="finishBtn" value="Finish and Close Statement" style="font-size:1.2em;font-weight:bold;width:250px;" /> #Html.ActionLink("Cancel", "Index", "Statements")
<p style="margin-top:1em;"><span style="color:green; font-size:14px;">#ViewBag.Message</span> <span style ="color:#b94a48; font-size:14px;font-weight:bold;">#ViewBag.Error</span></p>
<script type="text/javascript">
var popup;
function splitTransaction() {
popup = window.open("splittrans.htm", "Popup", "width=400,height=200");
popup.focus();
}
</script>
}
Here is what the page source looks like for one of the branch code table cells:
<td valign="top">
<input class="k-textbox" data-val="true" data-val-number="The field BranchCode must be a number." id="_0__BranchCode" name="[0].BranchCode" value="11" /><br />
Split Transaction
</td>
When I click on the link to "split transaction", how do I send the value of the textbox next to it to the function that opens the child window? Or how do I reference this textbox when sending the new value back to the parent window? There could be many of them on the page. It appears as if they are being named like this: _0__BranchCode, etc.
It would be better to handle the click event rather that using the onclick attribute
Split Transaction
and the script
$('.split).click(function() {
// get the adjacent (sibling) textbox value
var value = $(this).siblings().first().val();
// do something with the value
});
or you could use $(this).prev('.k-textbox').val() or $(this).closest('td').children('input').val();

Categories

Resources