JS or Jquery create unique span ID - javascript

I'm creating a li item with a span inside. I've built an onclick function in the span to grab the parent li's ID to pass into a JSON get request. I'm unsure of how to create a unique ID and read it in the JS function. Since this is built dynamically I didn't build a switch but I feel like i'm missing another option.
The problem here is that I can't capture the Li ID. I've tried this and also tried based on class, but all seem to be failing.
Li object creation:
$("#jdLists").append('<li class="bigger" id = "' + item.ID + '">'+
item.GROUP_NAME +
'<span title="Remove from list" class=" Sp icon icon-color icon-plus" style="float: right; vertical-align: middle;" '+
'onclick="spAdd()"></span>' +
'</li>');
on click function:
function spAdd() {
$(this).closest("li").attr('id');
}

Try like this:
// Should work for most cases
function uniqId() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
// Create elements properly and attach click event
// before appending to DOM so it delegates the event
var $li = $('<li/>', {
'class': 'bigger',
id: uniqId()
});
var $span = $('<span/>', {
'class': 'Sp icon icon-color icon-plus',
title: 'Remove from list',
text: 'I\'m a span',
click: function() {
alert( $(this).parent().attr('id') );
}
});
$('#jsLists').append( $li.append( $span ) );
It should alert the li's random id on click. Also instead of inline css, add another class for those styles; better, simpler, easier.
Demo: http://jsbin.com/avevim/1/edit (ctrl+enter to refresh and get new id)

Underscore provides a uniqueId function for cases like this. Rather than being tricky with dates and random numbers, it just keeps a global counter and increments it each time the function is called:
var idCounter = 0;
_.uniqueId = function(prefix) {
var id = '' + ++idCounter;
return prefix ? prefix + id : id;
};

Related

Setting up event handlers for buttons in Javascript / HTML

I would like to set up event handlers for all “Add” buttons.
are you fine with a Vanilla JS snippet?
Something along these lines would do:
function registerHandlers () {
var buttons = document.querySelectorAll('.button');
[].slice.call(buttons).forEach(function (button) {
button.addEventListener('click', onClick, false);
});
}
function onClick (event) {
event.preventDefault();
var button = event.target;
var id = button.id;
var desc = document.getElementById(id + '-img').getAttribute('title');
var qty = document.getElementById(id + '-qty').value;
addToTable(desc, qty);
}
function addToTable (desc, qty) {
var row = '<tr><td align="left">' + desc + '</td><td align="right">' + qty + '</td></tr>';
var tbody = document.querySelector('#orderlist tbody');
tbody.innerHTML = tbody.innerHTML + row;
}
registerHandlers();
The code is untested :-)
But here's how it works:
registerHandlers:
Find all elements on the page which have the class "button" (via CSS Selector)
Turn the results from a NodeList into an Array using [].slice.call.
Go over the list and register an event listener for "click"s on that element.
onClick:
Stop the default behaviour of the browser.
Determine the clicked button by inspecting the target property of an event.
Get the associated ID attribute's value.
Build the selector string for the image, search the whole document for it. Read the title attribute of the found image. (This can crash if no such element was found).
Same with the Quantity.
Update the table.
addToTable:
Build a string with the desc and qty in between. You might want to put more effort by using createElement or DOMParser and get some sanity checks that way.
Find the <tbody> of the orderlist.
Append it's innerHTML with your new row.
Finally call registerHandler to make the above work.

Unable to remove tr in a table using jquery

so I am having a problem in removing a particular tr in table using jquery.
So this is the scenario:
I have a table in which rows where clickable. And when I clicked one of them, I will be able to update the object data associated with that row. However, after updating the object, I want to reflect the changes in the td's of that particular tr.
My solution is, to remove the old tr and replace with the new tr. However, It did not remove the old tr instead just inserted the new tr. So this is my code:
function update_table_after_updating(selected_violator){
violators_table.find('tr').each(function (i, el) {
var tr = ($(this));
var td_text = $(this).find('td:first').text();
if(td_text == selected_violator.violator_id){
console.log(tr);
//I cant remove this row
tr.remove();
return false;
}
});
update_table(selected_violator);
}
The update_table() function
function update_table(violator){
var img_str1 = '<img class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.front_temp_file_path + '\">';
var img_str2 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.rear_temp_file_path + '\">';
var img_str3 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.right_temp_file_path + '\">';
var img_str4 = '<img style=\"margin-left: 10px;\" class=\"obj-pic\" src=\"' + Main.Vars.base_path + violator.left_temp_file_path + '\">';
violators_table.dataTable().fnAddData([
violator.violator_id,
violator.get_full_name(),
'Under Construction',
img_str1 + img_str2 + img_str3 + img_str4,
]);
$('#violators_tbl tbody tr').on('click', function(){
var td = $(this).find('td:first').text();
//returns violator object
selected_violator = get_violator(td);
show_modal('view_violator');
});
}
Thank you very much! Your responses will be greatly appreciated.
PS: I am using jquery DataTables.
Well this is kinda disappointing, I have searched through Jquery Docs then I have find this:
.empty() -> This method removes not only child (and other descendant)
elements, but also any text within the set of matched elements. This
is because, according to the DOM specification, any string of text
within an element is considered a child node of that element. Consider
the following HTML:
Unlike remove(). empty() also removes child nodes of the selected element.
And, voila! The tr has been removed.

