Closest and find not working jquery - javascript

I have a Bootstrap Tab and a Table within the Tab and within the Table, a row with input fields. The problem I am experiencing is when I have multiple rows within the table only the first row values get pulled. I am using 'closet' and 'find' but I'm not getting the desired values. What am I doing wrong?
<ul class="nav nav-tabs nav-justified itemTab">
<li>Inbox</li>
<li>Outbox</li>
</ul>
<div class="tab-content itemTab">
<div class="tab-pane fade in" id="tab5">
<table class="table table-condensed" id="utable">
<th>Location</th>
<th>Department</th>
<th>HD Number</th>
#foreach (var item in Model.items)
{
<tr class="#item.Id">
<div class="accordian-body collapse in" id="#item.Id">
<input type="text" class="form-control" id="loc">
<input type="text" class="form-control" id="dept">
<input type="text" class="form-control" id="hdnum">
</div>
<div class="row">
<div align="center">
<input type="submit" value="Transfer" class="btn btn-success" onclick="MoveItem(#item.Id)" id="moveButton" data-url="#Url.Action("Submit", "Item")" />
</div>
</div>
</tr>
}
</table>
</div>
<div class="tab-pane fade in" id="tab6">
#Html.Action("Outbox", "Item")
</div>
function MoveItem(id) {
var row = $('#' + id).closest('.itemTab');
var loc = $(row).find('#loc').val();
var dept = $(row).find('#dept').val();
var hdnum = $(row).find('#hdnum').val();
}

First, wrap the id value in quotes when generating parameter for MoveItem call:
onclick="MoveItem('#item.Id')"
Second, change your repeating id's to classes and go up only as far as the parent tr:
<input type="text" class="form-control" class="loc">
function MoveItem(id) {
var row = $('#' + id).closest('tr');
var loc = $(row).find('.loc').val();
}

Your closest
var row = $('#' + id).closest('.itemTab');
gets the tab - but all of the "rows" are in that tab.
Instead, get the "row"
var row = $('#' + id).closest('tr');
then the finds will find the item in the relevant row.

Related

I want to disable the selected Item from a Drop Down list for the next row's DropDown Dynamically

