Using jQuery input event to conditionally update a <td> innerHTML - javascript

I'd like to do something that at least for me is complicated.
I have this in a much larger table:
<table><tr>
<td class="editC" id="comments:942" onchange="TimeLine();" onclick="empty('comments:942');" title="Click to edit..."> Second test of new comment behavior
</td></tr></table>
Here is what is going on:
1) class="editC" = I use Editable to edit and write to the DB.
2) id="comments:942" = the id value
3) onchange="TimeLine();" = The timeLine() function gets information from another DB and puts it into a second HTML table on screen. This works.. no worries.
4) onclick="empty('comments:942')" = empty is a function to empty the field but it does not update the DB. I just want a clean input field to enter new data in place of the existing data.
What I'd like to happen is this.
a) If something is typed into this now empty field, all is good, my save.php code will save it to the DB. This works great.
b) But if nothing is typed into the now empty field, I want the old value put back in place without updating the DB. In my head this would be equivalent to first having cut the current value then pasting it back if nothing new had been typed.
It seems to me that jQuery should be able to do this with the input event.
function empty(thisID){
$(thisID).on('input',function(){
$(this).val() // should get current value
});
document.getElementById(thisID).innerHTML = ''; // empty the field
... but now what? How do I determine if a change was made? How do I replace the original value if a change wasn't made?
}
But now what? How do I determine if a change was made? How do I replace the original value if a change wasn't made?

td elements do not have an input event. It is however possible to nest an <input> tag inside a td.
$("td input").on("focusin", function() {
currentValue = $(this).prop("value");
$(this).prop("value", "");
}).on("focusout", function() {
if($(this).prop("value") === "") {
$(this).prop("value", currentValue);
}
});
Here, when the input is clicked, found using the focusin event, the value of the input is stored in a global variable. It needs to be global, because we have to use this variable in the next function. After the variable is stored, the input field is erased, by setting the value attribute to an empty string.
If the user didn't make any changes and leaves the input field, detected with the focusout event, the value attribute will be reset to what it once was.
Current Fiddle
http://jsfiddle.net/a592awoo/1/