Extract Link Query String Data And Create A New Link Inside A Different List

The goal is to have info from a link in #list and have it create a new link in #list3.
Here is the link http://jsfiddle.net/4y5V6/24/
Is there a way to make it where once you click a link it will push it to #list3 and make the link look like this twitch.tv/chat/embed?channel=(channelname)&popout_chat=true ?
Thank you for your time!!
HTML:
<div id="navi">
<ul>
<li>Stream Selection:</li>
<li>SC2<ul id="list"><li><ul></ul></li></ul></li>
<li>League<ul id="list2"><li><ul></ul></li></ul></li>
<li>Chat<ul id="list3"><li><ul></ul></li></ul></li>
</ul>
</div>
<iframe id="iframe1" name="iframe1" type="text/html" src="" frameBorder="0" height="200px" width="300px">
</iframe>
Current function that populates the list.
// first set of streams SC2
$.getJSON("https://api.twitch.tv/kraken/search/streams?q=starcraft&limit=18&&type=top&callback=?", function (data) {
var temp = "";
$.each(data.streams, function (index, item) {
temp = temp + "<li><a target='iframe1' href='http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + item.channel.name + "'>" + item.channel.display_name + "</a></li>";
});
$("#list ul ").html(temp);
});
// next set of streams LoL
$.getJSON("https://api.twitch.tv/kraken/search/streams?q=League%20of%20Legends&limit=18&&type=top&callback=?", function (data) {
var temp = "";
$.each(data.streams, function (index, item) {
temp = temp + "<li><a target='iframe1' href='http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + item.channel.name + "'>" + item.channel.display_name + "</a></li>";
});
$("#list2 ul ").html(temp);
});
$('#navi').on('click', '#list a', function(e) {
var x = $(this).prop('href'),
y = x.slice(x.indexOf('channel')+8),
z = 'twitch.tv/chat/embed?channel=('+y+')&popout_chat=true',
clone = $(this).clone().attr('href', z);
$('#list3 ul').append($('<li />', { html: clone }));
});
Fork
Alternate version: No duplicates.
Adding ability to open new chat link in new smaller window
jsFiddle only copies list 1 to list 3
jsFiddle Copies from both list 1 and 2 to list 3
// The following call is jQuery's way of assigning events to both "Static"
// && "Dynamic" Elements. This way, even if the element is loaded after
// page load, it still gets the event callback.
// Keep in mind, you do need either a static parent (such as below, I use
// `$('#navi')`, since I assume this element is always present on your page
// load) |OR| you can use `$(document)`. The later is often recommended
// against, as you could run into "slowed down response" issues or naming
// issues. Personally, I use `$(document)` all the time and haven't had a
// complaint yet.
// Then you simply assign your event(s) to your "Selectors"
// For just list 1 that would be
// .on('click', '#list a'
// For list 1, and 2 that would be
// .on('click', '#list a, #list2 a'
// See Also: http://api.jquery.com/on/
$('#navi').on('click', '#list a, #list2 a', function(e) {
var x = $(this).prop('href'), // get href of <a> clicked
y = x.slice(x.indexOf('channel')+8), // extract name
z = 'twitch.tv/chat/embed?channel=('+y+')&popout_chat=true', // create new href link
clone = $(this).clone().attr('href', z), // clone this <a> and replace href with new one created
item = $('<li />', { class: y, html: clone }); // create new <li> making our cloned <a> it's innerHTML
if (!$('#list3 ul .' + y).length) $('#list3 ul').append(item); // check <li> item doesn't already exist and add to list
}) // Thanks to jQuery "chaining", I don't have to "recall" our static parent
.on('click', '#list3 a', function(e) {
e.preventDefault();
var lnk = $(this).attr('href');
// The following is basic JavaScript and simply opens a new window
// simply adjust width and height based on PIXELS
// see more window.open options #: http://www.w3schools.com/jsref/met_win_open.asp
// See Also: http://stackoverflow.com/questions/tagged/javascript+window+open
window.open(lnk, "myWindowName", "width=800, height=600");
})

