Repeatedly show dynamic dropdowns - javascript

I want to repeatedly show drop downs in a table in order to take its value and update specific records.
I have able to make dynamic dropdown using this
function getEmployeeTaskStatusMain(){
var go_path = "Employee_Switch_Person.php?action=getEmployeeTaskStatusMain&vars=0";
$jq.get(go_path,
{
}, function(data)
{
if(JSON.parse(data).length == 0){
console.log(data);
return data;
}
else {
var dataToAppend;
dataToAppend = "<select name='EmployeeTaskStatus' class='EmployeeTaskStatus form-control'>"
dataToAppend += "<option value='0'>Select Status</option>";
//console.log(" " + data);
dataParse = JSON.parse(data);
for (var i = 0; i < dataParse.length; i++)
{
//console.log(dataParse[i]);
dataToAppend += "<option value=" + dataParse[i].TaskStatusMainId + ">" + dataParse[i].TaskStatusMain + "</option>";
}
dataToAppend +="</select>";
$jq(".taskStatusMain").html(dataToAppend);
//getEmployeeTaskStatusDetail(0);
return dataParse;
}
});
}
But do i need to repeat the above function for every table row in order to show the dropdown in each row with dynamic id(so that i can get it selected value)?
The table (is also making dynamically) where i have to show dropdown with each record and i want to take each dropdown selected value in order to update specfic record. what is the handy way?
Remember, There are two drop downs one dropwdown value updating on another dropdown value selection.

Why don't you return this data in the users array and render it in the HTML file inside the for loop for each user and loop through his status to render the drop down?
And then update that row using the on change event for the select tag
<tr>
<th>status></th>
</tr>
foreach($users as $user){
<tr>
<td>
<select>
foreach($user->status as $status-item){
<option>$status-item->name</option>
}
</select>
</td>
</tr>
}

Related

Adding Checkbox to dropdown list

I am new to JavaScript programming. My program gives me another dropdown
menu based on the selection of the first dropdown menu. I am trying figure out how I can add checkbox into my dropdown so that I can check different types of fruits or
vegetables.
<script>
window.onload = function() {
// provs is an object but you can think of it as a lookup table
var provs = {
'Vegetable': ['Broccoli', 'Cabbage','Carrot'],
'Fruit': ['Tomato', 'Apple','Orange']
},
// just grab references to the two drop-downs
food_select = document.querySelector('#food'),
type_select = document.querySelector('#type');
// populate the drop-down
setOptions(food_select, Object.keys(provs));
// populate the town drop-down
setOptions(type_select, provs[food_select.value]);
// attach a change event listener to the drop-down
food_select.addEventListener('change', function() {
// get the towns in the selected province
setOptions(type_select, provs[food_select.value]);
});
function setOptions(dropDown, options) {
// clear out any existing values
dropDown.innerHTML = '';
// insert the new options into the drop-down
options.forEach(function(value) {
dropDown.innerHTML += '<option name="' + value + '">' + value + '</option>';
});
}
};
</script>
<body>
<select id="food"></select><br><br><br>
<select id="type"></select>
<body>

Reset name attribute array indexes, dynamically add remove rows