One problem is you are passing in 'comments:942' to your empty function.
So when you do $(thisID) it is trying to find an element <comments:942>. To select by an id you need a #.
You could do this:
$('#'+thisID)
Or simply pass in '#comments:942'.
However, that won't work either. Using a : in an id is typically a bad idea, as it has a special meaning in CSS and jQuery selectors, so you may want to use a - instead. If that's not an option, you can escape the :.
Even with the jQuery selector fixed, I'm not sure how you are trying to get user input on a <td> element. You need an <input> element.
I believe you are trying to accomplish something like this:
$(document).ready(function() {
//this will add a click function to all elements with a class of 'editC'
$('.editC').on('click', function() {
//clear the current value
$(this).empty();
//append an input element
$(this).append($('<input type="text" placeholder="Enter new value">'));
//append a button
var btn = $('<button>Submit</button>');
//add click function on submit button to replace old td value with what is in the input
$(btn).on('click', function() {
//get the parent <td> element
var td = $(this).parent();
//get the previous element's value (the value of the <input> element)
var val = $(this).prev().val();
//remove the input element and button from the td
$(td).empty();
//set the text of the <td> to what was entered in the input element
$(td).text(val);
});
$(this).append(btn);
//unbind the click event, so that it does not perform this function when you click in the input element
$(this).unbind('click');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class='editC' id='comments-1'>Value 1</td>
<td class='editC' id='comments-2'>Value 2</td>
</tr>
</table>

Related

OnClick event is only getting the first dynamically created row/id

I have a table where if X has a value, display X, otherwise, add a link which when clicked will display a textbox where user can input the value. I dynamically assign IDs/classes to the link and textboxes but when I run the application, each click on any link only seems to trigger the first row. I put in alerts to show what row is being clicked and I always get the first row. Looking at the browser DOM explorer, I can see that each row has its own unique ID. How do I get each OnClick event to grab the correct corresponding ID?
C#/Razor code:
<td>
Unmapped
<input type ="submit" class="editAction hidden" value="#string.Format("tr{0}",i)" name="action:ChangeToEditSubAction" />
<input type="hidden" name="#Html.Raw("EntityMapping.EMREntityID")" value="#Html.Raw(Model.DisplayResults[i].EMREntityID)" />
<span class="#string.Format("tr{0}accountTxtBox",i) hidden">#Html.TextBoxFor(m => m.EntityMapping.AssignedHOAccountID)</span> </td>
Javascript Function
function UnmappedClick() {
//$(".accountTxtBox").removeClass("hidden");
//$(".unmapped").addClass("hidden");
//$("#btnSave").removeAttr('disabled');
//$(".editAction").click();
//$(".editAction").val(null);
alert($(".unmapped").attr('id'));
var txtBox = $(".editAction").val();
var actTextBox = "." + txtBox + "accountTxtBox";
$(actTextBox).removeClass("hidden");
alert(txtBox);
}
DOM Explorer Image
You can pass a parameter from your onclick event using the "this" keyword.
onclick="UnmappedClick(this.id)"
function UnmappedClick(id){
//now you have the specific ID
}
or if necessary pass the whole control over
onclick="UnmappedClick(this)"
you can try this
$(this).attr('id') // use this
instead of
$(".unmapped").attr('id')
This will give you the current elements id when you click
As you can see here, using $('.class') will return a list all the elements with that class. When you use $(".unmapped").attr('id') you'll always get the value of the first element in the list, that's why you always get the first row.
The same will happen with var txtBox = $(".editAction").val();. With $(actTextBox).removeClass("hidden"); you'll remove the class hidden from all the elements matched.
To get the id of an element you can use onclick="unmapped(this) or onclick="unmapped(this.id)" using the following code depending on the onclick attribute
function unmapped(element) {
var id = $(element).attr('id')
alert(id)
}
function unmapped(id) {
alert(id)
}
You can check this fiddle to see them in action.

How to get any column of any row of a Table in HTML?

Suppose there is Table with variable number of rows of fixed number of columns, and suppose each row has a button too, now I want to select for example a column's value(let's say this selected column is textarea, so I select it's content) when that row's button is clicked.
For example in above image I want that if submit is pressed than all data of 'textarea' of corresponding row should be stored in a variable.
You can use the jQuery closest() function to find an element near the clicked button. Add click handlers to the buttons and then traverse up to find the textarea.
$('.button').on("click",function(){
var thisRowsTA = $(this).closest("textarea");
console.log($(thisRowsTA).val());
});
A simply way is to:
Put an ID pattern to your textareas, like: txt_area_1, txt_area_2, txt_area_3.
Then, on the Click Event of your buttons, make them catch the corresponding textarea in their row. Use the ID patterns to do this.
Post your code for further help.
You will need to ad an event handler for each button. Inside of that you can write something like this.
function eventHandler(e){
var row = this; // start at the button
while(row.nodeName != 'TR' && row.parent){
// go up till we find the row
row = row.parent;
}
var textArea = row.querySelector('textarea');
var value = textArea.value;
// do something with supplied feedback.
}
In order to attach the handlers, you would do something like this.
function attachTableEvents(){
var table = document.querySelector('table'); // or more specific selector if needed
var buttons = table.querySelectorAll('button');
for (var i = buttons.length; i--;){
buttons[i].addEventListener(eventHandler);
}
}
Counting on the DOM structure is really BAD.
I would put an attribute in my controls that holds the line number. Then when clicking an element you can easily query the DOM by element type and the property value to get any elements in this line.
Later if you change to DIVs or change structure your will still run correctly

How to get data element of checkbox on change event

I've got a dynamic table of items with checkboxes next to each item. When a user selects a checkbox I want to grab the "Name" item from the table and add it to a textbox. See image:
The way I'm trying to accomplish this is by adding a "change" event to every checkbox and populating it's "data-name" element with the name of the text.
<tbody>
#foreach (var item in Model.Items)
{
<tr>
<td><input type="checkbox" name="selectBox" data-name="#item.Name" /></td>
As you can see I'm populating data-name with the item name as a way to get around pulling it directly (which I don't know how to do). Now in javascript/jquery I'm tying an event to every checkbox and attempting to get the data element using the following code:
$('input[name=selectBox]').change(function (item) {
var text = $(item).attr('data-name');
});
When the code runs the event is firing for all checkboxes, but "text" is undefined when I expect it to be the name data.
Looking for an answer to my method of doing this AND/OR a better way involving skipping the data element all together and getting the name value directly. Thanks for looking.
Try this:
var text = $(this).data('name');
The first parameter of your change function is the event, not the element itself. Also, jQuery automatically sets the function scope (this) to the element being changed.
See Documentation
In your case item is event object not DomElement, you can get element through event property currentTarget
$('input[name=selectBox]').change(function (item) {
var text = $(item.currentTarget).attr('data-name');
});
or use this because this refer` on current Element, it is the same as in previous example but shorter
$('input[name=selectBox]').change(function (item) {
var text = $(this).attr('data-name');
});

Selection from dropdownlist javascript event

I have this html part code :
<p><label>Taxe </label>
<select id="id_taxe" name="id_taxe" style="width: 100px;" onchange="taxselection(this);"></select>
<input id="taxe" name="taxe" class="fiche" width="150px" readonly="readonly" />%
</p>
Javascript method :
function taxselection(cat)
{
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
I'd like to set the value of taxe input to the selected value from the dropdownlist.It works fine only where the dropdownlist contains more than one element.
I try onselect instead of onchange but I get the same problem.
So How can I fix this issue when the list contains only one element?
This works:
$('#id_taxe').change(function(){
var thisVal = $(this).val();
var curVal = $('#taxe').val();
if(thisVal != curVal)
$('#taxe').val(thisVal);
$('#select option:selected').removeAttr('selected');
$(this).attr('selected','selected');
});
Use the change method which is very efficient for select boxes. Simply check the item selected isn't currently selected then if not, set the value of the input to the selected value. Lastly you want to remove any option's attr's that are "selected=selected" and set the current one to selected.
Just include this inside a $(document).ready() wrapper at the end of your HTML and the change event will be anchored to the select field.
Hope this helps.
http://jsbin.com/populo
Either always give an empty option, or in your code that outputs the select, check the amount of options, and set the input value straight away if there's only 1 option.
A select with just 1 option has no events, since the option will be selected by default, so there's no changes, and no events.
As DrunkWolf mentioned add an empty option always or you can try onblur or onclick event instead, depending on what you are actually trying to do.
Ok, just to stay close to your code, do it like this: http://jsfiddle.net/z2uao1un/1/
function taxselection(cat) {
var tax = cat.value;
alert(tax);
$("#taxe").val(tax);
}
taxselection(document.getElementById('id_taxe'));
This will call the function onload and get value of the element. You can additionally add an onchange eventhandler to the element. I highly recommend not doing that in the HTML! Good luck.

Passing a value from one input to another in jQuery

jsFiddle for reference:
http://jsfiddle.net/UxQV7/
What I'm trying to do is if the user clicks on "Add" on the 2nd row, the new form element is displayed underneath.
The user then types a number in that new form element, clicks the "Add" button and then that number will be populated in the Serial# input of the 2nd row and the new form element then is hidden.
The part I'm having trouble is once the user types in the number to that new form element, how do I know to send it back to the 2nd row.
Thanks very much.
You could do:
var index;
$(".addSerial").click(function(){
index = $(this).closest('tr').index();
console.log(index);
$("#serialAdd").toggle();
});
$("#submitSerial").click(function(){
$('table tr:eq('+index+') input:first').val($("#serialToAdd").val());
$("#serialAdd").toggle();
});
fiddle here http://jsfiddle.net/qWGKq/
You're going to have to store a reference value somewhere (in a global variable, for example) to indicate which <a> was clicked to display the Serial Number entry <div> or create it dynamically on the fly and destroy it afterwards.
Save the current row in a variable, and then filter the textbox out of it to set the value to: http://jsfiddle.net/UxQV7/1/.
var currentRow; // will be <tr> of row where user has clicked on Add
$(".addSerial").click(function(){
currentRow = $(this).parents('tr'); // set current row
$("#serialAdd").toggle();
});
$("#submitSerial").click(function(){
$("#serialAdd").toggle();
currentRow.find(':text:eq(2)').val($('#serialToAdd').val());
// find correct textbox in row and copy value
});
You can use jQuery's prev() to get the target input and save it:
var activeField;
$(".addSerial").click(function(){
$("#serialAdd").toggle();
activeField = $(this).prev();
return false;
});
$("#submitSerial").click(function(){
$("#serialAdd").toggle();
activeField.val( $("#serialToAdd").val() );
$("#serialToAdd").val("")
});
Demo: http://jsfiddle.net/7Xykw/
when these controls are rendered you need to have a serial number to each control in id that way you can easily identify controls and add values.
Check this working sample . http://jsfiddle.net/UxQV7/18/

Categories

Resources