How to pass the id of Div as an argument to a function

I have a Div that is dynamically added to a page with the click of a button using jQuery.
I would like to be able to remove the Div with the click of the cross-button.png using the RemoveArtist() function.
$("<div class=\"input-append\" id=\"artist"
+ artists.length - 1 + "\" ><label style=\"background-color:#e0ffff\">"
+ artistVal + "</label><img onclick=\"RemoveArtist()\" id=\"removeartist\""
+ " src=\"/Content/bootstrap/img/cross-button.png\" /></div>")
.appendTo(addDiv);
The remove artist fucntion should look like this:
var RemoveArtist = function (div,artistlength) {
$('div').remove();
artists.splice(artistlength, 1);
};
How can I pass the actual div to the RemoveArtist function and also the artistlength which is the artists.length - 1 value from the Div?
So basically I am trying to delete the Div and remove the artist from the artists array.
In my opinion, you'd be better of if you created actual elements instead of a string.
It's more stuff to write, but makes everyhing a lot easier to keep track of :
var input_append = $('<div />', {id: 'artist' + (artists.length - 1)}),
label = $('<label />', {style: 'background-color:#e0ffff',
text : artistVal
}
),
image = $('<img />', {id: 'removeartist',
src: '/Content/bootstrap/img/cross-button.png',
on: {
click: function() {
input_append.remove();
artists.splice(artists.length - 1, 1);
}
}
}
);
addDiv.append( input_append.append(label, img) );

create id dynamically

I am creating a element dynamically how would i give this an id?
_addQuestionElement : function() {
var el = new Element('div');
el.addClass('dg-question-label');
el.set('html', this._getCurrentQuestion().label);
$(this.html.el).adopt(el);
},
im using moo tools and jquery.
Many Thanks
Your code looks like Mootools, here's how I'd do it (cleaned up your code a bit)
_addQuestionElement: function() {
var el = new Element('div', {
'class': 'dg-question-label',
html: this._getCurrentQuestion().label,
id: 'yourId'
});
$(this.html.el).adopt(el);
}
If you're generating the same element multiple times, your id will need to somehow be unique each time.
You could also do without that el variable (unless of course it's used somewhere further in the function that you didn't include)
_addQuestionElement: function() {
$(this.html.el).adopt(new Element('div', {
'class': 'dg-question-label',
html: this._getCurrentQuestion().label,
id: 'yourId'
}));
}​
Just assign the id via (if you created the element with new Element()):
var yourCustomId = "myId";
el.id = yourCustomId;
Or use Mootools attr-setting capabilities:
var yourCustomId = "myId";
el.setProperty("id", yourCustomId);
You can give it like this,
var uniqueNumber = 1; //define uniqueNumber globally and increament at each element creation
With javascript
el.id = 'idprefix' + uniqueNumber++)
With jQuery
$(el).attr('id','idprefix' + uniqueNumber++);
In jQuery, to create a div with an ID, you would do something like this:
function createDiv(id) {
$("body").append("<div id=" + id + "></div>");
}
createDiv("myNewDivId");
_addQuestionElement, I think you need to generate a unique id for each question element.
var IDs = 0;
var pfx = "id_";
_addQuestionElement : function() {
...
el.attr("id", pfx + ++IDs);
var el = $('<div />') .attr('id', myVal);
all elements created or accessed by MooTools automatically get a unique uid (for the DOM) anyway, saves you from having to keep state yourself (if you want to be doing this automatically).
console.log( Slick.uidOf( new Element('div') ) )
so...
_addQuestionElement: function() {
var el = new Element('div.dg-question-label', {
html: this._getCurrentQuestion().label
});
// prefix number with uid-
el.set('id', 'uid' + Slick.uidOf(el)).inject(this.html.el);
},
to give it an id via the combined element constructor, it goes:
var el = new Element('div#someid.dg-question-label') or add it in the properties passed to the constructor:
new Element('div', { id: 'foo' })
You can use the jQuery plugin idfy.
Full Disclosure: I wrote that plugin :)

Categories