How do you fill a text field based on dynamically generated links? - javascript

The gist of it is that I have a dynamically generated drop down based off an array in JQuery. I have a text field next to it that should output an answer based on what was selected in the array.
<ul>
<li>
Vendor Contacts
<ul class="vendor_list">
</ul>
</li>
<input id="vendor_contact" type="text" />
</ul>
This is the HTML that I set up and here's the Javascript:
var vendors = ['vendor1, vendor2, vendor3'];
var contact_info = ['email1','email2','email3']
var vList = $('ul.vendor_list');
$.each(vendors, function (i)
{
var li = $('<li/>')
.addClass('menu_item')
.attr('role', 'menuitem')
.appendTo(vList);
var aaa = $('<a/>')
.addClass('vendors')
.text(vendors[i])
.appendTo(li);
});
What I think is the next step is:
$("#vendor_list").on('click', '.vendors', function () {
$("vendor_contact")val($(contact_info[i]))
Needless to say, I mind's pretty warped around this one. I'm starting to get into jQuery and just want to see how I can fill the text box in.

First, you have missing quotation marks in your vendors array:
var vendors = ['vendor1', 'vendor2', 'vendor3'];
Next, you should use class selector, not id on your .vendor_list element:
$(".vendor_list").on('click', '.vendors', function () {
// ...
Next, missing # sign, as you're selecting the element by its id:
$("#vendor_contact")val(//...
(by $("vendor_contact") you're trying to select a not existing tag <vendor_contact>)
Last thing, use something like data attribute to determine the actual selection:
$.each(vendors, function(i){
var li = $('<li/>')
.addClass('menu_item')
.attr('role', 'menuitem')
.appendTo(vList);
var aaa = $('<a/>')
.addClass('vendors')
.text(vendors[i])
// add 'data-id' attr:
.data('id', i)
.appendTo(li);
});
final JS:
$(".vendor_list").on('click', '.vendors', function () {
$("#vendor_contact").val(contact_info[$(this).data('id')]);
});
JSFiddle Demo

Related

Update href text value dynamically using JQuery

There are href links on the page, its text is not complete. for example page is showing link text as "link1" however the correct text should be like "link1 - Module33". Both page and actual texts starts with same text (in this example both will starts with "link1").
I am getting actual text from JSON object from java session and comparing. If JSON text starts with page text (that means JSON text "link1 - Module33" startsWith "link1" (page text), then update "link1" to "link1 - Module33".
Page has below code to show the links
<div class="display_links">
<ul id="accounts_links_container">
<li id="accounts_mb_2_id"><a href="javascript:void(0)" class="linksmall"
id="accounts_mb_2_a"> link1 </a></li>
<li id="accounts_mb_11_id"><a href="javascript:void(0)" class="linksmall"
id="accounts_mb_11_a"> link2 </a></li>
.
.
.
// more links
</ul>
</div>
Note : li id is not static its different for each page text, however ul id is static.
I am reading correct & full link text from JSON object (from java session) as below
var sessionValue = <%= json %>; // taken from String array
and reading page text as below :-
$('.display_links li').each(function() { pageValue.push($(this).text()) });
sessionValue has correct updated text and pageValue has partial texts. I am comparing using below code
for(var s=0; s<pageValue.length; s++) {
var pageLen = $.trim(pageValue[s]).length;
for(var w=0; w<sessionValue.length; w++) {
var sesstionLen = $.trim(sessionValue[w]).length;
var newV = sessionValue[w].substring(0, pageLen);
if($.trim(newV)==$.trim(pageValue[s])){
**// UPDATING VALUES AS BELOW**
pageValue[s]=sessionValue[w];
}
}
}
I am trying to update page value text to session value text as pageValue[s]=sessionValue[w]; (in above code) but its not actually updating the values. Sorry for the poor comparing text logic.
Please help, how to update it dynamically in the loop after comparing to make sure I am updating the correct link text.
pageValue[s]=sessionValue[w]; just updates the array; it has no effect whatsoever on the li's text.
If you want to update the li's text, you need to do that in your each. Here's an example doing that, and taking a slightly more efficient approach to the comparison:
$('.display_links li a').each(function() {
var $this = $(this);
var text = $.trim($this.text());
var textLen = text.length;
for (var w = 0; w < sessionValue.length; ++w) {
var sessionText = $.trim(sessionValue[w]);
if (sessionText.substring(0, textLen) == text) {
text = sessionText;
$this.text(text);
break; // Found it, so we stop
}
}
pageValue.push(text); // If you want it for something
});
I think it's cleaner to just select the elements you care about (in this case the anchor tags) and then use built-in functionality to compare rather than reimplementing a startsWith function.
var sessionValue = ['link1 - Module33', 'link2 - foobar'];
$('.display_links li a').each(function() {
var $this = $(this);
var text = $this.text().trim();
sessionValue.forEach(function(sessionValue) {
if (sessionValue.startsWith(text)) {
$this.text(sessionValue);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="display_links">
<ul id="accounts_links_container">
<li id="accounts_mb_2_id"> link1 </li>
<li id="accounts_mb_11_id"> link2 </li>
</ul>
</div>
The result of $(this).text() is a primitive string, not a reference to the textNode of the element. It doesn't matter if you update pageValue, because it is not related to the original element.
Instead of pushing the strings to an array to process, you can stay inside the $.each() loop and still have access to the elements, which is needed to update the text. Something like this:
$('.display_links li').each(function() {
var $li = $(this);
var liText = $.trim($li.text());
var liLen = liText.length;
for(var w = 0; w < sessionValue.length; w++) {
var sessionLen = $.trim(sessionValue[w]).length;
var newV = sessionValue[w].substring(0, liLen);
if ($.trim(newV) === liText) {
**// UPDATING VALUES AS BELOW**
$li.text(sessionValue[w]);
}
}
});
I am a noob and thought I would take a shot at this.
Here is my approach although the sessionValue array is a bit foggy to me. Is the length undetermined?
I declared var's outside of the loop for better performance so they are not declared over and over.
Iterate through elements passing each value through Compare function and returning the correct value and update immediately after all conditions are satisfied.
var i = 0;
$('.display_links li a').each(function(i) {
$(this).text(Compare($(this).text(), sessionValue[i]));
i++;
});
var Compare;
var update;
Compare = function(val1, val2) {
// Check if val1 does not equal val2 and see if val2 exists(both must be true) then update.
if(!val1 === val2 || val2) {
update = val2
}
return update;
}

Javascript- Creating To Do list not working

I deleted the button part in my script but not even the first part of my function is working where I type in input box and suppose to be added to the ...I don't understand why. When I run the code without the buttons code which is titled " //BUTTON creation " I get no error but no item is being added to the list. So I have two problems Items aren't being added to my list and aren't displaying and also if I include the button part its saying an error "list.appendChild is not a function"
<input type="text" placeholder="Enter an Activity" id="textItem">
<img src="images/add-button.png" id="addButton">
<div id="container">
<ul class="ToDo">
<!--
<li>
This is an item
<div id="buttons">
<button ></button>
<img src="images/remove-icon.png"id="remove">
<button id="complete"></button>
<img src="images/complete-icon.jpg" id="complete">
</div>
</li>
!-->
</ul>
</div>
<script type="text/javascript">
//Remove and complete icons
var remove = document.createElement('img').src =
"images/remove-icon.png";
var complete = document.createElement('img').src = "images/complete-icon.jpg";
//user clicks add button
//if there is text in the item field we grab the item into var text
document.getElementById("addButton").onclick = function()
{
//value item is the text entered by user
var value = document.getElementById("textItem").value;
//checks if there is a value typed
if(value)
{
addItem(value);
}
//adds a new item to the ToDo list
function addItem(text)
{
var list = document.getElementsByClassName("ToDo");
//created a varibale called item that will create a list item everytime this function is called
var item = document.createElement("li");
//this will add to the innerText of the <li> text
item.innerText = text;
//BUTTON creation
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('buttons');
buttons.classList.add('remove');
remove.innerHTML = remove;
var complete = document.createElement('buttons');
buttons.classList.add('complete');
complete.innerHTML = complete;
buttons.appendChild(remove);
buttons.appendChild(complete);
list.appendChild(buttons);
list.appendChild(item);
}
}
</script>
The problem is in the line:
var list = document.getElementsByClassName("ToDo");
list.appendChild(item);
The line var list = document.getElementsByClassName("ToDo"); will provide a collection, notice the plural name in the api.
You need to access it using :
list[0].appendChild(item);
There are other problems too in the code but hopefully this gets you going!
There are a couple of issues in your code that need to be addressed to get it to work properly.
1) You are creating your image elements and then setting the variables to the src name of that image and not the image object itself. When you use that reference later on, you are only getting the image url and not the element itself. Change var remove = document.createElement('img').src = "images/remove-icon.png" to this:
var removeImg = document.createElement('img')
removeImg.src = "images/remove-icon.png";
2) As #Pankaj Shukla noted, inside the onclick function, getElementsByClassName returns an array, you will need to address the first item of this array to add your elements. Change var list = document.getElementsByClassName("ToDo") to this:
var list = document.getElementsByClassName("ToDo")[0];
3) For your buttons, you are trying to creating them using: var remove = document.createElement('buttons'). This is invalid, buttons is an not the correct element name, its button. Additionally, you are re-declaring the variables remove and complete as button objects, so within the onclick function it reference these buttons, not the images you defined earlier. So when you assign the innerHTML to remove and complete, you are assigning the buttons innerHTML to itself. The solution is to change the image variables to something different.
4) Finally, also relating to the buttons, you are assigning the innnerHTML to an image object, that's incorrect. You can either insert the html text of the img directly, or append the image object as a child of the button, similar to how the button is a child of the div.
The updated code with all these changes looks like this:
//Remove and complete icons
var removeImg = document.createElement('img');
removeImg.src = "images/remove-icon.png";
var completeImg = document.createElement('img');
completeImg.src = "images/complete-icon.jpg";
//user clicks add button
//if there is text in the item field we grab the item into var text
document.getElementById("addButton").onclick = function() {
//value item is the text entered by user
var value = document.getElementById("textItem").value;
//checks if there is a value typed
if (value) {
addItem(value);
}
//adds a new item to the ToDo list
function addItem(text) {
var list = document.getElementsByClassName("ToDo")[0];
//created a varibale called item that will create a list item everytime this function is called
var item = document.createElement("li");
//this will add to the innerText of the <li> text
item.innerText = text;
//BUTTON creation
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('button');
remove.classList.add('remove');
remove.appendChild(removeImg);
var complete = document.createElement('button');
complete.classList.add('complete');
complete.appendChild(completeImg);
buttons.appendChild(remove);
buttons.appendChild(complete);
list.appendChild(buttons);
list.appendChild(item);
}
}

Hide same elements in a list

I have a problem I want to solve with jQuery. In a list, I want to check if two items have the same text, and if so I want to delete the second one.
I am not really sure how to go about it.
The markup is simple, kinda like this
<ul>
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>
I cannot use an active/inactive class because this list is dynamic and I don't know in advance how it's going to be populated.
Any idea?
$.inArray for a tmp array would work.
$(document).ready(function(){
var tmparr = [];
$('.list li').each(function(i,item){
if($.inArray($(this).text(), tmparr) >= 0){
$(this).remove();
}else{
tmparr.push($(this).text());
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li>Text1</li>
<li>Text2</li>
<li>Text1</li>
<li>Text3</li>
<li>Text3</li>
<li>Text4</li>
<ul>
You can achieve this e.g. like this:
var unique = {};
$('li').each(function() {
var txt = $(this).text();
if (unique[txt])
$(this).remove();
else
unique[txt] = true;
});
Fiddle
As explanation: unique is initialized as object. While each() iterates over all li elements, the if (unique[txt]) is true in case it was previously set to true for the text of the li currently processed. In this case the current li will be removed. If not, unique[txt] for the text of the current li is set to true and added to unique. As it might not be clear what unique finally contains: { Text1=true, Text2=true, Text3=true, Text4=true }
You will need to iterate over your li elements and store their text in an array. If the text for the ith element is already in the array, skip it. Once you have an array of unique text strings, remove all li elements and generate new ones from the information in your array.
http://jsfiddle.net/k255o52e/1/
$('ul li').each(function () {
var txt = $(this).text();
// finds all LI that contain the same text
// excludes the first element
var $li = $('li:contains("' + txt + '"):not(:first)');
// and removes the other
$li.remove();
})
UPDATE:
$('ul li').each(function () {
var txt = $(this).text();
var $li = $('li:contains("' + txt + '"):not(:first)').filter(function(index)
{
return $(this).text() === txt;
});
$li.remove();
})

How to find number of <ul> inside each div

I have a large file of this form [similar div's throughout]. I want to be able to select a div, find the number of ul's in it and traverse through each of them to get value of each li in it.
<div class="experiment">
<div class="experiment-number">5</div>
<ul class="data-values">
<li><div></div> 14</li>
<li><div></div> 15</li>
</ul>
<ul class="data-values">
<li><div></div> 16</li>
</ul>
</div>
I have tried looping through all experiment divs, then select the uls, but it selects all the ul in the page, not only the ones under current div.
$('experiment ul').eq('$i');
Your HTML is currently incorrect, since you're simply starting new <div> and <ul> elements rather than closing the existing ones. Ignoring that because it's trivial to fix, we'll move on to the real issue.
You need to select all of the <div class="experiment"> elements, then iterate through them. To do that you can use the .each() function. It might look something like this:
var experiments = $('.experiment'); // all of them
experiments.each(function(i, val) { // will iterate over that list, one at a time
var experiment = $(this); // this will be the specific div for this iteration
console.log("Experiment: " + experiment.find('.experiment-number').text());
// outputs the experiment number
console.log("Experiment ULs: " + experiment.find('ul').length);
// number of <ul> elements in this <div>
var total = 0;
experiment.find('ul.data-values li').each(function() {
total += parseInt($(this).text(), 10);
});
console.log("Experiment total: " + total);
// outputs the total of the <li> elements text values
});
Take a look at this jsFiddle demo.
to get all the ul inside div.experiment
var ul = $('.experiment').find('ul');
and to get all li elements inside each ul found above
ul.each(function(list) {
var li = $(list).find('li');
});
$('.experiment').each(function() {
var cnt = $(this).children('ul').length;
$(this).find('.experiment-number').text(cnt);
});
First of all you need to work out the correct selector for each DIV.
The selector you want is:
".experiment"
Notice the . to denote a class selector.
This will allow you access to each DIV element. If you then want to loop though each of these, you can do so like this:
$(".experiment").each(function(){
var div = $(this);
var elementsInThisDiv = div.find("ul");
//you now have a list of all UL elements in the current DIV only
var numberOfElements = elementsInThisDiv.length;
//you now have a count of UL elements belonging to this DIV only
//you can loop the UL elements here
$(elementsInThisDiv).each(function(){
var ul = $(this);
//do something with the UL element
//like get the LI elements...
var liElements = ul.find("li");
});
});
IMPORTANT: There is also an error with your HTML, you need to close your <ul> elements correctly using </ul>

highlite text parts with jquery, best practice

i have a list of items containig names.
then i have a eventlistener, which ckecks for keypress event.
if the user types i.g. an A all names starting with an A should be viewed with the A bold. so all starting As should be bold.
what is the best way using jquery to highlite only a part of a string?
thanks for your help
Here's a function you can call during your keypress event to highlight a search string:
function Highlight(search)
{
$('ul > li').each(function() {
if (this.innerHTML.indexOf(search) > -1)
{
var text = $(this).text();
text = text.replace(search, "<span id='highlight' style='font-weight: bold'>" + search + "</span>");
$(this).html(text);
}
else
{
this.innerHTML = $(this).text();
}
});
}
Test html:
<ul id='list'>
<li>Bob Jones</li>
<li>Red Smith</li>
<li>Chris Edwards</li>
</ul>
It's not quite as elegant as Pointy's answer, but it handles the matching strings requirement.
There are jQuery plugins to do text highlighting, but I've not seen one that highlights parts of words.
One possible solution would be to put all your names on the page with the first letter surrounded by a <span> tag, with a class:
<span class='A FL'>A</span>ugustine
<span class='C FL'>C</span>arlos
You can then use jQuery to fiddle with those by class name.
$('whatever').keypress(function(ev) {
var k = e.which.toUpperCase();
$('#textContainer span.FL').css('font-weight', 'normal');
$('#textContainer span.' + k).css('font-weight', 'bold');
});
Note that bold characters are fatter than normal characters, so this is going to have a "wiggly" effect that your users might not like. You might consider changing color instead.
thanks for your help...
i figured it out and the detailed resolution comes here:
var communities = $('#mylist').find('.name');
var temp_exp = new RegExp("^("+match_string+")","i");
communities.each(function(i){
var current = $(this);
var name = current.text();
name = name.replace(temp_exp, '<b>$1</b>');
current.html(name);
});
while all items have to have the class "name".

Categories

Resources