The HTML for the form is :
<form id="flowform" class="form" role="form" autocomplete="off">
<table id="add-flow-level" class="table table-striped table-borderless" style="width: 100%">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="col-sm-4">
<label class="required ">Min Amount</label>
<input type="text"
id="minAmount" name="minAmount" class="form-control min"
style="border-radius: 1rem; width: 183px;"
maxlength="100" required="required"
/>
<!-- onfocus = "maxAmountCheck(this.id);" -->
</div>
</td>
<td>
<div class="col-sm-4">
<label class="required ">Max Amount</label>
<input
type="text" id="maxAmount" name="maxAmount"
class="form-control max"
style="border-radius: 1rem; width: 183px;"
maxlength="100" required="required" />
<!-- onfocus = "maxAmountCheck(this.id);"/ -->
</div>
</td>
<td>
<div class="col-sm-4">
<label class="required">Approver</label>
<select class="form-control" id="approver" name="approver"
style="border-radius: 1rem; width: 183px;"
required="required" >
<!-- onfocus = "approverCheck(this.id);" -->
<option th:value="0">Select User</option>
<option th:each="usersList : ${usersList}"
th:value="${usersList.id}"
th:utext="${usersList.firstName +' '+ usersList.lastName}" />
</select>
</div>
</td>
<td>
<a href="#" id="addFlowLevelRow" class="btn btn-primary btn-label-left addFlowLevelRow" title="Add Next" style="margin-top: 18px;">
<i class="fa fa-plus" aria-hidden="true"></i>
</a>
</td>
</tr>
</tbody>
</table>
<br>
<div class="row">
<label class="control-label col-sm-5" style="margin-top: 8px;"></label>
<div class="col-sm-2">
<input type="submit" class="btn btn-primary btn-label-left"
value="Save" id="submitbtnflow" name="submitbtnflow"
style="border-radius: 1rem;">
</div>
<p id="msg" style="color: green;"></p>
</div>
</form>
js file
var countOfRows =1;
$(".addFlowLevelRow").click(function() {
var remv = "<a href='#' id='removeFlowLevelRow' class='btn btn-primary btn-label-left removeFlowLevelRow' title='Remove Row' style='margin-top: 33px;'><i class='fa fa-minus' aria-hidden='true'></i></a>";
var txt = $(this).closest("tr").find('#removeFlowLevelRow').attr('href');
if (txt == undefined && countOfRows < 5) {
var newRow = $(this).closest("tr").clone(true).appendTo("#add-flow-level").append(remv);
if(countOfRows == 4)
{
document.getElementsByClassName("addFlowLevelRow")[4].style.display = "none";
console.log("Removal of - button at row = "+countOfRows);
}
countOfRows++;
console.log("Number of row = "+countOfRows);
}
else if(countOfRows < 5){
var newRow = $(this).closest("tr").clone(true).appendTo("#add-flow-level");
if(countOfRows == 4)
{
document.getElementsByClassName("addFlowLevelRow")[4].style.display = "none";
console.log("Removal of - button at row = "+countOfRows);
}
countOfRows++;
console.log("Number of row =" +countOfRows);
}
var input = document.getElementsByClassName('max');
newRow.find('.min').val(input.value);
newRow.find('.max').val("");
newRow.find('#approver').val(0);
});
$(document).on('click', '#removeFlowLevelRow', function(e) {
console.log("view----");
$(this).closest("tr").remove();
countOfRows--;
console.log("After - Button count is = "+countOfRows);
});
$('#approver').on('change', function() {
alert("alerrt called");
var select = document.getElementById('approver');
var value = select.options[select.selectedIndex].value;
alert(value);
var index = value;
if (index > -1) {
// ${usersList}.splice(index, 1);
}
alert("ye ky tha"+select.value);
//return ${usersList};
});
I want that Super Admin to be disabled for the 2nd row and show values other than super Admin in that drop down.
Whenever the user clicks on + button it creates a clone of the row.
I have not created the new row separately but I want the new drop down to not have the value that are selected in the first drop down and this should go till 5 rows.
id's in the DOM should always be unique otherwise it can lead to strange behaviour in the page
so firstly you need to give each row's "approver" select element a separate id e.g. approver0,1,2... (or just remove the id) and instead have a common class for these elements e.g. "form-control approver"
Then in your onchange function, loop through the approver class and disable the select options that don't appear, here is some psuedo code to start working with
var a = document.getElementsByClassName("approver")
//loop through all approver select elements
for(i in a) {
if(a[i] = this) {
//do nothing if we loop to the element that has just been changed
}
else {
//if the approver select isn't the one we've just changed, loop through the options
options = a[i].childNodes
for(j in options){
if(options[j].value = this.value) {
//if the option matches the one we've just selected disable it
options[j].setAttribute("disabled")="disabled"
}
else {
//Otherwise re-enable it so we don't disable all elements by changing the selection
options[j].removeAttribute("disabled")
}
}
In this rudimentary example changing the next approver option will overwrite disabling the previous selection so you may need to also keep track of what has been selected in all other drop downs. but hopefully this gets you started

Jquery filtering elements, Speed problem when elements increase

I have produced a table but I am using <div>s instead of <tr>s and <td>s. here is an example:
<div class="tbl tbl1">
<div class="thead">
<div class="tr">
<div class="td colTitle" style="width: 120px"><span>Title</span></div>
<div class="td colLink" style="width: 190px"><span>Link</span></div>
<div class="td colSize numeric" style="width: 75px"><span>Size(MB)</span></div>
<div class="td colUploadDate" style="width: 75px"><span>UploadDate</span></div>
<div class="td colOpen" style="width: 50px; max-width: 50px;"><span>Show</span></div>
</div>
<div class="tr">
<div class="td colTitle">
<input type="text" class="Filter" />
</div>
<div class="td colLink">
<input type="text" class="Filter" />
</div>
<div class="td colSize">
<input type="text" class="Filter" />
</div>
<div class="td colUploadDate">
<input type="text" class="Filter" />
</div>
<div class="td colOpen">
</div>
</div>
</div>
<div class="tbody">
</div>
</div>
I will fill tbody part with server-side operations.
I use below codes to filter my rows based on values entered in filter inputs.
$(".Filter").on('input', function () {
filterGrid();
$(".rowCount").val($(".tbody .tr:visible").length);
});
function filterGrid() {
$('.tbody .tr').each(function () {
var v = 1;
var x = $(this);
$(".thead .Filter[value!='']").each(function () {
var i = $(this).parent(".td").index();
if (x.children(".td:eq(" + i + ")").html().indexOf($(this).val()) != -1) {
v = v * 1;
} else {
v = 0;
return false;
}
});
if (v == 1) {
x.show();
} else {
x.hide();
}
});
}
My code works fine when I have a few number of rows, but when the number of loaded rows increases it takes more time to do filtering operation. Now I have two Question:
1- can my filter function be optimized to operate more rapidly?
2- when I enter the first letter I can't enter the second letter until the end of filtering based on the first letter. can I enforce javascript to break the operation and start a new one when I hit a button?

When user hit enter, it changes dropdown menu content and textfield data to its default

i have a form where i need such facility where user input some data in textfield and hits enter that time using jquery it should create new controls like new textfield, dropdown menu, textfield. and its works also, but it has a bug like when user input another data and hits enter that time value of previous controls, dropdown and textfield changes to its default. help me to solve it
Here is my code :
<script type="text/javascript">
function addMbo(value){
var div = document.getElementById('mboTable');
var keycode = (event.keyCode ? event.keyCode : event.which);
if(keycode == '13'){
event.preventDefault();
var divName = document.getElementById('mboName');
var divState = document.getElementById('mboState');
var divProgress = document.getElementById('mboProgress');
divName.innerHTML = divName.innerHTML + "<input class=form-control type=text name=mboName value='" + value + "' id=mboNamw/>"
divState.innerHTML = divState.innerHTML + "<select class=form-control > <option value=1>In Progress </option><option <value=2>Completed</option><option value=3>Cancled</option></select>"
divProgress.innerHTML = divProgress.innerHTML + "<input class=form-control type=text name=progress id=progress />"
document.getElementById('mboNameInput').value = null;
}
}
</script>
HTML code:
<div class="col-sm-4">
<div class="row">
<div class="col-sm-5">
<b>Objectives</b>
</div>
<div class="col-sm-4">
<b>Status</b>
</div>
<div class="col-sm-3">
<b>Compl. %</b>
</div>
</div>
<div class="row">
<div id="mboTable">
<div id="mboName" class="col-sm-5"></div>
<div id="mboState" class="col-sm-4"></div>
<div id="mboProgress" class="col-sm-3"></div>
</div>
</div>
<div class="row" >
<div class="col-sm-5">
<input type="text" id="mboNameInput" class="form-control " onkeydown="addMbo(this.value)" placeholder="Your MBO...">
</div>
</div>
</div>
here is jsfiddle
Check below solution will work out for you
$(function() {
$("#mboNameInput").on("keydown", function(e) {
if (e.keyCode == 13) {
var $nameDiv= $("#mboName");
var $stateDiv= $("#mboState");
var $progressDiv= $("#mboProgress");
$nameDiv.append($("<input/>").attr("type","text").attr("value",$(this).val()));
$stateDiv.append($("<select/>").append($("<option/>").text("InProgress")).append($("<option/>").text("Completed")).append($("<option/>").text("Canceled")));
$progressDiv.append($("<input/>").attr("type","text"));
$(this).val('');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered table-responsive">
<tr>
<th>Objectives</th>
<th>Status</th>
<th>% Comp</th>
</tr>
<tr>
<div id="mboTable">
<td><div id="mboName" class="col-lg-4"></div></td>
<td><div id="mboState" class="col-lg-5"></div></td>
<td><div id="mboProgress" class="col-lg-3"></div></td>
</div>
</tr>
<tr>
<td>
<div class="col-lg-5">
<input type="text" id="mboNameInput" class="form-control " placeholder="Your MBO..."></div>
</td></tr> </table>

How do I get a <div> on a nearby node in the DOM?

I'm trying to write some JavaScript that could be used throughout my app, and allow a checkbox to show/hide a nearby element.
If I have these elements:
<div class="optionable" style="display: block;">
<div class="row">
<div class="col-md-2">
<input checked="checked" class="form-control"
data-val="true" id="IsActive"
name="IsActive"
onclick="CheckboxOptionsToggle(this);"
type="checkbox" value="true">
</div>
<div class="col-md-8">
Chapter
</div>
</div>
<div class="row options">
<div class="col-md-12">
Some data here...
</div>
</div>
</div>
And this script:
CheckboxOptionsToggle = function (thisCheckbox) {
debugger;
var optionElement = $('.options');
if (thisCheckbox.checked) {
$(thisCheckbox).closest(optionElement).show();
} else {
$(thisCheckbox).closest(optionElement).hide();
}
}
But this isn't working. I would like the checkbox with the onclick="CheckboxOptionsToggle(this);" to trigger the options element in the same optionable div to either show or hide.
What am I doing wrong in my JavaScript/jQuery?
UPDATE: This is my final solution:
$('.optionToggle').on('change', function () {
$(this).closest('.optionable').find('.options').toggle(this.checked);
});
$(document).ready(function () {
var toggleElements = document.body.getElementsByClassName('optionToggle');
for (var i = 0; i < toggleElements.length; i++) {
var thisCheck = $(toggleElements[i]);
thisCheck.closest('.optionable').find('.options').toggle(thisCheck.prop('checked'));
}
});
<div class="optionable" style="display: block;">
<div class="row">
<div class="col-md-2">
<input checked="checked" class="form-control optionToggle"
data-val="true" id="IsActive"
name="IsActive"
type="checkbox" value="true">
</div>
<div class="col-md-8">
Chapter
</div>
</div>
<div class="row options">
<div class="col-md-12">
Some data here...
</div>
</div>
</div>
Be more generic, and stop using inline event handlers
$('[type="checkbox"]').on('change', function() { // or use class to not attach to all
$(this).closest('.optionable').find('.options').toggle(this.checked);
}).trigger('change');
FIDDLE
You can change it like
CheckboxOptionsToggle = function (thisCheckbox) {
debugger;
var optionElement = $('.options');
if (thisCheckbox.checked) {
$(thisCheckbox)..closest('div.optionable').find(optionElement).show();
} else {
$(thisCheckbox)..closest('div.optionable').find(optionElement).hide();
}
}
I would stay away from .closes, because it is so specific, instead I would go with more reusable code like so:
HTML:
<input type="checkbox" id="toggler" data-target-class="some-div" class="toggler" value="myValue" checked> Toggle Me
<div class="some-div">
Some Text within the div.
</div>
JS:
$('#toggler').on('click', function() {
var targetClass = $(this).data('target-class');
$('.' + targetClass).toggle($(this).checked);
});
JSFiddler: https://jsfiddle.net/ro17nvbL/
I am using data element on the checkbox to specifiy which divs to show or hide. This allows me to not only hide/show divs but anything n the page, and not only one instance but as many as needed. Way more flexible - still does the same job.

Div not changing on button click

I have created a webpage that have some big divs in it.
I have a button on that page. On the click of that button I want the current div to change and bring the next div up.
I have written some code but unfortunately it's not working :(
HTML:
<div class="tutorial">
<p class="heading">Tell us about yourself</p>
<div class="body">
<table>
<tr>
<td>
<label for="full_name">What's your full name?</label>
</td>
</tr>
<tr>
<td>
<input type="text" name="full_name" id="full_name" placeholder="Full Name" />
</td>
</tr>
<tr>
<td>
<br/>
</td>
</tr>
<tr>
<td>
<label for="about">Describe yourself:</label>
</td>
</tr>
<tr>
<td>
<textarea id="about" name="about" rows="5" cols="40" placeholder="Share you hobbies, interests and more about yourself"></textarea>
</td>
</tr>
<tr>
<td width="900px" height="60px"></td>
<td>
<button id="next" class="btn">Next</button>
</td>
</tr>
</table>
</div>
</div>
<div class="tutorial hidden">
<p class="heading">Tell us about yourself!</p>
<div class="body">Body</div>
</div>
<div class="tutorial hidden">
<p class="heading">Tell us about yourself!</p>
<div class="body">Body</div>
</div>
<div class="tutorial hidden">
<p class="heading">Tell us about yourself!</p>
<div class="body">Body</div>
</div>
<div class="tutorial hidden">
<p class="heading">Tell us about yourself!</p>
<div class="body">Body</div>
</div>
JS:
$(function () {
var tutorials = $("div.tutorial");
var idNumber = 1;
tutorials.each(function () {
$(this).attr("id", idNumber);
idNumber++;
});
var nextButton = $("#next");
$(nextButton).on('click', function () {
var currentTutorial = $("div.tutorial").not(".hidden");
var currentTutorialId = currentTutorial.prop("id");
currentTutorial.addClass("hidden");
var nextTutorialId = currentTutorialId++;
var nextDiv = null;
if ($("div.tutorial").is("#" + nextTutorialId)) {
var nextDiv = $("div.tutorial");
}
nextDiv.removeClass("hidden");
});
});
Removed CSS to shorten the question's length. :)
What I want:
I want the next button to hide the current div and bring up the very next div after it.
What I have done:
var currentTutorial = $("div.tutorial").not(".hidden");
var currentTutorialId = currentTutorial.prop("id");
currentTutorial.addClass("hidden");
var nextTutorialId = currentTutorialId++;
var nextDiv = null;
if ($("div.tutorial").is("#" + nextTutorialId)) {
var nextDiv = $("div.tutorial");
}
nextDiv.removeClass("hidden");
You are trying to select by id, however I don't see any id for the .tutorial divs. However, you could simply use the next jQuery function to get the nextSibling of the current div. You also have to make sure that there's at least one div without the .hidden class initially.
E.g.
$('div.tutorial:not(.hidden)').addClass('hidden').next().removeClass('hidden');
You need to remove the id from your buttons and instead use a class and change your selector for the click binding. As sugessted by #koala_dev.
You can use prev() and next() functions like
$(nextButton).on('click', function () {
var currentTutorial = $("div.tutorial").not(".hidden");
var currentTutorialId = currentTutorial.prop("id");
currentTutorial.addClass("hidden");
currentTutorial.next('div').show();
nextDiv.removeClass("hidden");
});

Categories

Resources