How to pass an attribute to the function hover? - javascript

I have a table which is populated taking data from an array of contacts. I need to pass to the function hover one of each contact data (your image). How could he?
Here is the code of the dynamic creation of each row.
What would have to put behind tr, to capture it on hover?
for(var i in tbContactos)
{
var contacto = JSON.parse(tbContactos[i]);
$("#tblList tbody").append("<tr alt="+contacto.Imagen+">");
.....
.....
$("#tblList").hover(function(event){
var src = $(this).attr("alt");
............
............

To attach hover event you can use .on(), see below code -
$("#tblList tbody").on("mouseenter","tr",function(){
// do stuff for mouse enter event
var trAttr = $(this).attr('alt');
}).on("mouseleave","tr",function(){
// do stuff for mouse leave event
var trAttr = $(this).attr('alt');
});

try this:
$("#tblList tbody").append("<tr onMouseOver='test(this)' alt="+contacto.Imagen+">");
function test(row){
//here you will get the entire row.
row.getElementsByTagName("td")//will return an array of columns within the row
}

Related

Form values are overwritten after change

I have a form that shows up when each row in a table is double clicked. The values of this form can be updated and the form should be submitted with all row changes. But each time I double click on a row and edit the values of that form for that row, the previous values I had changed get overwritten. In order to work around this, I tried adding all the changes to a map with the row id as the key and the values of the form as the value. But the form still won't update with the new values. Here is a fiddle to demonstrate what I mean:
https://jsfiddle.net/4fr3edk7/2/
If I double click on the row that says "Adam Smith" and change that name to John Doe, when I double click on the second row and then double Click on "Adam Smith" again, it should say "John" on the first textbox and "Doe" on the second one. But the new value never seems to save.
This code snippet loops through each key, then loops through each value of that key:
for(var i = 0; i<key.length; i++){
var getval = globalchanges[key[i]];
for(var k=0; k<getval.length; k++){
$("#input1").val(getval[0]);
$("#input2").val(getval[1]);
}
}
How can I get the new changes to save? (The table rows don't have to show the changes, just the textbox values). Any help would be appreciated.
First, as mentioned by #Taplar you are binding the click event multiple times. Your approach is close enough, the idea of storing the changes is valid. You should have 2 functions, store the changes on button click and the second one to retrieve the changes by id.
Updated Fiddle
This function will get the values of the form and will store in on a global object
function setMap(id){
var firstrow = $("#input1").val();
var secondrow = $("#input2").val();
globalchanges[id] = [firstrow,secondrow];
}
This other function will check if the global object has values for the passed id, if not, it will use the values on the row
function getMap(id, tr){
if(globalchanges[id] != undefined && globalchanges[id].length == 2){
$("#input1").val(globalchanges[id][0]);
$("#input2").val(globalchanges[id][1]);
}
else{
$("#input1").val($(tr).find('td').eq(1).text());
$("#input2").val($(tr).find('td').eq(2).text());
}
}
Please note there are also changes on the dbclick and click events, they should be separated
$("#table tr").dblclick(function(){
$("#txtbox-wrapper").css({"display" : "block"});
var id = $(this).find('td').eq(0).text();
$('#id').val(id);
getMap(id,this);
});
$("#savebtn").click(function(){
var id = $('#id').val();
setMap(id);
});
And that we added and additional input to store the id on the form.
You are going to need to rethink your logic because of this part
$("#table tr").dblclick(function(){
$("#txtbox-wrapper").css({"display" : "block"});
var id = $(this).find('td').eq(0).text();
$("#input1").val($(this).find('td').eq(1).text());
$("#input2").val($(this).find('td').eq(2).text());
$("#savebtn").click(function(){
addToMap(id);
});
});
-Every time- you double click a table row you are adding a new click binding to the savebtn element. This means if you double click both rows, when you click that button it will execute addToMap for both ids. You may have other issues with your logic relying on only two other inputs for multiple rows, but this double/triple/+ binding is going to bite you.
There are few changes required in your logic as well as implementation.
1: Do not bind save event inside row click.
2: You are selecting the value in row double click event from td element. You need to update this element to keep your logic working
3: Keep track of which row is getting updated.
Updated Code
var globalchanges = {};
var rowSelected = null;
$("#table tr").dblclick(function() {
$("#txtbox-wrapper").css({
"display": "block"
});
rowSelected = $(this).find('td').eq(0).text();
$("#input1").val($(this).find('td').eq(1).text());
$("#input2").val($(this).find('td').eq(2).text());
});
$("#savebtn").click(function() {
addToMap(rowSelected);
});
function addToMap(row) {
var array = [];
var changes = {};
var firstrow = $("#input1").val();
var secondrow = $("#input2").val();
array.push(firstrow, secondrow);
globalchanges[row] = array;
makeChanges(row);
}
function makeChanges(row) {
var key = Object.keys(globalchanges);
console.log(key);
$("#table tr td").each(function(k, v) {
if ($(v).text() == key) {
$(v).next().html(globalchanges[row][0]);
$(v).next().next().html(globalchanges[row][1]);
globalchanges = {};
}
});
}
Working fiddle : https://jsfiddle.net/yudLxsgu/

javascript editable table does not work properly

I am using the following code to make a html table editable (this code is obtained from an online tutorial link: http://mrbool.com/how-to-create-an-editable-html-table-with-jquery/27425).
$("td").dblclick(function () {
//Obtain and record the value in the cell being edited. This value will be used later
var OriginalContent = $(this).text();
//Addition of class cellEditing the cell in which the user has double-clicked
$(this).addClass("cellEditing");
//Inserting an input in the cell containing the value that was originally on this.
$(this).html("<input type='text' value='" + OriginalContent + "' />");
//directing the focus (cursor) to the input that was just created, so that the user does not need to click on it again.
$(this).children().first().focus();
//the opening and closing function that handles the keypress event of the input.
//A reserved word this refers to the cell that was clicked.
//We use the functions first and children to get the first child element of the cell, ie the input.
$(this).children().first().keypress(function (e) {
//check if the pressed key is the Enter key
if (e.which == 13) {
var newContent = $(this).val();
$(this).parent().text(newContent);
$(this).parent().removeClass("cellEditing");
}
});
$(this).children().first().blur(function(){
$(this).parent().text(OriginalContent);
$(this).parent().removeClass("cellEditing");
});
});
It seems to work fine. Then I am using the following function to read the contents of the table and create a json representation:
function showRefTable(){
var headers = [];
var objects = [];
var headerRow = $('#dataTable thead tr');
var rows = $('#dataTable tbody tr');
headerRow.find('th').each(function(){
headers.push($(this).text());
});
for (var i=0; i<rows.length; i++){
var row = rows.eq(i);
var object = new Object();
for (var j=0; j<row.find('td').length; j++){
object[headers[j]] = row.find('td').eq(j).text();
}
objects.push(object);
}
var json = JSON.stringify(objects);
alert(json);
}
This function is used as a callback to an onclick event.
The problem is that the function used to read the table contents shows the original contents even if I make an edit (show page source shows the original content).
Thanks
It's really bad to read table contents from .text(). You will not be able to use any formatting for numbers and many other problems. You'd better of keeping table contents in standalone datasourse object and redrawing table from it every time when user changes values.
I would advise using kendo grid - it's powerfull, reliable js table.
EDIT: your function does not work, becuse you said you call it as callback to onclick event. So you read contents of the table before they actually changed.
You should read contents when they are saved. In your case, try calling you function when user saves the input (presses Enter)
if (e.which == 13) {
var newContent = $(this).val();
$(this).parent().text(newContent);
$(this).parent().removeClass("cellEditing");
//Now, when content is changed, call your function
showRefTable();
}

Append additional key values to a different <div>

I've got radios attached to divs, and when the div is clicked the info on the widget updates to display the data associated to the div. I'm getting the data from the Yahoo API with JSON script. The appropriate data is appearing on my div called "Current", but when I click on "24-Hour" I get nothing.
Check out my script on this fiddle: http://jsfiddle.net/thetuneupguy/r2Bca/11/
$.each(data.query.results.quote, function (key, obj) {
var $lc = $('<tr/', {
'class': 'my-new-list'
}).appendTo('#blk-2 table');
$lc.append($('<td/>').text(obj.Name || "--"));
$lc.append($('<td/>').text(obj.PreviousClose || "--"));
});
It appears that I forgot to close out a tag, which I have caught and fixed...
var $lc = $('<tr/', {
should be...
var $lc = $('<tr/>', {

How to use arrays in javascript to match up divs when event fires?

I have a set of two divs - First set: when people mouse over these divs, it will fire an event, Second set: when the event is fired, these divs will be displayed.
When you mouse over a div in the first set, it should display its corresponding div in the second set. I thought an easy way to match the mouseover divs with the correct div to display would be using arrays. I've been able attach the event listeners properly, but I can't figure out how to set it up so that when you mouseover one object of an array, it displays the array object with the same index number. I think if I could figure out how to recoginze the index number of the object I am mousing over, I could get it to work. I've tried a lot of things, but haven't been able to create anything that works. Here's the code:
<script>
$(document).ready(function(){
//create array of divs to mouse over
var ar = new Array();
ar[0] = $("#home");
ar[1] = $("#doc");
var length = ar.length;
//create array of divs to display when event is fired
var des = new Array();
des[0] = $("#homeDes");
des[1] = $("#docDes");
// start for
for ( var i = 0; i< length; ++i )
{
ar[i].bind("mouseover",function(){$(des[i]).css("display","block");});
ar[i].bind("mouseout",function(){$(des[i]).css("display","none");});
}
//end for
});
//end
</script>
I would tend toward making a more flexible approach to this so that you don't need to change your javascript when you change your HTML. Consider classing your elements that need to have the bindings and providing data attribute to specify the target. Your HTML for divs to be bound might look like this:
<div id="home" class="mouseoverToggleTrigger" data-target="#homeDes">...</div>
And the jQuery might look like this:
$(document).ready(function(){
$('.mouseoverToggleTrigger').hover(function() {
var $target = $($(this).data('target'));
$target.toggle();
}
});
Note this is assuming you are using HTML5 for which jQuery, by default, converts data-* into values retrievable via data().
For pages that are not HTML5, this more generalized solution will work
$(document).ready(function(){
$('.mouseoverToggleTrigger').hover(function() {
var $target = $($(this).prop('data-target'));
$target.toggle();
}
});
One additional bit of flexibility this gives, is that you now don't have to limit yourself to a one-to-one trigger to target mapping. You could specify a class name or other jQuery selector for data-target values to get highly customized behavior, such as one trigger toggling all elements of a certain class that are children of another class.
$(document).ready(function(){
//create array of divs to mouse over
var ar = new Array();
ar[0] = $("#home");
ar[1] = $("#doc");
var length = ar.length;
//create array of divs to display when event is fired
var des = new Array();
des[0] = $("#homeDes");
des[1] = $("#docDes");
// start for
for ( var i = 0; i< length; ++i )
{
// WRAP THE BODY OF THE FOR LOOP IN A FUNCTION
function(index) {
ar[index].bind("mouseover",function() {
$(des[index]).css("display","block");}
);
ar[index].bind("mouseout",function() {
$(des[index]).css("display","none");
});
}(i);
}
//end for
});
When the events are fired the value of i is the length of the array, you have to pass the value of i to another function so that in each function scope the value of index will be the value of i when it was called.
A simpler approach code wise is to give the common elements common classes and then use jQuery index() and eq() to match pairings
HTML
<a id="home" class="hoverMe">
<a id="doc" class="hoverMe">
<div id="homeDes" class="content">
<div id="docDes" class="content">
JS
var $content=$('.content')
var $links=$('.hoverMe').hover(function(){
$content.eq( $links.index(this) ).show()
},function(){
$content.eq( $links.index(this) ).hide()
})
index() API Docs
eq() API Docs

On events in loop in dynamic elements

I need to set events to elements makes "on the fly", like var X = $('HTML CODE HERE'), but when I set the events to the last element, all other elements get this last event.
Example here: http://jsfiddle.net/QmxX4/6/
$(document).ready(function() {
var ulItem = $('.lst');
for (var x=0; x<5; x++) {
var newItemElement = $('<li style="border:solid 1px blue;width:200px;height:40px;"></li>');
ulItem.append(newItemElement);
var generator = Math.random();
newItemElement.on('click', function() {
console.log(generator);
});
}
});
All elements are diferents, and I attach the event in the element directly, im try to append before and after add event to element, but not work, all element get the last event.
If you make click in the <li></li> get code generated in the last event, but "in theory" all elements have diferent events attached..
But if I make other loop appending elements after append al items to <ul></ul>, like this:
$.each($(ulItem).children('li'), function(i, item) {
console.log($(this));
var generator = Math.random();
$(this).on('click', function() {
console.log(generator);
});
});
Works... what is the problem?
In your first loop, the generator variable belongs to the ready callback function, and the inner log functions all share it.
In your second loop, the generator variable belongs to the each callback function which is called once for each item and therefore the log functions all see a different variable.

Categories

Resources