I have to post data via ajax and need the name attribute array indexes to reset.
For example:
1st row:
<select data-placeholder="Colours" class="colours chosen-select"
multiple tabindex="4" name="colours[0][]">
<option value="">Red</option>
<option value="">Orange</option>
</select>
2nd Row dynamically added:
<select data-placeholder="Colours" class="colours chosen-select"
multiple tabindex="4" name="colours[1][]">
<option value="">Red</option>
<option value="">Orange</option>
</select>
The name colours array must increment by 1 everytime I add, as well as reset the values when I remove.
I have looked around but not found any solution.
Here is what I have:
Adding:
var tbl = $("#service");
$("#addRowBtn").click(function () {
var count = $('#rowCount tr').length;
$("<tr>" +
"<td>" +
"<select data-placeholder=\"Colours\" class=\"colours chosen-select\"
multiple tabindex=\"4\"\ name=\"colours[" +
count +
"][]\">" +
"<option value=\"\">Red</option>" +
"<option value=\"\">Orange</option>" +
"</select></td>" +
"<td><i style=\"color:#d64830\" class=\"delRowBtn fa fa-minus-
circle\"></i></td></tr>").appendTo(tbl);
Deleting a row:
$(document.body).delegate(".delRowBtn", "click", function () {
$(this).closest("tr").remove();
});
I have added var count to increment the indexes, but I'm not able to reset the values when removing.
Please help!
You can try to cycle all select of your table and change the attribute "name" of each select everytime you delete an item.
$('#rowCount tr td select').each(function(idx, item){
$(item).attr("name", "colours[" + idx + "][]")
});
update
like suggest #ChayimFriedman the cool version of previous suggestion
$('#rowCount select').attr('name', function(idx) { return "colours[" + idx + "][]"; });

How can I perform dynamic operations on dynamically added elements?

My objective:
Filling in the 'performer-payments' table dynamically with JS/Jquery
For each (dynamically added) row in the table, one of the data cells contains a dropdown box.
This dropdown box should, when a certain option is selected, make visible another dropdown box (in the same cell). Otherwise, this second dropdown should be invisible.
Elsewhere I am accomplishing the hide/show dynamics by means of a toggleVisible function, which simply adds custom classes which is marked by css to hide or show the element.
The relevant code:
The table I want to populate:
<table id='performer-payments' class='performer-profile payments-table'>
<tr>
<th> Period </th>
<th> Amount </th>
<th> Paid? </th>
</tr>
</table>
The code that populates the table:
for (period in data['Performers'][performer]['Payments']) {
var amount = utils.calcPerformerCut(data, performer, period);
var row = "<tr>";
row += "<td> " + period + " </td>";
row += "<td> " + amount + " $ </td>";
row += "<td>";
row += "<div class='performer-profile payment-status'>";
row += data['Performers'][performer]['Payments'][period];
row += "</div>";
row += "<select id='payment-status-" + performer + "-" + period + "' class='perfomer-profile hidden-onload displayNone payment-status-menu'>";
row += "<option value='paid'>Paid</option>";
row += "<option value='unpaid'>Unpaid</option>";
row += "<option value='transfer'>Transfer to...</option>";
row += "</select>";
row += "<select id='payment-transfer-period-" + performer + "-" + period + "' class='performer-profile hidden-onload displayNone payment-period-menu'>";
for (var i=0; i < data['Periods'].length; i++) {
row += "<option value='" + period + "'>" + period + '</option>';
}
row += "</select>";
row += "</td>";
row += "</tr>";
$('#performer-payments').append(row);
$('#performer-payments').on('change', {perf: performer, per: period}, function (even) {
if (even.target.value == 'transfer') {
utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), true);
} else {
utils.toggleVisible($('#payment-transfer-period-' + even.data.perf + '-' + even.data.per), false);
}
});
}
For reference, the code that toggles visibility:
exports.toggleVisible = function (selector, visible) {
if (visible) {
selector.removeClass('displayNone').addClass('displayBlock');
} else {
selector.removeClass('displayBlock').addClass('displayNone');
}
}
There are (at least) two issues with this:
The #payment-transfer-period-... select box is never displayed, even when the 'transfer' option is chosen in the first select box. From debugging efforts it seems to me that it could be that the #payment-transfer-period-.. for some reason is not a valid object yet, or something like that.
(Obviously, really), the on-change event is triggered N times (N=number of periods) because I am just telling the program to trigger whenever something in the table changes. I would like it to trigger only for the relevant dropdown, but when I tried adding the #payment-status-... as a selector to the .on() function, it made it never trigger.
Note: I welcome feedback on this in general - I am an experienced programmer but have very little experience with HTML/JS/Jquery. Further, I have decided to not use templates for this project since I am trying to learn the basics, so if you get pancreatitis from seeing the way I am 'dynamically' adding the rows to the table, I apologize but it is partly intentional.
Other than that, please ask for clarifications if something is not clear here.
Edit: Here is the relevant part of the data structure:
data = {
'Performers': {
'Dira Klaggen': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Paid',
'Q3': 'Unpaid'
},
},
'Holden Bolden': {
'Payments': {
'Q2': 'Transferred to Q3',
'Q3': 'Unpaid'
}
},
'Manny Joe': {
'Payments': {
'Q1': 'Paid',
'Q2': 'Unpaid',
'Q3': 'Unpaid',
}
}
},
'Periods': [
'Q1',
'Q2',
'Q3'
]
}
You do not attach the change handler to the right element. I should be the first select in the row... Instead of the whole table.
Try this change handler:
$('#performer-payments').find('#payment-status-' + performer + '-' + period).on('change', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
Second approach:
You could simplify that by using a class instead of a "complicated" unique id for the first select.
Say you use the class "payment-status":
The handler would be:
$('#performer-payments').on('change', '.payment-status', function(){
if ($(this).val() == 'transfer') {
$(this).next('select').show();
} else {
$(this).next('select').hide();
}
});
And this handler can be out of the row appending loop because it uses delegation.
Let's clean up your code by doing the following things:
Use classes instead of ugly IDs.
Use data-attributes or hidden input fields to hold extra information.
Use event delegation to bind dynamically-created elements. Inside the event handler, use tree traversal methods to limit the scope of the search based on the current element this.
Let's apply these things.
Build each row like this. {PLACEHOLDER} is where you put your variable stuff like you have in your code.
<tr>
<td>{PERIOD}</td>
<td>{AMOUNT} $ </td>
<td>
<div class='performer-profile payment-status'>
{SOMETHING-RELATING-TO-PERFORMER-PAYMENT-PERIOD}
</div>
<!-- remove ID -->
<!-- store performer and period in data-attributes -->
<select class='perfomer-profile hidden-onload displayNone payment-status-menu' data-performer='{PERFORMER}' data-period='{PERIOD}'>
<option value='paid'>Paid</option>
<option value='unpaid'>Unpaid</option>
<option value='transfer'>Transfer to...</option>
</select>
<!-- remove ID -->
<select class='performer-profile hidden-onload displayNone payment-period-menu'>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<option value='{PERIOD}'>{PERIOD}</option>
<!-- etc -->
</select>
</td>
</tr>
In your JavaScript, create a delegated event handler. Note the syntax.
$(function () {
// ...
for (period in data['Performers'][performer]['Payments']) {
// build and append row
}
// create delegated event handler once and outside FOR loop
$(document).on('change', '.payment-status-menu', function () {
// get the current status menu
var statusMenu = $(this);
// find its related period menu
var periodMenu = statusMenu.closest('tr').find('.payment-period-menu');
// toggle its visibility
periodMenu.toggle(this.value == 'Transfer');
// of course, this could be a one-liner
//$(this).closest('tr').find('.payment-period-menu').toggle(this.value == 'Transfer');
});
});
It doesn't seem like you need (2.) but if you do, within the event handler, use statusMenu.data('performer') or statusMenu.data('period') to get its performer and period values. You could also do this.dataset.performer or this.dataset.period.

How to add elements in span using javascript

I am having the drop down list by selecting the country sode the state drop down list populated dynamically using javascript
<div id="ddlState" class='selectBox'>
<span class='selected' id="StatesID">Select a State</span>
<span class='selectArrow'>&#9660</span>
<div class="selectOptions" id="stateSelectOption">
<span class="selectOption" id="ddlStateText" >Select a State</span>
</div>
</div>
on clicking country the state is populated for tht the code is below
$('#CountriesID').click(function () {
var items;
$('#CountriesID').removeClass("input-validation-error");
if (!$("select#CountriesID").val() == "Select a Country") {
document.getElementById("disableasterisk9").style.display = "";
}
else {
document.getElementById("disableasterisk9").style.display = "none";
}
var countryid = $('#CountriesID').text();
$.getJSON(
"#Url.Action("StateList1", "UserRegistration")" + '/' + countryid,
function (data) {
var items = "<span id='ddlStateText' class='selectOption'>Select a State </span>";
$.each(data, function (i, state) {
items += "<span id='ddlStateText' value='" + state.Value + "' class='selectOption'>" + state.Text + "</span>";
});
$('#stateSelectOption span').html(items);
}
);
});
the list is populated but the selection is not working properly it rendering all the state items in one span tag so for selecting any element all list get selected
I need that the individual element should get selected
What see in the code on this line is that you are adding your html inside the span, so just take away that:
$('#stateSelectOption span').html(items)
The line must look like this (it will insert the code inside the div and not the span):
$('#stateSelectOption').html(items)
I tested it on jsfiddle:
http://jsfiddle.net/uz2vf/

html table editable and non-editable cells with jQuery

Is there a plugin or way to make certain table columns (not rows) editable and others not editable
with jQuery?
I have seen plugins for clicking on a cell to make it editable, but I mean explicitly making a cell/column editable or not.
I have a way of doing it but it feels like a bit of a hack job.
Here is my function for making a column editable:
function isEditable(rowArray, headersArray)
{
var counter = 0;
var notEditable = ['product code', 'product'];
for(i in rowArray){
counter = 0;
data = headersArray[i].toLowerCase();
for(a in notEditable){
if(data == notEditable[a]){
counter++;
}
}
if(counter > 0){
rowArray[i] += 'notEditable';
}
}
return rowArray;
}
it compares the header of the cell to an array of predefined values which = a non-editable column.
Then I build the row:
function buildHTMLTableRow(row, mutable)
{
output = '';
output += '<tr>';
for(var i = 0; i < row.length; i++)
{
value = trim(row[i]);
if(mutable){
index = value.indexOf('notEditable');
if(index != -1){
value = value.substring(0, index);
output += '<td>' + value + '</td>';
}
else{
output += '<td><input size="5" type="text" value="' + value + '" /></td>';
}
}
else{
output += '<td>' + value + '</td>';
}
}
output += '</tr>';
return output;
}
The mutable parameter decides if the row is editable or not, and the indexOf('noteditable') decides for the cell(but pretty much column) from the isEditable function.
Is there a plugin that does this better, or should I just settle with what I have?
Visit this jsFiddle link: Disable Columns
Following is the data flow:
I have created a row Array named "rowsD". When page loads I am populating my table (id=myData) with these rows.
Now creating another array called disableHeaders wherein I am passing the headers,
which you need to disable entire columns.
I am calling function disableFields passing disableHeaders as parameter
In the function, first I am fetching the index of the header whose value is equal to the values in headers array
If I find one, then from Input tag I am extracting the Value attribute using $(this).find('input') selector
Finally I am replacing the current child with Label tag passing the extracted Input tags Value
You may also comment out disableFields(disableHeaders); line to actually see, how table gets rendered initially
Thank you

Categories

Resources